feat(security): implement TOTP two-factor authentication support#12615
feat(security): implement TOTP two-factor authentication support#12615severfire wants to merge 1 commit into
Conversation
- Added TOTP (Time-based One-Time Password) functionality for enhanced security. - Introduced new API endpoints for TOTP setup, enabling, disabling, and verifying login. - Updated user model to include TOTP secret and enabled status. - Integrated TOTP checks into the login process, requiring a second factor for users with TOTP enabled. - Added frontend components and hooks for TOTP management, including status checks and user prompts. - Updated localization files to include TOTP-related messages and instructions. - Added unit tests for TOTP functionality and API endpoints.
|
Important Review skippedAuto reviews are disabled on base/target branches other than the default branch. Please check the settings in the CodeRabbit UI or the ⚙️ Run configurationConfiguration used: Path: .coderabbit.yaml Review profile: CHILL Plan: Pro Run ID: You can disable this status message by setting the Use the checkbox below for a quick retry:
✨ Finishing Touches🧪 Generate unit tests (beta)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
|
@ogabrielluiz Hi, could this be released into 1.9.1? :-D I always dreamed about 2FA in Langflow :-) |
|
@severfire Changed base to v1.10, will get it reviewed for that! Thanks |
|
@jordanrfrazier Thanks! This PR would be part of the ISO 27001 goals :-) |
841d2d7 to
242c6c7
Compare
feat: TOTP Two-Factor Authentication
Summary
This PR adds opt-in TOTP (Time-based One-Time Password) two-factor authentication to Langflow, compatible with Google Authenticator, Authy, and any RFC 6238-compliant app. Users can enable 2FA from the Settings page; once enabled, login requires both the password and a 6-digit code from their authenticator app.
What Changed
Backend
New service —
services/auth/totp.pypyotpSECRET_KEY) before being written to the databaseTTLCachefor 3 TOTP windows (90 s); re-using the same code within that window is rejectedpartial_tokenis issued at password-login when the user has TOTP enabled; afterMAX_VERIFY_ATTEMPTS(5) consecutive wrong codes, the token is permanently burnedvalid_window=1)New router —
api/v1/totp.pyGET/api/v1/totp/statusPOST/api/v1/totp/setupPOST/api/v1/totp/enablePOST/api/v1/totp/disablePOST/api/v1/totp/verify-loginModified —
api/v1/login.pypartial_tokeninstead of full access/refresh tokens/totp/verify-loginDatabase migration —
alembic/versions/a3b4c5d6e7f8_add_totp_fields_to_user.pytotp_secret(VARCHAR, nullable) andtotp_enabled(BOOLEAN, defaultfalse) columns to theusertableDependency —
pyotpadded tolangflow-basedependenciesFrontend
New component —
SettingsPage/GeneralPage/components/TotpFormstatus→setup→disableqrcode.react) alongside the raw base32 secret for manual entry, then asks the user to enter the first 6-digit code to confirm enrollmentautoComplete="one-time-code"on all OTP inputs for browser/OS autofill supportNew React Query hooks —
controllers/API/queries/auth/useGetTotpStatus— query for current TOTP statususePostTotpSetup— mutation to generate a new secretusePostTotpEnable— mutation to confirm and enableusePostTotpDisable— mutation to disable with code verificationusePostTotpVerifyLogin— mutation to complete the 2FA login stepModified —
pages/LoginPage/index.tsxpartial_token; when it does, the login form transitions to a TOTP code-entry stepi18n —
locales/en.jsonDependency —
qrcode.reactadded topackage.jsonTests
src/backend/tests/unit/test_totp.py(557 lines)Security Design Notes
partial_tokenis JWT-signed withtype: "partial", preventing it from being used as a normal session tokenTest Plan
uv run pytest src/backend/tests/unit/test_totp.py