c4cee35adb
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>
60 lines
2.3 KiB
TOML
60 lines
2.3 KiB
TOML
name = "arcrun-cypher-executor"
|
||
main = "src/index.ts"
|
||
compatibility_date = "2025-02-19"
|
||
compatibility_flags = ["nodejs_compat"]
|
||
|
||
# 測試環境不啟用 Service Binding(Miniflare 無法解析外部服務)
|
||
|
||
# 2026-06-04:移除 WASM_BUCKET R2 mock。R2 wasm 路徑已 dead,不再需要測試 mock。
|
||
|
||
# KV mock(BUILD-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 mock(Miniflare 本地 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 指到假 host(fetchMock 攔截,絕不外連——尤其不打官方 uncle6 fallback)
|
||
KBDB_BASE_URL = "https://kbdb.test"
|
||
CONSOLE_TENANT = "leo"
|
||
# portal-auth P3:graph 粗閘放行後的轉發目標也指假 host(fetchMock 攔截,絕不外連)
|
||
KBDB_GRAPH_URL = "https://graph.test"
|
||
# D61(ADR D61 / Leo/arcrun-rag#55):認證儲存(lib/portal-auth-store.ts)走 CF Workers
|
||
# Scripts secrets 管理 API(https://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"
|