Skip to content
Flows
App Builder Generated Intermediate · 45-90 minutes

Add Time‑Based One‑Time Password (TOTP) 2FA

Integrate real TOTP two‑factor authentication into an existing app with full persistence and verification.

Start Route · 6 steps

The route

6 steps to Done

  1. 01

    Locate and back up the user authentication module

    Identify where users are stored and how passwords are verified so we can safely extend the model.

    Preview prompt + verify gate ▾

    Search the codebase for the User schema/model definition and the login endpoint. List the exact file paths, show the fields defined in the User model, and copy the login function code that verifies the password. Include any ORM/ODM import statements. Do not modify anything yet.

    • Can you locate the User model file?
    • Is the password verification code shown verbatim?
    • Did the AI include full import statements and middleware references?
  2. 02

    Add a TOTP secret field to the User model

    Persist each user’s 2FA secret so it can be used for verification.

    Preview prompt + verify gate ▾

    Modify the User model definition from step 1 to include a new field `totpSecret` of type string (or varchar) that can be null. If the project uses migrations, generate a migration script that adds this column to the users table without dropping data. Provide the updated model code and the full migration file content. Do not run the migration; just output the code.

    • Is `totpSecret` present in the model definition?
    • Does the migration add the column without affecting other fields?
    • Is the migration syntax correct for the project's DB (e.g., Knex, Sequelize, TypeORM)?
  3. 03

    Create an enrollment endpoint that generates a TOTP secret and QR code

    Allow users to enable 2FA by receiving a scannable QR code linked to a secret stored in the DB.

    Preview prompt + verify gate ▾

    Implement a new authenticated POST endpoint `/2fa/enroll`. Inside, generate a TOTP secret using `otplib` (or an equivalent library). Save the secret to the current user's `totpSecret` field and persist the change. Create a URI of the form `otpauth://totp/<APPNAME>:<email>?secret=<SECRET>&issuer=<APPNAME>` and generate a PNG QR code image encoded as a base64 data URL using a library like `qrcode`. Return a JSON response `{ "qrCode": "data:image/png;base64,...", "secret": "<secret>" }`. Do not include any HTML; only raw JSON. Ensure the secret is saved to the DB before responding.

    • Does the endpoint generate a real TOTP secret?
    • Is the secret saved to the user's record before response?
    • Is the returned `qrCode` a base64 data URL (starts with `data:image/png;base64,`)?
  4. 04

    Create a verification endpoint for TOTP codes

    Validate the 6‑digit code supplied by the user during login or 2FA prompt.

    Preview prompt + verify gate ▾

    Implement an authenticated POST endpoint `/2fa/verify` that accepts JSON `{ "token": "123456" }`. Retrieve the current user's `totpSecret` from the DB. Use `otplib` to verify the token against the secret, allowing the default time step window. Return `{ "valid": true }` if the token matches, otherwise `{ "valid": false, "error": "Invalid code" }`. Ensure no placeholder logic; the verification must run against the stored secret.

    • Does the endpoint read `totpSecret` from the DB?
    • Is the token verified with `otplib` (or equivalent) rather than a dummy check?
    • Does the response JSON correctly indicate success or failure?
  5. 05

    Integrate TOTP verification into the existing login flow

    Require a valid TOTP token after password verification for users who have a `totpSecret` set.

    Preview prompt + verify gate ▾

    Edit the existing login controller (from step 1) so that after successful password check, it examines `user.totpSecret`. If the field is null, proceed to create the session/JWT as before. If the field is non‑null, do NOT create a session yet; instead return JSON `{ "2faRequired": true, "message": "Enter TOTP code" }`. The client must then call the `/2fa/verify` endpoint (implemented in step 4). On a successful verification response, the server should finally issue the session/JWT token. Provide the full updated login function code, including the new branch and any helper to finalize the session after TOTP verification. No placeholder comments; include real conditional logic.

    • Does the login function return a `2faRequired` flag when a secret exists?
    • Is the session token withheld until after TOTP verification?
    • Is there concrete code showing how to finalize the session post‑verification?
  6. 06

    Test the full 2FA flow end‑to‑end

    Verify that enrollment, verification, and login with 2FA all work with real data and persistence.

    Preview prompt + verify gate ▾

    Provide a precise, numbered test script that a developer can run with `curl`: 1. Register a new user (or use an existing one without 2FA). 2. Log in with email/password → receive auth token. 3. Call `/2fa/enroll` with the token → capture the `qrCode` data URL and `secret`. 4. Decode the secret (or scan the QR with an authenticator app) and generate a current TOTP code. 5. POST the code to `/2fa/verify` using the same auth token → expect `{ "valid": true }`. 6. Attempt regular login again → expect `{ "2faRequired": true }`. 7. Submit the current TOTP to the verification endpoint → on success receive a final session token. Include the exact `curl` command syntax, required headers, and example JSON bodies. No mock responses; the commands must be ready to run against the actual server. After the script, self‑audit with "PASS" if all six commands are present, correctly reference endpoints, and specify how to read the QR/secret. Otherwise "FAIL" with missing step.

    • Can you execute the curl commands without editing placeholder values?
    • Does the enrollment response include a real base64 QR data URL?
    • Is a final auth token returned only after successful TOTP verification?