Files
Arcrun/cypher-executor/wrangler.test.toml
T
uncle6me-web c4cee35adb feat(auth): 認證與資料分離——搬動知識資料時登入不再跟著壞掉(D61 / arcrun-rag#55)
leo 2026-08-10 下令:「登入認證資料要分離⋯⋯就算只有我一個人存在單獨的 json 檔也好,
它不能被改資料庫的連結導致無法登入。」「昨天不能登入 portal,今天不能登入 mcp,
這根本就是一個問題。」

病:portal 帳號住 KBDB(owner_id = {CONSOLE_TENANT}::portal),console 管理員帳密住
SESSIONS_KV。兩者都靠 binding 指過去,重裝/遷移一定會被重新指一次 ⇒ 保險箱的鑰匙
放在保險箱裡。2026-08-09 leo 資料一個位元組都沒動,卻被鎖在門外。

修:認證搬到 CF Workers per-script Secrets(掛在 script 上,與 bindings 兩套資源,
重部不會洗掉;journeys/gemini-key-lost-on-reinstall.md 與 installer worker.js:1148 皆有實證)。
- 新增 lib/portal-auth-store.ts:自足的 JSON,讀取零網路呼叫,>4.6KB 自動溢位分片
- portal.ts 的帳號讀寫全部改走它;KBDB 只留為舊實例的回退讀路徑,登入成功順手搬過去
- console-auth.ts 的第二份認證資料同樣搬離 KV
- 不牴觸 D38:KBDB 三張核心表不增不減,本案是把東西搬出去
- 沿用 credentials.ts 既有的 putWorkerSecret/deleteWorkerSecret,不另造第二套寫入路徑(D36)

明顯失敗(把 #10「寧可明顯失敗,不要靜默錯置」套到門鎖上):
- 「這台實例讀不到任何登入資料」回 503 + code=auth_store_empty,且**不計入 5 次鎖定**
  (08-09 leo 就是被系統自己的誤判鎖了 15 分鐘)
- /console/setup 遇既有帳號改說「你剛才輸入的密碼沒有被採用」,不再只說「已設定過」
- /health 與 /console/auth-status 吐 auth_store 狀態(住哪、寫不寫得進去)

stage 實測撞到並修掉的坑:改 secret 會產生 worker 新版本,既有 isolate 讀到的還是舊 env
⇒ 「建好帳號立刻登入」有 15 秒以上 401,還被算進鎖定。加一層短 TTL 的 KV 加速器
(非真相源,只在 secret 查不到/密碼對不上時問一次),換 KV 不影響不變量。

驗收:stage(youlin)把知識資料庫換成另一顆空的 + 換租戶代號 + SESSIONS_KV 換成空的,
三樣一起換之後 portal / MCP /authorize / console 三條登入路徑仍全綠(複跑 3 次)。
對照組(舊版程式碼同樣換庫):登入回「email 或密碼錯誤」,5 次後鎖 15 分鐘。

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-08-10 14:13:37 +08:00

60 lines
2.3 KiB
TOML
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
name = "arcrun-cypher-executor"
main = "src/index.ts"
compatibility_date = "2025-02-19"
compatibility_flags = ["nodejs_compat"]
# 測試環境不啟用 Service BindingMiniflare 無法解析外部服務)
# 2026-06-04:移除 WASM_BUCKET R2 mock。R2 wasm 路徑已 dead,不再需要測試 mock。
# KV mockBUILD-006
[[kv_namespaces]]
binding = "EXEC_CONTEXT"
id = "test-exec-context"
[[kv_namespaces]]
binding = "WEBHOOKS"
id = "test-webhooks"
[[kv_namespaces]]
binding = "CREDENTIALS_KV"
id = "test-credentials-kv"
[[kv_namespaces]]
binding = "RECIPES"
id = "test-recipes"
# console session mock(分流台勾掉 route 測試;console-auth.ts 的 session 真身存這個 KV
[[kv_namespaces]]
binding = "SESSIONS_KV"
id = "test-sessions-kv"
# portal-auth P3/portal/data/workflows 讀最近執行(stats:{name}:{ts}
[[kv_namespaces]]
binding = "ANALYTICS_KV"
id = "test-analytics-kv"
# credential-store-migration T8/T9 測試用 D1 mockMiniflare 本地 SQLite,非真實 leo21c D1
# schema 由 tests/setup.ts 在測試啟動時建表,不用 migrations_dir——0002_credentials.sql 就一張表,
# 直接 exec 比接 migrations 機制簡單)
[[d1_databases]]
binding = "CREDENTIALS_DB"
database_name = "test-credentials-db"
database_id = "test-credentials-db-id"
[vars]
ENVIRONMENT = "test"
# 分流台勾掉 route 測試:KBDB 指到假 hostfetchMock 攔截,絕不外連——尤其不打官方 uncle6 fallback
KBDB_BASE_URL = "https://kbdb.test"
CONSOLE_TENANT = "leo"
# portal-auth P3graph 粗閘放行後的轉發目標也指假 host(fetchMock 攔截,絕不外連)
KBDB_GRAPH_URL = "https://graph.test"
# D61ADR D61 / Leo/arcrun-rag#55):認證儲存(lib/portal-auth-store.ts)走 CF Workers
# Scripts secrets 管理 APIhttps://api.cloudflare.com/...),authStoreWritable() 只看這兩項
# 存不存在。測試環境預設就緒(比照真實已裝妥的實例),值是明顯的假字串、非真實金鑰;實際的
# PUT/DELETE 呼叫一律靠 tests/*.ts 裡的 fetchMock 攔截,不外連。要測「寫入路徑未就緒」
# 的分支才需要繞過 SELF、直接呼叫 router.fetch(req, fakeEnv, ctx) 帶缺項的 env(見
# tests/health.test.ts 既有前例)。
CF_SECRETS_API_TOKEN = "test-fake-not-a-real-token" # credential-ok:測試假值,見上方註解
CF_ACCOUNT_ID = "test-account"