bigcode
|
c4b5e65159
|
v2.6.0: 接入不再自动建 catch-all 邮箱(手动添加);删除账号/域名时清理 Cloudflare 侧资源(关闭 Email Routing + 删除 Email Worker,尽力而为+告警)
|
2026-10-01 02:19:30 +08:00 |
|
bigcode
|
8c5ed7fc8b
|
v2.4.1 回读校验收紧到 status:SPF 冲突(misconfigured)不再谎报已配置
实测 adx9.com 全链路时发现的新缺口:/enable 成功后 enabled=true,但 zone 的
Email Routing status 可能仍是 misconfigured(SPF 指向旧邮件服务)——
照 v2.4.0 的校验(enabled===true)照样会把域名标成「已配置」,而邮件根本不会投递,
与 MX 假成功是同一类问题。
- cfapi: 回读校验增加 status 判定:
- ready / unlocked(过渡态,实测邮件照常投递)视为成功
- misconfigured* 判失败,并把状态对象里的 errors 翻译成中文
(spf.foreign = 现有 SPF 指向其它邮件服务;spf.missing = 给出应替换的 SPF 内容)
- cf-mock: 读回的状态随 emailRoutingStatusAfterEnable 可配置
- oauth.test 新增 2 例:misconfigured 判失败(不标 active)、unlocked 视为成功
线上排查记录(2026-09-30,已手工修复):
adx9.com 删除自建 MX(10 mx.adx9.com)→ POST /email/routing/enable 成功但
status=misconfigured/locked(errors: spf.foreign/spf.missing)→ PATCH
/email/routing/dns(unlock)→ 替换 SPF TXT 为 v=spf1 include:_spf.mx.cloudflare.net
~all → Graph API 发测试邮件 → Console 收到(msg_7eb6afeba6179293),全链路打通。
|
2026-09-30 22:18:13 +08:00 |
|
bigcode
|
ecce90dfab
|
v2.4.0 修 Email Routing 假成功 + 加 API Token 接入与邮箱/域名页交互改进
问题 6(收不到邮件、Dashboard 邮件路由里看不到域名)的根因:
上一版把「开启 Email Routing」改成了 PUT /zones/{id}/email/routing,
但实测该接口(以及 PATCH)是**纯回显** —— 返回 success:true 但 enabled 纹丝不动,
域名在 Cloudflare 侧仍是 unconfigured、连 MX 记录都没有。Console 却照它的返回值
把域名标成「已配置 Email Workers」,于是「显示配好了却收不到邮件」。
实测只有 POST /zones/{id}/email/routing/enable 真的开启(线上对 adx9.com 与
galaxyemail.com 逐一验证)。
后端
- cfapi: 改用 /enable,并在开启后回读 GET 校验 enabled===true,不满足即判失败;
新增 CFApiError(带 Cloudflare 错误码)与 getEmailRoutingSettings
- cfapi: 错误码 2008(Non-Cloudflare MX records exist)翻译成中文并点名冲突的 MX 记录
- provision: Email Worker 统一命名 wmailhub-email(原先按账号 id 拼名),
部署走 PUT,同名即覆盖更新
- db: 新增 decryptAccountToken —— 按账号取 token,不再取「最近一条连接」,
并跳过已过期的 OAuth token;oauth_connections.account_id 真正写入
- resources: 新增 POST /api/accounts/token(API Token 方式添加账号):
先校验 token 与账户 ID,确认可用才建账号并自动接入
前端
- 账号:「添加账号」改为模态窗口,OAuth / API Token 两个 tab,各自带说明
- 域名: 删除「Email Worker」列;「设置 Email Workers / 重新配置」先弹确认框
(说明会改 MX 与路由),执行期间按钮 loading 且互相禁用;error 状态改成可读的 Alert + 重试
- 邮箱: 删除「状态」列(已由「启用」开关承担);地址列加复制按钮(带弹跳+变绿动画);
「添加邮箱」窗口的域名只列已装 Email Workers 的、支持搜索、默认选中最近使用的域名;
地址框可一键从 namedb 取随机用户名;勾选 catch-all 后地址框禁用
- 收件箱: 域名筛选只显示已装 Email Workers 的域名
测试
- cf-mock 复刻「PUT/PATCH 回 success 但不改 enabled」与 2008,锁住本次修复
- oauth.test 新增 4 例:2008 冲突、回读校验、API Token 接入、Token/账户 ID 校验失败
- ui-smoke 覆盖新增的添加账号/添加邮箱/确认框等交互(28/28 通过)
文档: docs/02 补「三种开启接口只有 /enable 有效」的实测表、2008 处理、
两种接入方式与按账号取 token 的说明
|
2026-09-30 18:20:44 +08:00 |
|
bigcode
|
e7db6762fd
|
fix(email): 开启 Email Routing 改用 PUT,并补上 zone-settings.write 权限
POST /zones/{id}/email/routing 不是有效路由,Cloudflare 返回
10405 Method not allowed for this authentication scheme。正确接口是
PUT /zones/{id}/email/routing(Apply Email Routing settings);
POST .../email/routing/enable 能用但官方已标 Deprecated。
该接口的 Accepted Permission 是 Zone Settings Write,而不是 Email Routing 权限族
—— 权限名和接口所属资源组对不上,Email Routing 四个权限全勾也不够。
- CF_OAUTH_SCOPES_DEFAULT / 探测候选集加 zone-settings.write;设置页文案同步
- cfapi 的 API 错误带上 Cloudflare 错误码(如 10405),便于区分路径错与权限错
- cf-mock 对非 PUT 的 /email/routing 返回 10405,旧写法会被打回
- 88/88 测试
|
2026-09-30 17:26:29 +08:00 |
|
bigcode
|
42c488050b
|
fix(oauth): token 兑换改用 HTTP Basic(client_secret_basic),修 401
Cloudflare OAuth 客户端默认 token_endpoint_auth_method = client_secret_basic,
只接受 Authorization: Basic 头。之前把 client_id/secret 放在 POST body
(client_secret_post),token 端点直接 401 invalid_client,描述里点名
"method 'client_secret_post' was requested" —— 表现为 Cloudflare 授权成功、
回调却报 token exchange failed: 401。
- exchangeToken 改 Basic 认证,凭据按 RFC 6749 §2.3.1 先 form-urlencoded 再 base64
- 失败时带回 Cloudflare 原始 error/error_description;invalid_client 额外提示
「secret 只在创建时显示一次,轮换后旧值失效」
- cf-mock 复刻「只认 Basic」的行为,没有 Basic 头就返回 401(旧代码会被打回)
- 断言 token body 不含 client_id/client_secret,Basic 头解出正确凭据
- 88/88 测试
|
2026-09-30 17:16:14 +08:00 |
|
bigcode
|
5b887908e2
|
feat(oauth): 账号名改从 zone.account 取,去掉 account-settings.read 依赖
实测确认 GET /zones 每个 zone 自带 account {id,name},该接口只需 zone.read,
因此账号 id 与账号名都不必再调 GET /accounts(account-settings.read)。
顺带修掉 account_id 旧字段在当前响应里已为 null 导致的降级路径取不到账号 id。
- RealCFApi.discover 只列 /zones,移除 listAccounts 与 accountSource
- scope 候选集去掉 account-settings.read;设置页移除「含账号名权限」按钮
- 设置页 Scope 说明与 docs/02、README 同步(补 User Details Read 的区别说明)
- 85/85 测试通过(新增 zone 带 account / 不带 account 两种断言)
|
2026-09-30 17:03:59 +08:00 |
|
bigcode
|
7a1625d575
|
fix: v2.3.2 用探测确定真实 scope 词表,接入已实测可用
- 上一版默认 scope 名是猜的(account.read / email_routing.write),全部被拒。
正确词表是点号分隔的 <group>.<verb>,且:
- 账号是 account-settings.read(选择器里叫 Account Settings Read),不是 account.read
- Workers 脚本是 workers-scripts.write,不是 workers_scripts.write
- Email Routing 在选择器里是四个独立权限,改 catch-all 对应 email-routing-rule.write
- account:read 这种冒号写法是 wrangler 的第一方简写,第三方 client 一律被拒
- client 注册的 scope 是上限不是默认:没勾的权限即使账号有也不生效
- preflight 扩展 scope 探测:授权端点在同意页之前就校验并点名拒绝的 scope,
逐轮「请求剩余候选 -> 剔除被点名项」即可收敛出 App 已授权集合(未认证请求,
不登录/不产生授权),结果按 allowed/denied 返回并在设置页用绿/橙标签展示
- 缺少账号级读权限时不再失败:discover() 先试 /accounts,403 则改为列 token 可见的 /zones,
用 zone 自带的 account_id 反推账户(展示名用第一个域名)
- 默认 scope 收敛为接入必需的三项(zone.read / workers-scripts.write /
email-routing-rule.write),account-settings.read 改为可选:勾了才显示真实账号名
- 实测:线上 preflight 已 ok=true(Cloudflare 跳登录页),无需再改 App 即可「添加账号」
|
2026-09-30 16:26:43 +08:00 |
|
bigcode
|
1f4d45f719
|
fix: v2.3.1 Cloudflare OAuth scope 点号格式 + 授权失败可读提示 + 配置自检
- 根因:Cloudflare OAuth 的 scope 是点号分隔(account.read),冒号写法不被接受,
授权端点直接返回 error=invalid_scope。默认 scope 改为
account.read zone.read email_routing.write workers_scripts.write
- scope 可在设置页自定义(settings.cf_oauth_scopes),需与 App 登记值逐字一致
- 新增 GET /api/oauth/cloudflare/preflight + 设置页「检测授权配置」按钮:
只读探测授权端点(不跟随跳转),区分 登录同意页 / 弹回回调 / Cloudflare /oauth/error,
并把 invalid_scope、invalid_request 翻译成可执行的处置建议
- 回调端点处理 error 参数:不再拿空 code 去兑换 token,改为跳回账号页并弹窗说明原因
(此前会落到 SPA 404 空壳页)
- 账号页读取 ?oauth_error= 弹窗展示 Cloudflare 的原始描述
- docs/02 补 Cloudflare OAuth App 配置清单(Redirect URL / Client URI 域名校验 /
Promote to public / 点号 scope);83 个测试全通过
|
2026-09-30 16:08:27 +08:00 |
|
bigcode
|
e2c3c353cf
|
refactor: v2.2.0 移除本地 sim 模式,Cloudflare OAuth 只走真实授权
- 删除 SimCFApi / WMAILHUB_SIM_CF / isRealOAuth / POST /api/oauth/cloudflare/sim/approve
- 删除前端 OAuthSim 模拟授权页与 /oauth/sim/authorize 路由;账号页「添加账号」整页跳 Cloudflare
- 迁移 0005 删除 cf_sim_resources 表
- 未配置 CF_OAUTH_CLIENT_ID/SECRET 时 start/callback 一律 503(不再降级出假账号假资源)
- 修 OAuth 回调端点:跨站重定向不携带 SameSite=Strict 会话 cookie,改为由一次性 state 承担 CSRF 防护
- 测试改用 tests/cf-mock.ts 在 fetch 层拦截 Cloudflare API,断言真实 HTTP 调用(72/72 通过)
- 本地 dev 无账号时只拉起 Console 并提示人工授权,不再自动造账号
|
2026-09-30 15:33:58 +08:00 |
|