Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
24 commits
Select commit Hold shift + click to select a range
a654f4a
feat(auth): add independent email verification-code sign-in across cl…
bobleer Sep 15, 2026
d7bfebc
fix(deploy): include vendored engine patch in market build contexts
bobleer Sep 15, 2026
0468052
fix(auth): declare UTF-8 email body so codes render inline
bobleer Sep 15, 2026
fb21bf3
fix(auth): include MIME version for encoded text messages
bobleer Sep 15, 2026
3c38f05
fix(mobile): use nominal runtime locations in HarmonyOS adapters
bobleer Sep 15, 2026
13ea9ac
feat(auth): add branded HTML verification email with plain-text fallback
bobleer Sep 15, 2026
fd6a60a
fix(auth): use the application icon in verification emails
bobleer Sep 15, 2026
c3256f1
feat(auth): polish sign-in pages and use a dedicated browser popup
bobleer Sep 15, 2026
71823bc
fix(mobile): preserve control of the cross-origin sign-in popup
bobleer Sep 15, 2026
370e4a4
fix(auth): embed the original application logo in verification emails
bobleer Sep 15, 2026
ccedcd5
fix(account): show verified email and provide avatar fallbacks
bobleer Sep 15, 2026
27035e7
chore(markets): remove footer package policy taglines
bobleer Sep 15, 2026
390a296
feat(mobile): guide users through connecting their first device
bobleer Sep 15, 2026
098ebc6
fix(web): align chat app pairing card content
bobleer Sep 15, 2026
e76330c
Merge upstream/main into bob/email-code-login
bobleer Sep 15, 2026
45d9e92
fix(auth): carry client locale through sign-in and verification email
bobleer Sep 15, 2026
908aa9d
feat(auth): support explicitly configured private SMTP relays
bobleer Sep 15, 2026
49c80ed
docs(mail): allow sender addresses across the owned domain
bobleer Sep 15, 2026
074d680
docs(mail): add maintenance runbook and link email branding to website
bobleer Sep 15, 2026
6b0ca48
test(cli): keep mock model alive through cold terminal startup
bobleer Sep 15, 2026
cda758e
test(auth): verify persistent brute-force and send limits under concu…
bobleer Sep 15, 2026
2c68566
fix(auth): raise email send limits for self-hosted delivery
bobleer Sep 15, 2026
319e765
fix(auth): require eight-digit email verification codes
bobleer Sep 15, 2026
340dc33
fix(auth): harden token transactions and sign-in failure handling
bobleer Sep 15, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
57 changes: 57 additions & 0 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -135,6 +135,7 @@ indexmap = "2"
include_dir = "0.7"
aes = "0.8"
hmac = "0.12"
lettre = { version = "0.11.23", default-features = false }
hex = "0.4"
chardetng = "0.1.17"
encoding_rs = "0.8.35"
Expand Down
8 changes: 8 additions & 0 deletions assets/brand/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -42,3 +42,11 @@ icon containers with `node --test scripts/generate-brand-assets.test.mjs`.
by the release letter's connected animation rig. The gradients belong to this
illustration, not to the application theme. Vite bundles this source directly;
it is independent of the application icon generator and needs no PNG export.

Verification emails use the silver application mark on its black rounded-square
background, generated at
`src/miniapp-market-web/public/assets/openbitfun-email-app-icon.png`. The market build
publishes this stable anonymous image path for email clients; it contains no
recipient or verification data and does not require authentication.

The previous email mark URL remains available for already-sent messages.
1 change: 1 addition & 0 deletions deploy/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ Production origin restore and product deploys for the current OpenBitFun host
| [openbitfun-host/](openbitfun-host/README.md) | New-host restore: website, release mirror, Relay Nginx, New API boundary |
| [miniapp-market/](miniapp-market/README.md) | MiniApp market only |
| [skin-market/](skin-market/README.md) | Skin market only |
| [outbound-mail/](outbound-mail/README.md) | Send-only Postfix/OpenDKIM: auth integration, DNS, maintenance and rollback |

An Agent that is asked to move or rebuild the server starts at
`openbitfun-host/AGENTS.md`.
56 changes: 56 additions & 0 deletions deploy/miniapp-market/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -497,3 +497,59 @@ API 的 Relay/客户端。两个市场各自的网页仍在所属 Compose 项目
统一 callback 迁移时,先部署 auth 回调路由和服务配置,再在 GitHub OAuth App
设置中添加上述精确 Redirect URI。设置更新前,新发起的登录暂时无法完成。
旧市场 callback 路由作为 Cookie 会话完成端点保留,不扩大 Cookie Domain。

## 邮箱验证码发布补充

邮箱登录与 GitHub 登录是独立账号,不自动绑定或合并。部署前需同时验证身份服务、
当前版本 Relay 和 Skin 身份消费者;保留旧 GitHub 数字账号及旧授权启动行为。
客户端使用 `methods=all` 主动选择统一登录页,旧客户端继续走原 GitHub URL。

SMTP 配置单独存放在 `/etc/openbitfun-miniapp-market/smtp.env`,root:root 0600,
Compose 以可选 env_file 加载;不要将其复制到 checkout,也不要打印内容。
使用现有企业邮箱的 SMTP 配置,变量参见后端 README。不要复制收件人列表、测试
主题或 BCC 等与认证发信无关的配置。发件配置更新后需重建容器,核对
`emailAuthConfigured=true`。真实收件验收只向操作者明确指定的地址发送。

