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 测试
This commit is contained in:
+21
-6
@@ -111,7 +111,10 @@ describe("Cloudflare OAuth(真实授权,Connect Cloudflare Account)", () => {
|
||||
await authedFetch(t, cookie, `http://localhost/api/domains/${example.id}/setup`, { method: "POST" })
|
||||
).json()) as { ok: boolean; error?: string };
|
||||
expect(setup.ok).toBe(true);
|
||||
expect(cf.hit("POST", "/zones/zone-example/email/routing")).toBe(true);
|
||||
// 开启 Email Routing 必须是 PUT(POST 到同一路径是 10405,桩会拒)
|
||||
expect(cf.hit("PUT", "/zones/zone-example/email/routing")).toBe(true);
|
||||
expect(cf.calls.some((c) => c.method === "POST" && c.path === "/zones/zone-example/email/routing")).toBe(false);
|
||||
expect(cf.bodyOf("PUT", "/zones/zone-example/email/routing")).toContain('"enabled":true');
|
||||
expect(cf.hit("PUT", "/zones/zone-example/email/routing/rules/catch_all")).toBe(true);
|
||||
const after = (await (
|
||||
await authedFetch(t, cookie, "http://localhost/api/domains")
|
||||
@@ -346,8 +349,8 @@ describe("Cloudflare OAuth(真实授权,Connect Cloudflare Account)", () => {
|
||||
await authedFetch(t, cookie, "http://localhost/api/oauth/cloudflare/start")
|
||||
).json()) as { url: string };
|
||||
const scope = new URL(start.url).searchParams.get("scope") ?? "";
|
||||
// 默认只请求接入必需的三项(账号名权限可选,缺失时从 zone 反推)
|
||||
expect(scope).toBe("zone.read workers-scripts.write email-routing-rule.write");
|
||||
// 默认请求接入必需的四项(最后一项 zone-settings.write 用于开启 Email Routing)
|
||||
expect(scope).toBe("zone.read workers-scripts.write email-routing-rule.write zone-settings.write");
|
||||
expect(scope).not.toContain(":");
|
||||
|
||||
// settings 里自定义 scope 后生效
|
||||
@@ -439,8 +442,15 @@ describe("Cloudflare OAuth(真实授权,Connect Cloudflare Account)", () => {
|
||||
expect(res.error).toBe("invalid_request");
|
||||
expect(res.hint).toContain("Redirect URL");
|
||||
|
||||
// 默认 scope(三项)全被授权 => 直接通过
|
||||
installCloudflareMock({ scopesAllowed: ["zone.read", "workers-scripts.write", "email-routing-rule.write"] });
|
||||
// 默认 scope(四项)全被授权 => 直接通过
|
||||
installCloudflareMock({
|
||||
scopesAllowed: [
|
||||
"zone.read",
|
||||
"workers-scripts.write",
|
||||
"email-routing-rule.write",
|
||||
"zone-settings.write",
|
||||
],
|
||||
});
|
||||
res = (await (
|
||||
await authedFetch(t, cookie, "http://localhost/api/oauth/cloudflare/preflight")
|
||||
).json()) as PreflightBody;
|
||||
@@ -473,7 +483,12 @@ describe("Cloudflare OAuth(真实授权,Connect Cloudflare Account)", () => {
|
||||
]),
|
||||
);
|
||||
expect(res.scopes.allowed).toEqual(
|
||||
expect.arrayContaining(["zone.read", "workers-scripts.write", "email-routing-rule.write"]),
|
||||
expect.arrayContaining([
|
||||
"zone.read",
|
||||
"workers-scripts.write",
|
||||
"email-routing-rule.write",
|
||||
"zone-settings.write",
|
||||
]),
|
||||
);
|
||||
|
||||
// App 什么都没勾时:全部候选都算待勾选
|
||||
|
||||
Reference in New Issue
Block a user