feat(auth): Two-Factor Authentication (TOTP) + Refresh Token Session Management - #130
Merged
Conversation
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Adds TOTP-based two-factor authentication and multi-session management
(refresh token rotation + a user-facing "Active sessions" page) to
DocAnalytics auth.
What's included
Backend
Userentity:two_factor_enabled,two_factor_secretTwoFactorRecoveryCodeentity + table (BCrypt-hashed, single-use)RefreshToken: addeduser_agent,ip_address,last_used_atforsession visibility
ITwoFactorService/TwoFactorService(Otp.NET) — TOTP generation,validation, recovery code hashing/verification
IRefreshTokenService/RefreshTokenService— rotation now recordsdevice info per issue/rotate
AuthController— 6 new endpoints:2fa/setup,2fa/confirm,2fa/disable,login/2fa,sessions(GET),sessions/{id}(revoke),sessions/revoke-othersRateLimitingExtensionsAddTwoFactorAuthFrontend
requires_two_factorfrom/auth/logininto an MFA-challenge step
TwoFactorSetupComponent— QR + manual key display, confirm flow,one-time recovery code reveal
SessionsComponent— active session table, per-row revoke, revoke-allKnown issue / follow-up needed
Recovery code redemption on
POST /auth/login/2facurrently returns 401even for freshly-generated, unused codes, despite
TwoFactorService'shash/verify logic being correct in isolation. Suspect the bug is one
layer up in
AuthService's login-with-2FA method (likely comparing afreshly computed hash directly instead of calling
VerifyRecoveryCode,which won't work against salted BCrypt hashes). Needs a fix before
recovery codes can be relied on — tracked as a follow-up, not blocking
this PR since TOTP login itself works end-to-end.
Testing done
dotnet build), all production projects compileAuthService/AuthControllerconstructorsignatures (18 pre-existing failures fixed)
ng build), no errorsTOTP code → sessions page shows session → revoke works
rebuild.ps1) — verified via container logsHow to test locally
dotnet ef database update(migrationAddTwoFactorAuth)./rebuild.ps1