# How to Set Up Two-Factor Authentication (2FA) with TOTP in TREK

> Secure your TREK account with Time-Based One-Time Password (TOTP) 2FA. Follow our simple guide to set up and verify your TOTP codes for enhanced security.

- Repository: [Maurice/TREK](https://github.com/mauriceboe/TREK)
- Tags: how-to-guide
- Published: 2026-07-04

---

**TREK implements Time-Based One-Time Password (TOTP) 2FA through a two-step flow where the server generates a secret and QR code for enrollment, and the `/api/auth/mfa/verify-login` endpoint validates 6-digit codes during authentication.**

TREK is an open-source application that provides enterprise-grade security features including standard TOTP-based two-factor authentication. This guide explains how to implement and manage 2FA in your TREK instance based on the actual source code implementation in the `mauriceboe/TREK` repository.

## Enabling TOTP 2FA for Your Account

When users navigate to **Settings → Account** and select **"Set up two-factor authentication"**, the system initiates a secure enrollment process. The server generates a unique secret and renders it as a QR code image that can be scanned by any authenticator app such as Google Authenticator, Authy, or 1Password.

The enrollment flow is documented in the project's [`wiki/Two-Factor-Authentication.md`](https://github.com/mauriceboe/TREK/blob/main/wiki/Two-Factor-Authentication.md) file, which provides step-by-step instructions and screenshots for the UI elements described in lines 13-19.

### Generating the Secret and QR Code

The backend handles secret generation through the `POST /api/auth/mfa/setup` endpoint. This endpoint creates a cryptographically secure secret and returns both the raw secret string and a QR code image for scanning.

While the server-side implementation resides in [`server/src/routes/auth.ts`](https://github.com/mauriceboe/TREK/blob/main/server/src/routes/auth.ts), the client-side interaction follows this pattern:

```javascript
// Initiate MFA setup
await authStore.setupMfa();  // Calls GET /api/auth/mfa/setup

// Display QR code to user
// User scans code into authenticator app

```

### Verifying the Setup

After scanning the QR code, the user must enter the 6-digit code from their authenticator app to confirm the device is synchronized correctly. The frontend sends this code to the server to complete enrollment:

```javascript
const code = prompt('Enter the 6-digit code from your app');
await authStore.confirmMfa({ code });  // POST /api/auth/mfa/verify-setup

```

Upon successful verification, the server generates **ten single-use backup codes** that can be used if the authenticator device becomes unavailable. These codes are displayed in the UI as referenced in the Wiki documentation lines 18-19.

## Logging In with 2FA

The TREK authentication flow uses a two-step process when 2FA is enabled. First, the user submits their email and password to `POST /api/auth/login`, which returns a temporary session token. Then, the client prompts for the TOTP code before granting full access.

The verification endpoint is defined in [`client/src/api/client.ts`](https://github.com/mauriceboe/TREK/blob/main/client/src/api/client.ts) at line 239:

```typescript
// client/src/api/client.ts
verifyMfaLogin: (data: MfaVerifyLoginRequest) => 
    apiClient.post('/auth/mfa/verify-login', data).then(r => r.data),

```

This translates to a `POST` request to `/api/auth/mfa/verify-login`. According to the middleware policy in [`server/src/middleware/mfaPolicy.ts`](https://github.com/mauriceboe/TREK/blob/main/server/src/middleware/mfaPolicy.ts) at line 14, this endpoint is explicitly marked as **public** to allow access during the intermediate authentication state.

Complete login implementation:

```javascript
// Step 1: Password authentication
const tempToken = await api.login({ email, password });

// Step 2: MFA verification
const mfaCode = prompt('Enter your 2FA code');
const finalToken = await api.verifyMfaLogin({ 
    token: tempToken, 
    code: mfaCode 
});
// Store finalToken for subsequent API calls

```

Integration tests in [`server/tests/integration/auth.test.ts`](https://github.com/mauriceboe/TREK/blob/main/server/tests/integration/auth.test.ts) (lines 401-410) verify that valid TOTP codes successfully complete the login flow and upgrade the session to fully authenticated status.

## Managing Backup Codes and Disabling 2FA

TREK provides secure mechanisms for account recovery and 2FA removal. The ten single-use backup codes generated during enrollment can each be used once in place of a TOTP code during login.

To disable 2FA, users must navigate to the same settings page and provide both their **password** and a current TOTP code (or one backup code). The backend validates both credentials before toggling the `mfaEnabled` flag off:

```javascript
await api.disableMfa({ password, code });  // POST /api/auth/mfa/disable

```

This security measure prevents unauthorized users from disabling 2FA even if they have temporary access to an unlocked session.

## Admin-Enforced 2FA Policies

Administrators can mandate organization-wide two-factor authentication. When enabled, the MFA policy middleware intercepts API requests from users without active 2FA setup and returns a **403 Forbidden** response.

The client application handles this by redirecting affected users to the settings page to complete 2FA enrollment before accessing protected resources. This enforcement mechanism utilizes the same [`server/src/middleware/mfaPolicy.ts`](https://github.com/mauriceboe/TREK/blob/main/server/src/middleware/mfaPolicy.ts) middleware that handles the public route exceptions for the verification endpoint.

## Summary

- **TREK uses standard TOTP** (Time-Based One-Time Password) for 2FA, compatible with any authenticator app that supports RFC 6238.
- **Enrollment** requires scanning a QR code generated by `POST /api/auth/mfa/setup` and verifying the first 6-digit code via `POST /api/auth/mfa/verify-setup`.
- **Login flow** is split: credentials return a temporary token, then `POST /api/auth/mfa/verify-login` (defined in [`client/src/api/client.ts`](https://github.com/mauriceboe/TREK/blob/main/client/src/api/client.ts) line 239) validates the TOTP code and returns the full session token.
- **Backup codes** are ten single-use codes generated during enrollment, stored in the UI as documented in [`wiki/Two-Factor-Authentication.md`](https://github.com/mauriceboe/TREK/blob/main/wiki/Two-Factor-Authentication.md).
- **Disabling 2FA** requires both password and current TOTP code, enforced by the backend before modifying the `mfaEnabled` flag.
- **Admin enforcement** uses middleware in [`server/src/middleware/mfaPolicy.ts`](https://github.com/mauriceboe/TREK/blob/main/server/src/middleware/mfaPolicy.ts) to require 2FA for all users, redirecting to settings with a 403 response if not configured.

## Frequently Asked Questions

### How do I reset 2FA if I lose my authenticator device?

Use one of the ten single-use backup codes generated during initial setup. These codes can be entered in place of a TOTP code during the login flow. If you have also lost your backup codes, you will need to contact an administrator to manually reset your MFA status in the database, as TREK does not provide automatic account recovery without these credentials.

### Which authenticator apps are compatible with TREK's 2FA?

Any authenticator application that supports the standard TOTP algorithm (RFC 6238) will work with TREK. This includes Google Authenticator, Authy, Microsoft Authenticator, 1Password, and hardware keys that implement TOTP. The system generates a standard QR code that encodes the secret in the `otpauth://` URI format.

### Why does the login API return a temporary token instead of the final session?

This two-step authentication pattern prevents brute-force attacks on the TOTP endpoint. The first step (`POST /api/auth/login`) validates the password and returns a temporary token that can only be exchanged for a full session by providing a valid TOTP code or backup code to `POST /api/auth/mfa/verify-login`. As implemented in [`server/src/middleware/mfaPolicy.ts`](https://github.com/mauriceboe/TREK/blob/main/server/src/middleware/mfaPolicy.ts), the verification endpoint is marked as public specifically to allow this intermediate state.

### Can administrators force all users to enable 2FA?

Yes. Administrators can enable organization-wide MFA enforcement. When active, the middleware in [`server/src/middleware/mfaPolicy.ts`](https://github.com/mauriceboe/TREK/blob/main/server/src/middleware/mfaPolicy.ts) returns a 403 Forbidden response for any API request from users without `mfaEnabled` set to true. The TREK frontend automatically redirects these users to **Settings → Account** to complete 2FA setup before they can access the application.