Authentication API

Authentication endpoints for user registration and login.

Register

POST /api/auth/register
Content-Type: application/json

{
  "username": "string",
  "email": "string",
  "password": "string"
}

Response

{
  "token": "jwt-token",
  "refreshToken": "refresh-token",
  "user": {
    "id": "uuid",
    "username": "string",
    "email": "string"
  }
}

Login

POST /api/auth/login
Content-Type: application/json

{
  "username": "string",
  "password": "string"
}

Login with 2FA

POST /api/auth/2fa/verify
Content-Type: application/json

{
  "tempToken": "string",
  "code": "string"
}

Refresh Token

POST /api/auth/refresh
Content-Type: application/json

{
  "refreshToken": "string"
}

Get Current User

GET /api/auth/me
Authorization: Bearer <token>

Logout

POST /api/auth/logout
Authorization: Bearer <token>

Change Password

POST /api/auth/password/change
Authorization: Bearer <token>
Content-Type: application/json

{
  "currentPassword": "string",
  "newPassword": "string"
}

Password Reset

POST /api/auth/password/forgot
Content-Type: application/json

{
  "email": "string"
}
POST /api/auth/password/reset
Content-Type: application/json

{
  "token": "string",
  "newPassword": "string"
}
POST /api/auth/password/validate-token
Content-Type: application/json

{
  "token": "string"
}

Email Verification

POST /api/auth/email/verify/send
Authorization: Bearer <token>
GET /api/auth/email/verify?token=<token>

Two-Factor Authentication

Get 2FA Status

GET /api/auth/2fa/status
Authorization: Bearer <token>

Setup 2FA

POST /api/auth/2fa/setup
Authorization: Bearer <token>

Enable 2FA

POST /api/auth/2fa/enable
Authorization: Bearer <token>
Content-Type: application/json

{
  "secret": "string",
  "code": "string"
}

Disable 2FA

POST /api/auth/2fa/disable
Authorization: Bearer <token>
Content-Type: application/json

{
  "code": "string"
}

Get Recovery Codes

GET /api/auth/2fa/recovery-codes
Authorization: Bearer <token>

Sessions

Get All Sessions

GET /api/auth/sessions
Authorization: Bearer <token>

Revoke Session

POST /api/auth/sessions/revoke
Authorization: Bearer <token>
Content-Type: application/json

{
  "sessionId": "uuid"
}

Revoke All Sessions

POST /api/auth/sessions/revoke-all
Authorization: Bearer <token>

Rotate Token

POST /api/auth/sessions/rotate
Authorization: Bearer <token>

Get Active Sessions Count

GET /api/auth/sessions/count
Authorization: Bearer <token>

OIDC Endpoints

OpenID Connect (OIDC) authentication enables single sign-on with identity providers. Configure with environment variables:

VariableDefaultDescription
OIDC_ENABLEDfalseEnable OIDC authentication
OIDC_ISSUER_URL-OIDC provider issuer URL (e.g., https://accounts.google.com)
OIDC_CLIENT_ID-OAuth2 client ID from the provider
OIDC_CLIENT_SECRET-OAuth2 client secret from the provider

OAuth2 scopes requested: openid, profile, email. Redirect URI is /api/auth/oidc/callback.

OIDC Login

Initiates the OIDC authentication flow. Generates a CSRF state token and redirects the user to the OIDC provider's authorization page.

GET /api/auth/oidc/login

Auth Required: No

Success Response: 307 Temporary Redirect

Location: https://provider.com/auth?state=...&access_type=online
Set-Cookie: oidc_state=<state>; Path=/; HttpOnly; Secure; SameSite=Lax
StatusDescription
307Redirect to OIDC provider
404OIDC not enabled
500Failed to generate state

OIDC Callback

Handles the redirect from the OIDC provider. Exchanges the authorization code for tokens, verifies the ID token, finds or creates a user, and returns authentication tokens.

GET /api/auth/oidc/callback?code=<authorization_code>&state=<state_token>
Cookie: oidc_state=<state>

Auth Required: No

Query Parameters:

ParameterTypeRequiredDescription
codestringYesAuthorization code from OIDC provider
statestringYesCSRF state token (must match oidc_state cookie)

Success Response: 200 OK

{
  "access_token": "eyJhbGciOiJIUzI1NiIs...",
  "refresh_token": "eyJhbGciOiJIUzI1NiIs...",
  "expires_in": 86400,
  "user": {
    "id": "550e8400-e29b-41d4-a716-446655440000",
    "username": "john",
    "email": "john@example.com",
    "display_name": "John Doe",
    "avatar_url": "",
    "is_admin": false
  }
}

Also sets access_token and refresh_token as HttpOnly cookies.

User Creation: If no existing user matches the OIDC subject, a new user is created with username derived from (in priority order): preferred_username claim, name claim, email local part, or a random UUID prefix.

StatusDescription
200Authentication successful
400State cookie not found or invalid state
404OIDC not enabled
500Authentication failed (token exchange, user creation, etc.)

OIDC Config

Returns whether OIDC authentication is enabled. Frontend clients use this to conditionally show/hide the OIDC login button.

GET /api/auth/oidc/config

Auth Required: No

Success Response: 200 OK

{
  "enabled": true
}

OAuth Endpoints

OAuth authentication supports Google, GitHub, and Discord with callback routes. The OAuth model type also defines Twitter, Slack, and Microsoft as supported provider values.

MethodEndpointDescription
GET/api/auth/oauth/providersGet available OAuth providers
POST/api/auth/oauth/loginStart OAuth flow
GET/api/auth/oauth/google/callbackGoogle OAuth callback
GET/api/auth/oauth/github/callbackGitHub OAuth callback
GET/api/auth/oauth/discord/callbackDiscord OAuth callback

Authentication Security Features

FeatureDescription
Password HistoryPrevents reuse of the last 5 passwords
Password ExpiryPasswords expire after 90 days
Login Attempt Tracking5 failed attempts triggers a 15-minute account lockout
JWT Token Family RotationRefresh tokens use token families for replay detection
AES-256-GCM EncryptionOptional encryption for 2FA secrets via ENCRYPTION_KEY
Password Reset Rate LimitingPer-email rate limiting for password reset requests
Email Verification Tokens24-hour expiry JWT tokens for email verification
TOTP 2FASHA1, 6 digits, 30s period, 10 bcrypt-hashed recovery codes