visionA/docs/autoflow/07-delivery/phase-0.6-handover.md
jim800121chen fb7da5d180 chore(autoflow): migrate .autoflow/ 共享層文件至 docs/autoflow/
依 autoflow-agent workspace v2 設計把 PRD / 設計 / 架構 / 交付類
共享文件從個人層 .autoflow/(ignored)搬到 docs/autoflow/(進 git),
讓團隊可共享產品與架構文件,個人層只留 progress / review / testing 等
per-branch 筆記。

- 02-prd/        21 個檔(PRD、features、market-analysis 等)
- 03-design/     18 個檔(design-spec、wireframes、flows 等)
- 04-architecture/ 31 個檔(TDD、design-doc、ADR×14、API 規格等)
- 07-delivery/   3 個檔(project-summary、phase-0.6-handover、stage-deployment-setup)

合計 73 檔。原檔已從 .autoflow/ 移除(migration 工具執行 git mv,
但因 .autoflow/ 在 .gitignore 中、git 將此操作視為新增、無 rename history)。
2026-05-04 16:55:55 +08:00

185 lines
7.9 KiB
Markdown
Raw Permalink 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.

# Phase 0.6 OIDC 接入 — 交接摘要
> 日期2026-04-26
>
> 範圍visionA-backend StaticAuthProvider → Innovedus Member Center OIDCBFF Pattern + Authorization Code + PKCE
>
> 上位文件:`.autoflow/04-architecture/oidc-tdd.md`、`.autoflow/04-architecture/adr/adr-010-oidc-bff.md`、`.autoflow/04-architecture/adr/adr-011-supersede-static-auth.md`
>
> 整體交付:見 `.autoflow/07-delivery/project-summary.md`
---
## 1. Phase 0.6 完成項目
### BackendOB1-OB6
- **OB1** `internal/oidc/`coreos/go-oidc 包裝discovery + JWKS + token exchange + id_token 驗簽24 tests / 93.4% 覆蓋)
- **OB2** `internal/usersession/`in-memory session store + cookie HMAC 簽章24 tests
- **OB3+OB4** `internal/api/middleware/auth.go` + 4 個 OIDC handler`/api/auth/login` / `/callback` / `/logout` / `/me`14 tests
- **OB5** 完全移除 `StaticAuthProvider`、AuthenticatedClient fixture 統一17 packages 全綠 / oidc_e2e build tag 移除)
- **OB6** ADR-011 推翻 ADR-005 Auth 部分DB 部分仍有效)
### FrontendOF1-OF2
- **OF1** login 頁改 OIDC redirect 按鈕11 tests + i18n
- **OF2** API client `credentials: 'include'`、auth-store 拔 localStorage、改 cookie session107 tests 綠)
### FrontendOF3-OF4
- **OF3** register 頁移除、account 接 `/api/auth/me`(待補)
- **OF4** i18n 補齊(待補)
### DevOpsOD1
- 5 service docker-composepostgres / member-center / member-center-web / member-center-init / visiona-api / visiona-proxy全 healthy
- `docs/DEV-SETUP.md` 完整 setup + 故障排除(含 §7.6 OIDC flow 階段問題)
### DevOpsOD2
- `make dev-with-mc` Makefile target + `.env.example` 整理待補MC bug 修復後加 seed script
### TestingOT1
- `internal/oidc/oidctest/`fake OIDC server自簽 JWKS / 模擬 authorize / token endpoints
- `internal/api/handlers/oidc_e2e_test.go`6 個 e2e cases`PairingTokenBindsToOIDCUser`,驗 OIDC sub 真的有貫通到 PairingStore
- 17 packages 全綠 / build tag 已拿掉(合進主測試)
### TestingOT2範圍調整
- 因 MC 兩個 bug 阻擋自動 e2epassword grant 缺 sub claim、admin API 不接受 client_secret原訂「真 MC e2e」改為
- `docs/SMOKE-TEST.md`:完整 7 階段手動煙測 checklist
- `docs/DEV-SETUP.md` §7.6 補 OIDC flow 故障排除對照表
- 真 MC 自動 e2e 列入 Phase 1 TODO待 MC 修 bug
---
## 2. 跑通的 Demo
### Demo AOIDC Flow手動需先依 `docs/DEV-SETUP.md` §5 註冊 OAuth client
**端到端使用者旅程**(對應 `docs/SMOKE-TEST.md` 階段 3-7
```
[browser] http://localhost:3000/login
↓ 點「使用您的 Innovedus 帳號登入」
[backend] GET /api/auth/login
↓ 產 PKCE + state + nonce存 pending session10 分鐘 TTL
↓ Set-Cookie: visiona_pending_sid
↓ 302 to MC /oauth/authorize?response_type=code&...&code_challenge=...
[MC] http://localhost:5050/oauth/authorize
↓ 顯示登入頁 → demo@visiona.local / Demo12345!
↓ 同意授權
↓ 302 back to http://localhost:3721/api/auth/callback?code=...&state=...
[backend] GET /api/auth/callback
↓ 驗 stateCSRF
↓ POST MC /oauth/token (code + verifier + client_secret)
↓ 驗 id_tokeniss / aud / exp / nonce / JWKS 簽章)
↓ 建 visionA sessionuser_id = OIDC sub, 7d / 24h idle
↓ Set-Cookie: visiona_session
↓ 302 to http://localhost:3000{return_to}
[browser] dashboard 顯示已登入 demo user
↓ 後續 API request 自動帶 visiona_session cookie
[backend] /api/devices /api/models /api/auth/me 全帶 cookie 認證
```
### Demo BPairing Token 綁 OIDC user關鍵承諾驗證
**目的**:驗證取代 StaticAuth 後pairing token 不再綁 `demo-user` 而是真實 OIDC sub。
```
[browser] /devices/pair → 點「產生 Pairing Token」
[backend] POST /api/pairing/token (cookie: visiona_session)
↓ middleware 解 cookie → UserContext{UserID: <OIDC sub>}
↓ PairingStore.Create(userID=<OIDC sub>, token=vAc_xxx)
↓ log: "PairingStore Create userID=<UUID>"
[browser] 拿到 token vAc_xxx
↓ 餵給 local-tool agent
[agent] 連 visiona-proxy → 帶 pairing token → 換 session token
[backend] agent 連入 → 後端 binding user_id 是 OIDC sub與 step 2 一致)
```
### Demo Cfake OIDC e2e自動化
```
go test ./internal/api/handlers/... -run TestOIDCE2E
```
跑完含 6 個 case
- LoginRedirectsToProvider
- CallbackCreatesSession
- StateMismatchRejected
- NonceMismatchRejected
- ExpiredTokenRejected
- **PairingTokenBindsToOIDCUser**(最關鍵)
17 packages 全綠 / build tag 已合進主測試。
---
## 3. 手動 Demo Flow
完整步驟見 **`docs/SMOKE-TEST.md`**7 階段 / 預估 30 分鐘:
| 階段 | 內容 | 時間 |
|------|------|------|
| 1 | 基礎服務驗證5 service + frontend healthy| 5 min |
| 2 | MC 設定(建 tenant + OAuth client + demo user| 10 min |
| 3 | 完整 Login Flowredirect chain 走完)| 5 min |
| 4 | API 帶 Cookie 驗證(/me + /devices + /models| 3 min |
| 5 | Pairing Token 綁 OIDC user**關鍵承諾**| 5 min |
| 6 | 登出 + 重登 | 3 min |
| 7 | 跨頁 Refresh / 持久化 | 2 min |
每個階段都有對應的「故障排除 #N」可查;卡住先看 `docs/SMOKE-TEST.md` §故障排除 + `docs/DEV-SETUP.md` §7。
---
## 4. 已知 Limitation
| # | Limitation | 影響範圍 |
|---|-----------|---------|
| 1 | MC admin API 不能 seed OAuth clientpassword grant + client_secret 兩個 bug| §2 OAuth client 註冊必須手動走 Web UI自動 e2e blocked |
| 2 | MC 只支援 `usage=webhook_outbound` 帶 redirect_uris | 雛形借用,命名語意不對 |
| 3 | visionA-backend in-memory session store 重啟即消失 | 所有 user 重登 |
| 4 | 沒有 RP-initiated logout | 登出 visionA 不會把 MC session 也登出 |
| 5 | 沒有 refresh token rotation | 24h idle / 7d absolute 後必須重登 |
| 6 | host visiona-locallocal-tool佔 3721 與 docker compose 衝突 | 兩個只能擇一跑 |
---
## 5. Phase 1 TODO
### MC teamunblock visionA 自動化)
- [ ] **MC-1** 修 password grant Identity user 缺 sub claim → 500 bug
- [ ] **MC-2** admin API 接受 + 回傳 client_secret
- [ ] **MC-3** 新增 `usage=web_app` OAuth client 類型
### visionA Phase 1
- [ ] **OD2** `make dev-with-mc` + `make dev-seed` script依賴 MC-1 + MC-2
- [ ] **OT2 補完** 真 MC 自動 e2e用 testcontainers 起真 MC把 SMOKE-TEST §3-§7 全自動)
- [ ] **OF3 OF4** register 頁移除 + account 改造 + i18n 補齊
- [ ] **OB-Phase1-1** in-memory session store → Redis
- [ ] **OB-Phase1-2** RP-initiated logoutOIDC end_session_endpoint
- [ ] **OB-Phase1-3** Refresh token rotation依賴 MC 上 refresh token 支援)
- [ ] **OB-Phase1-4** Member Center webhookuser 刪除 / 停用通知)
---
## 6. 相關文件索引
| 主題 | 文件 |
|------|------|
| 架構決策 | `.autoflow/04-architecture/adr/adr-010-oidc-bff.md``adr/adr-011-supersede-static-auth.md` |
| TDD含時序圖、模組設計、env、安全考量| `.autoflow/04-architecture/oidc-tdd.md` |
| Dev 環境 setup | `docs/DEV-SETUP.md` |
| 手動煙測 | `docs/SMOKE-TEST.md` |
| 整體 visionA 交付 | `.autoflow/07-delivery/project-summary.md` |
---
## 7. 驗收狀態
- [x] 端到端 redirect chain 通fake OIDC e2e 自動驗)
- [x] Pairing token 綁 OIDC subOT1 PairingTokenBindsToOIDCUser ✅)
- [x] StaticAuthProvider 完全移除OB5 ✅)
- [x] Frontend 完全不接觸 tokenOF1 + OF2 ✅)
- [x] docker-compose 一鍵起 5 serviceOD1 ✅)
- [x] 手動煙測 checklist 完整OT2 ✅,本文件對應)
- [ ] OF3 + OF4 完成(待補;不阻擋 Phase 0.6 驗收,列入 Phase 1
- [ ] OD2 Makefile + seed script依賴 MC bug 修復;列入 Phase 1
- [ ] 真 MC 自動 e2e依賴 MC bug 修復;列入 Phase 1