> ## Documentation Index
> Fetch the complete documentation index at: https://docs.equa.cc/llms.txt
> Use this file to discover all available pages before exploring further.

# Authentication

> Session-based authentication, login methods, and cookie handling for the Equa API

> **Source:** `equa-server/modules/auth/src/sessions.ts`, `authentication.ts`, `google-auth.ts`, `modules/api/src/server.ts`, `magic-link.ts`

# Authentication

The Equa API uses **session-based authentication** powered by `express-session`. After a successful login, the server creates a session and returns a session cookie. This cookie must be included in all subsequent API requests.

The server route examples below use the application route prefix (`/v1/...`). In the current browser deployment, those routes are reached through the same-origin SPA path `/api/v1/...`.

## How Sessions Work

1. The client sends credentials to a login endpoint
2. The server validates credentials and creates a session stored in the database (TypeORM session store)
3. A `Set-Cookie` header is returned with the session ID
4. The client includes this cookie on every subsequent request
5. The server validates the session on each request and identifies the user

## Session Configuration

| Setting             | Value                   | Description                                                      |
| ------------------- | ----------------------- | ---------------------------------------------------------------- |
| `maxAge`            | 604,800,000 ms (7 days) | Session expiration time (configurable via `API_SESSION_MAX_AGE`) |
| `rolling`           | `true`                  | Session expiry resets on each request                            |
| `resave`            | `false`                 | Session is not re-saved if unmodified                            |
| `saveUninitialized` | `false`                 | Empty sessions are not persisted                                 |
| `sameSite`          | `lax`                   | Mitigates CSRF by limiting cross-site cookie sends               |
| `httpOnly`          | `true`                  | Prevents JavaScript access to the session cookie                 |
| `secure`            | `true` in production    | Cookie only sent over HTTPS                                      |
| `proxy`             | `true`                  | Trust the reverse proxy for secure cookies                       |

## Login Methods

### Email and Password

```
POST /v1/user/login
```

```json theme={null}
{
  "email": "user@example.com",
  "password": "your-password"
}
```

Returns the authenticated user object and sets the session cookie.

### Google OAuth

```
POST /v1/user/google-auth
```

```json theme={null}
{
  "token": "google-oauth-id-token"
}
```

Accepts a Google OAuth ID token (obtained from Google Sign-In on the client). Creates or links the user account and establishes a session.

#### Google OAuth Redirect Mode (form POST)

```
POST /v1/user/google-auth/redirect
Content-Type: application/x-www-form-urlencoded
```

Used by Google Sign-In redirect/form flows where Google posts credentials as form data instead of JSON.

Required form fields:

* `credential`: Google OAuth ID token
* `g_csrf_token`: CSRF token from the form body

CSRF validation requirements:

* The `g_csrf_token` value must be present in both the request body and the `g_csrf_token` cookie.
* The two values must match, or the request is rejected.

Behavior:

* **Success:** Creates/links the user session and redirects to `/login?authenticated=true`.
* **Missing credential:** Returns `400` with `{ "message": "Missing credential" }`.
* **CSRF mismatch/missing token:** Returns `403` with `{ "message": "CSRF token validation failed" }`.
* **Auth failure during verification:** Redirects to `/login?error=auth_failed`.

### Magic Link

Magic links provide passwordless email-based authentication.

<Warning>
  The magic link module (`modules/auth/src/magic-link.ts`) implements token generation, verification, and session creation, but dedicated REST endpoints (`POST /v1/user/magic-link` and `POST /v1/user/magic-link/verify`) are not currently registered in `auth-endpoints.ts`. The implementation exists but is not yet wired to the endpoint layer.
</Warning>

The magic link flow (when fully wired) works as follows:

**Step 1: Request a magic link** — Generates a 32-byte hex token (`crypto.randomBytes(32).toString('hex')`), stores it with a 15-minute expiry, and sends an email to the user. The response is always successful to prevent email enumeration.

**Step 2: Verify the magic link token** — Validates the token (must be unused, not expired), marks it as used, creates a logged-in session, and returns the user object.

## Making Authenticated Requests

All API calls from the browser must include credentials so the session cookie is sent:

```javascript theme={null}
const response = await fetch('/api/v1/organization', {
  method: 'GET',
  credentials: 'include',
  headers: {
    'Content-Type': 'application/json',
  },
})
```

## Checking the Current Session

To verify the current session is valid and retrieve the authenticated user:

```
GET /v1/user/current
```

Returns the current user object if the session is valid, or an unauthenticated response otherwise.

## Debugging Sessions (Development Only)

For local session debugging, use the auth diagnostic endpoint:

```
GET /v1/auth/diagnostic
```

This endpoint is available in development and test environments. It is disabled in production (`NODE_ENV=production`).

Example response shape:

```json theme={null}
{
  "hasSession": true,
  "hasUser": true,
  "userId": "uuid-or-null",
  "sessionIdPrefix": "abcd1234...",
  "hasConnectSidCookie": true,
  "cookieSecure": false,
  "cookieMaxAge": 604799999,
  "timestamp": "2026-02-22T17:45:31.712Z"
}
```

Use this endpoint to confirm whether a 401/403 is caused by a missing session, expired session, or cookie configuration mismatch.

## Logout

```
POST /v1/user/logout
```

Destroys the server-side session and clears the session cookie. Requires an active session.

## Two-Factor Authentication (2FA)

Equa supports TOTP-based two-factor authentication.

| Endpoint                   | Method | Description                               |
| -------------------------- | ------ | ----------------------------------------- |
| `GET /v1/user/2fa`         | GET    | Generate a new 2FA secret/QR code         |
| `POST /v1/user/2fa/verify` | POST   | Verify a 2FA token                        |
| `POST /v1/user/2fa`        | POST   | Enable 2FA on the account (auth required) |

## CORS and Cookies

The API server is configured to accept cross-origin requests from the Equa frontend domain. Ensure your requests include:

* `credentials: 'include'` on all fetch calls
* The correct `Content-Type` header for JSON payloads
* HTTPS in production (required for secure cookies)
