mirror of
https://github.com/azaion/admin.git
synced 2026-06-21 14:11:10 +00:00
8b7d8a4275
Archive AZ-556 + AZ-557 task specs, mark dependencies table 25/25 done (82/82 pts), write batch_06_cycle2_report.md and the sprint-level implementation_report_auth_modernization_cycle2_hotfix.md, advance _autodev_state.md to step 11 (Run Tests). Per implement skill step 16, the final-suite gate is owned by the test-run skill; not run here to avoid duplicate full runs. Co-authored-by: Cursor <cursoragent@cursor.com>
5.9 KiB
5.9 KiB
Batch Report
Batch: 6 (cycle 2)
Tasks: AZ-556 (unify_login_error_codes), AZ-557 (mfa_brute_force_lockout)
Date: 2026-05-14
Commit: 4bf2e68 on dev
Task Results
| Task | Status | Files Modified | Tests | AC Coverage | Issues |
|---|---|---|---|---|---|
| AZ-556 unify_login_error_codes | Done | 8 files | E2E updated/new | 6 of 7 covered (AC-5 deferred) | 1 Medium spec-gap |
| AZ-557 mfa_brute_force_lockout | Done | 4 files | 4 new E2E tests | 6 of 7 covered (AC-4 by code-attachment + AZ-537 stub parity) | 1 Medium, 1 Low spec-gap |
Files Modified
Production:
Azaion.Common/BusinessException.cs— newInvalidCredentials = 70; deprecation notes on 5 legacy membersAzaion.AdminApi/BusinessExceptionHandler.cs— mapInvalidCredentials→ 401Azaion.Common/Entities/AuditEvent.cs— newLoginFailedUnknownEmail,LoginFailedDisabledAzaion.Services/AuditLog.cs— new recorders;CountRecentFailedLoginsaggregates both event typesAzaion.Services/Security.cs—DummyHashForTiming+VerifyDummyAzaion.Services/UserService.cs— rewrittenValidateUser; newRegisterMfaFailedLogin; sharedRegisterFailedLoginCorewithFailureKindenumAzaion.Services/MfaService.cs— lockout + rate-limit checks BEFORE TOTP verify; counter reset on success; delegates failure accounting toUserServiceAzaion.AdminApi/Program.cs—/login/mfauser-not-found →InvalidCredentials
Tests:
e2e/Azaion.E2E/Tests/AuthTests.cs— renamed + updated 2 tests; added 2 new (byte-equality + disabled-account audit row)e2e/Azaion.E2E/Tests/PasswordHashingTests.cs— assert 401 + code 70e2e/Azaion.E2E/Tests/LoginRateLimitTests.cs— assert 401 + code 70 + Retry-Aftere2e/Azaion.E2E/Tests/SecurityTests.cs— disabled-user test aligned with new contracte2e/Azaion.E2E/Tests/MfaLoginTests.cs— new AZ557_AC1, AZ557_AC2, AZ557_AC5, AZ557_AC7
AC Test Coverage: 12 of 14 covered + 2 with documented deferrals
| AC | Covered by | Notes |
|---|---|---|
| AZ-556 AC-1 | Login_with_unknown_email_returns_401_invalid_credentials + identical-body comparison test |
Audit-row check included |
| AZ-556 AC-2 | Login_with_wrong_password_returns_401_invalid_credentials + existing AZ-537 fail-count tests |
|
| AZ-556 AC-3 | Login_with_disabled_account_returns_401_invalid_credentials_indistinguishable_from_wrong_password |
Byte-equality + login_failed_disabled audit row asserted |
| AZ-556 AC-4 | Audit-row assertion on AC-3 test (real-hash verify would never produce login_failed_disabled) |
Indirect but tight |
| AZ-556 AC-5 | Deferred — structural mitigation only (VerifyDummy uses identical Argon2id params) |
See finding F1 in review report |
| AZ-556 AC-6 | Per-category audit-row assertions in AC-1 and AC-3 tests | |
| AZ-556 AC-7 | LoginRateLimitTests.AC3_Per_account_threshold_locks_account_returns_423 (now 401 + Retry-After) |
|
| AZ-557 AC-1 | MfaLoginTests.AZ557_AC1_Wrong_MFA_at_threshold_locks_account_and_audits_mfa_login_failed |
Seeded counter at threshold-1 for isolation |
| AZ-557 AC-2 | MfaLoginTests.AZ557_AC2_Mixed_password_and_MFA_failures_aggregate_to_lockout |
|
| AZ-557 AC-3 | Behaviourally via AC-1/AC-2 (counter aggregates both event types) | See finding F2 — direct unit test deferred |
| AZ-557 AC-4 | Code-attachment (Program.cs:374) + AZ-537 stub-parity |
See finding F3 — behavioural test would destabilise suite |
| AZ-557 AC-5 | MfaLoginTests.AZ557_AC5_Locked_account_at_MFA_step_returns_invalid_credentials_with_retry_after |
Lockout dominates valid TOTP |
| AZ-557 AC-6 | Audit-row assertion in AC-1 test | |
| AZ-557 AC-7 | MfaLoginTests.AZ557_AC7_Correct_TOTP_after_partial_failures_resets_counter |
Code Review Verdict: PASS_WITH_WARNINGS
See _docs/03_implementation/reviews/batch_06_cycle2_review.md.
Auto-Fix Attempts: 0
All findings accepted as documented (no code changes required).
Stuck Agents: None
Open Questions (for the user)
- AZ-557 recovery-code-during-lockout: the original Jira description listed an AC bullet "Locked-out user can still complete recovery-code login (recovery codes follow their own one-time-use semantics)" that did NOT survive into the local task spec
_docs/02_tasks/done/AZ-557_mfa_brute_force_lockout.md. The current implementation treats recovery codes the same as TOTP under lockout (rejected). If the Jira AC was intentional, a follow-up is needed to bypass the lockout check on the recovery-code branch only.
Next Batch
All cycle-2 hotfix tasks complete. Autodev auto-chains to Step 11 (Run Tests). Final implementation report for the cycle handed off to test-run/SKILL.md.
Process Notes
- Step 14.5 cumulative review is per-skill spec triggered every 3 batches. Cycle 2 has no cumulative review files (
_docs/03_implementation/cumulative_review_*.mdabsent). Surfacing as an explicit user decision in the end-of-turn summary rather than back-filling six batches of cumulative review inline. - Step 15 Product Implementation Completeness Gate: both task specs name only internal admin code (no external SDKs, hardware, or cloud integrations to verify). Promised behaviour —
InvalidCredentials,VerifyDummy, shared lockout pipeline, audit recorders — all has production code paths and is wired throughMapPost("/login")/MapPost("/login/mfa"). PASS.