[CLAUDE] Phase5.1/3.2: IDOR filter + SLA auto-approve job + admin password warning

IDOR filter ContractsController:
- ListContractsQueryHandler + ICurrentUser: non-admin chi thay HD minh la Drafter hoac role eligible phase hien tai
- GetContractQueryHandler + ICurrentUser: throw ForbiddenException neu truy cap HD khong lien quan
- GetEligiblePhases() internal static trong ListContractsQueryHandler — mirror GetMyInboxQueryHandler.PhaseActorRoles (Drafter/DeptManager → DangSoanThao/DangDamPhan/DangInKy, ProjectManager+PRO+CCM+FIN+ACT+EQU → DangGopY, CostControl → DangKiemTraCCM, Director+AuthorizedSigner → DangTrinhKy, HrAdmin → DangDongDau)

SLA Expiry BackgroundService (Phase 3 iteration 2 partial):
- Infrastructure/HostedServices/SlaExpiryJob MOI: BackgroundService moi 15 phut (delay 30s startup)
- Query Contracts WHERE SlaDeadline < UtcNow AND Phase NOT IN (DaPhatHanh, TuChoi)
- Map phase → next (happy path). Goi IContractWorkflowService.TransitionAsync voi actorUserId=null + Decision=AutoApprove + comment 'AUTO: het SLA phase X (Nh qua han)'
- Try-catch tung contract, 1 fail khong block batch
- Log structured: 'SlaExpiryJob: auto-approved contract {Id} {From} → {To}'
- Package Microsoft.Extensions.Hosting added to Infrastructure
- DI register AddHostedService<SlaExpiryJob>

Admin password warning (Phase 5.1):
- DbInitializer.WarnDefaultAdminPasswordAsync: check CheckPasswordAsync voi AdminPassword default → log WRN '⚠️  Admin user vẫn dùng password mặc định. ĐỔI NGAY trong production!'
- Chain vao InitializeAsync sau cac seed

E2E verified:
- Admin GET /contracts → total 1 (see all)
- Drafter GET /contracts → total 0 (IDOR filter, chua tao HD nao)
- API startup log: '⚠️  Admin user admin@solutionerp.local vẫn dùng password mặc định'
- Build + TS check → pass

Docs:
- STATUS.md: Phase 5.1 hau nhu xong (IDOR + admin warning + SLA job tick), cumulative BE 3900 LOC
- migration-todos.md: tick Phase 5.1 IDOR + admin warning, Phase 3 iter 2 SlaExpiryJob + E2E non-admin + admin warning
- session log 2026-04-21-1730-idor-sla-job.md

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
pqhuy1987
2026-04-21 13:15:14 +07:00
parent 11e61c9c39
commit 1b5ef2ed51
8 changed files with 267 additions and 19 deletions

View File

@ -2,9 +2,9 @@
> **Update rule:** trước khi bắt đầu 1 task → ghi row vào `🔥 In Progress`. Xong → chuyển sang `✅ Recently Done`.
**Last updated:** 2026-04-21 16:30
**Last updated:** 2026-04-21 17:30
## 📍 Phase hiện tại: **Phase 5.1 Security + Users Mgmt xong** — chờ Gitea URL để deploy Phase 5 prod
## 📍 Phase hiện tại: **IDOR + SLA Job xong** — gần đủ feature, chờ Gitea URL cho Phase 5 deploy prod
## 🔥 In Progress
@ -14,7 +14,8 @@ _(không có)_
| Ngày | Ai | Task | Commit |
|---|---|---|---|
| 2026-04-21 | Claude | **Phase 5.1 Security + Users Mgmt** — Security headers middleware (CSP, X-Frame-Options, Referrer-Policy, Permissions-Policy) + Identity account lockout (5 fail → 15min) + LoginHandler check IsLockedOut + AccessFailedAsync. BE Users CQRS 8 feature + UsersController 7 endpoint. FE admin `/system/users` — list + create + gán role + reset password + unlock + toggle active | (sắp commit) |
| 2026-04-21 | Claude | **IDOR + SLA Job + Admin warning** — ContractsController List/GetDetail filter theo role (non-admin chỉ thấy HĐ mình là Drafter hoặc role eligible phase). SlaExpiryJob BackgroundService auto-approve quá hạn mỗi 15min với Decision=AutoApprove. DbInitializer warn log khi admin vẫn dùng password default | (sắp commit) |
| 2026-04-21 | Claude | **Phase 5.1 Security + Users Mgmt** — Security headers + Identity lockout + LoginHandler check + Users CQRS + UsersController + FE `/system/users` | `11e61c9` |
| 2026-04-21 | Claude | **Phase 5 Prep** — BE rate limit + health check + Serilog file + HSTS + scripts deploy-iis/backup-sql + .gitea/workflows/deploy.yml + 4 guides + FE refresh token queue pattern | `46a2cab` |
| 2026-04-21 | Claude | **Phase 4 Report MVP + Docs Consolidation** — Dashboard KPI + Excel export + rules.md + architecture.md + schema-diagram.md + gotchas update 26 pitfalls | `fe7ad8e` |
| 2026-04-21 | Claude | **Phase 3 Workflow MVP** — 9 phase state machine + gen mã HĐ RG-001 | `7e957a7` |
@ -47,16 +48,18 @@ Session logs: [P0](changelog/sessions/2026-04-21-1045-phase0-scaffold.md) · [P1
- [ ] Smoke test end-to-end prod
- [ ] UAT 1 tuần 2-3 user thật
### Phase 5.1 Security — xong gần hết
### Phase 5.1 Security — hầu như xong
- [x] Security headers middleware (X-Content-Type-Options, X-Frame-Options, Referrer-Policy, Permissions-Policy, CSP)
- [x] Identity account lockout (5 fail → 15min, config-driven)
- [x] Password policy config-driven (default 8 dev, override prod `Identity:Password:RequiredLength`)
- [x] Password policy config-driven
- [x] LoginHandler check lockout + AccessFailedAsync + reset on success
- [x] BE Users management + FE admin UsersPage (tạo user test permission non-admin)
- [ ] IDOR check ContractsController (user không xem HĐ không liên quan)
- [x] BE Users management + FE admin UsersPage
- [x] IDOR check ContractsController (non-admin chỉ thấy HĐ mình/role eligible)
- [x] Admin password warning log startup
- [x] SLA Expiry BackgroundService auto-approve
- [ ] Dependencies scan CI (`dotnet list package --vulnerable` + `npm audit`)
- [ ] Admin mặc định warning log force đổi password
- [ ] Roles CRUD — optional
### Polish iterations