Add Google Authenticator (TOTP) as MFA factor: device mapping + login
Backend:
- New dependency dev.samstevens.totp:totp:1.7.1 (bundles ZXing for QR PNG).
- TotpService: secret/QR/otpauth-URL/verify primitives. SHA1, 6 digits, 30s —
the standard combo every consumer authenticator app accepts unconfigured.
Issuer label is configurable via FINERACT_MFA_TOTP_ISSUER, defaults to
"CBSnexora".
- Two-step device mapping driven by TotpEnrollmentService:
* POST /v1/mfa/totp/setup — generate secret, upsert m_user_mfa_factor row
as factor_type=TOTP/verified=false, return {secret, qrDataUri, otpAuthUrl,
issuer, factorId}. Refuses to overwrite an already-verified-and-active
factor so an accidental click can't unbind the user's working device.
* POST /v1/mfa/totp/verify — body {code}; verify against the stored secret
and flip verified=true on success.
- Login wiring in MfaFactorBackedTwoFactorServiceImpl:
* getDeliveryMethodsForUser surfaces verified TOTP factors as
{name:"totp", target:"Google Authenticator"} so the picker offers it
alongside SMS/EMAIL.
* createNewOTPToken("totp") creates a no-op OTPRequest (no LincPay/SMTP
round-trip) carrying the factor id in the token field so validate can
look up the secret.
* createAccessTokenFromOTP branches on channel — TOTP path verifies code
vs factor.secret with totp library (sliding 1-step window) and mints
a TFAccessToken with the same lifetime + extended-token logic as OTP.
* Defence-in-depth: re-checks at validate time that the factor still
belongs to the user, is verified, and not disabled.
- TwoFactorConstants.TOTP_DELIVERY_METHOD_NAME = "totp".
- SecurityConfig: /api/*/mfa/totp/** is fullyAuthenticated() (exempt from
the TFA gate so users can enrol before they can satisfy 2FA).
UI changes pending (see chat): add a "Google Authenticator" tile on the
MFA Factors settings page that calls /setup → shows QR + secret → calls
/verify; extend two-factor-authentication.component.ts iconFor() and copy
for the new "totp" delivery method. Existing requestOTP / validateOTP
pipeline handles the login flow transparently.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Opus 4.7
parent
6558ea6998
commit
45a041b023
@@ -48,7 +48,11 @@
|
||||
"PowerShell(Get-Process -Id 9340 -ErrorAction SilentlyContinue | Select-Object Id, ProcessName, StartTime, @{Name='MemMB';Expression={[math]::Round\\($_.WorkingSet64/1MB,0\\)}}, Path | Format-List)",
|
||||
"Bash(git -c core.editor=true rebase --continue)",
|
||||
"Bash(git rebase *)",
|
||||
"Bash(rm -rf .git/rebase-merge; git status -sb | head -3)"
|
||||
"Bash(rm -rf .git/rebase-merge; git status -sb | head -3)",
|
||||
"Bash(git -c commit.gpgsign=false commit -m ' *)",
|
||||
"Bash(git pull *)",
|
||||
"Bash(./gradlew :fineract-security:compileJava :fineract-provider:compileJava -q)",
|
||||
"Bash(git ls-remote *)"
|
||||
],
|
||||
"additionalDirectories": [
|
||||
"c:\\Users\\adity\\Music\\CBS\\cfcfrms-bank-api",
|
||||
|
||||
Reference in New Issue
Block a user