portal-auth P2(#24 #25):portal_user 模型+認證 API(不 merge,待總管審) (#51)

This commit was merged in pull request #51.
This commit is contained in:
Leo
2026-07-14 04:19:54 +00:00
parent 7f409646e5
commit 1260d8cffb
11 changed files with 1372 additions and 14 deletions
+23 -8
View File
@@ -41,14 +41,29 @@
## P2 — portal_user 模型+認證 APIdesign §2/§4)|觸碰:`cypher-executor/`(新 route 檔)
- [ ] seed template `portal_user``portal_library`init-seed 慣例)
- [ ] PBKDF2-SHA256 雜湊模組(600k iters、常數時間比對、`pbkdf2-sha256$…` 格式)
- [ ] `POST /portal/admin/bootstrap`console owner session 閘)
- [ ] login/logout/session/改密碼(KV `portal_sess:`、TTL var、每請求回讀 record 驗 status
- [ ] admin 用戶 CRUDlibraries 授權+庫目錄 CRUDrole=admin 閘
- [ ] 登入失敗節流(5 次/15 分鐘,KV TTL
- [ ] 順手修 `record-crud.ts` updateRecord grow 路徑漏 owner_iddesign §2.2 附帶)
- [ ] 測試:bootstrap 閘、登入對錯、停用即拒(session 立即失效)、role 閘、雜湊格式、`{tenant}::portal` 子 namespace 隔離(**搜 email 搜不到**
- [x] seed template `portal_user``portal_library`init-seed 慣例)
- 實作註(2026-07-14):種子資料 `cypher-executor/src/lib/portal-seeds.ts`*-seeds.ts 慣例類別);
冪等 ensure 在 `routes/portal.ts` `ensurePortalTemplates()`,掛進 `POST /init/seed`(回應加
`portal_templates` 區塊)+ bootstrap 前自動 ensure(沒跑過 seed 也能 bootstrap)。
- [x] PBKDF2-SHA256 雜湊模組(600k iters、常數時間比對、`pbkdf2-sha256$…` 格式
- `cypher-executor/src/lib/portal-auth.ts`WebCrypto deriveBitsverify 從儲存格式解析 iterations
→ 換 KDF/參數可共存漸進遷移;constantTimeEqual 同 mcp PR#15 實作)。
- [x] `POST /portal/admin/bootstrap`console owner session 閘
- [x] login/logout/session/改密碼(KV `portal_sess:`、TTL var、每請求回讀 record 驗 status
- `PORTAL_SESSION_TTL` 進 wrangler.toml [vars]types.ts(預設 604800)。
- [x] admin 用戶 CRUDlibraries 授權+庫目錄 CRUDrole=admin 閘)
- 安全註:admin 操作目標 record 需過「email head entry 指回同 record_id」成員驗證(防拿任意
record_id 改到不相干 KBDB record);列表/回應一律剝除 password_hash;未帶密碼建帳號 →
server 產一次性密碼隨回應回傳一次(不落地明碼)。
- [x] 登入失敗節流(5 次/15 分鐘,KV TTL
- [x] 順手修 `record-crud.ts` updateRecord grow 路徑漏 owner_iddesign §2.2 附帶)
- 修法:首查 JOIN entries 帶回 record 既有 owner_idgrow 的新 entry 沿用。回歸測試
`kbdb/tests/record-grow-owner.test.ts`3 項:帶 owner/原無 owner 維持 null/非 grow 不 INSERT)。
- [x] 測試:bootstrap 閘、登入對錯、停用即拒(session 立即失效)、role 閘、雜湊格式、`{tenant}::portal` 子 namespace 隔離(**搜 email 搜不到**
- 單元:`cypher-executor/tests/portal-auth.test.ts` 20 項(fetchMock 假 KBDB host,絕不外連);
cypher 全套 133/134(唯一失敗=executor「不存在的零件」pre-existingstash 複驗);kbdb 20/20
兩包 tsc exit 0。端到端:本機雙 worker(隔離 persist33/33 全綠,含**搜尋隔離實測**
(租戶 ns 搜 email/雜湊 0 筆+對照組 leo::portal 搜得到=非假綠)與明碼落地抽查 0 筆。
- **驗收**=#25 驗收):新增用戶能登入;停用登入被拒+既有 session 失效;KBDB 無新表;密碼抽查非明碼
- **工程量**:中(約 1 個 CC 工作天)