`/sign-in` 改为统一登录网页;auth vhost 仅新增 `/config` 和指定 login/email API,
验证码完成后经一次性 grant 跳转至 market host 设置 Cookie。登录票据放在 fragment,
Nginx 日志必须继续只记录 `$uri`,不能记录验证码 body 或 grant query。

migration 0002 保留原用户 ID 和外键,但旧 binary 不认识邮箱用户;发布后不能把
回退镜像当作数据库回滚。先完成两个市场的一致性备份和恢复演练,保留旧镜像,
出现问题优先向前修复;不得未经确认恢复备份或丢弃新增用户。

### 登录语言与验证码邮件

各端打开 `https://auth.openbitfun.com/sign-in` 时通过 `locale` 查询参数传递当前界面语言。
认证页优先使用该参数,其次使用已保存的语言和浏览器语言;别名遵循共享 i18n contract。
发送验证码请求可携带 `locale`(`en-US`、`zh-CN` 或 `zh-TW`),邮件主题、HTML 和纯文本使用同一语言。
旧客户端省略该字段或传入未知值时默认发送英文邮件,不影响验证码和令牌协议。

### Same-host outbound SMTP relay

完整维护流程见 [自建发信服务维护手册](../outbound-mail/README.md)。

For a send-only Postfix relay on the auth server, set `SMTP_SECURITY=local`,
`SMTP_HOST` to its literal loopback/private IPv4 address, `SMTP_PORT` to the
private listener port, and `SMTP_USERNAME` to the sender address. Leave
`SMTP_PASSWORD` unset. This explicit mode does not send credentials or use TLS;
use it only over loopback or an isolated same-host Docker bridge. Public IPs,
DNS names, and supplied passwords are rejected. Existing `ssl`/`starttls`
configurations retain certificate validation and authenticated delivery.

Bind Postfix only to loopback and the auth bridge gateway; restrict `mynetworks`
to loopback and the auth container's exact address, with `permit_mynetworks,
reject` relay/client restrictions. Recheck the container address after deployment.
Do not expose SMTP through a public Docker port or WAF. Restrict envelope senders
to the owned sender domain (for example, `*@openbitfun.com`), sign all its sender
addresses with OpenDKIM, and keep `relayhost` empty for direct
MX delivery. Enable opportunistic TLS for outbound delivery, persistent queues,
and systemd startup ordering after Docker. Keep DKIM private keys and any SMTP
configuration under root-controlled server paths, outside the repository.

Before switching production auth, publish a matching A/PTR identity, add the
outbound IP to the existing SPF record (never create a second SPF record), publish
DKIM, and establish DMARC. Keep existing MX records when inbound email remains
with another provider. Verify real delivery and recipient authentication headers;
SMTP queue acceptance alone does not prove delivery to the inbox. Preserve the
previous SMTP configuration for rollback until the new route is verified.
2 changes: 2 additions & 0 deletions deploy/miniapp-market/docker-compose.yml
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,8 @@ services:
- "127.0.0.1:9710:9710"
env_file:
- /etc/openbitfun-miniapp-market/market.env
- path: /etc/openbitfun-miniapp-market/smtp.env
required: false
environment:
MARKET_GITHUB_CALLBACK_URL: https://auth.openbitfun.com/api/v1/auth/github/callback
MARKET_BIND: 0.0.0.0:9710
Expand Down
8 changes: 8 additions & 0 deletions deploy/miniapp-market/market.env.example
Original file line number Diff line number Diff line change
Expand Up @@ -7,3 +7,11 @@ MARKET_GITHUB_CLIENT_SECRET=
MARKET_SESSION_SECRET=replace-with-at-least-32-random-bytes
MARKET_ADMIN_GITHUB_IDS=24753352
RUST_LOG=openbitfun_miniapp_market=info,tower_http=info

# Optional email-code sign-in. Production stores these in a separate root-only smtp.env.
# SMTP_HOST=smtp.qiye.aliyun.com
# SMTP_PORT=465
# SMTP_SECURITY=ssl
# SMTP_USERNAME=hello@openbitfun.com
# SMTP_PASSWORD=
# SMTP_FROM_NAME=OpenBitFun
4 changes: 2 additions & 2 deletions deploy/miniapp-market/nginx-auth.openbitfun.com.conf
Original file line number Diff line number Diff line change
Expand Up @@ -61,7 +61,7 @@ server {
}

location = /sign-in {
proxy_pass http://127.0.0.1:9710/miniapp/api/v1/auth/github/start;
proxy_pass http://127.0.0.1:9710/miniapp/auth/sign-in;
}
location = / {
proxy_pass http://127.0.0.1:9710/miniapp/auth/complete;
Expand All @@ -70,7 +70,7 @@ server {
proxy_pass http://127.0.0.1:9710/miniapp/auth/complete;
}
# Bearer-token APIs only; marketplace mutations are not exposed here.
location ~ ^/api/v1/(me|auth/desktop/(start|poll)|auth/(refresh|logout))$ {
location ~ ^/api/v1/(me|config|auth/desktop/(start|poll)|auth/login/(start|github)|auth/email/(send|verify)|auth/github/(start|callback)|auth/(refresh|logout))$ {
rewrite ^/api/v1/(.*)$ /miniapp/api/v1/$1 break;
proxy_pass http://127.0.0.1:9710;
}
Expand Down
Loading
Loading