Skip to main content

Auth Service API Documentation

Base URL

/api/auth

📘 TypeScript Interfaces

Use these interfaces for your frontend integration.

// User Object (from profile/login response)
export interface User {
id: number;
email: string;
name: string | null;
phone: string | null;
administrator: boolean;
disabled: boolean;
readonly: boolean;
deviceReadonly: boolean;
limitCommands: boolean;
expirationTime: string | null; // ISO 8601
attributes: Record<string, any>;
}

// Login Request
export interface LoginRequest {
email: string;
password: string;
}

// Login Response (Standard)
export interface LoginResponse {
accessToken: string;
user: User;
}

// Login Response (2FA Required) - HTTP 202 Accepted
export interface Login2FARequiredResponse {
require_2fa: true;
temp_token: string;
type: 'totp' | 'email';
message: string;
}

// Registration Request
export interface RegisterRequest {
email: string;
password: string;
name: string;
termsPrivacyAccepted: boolean; // REQUIRED - must be true
}

// Registration Response
export interface RegisterResponse {
message: string;
email: string;
}

// 2FA Setup Response (from /2fa/setup)
export interface TwoFactorSetupResponse {
secret: string; // Base32 TOTP secret
otpauth_url: string; // URI for QR code generation
}

// 2FA Verify Response (from /2fa/verify)
export interface TwoFactorVerifyResponse {
message: string;
backup_codes: string[]; // 10 codes, save these!
}

// 2FA Login Request
export interface Login2FARequest {
temp_token: string;
code: string; // TOTP code or backup code
}

// Password Reset Request
export interface PasswordResetRequest {
email: string;
}

// Password Update Request
export interface PasswordUpdateRequest {
token: string;
password: string;
}

// Verify Email Request
export interface VerifyEmailRequest {
token: string;
}

// Generic Message Response
export interface MessageResponse {
message: string;
}

// OpenID Token Request (Mobile)
export interface OpenIDTokenRequest {
provider: string;
id_token: string;
}

// OpenID Token Response (Mobile)
export interface OpenIDTokenResponse {
accessToken: string;
user: User;
}

// Health Check Response
export interface HealthResponse {
status: 'healthy' | 'degraded';
service: string;
ready: boolean;
database: 'connected' | 'disconnected';
}

🛠️ Frontend Integration Guide

1. Authentication

The Auth Service uses JWT Bearer tokens in the Authorization header.

Frontend Requirement: You MUST store the accessToken from login response and include it in all authenticated requests.

// Example using fetch
await fetch('/api/auth/profile', {
method: 'GET',
headers: {
'Authorization': `Bearer ${accessToken}`
}
});

2. OpenID Connect (Social Login)

The flow is redirect-based.

  1. Redirect user to /api/auth/openid/auth?provider=google&ret=web.
  2. User logs in at provider (Google/Facebook/Apple).
  3. Provider redirects back to backend callback.
  4. Backend redirects to your frontend URL with token.
    • If 2FA enabled: Redirects to /login/2fa?token={temp_token}&type={totp|email}
    • Web success: Redirects to {WEB_URL}?openid=success&access_token=...
    • App success: Deep link com.visla.vislagps://oauthredirect?openid=success&access_token=...

3. 2FA Flow

When login returns 202 Accepted with require_2fa: true:

  1. Store the temp_token from response.
  2. Prompt user for TOTP code (or backup code).
  3. Call POST /api/auth/2fa/login with { temp_token, code }.
  4. On success, accessToken and user object are returned.

4. Password Requirements

Passwords must meet these requirements:

  • Minimum 8 characters
  • At least one uppercase letter (A-Z)
  • At least one lowercase letter (a-z)
  • At least one digit (0-9)

If requirements aren't met, registration/password-reset returns 400 Bad Request with details.

5. Error Handling

StatusMeaningAction
401 UnauthorizedNot logged in or token expiredRedirect to login.
403 ForbiddenAccount disabled, expired, or email not verifiedShow error message.
409 ConflictEmail already registeredShow validation error.

📡 Endpoints

1. Authentication & Session

Login

POST /login

  • Content-Type: application/json
  • Body: LoginRequest
{
"email": "user@example.com",
"password": "password123"
}
  • Response:
    • 200 OK: LoginResponse - Login successful. Returns accessToken and user.
    • 202 Accepted: Login2FARequiredResponse - 2FA required.
    • 401 Unauthorized: Invalid credentials.
    • 403 Forbidden: Account disabled, expired, or email not verified.

Logout

DELETE /logout

  • Auth Required: Yes (Authorization: Bearer <token>)
  • Response: 204 No Content. Access token blacklisted in Redis.
  • Note: Access token is immediately invalidated and cannot be reused.

Get Profile

GET /profile

  • Auth Required: Yes
  • Response: User

Delete Account

DELETE /account

  • Auth Required: Yes
  • Response: 204 No Content. Account deleted.

2. Registration & Verification

Register

POST /register

  • Content-Type: application/json
  • Body: RegisterRequest
{
"email": "user@example.com",
"name": "John Doe",
"password": "securepassword",
"termsPrivacyAccepted": true
}
  • Response: 201 Created RegisterResponse
  • Errors:
    • 400 Bad Request: Terms not accepted.
    • 403 Forbidden: Registration disabled.
    • 409 Conflict: Email already registered.

Verify Email

POST /verify

  • Content-Type: application/json
  • Body: VerifyEmailRequest
{
"token": "verification_token_from_email"
}
  • Response: 200 OK { message, email }

Resend Verification

POST /resend-verification

  • Content-Type: application/json
  • Body:
{
"email": "user@example.com"
}
  • Response: 200 OK MessageResponse
    • Always returns success to prevent email enumeration.

3. Password Reset

Request Password Reset

POST /password/reset

  • Content-Type: application/json
  • Body: PasswordResetRequest
{
"email": "user@example.com"
}
  • Response: 200 OK { message: "If email exists, reset link sent" }
    • Always returns success to prevent email enumeration.

Update Password

POST /password/update

  • Content-Type: application/json
  • Body: PasswordUpdateRequest
{
"token": "reset_token_from_email",
"password": "new_secure_password"
}
  • Response: 200 OK { message: "Password updated successfully" }
  • Errors:
    • 400 Bad Request: Invalid or expired token.
    • 404 Not Found: User not found.

4. OpenID Connect (Social Login)

Supported providers: google, facebook, apple

Initiate OAuth Flow

GET /openid/auth

  • Query Params:
    • provider: google | facebook | apple
    • ret: web (default) | app
  • Response: 307 Redirect to provider's OAuth page.

OAuth Callback (Internal)

GET/POST /openid/callback

  • Internal: Handled automatically by OAuth flow.
  • Redirects:
    • Success → Frontend with tokens
    • 2FA Required → /login/2fa?token=...&type=...
    • Error → /login?error=...

Mobile Token Exchange

POST /openid/token

  • Content-Type: application/json
  • Body: OpenIDTokenRequest
{
"provider": "google",
"id_token": "GOOGLE_ID_TOKEN_HERE"
}
  • Note: Only Google is supported for mobile token exchange.
  • Response: 200 OK OpenIDTokenResponse

5. Two-Factor Authentication (2FA)

Setup TOTP

POST /2fa/setup

  • Auth Required: Yes
  • Body: None
  • Response: 200 OK TwoFactorSetupResponse
{
"secret": "JBSWY3DPEHPK3PXP",
"otpauth_url": "otpauth://totp/Visla%20GPS:user@example.com?secret=JBSWY3DPEHPK3PXP&issuer=Visla%20GPS"
}
  • Error: 400 Bad Request if TOTP already enabled.
  • Note: Secret is stored in Redis for 10 minutes. Use otpauth_url to generate QR code.

Verify & Enable 2FA

POST /2fa/verify

  • Auth Required: Yes
  • Content-Type: application/json
  • Body:
{
"code": "123456"
}
  • Response: 200 OK TwoFactorVerifyResponse
{
"message": "TOTP enabled",
"backup_codes": ["a1b2c3d4", "e5f6g7h8", ...]
}
  • Important: Save the backup codes! They are only shown once.

Disable 2FA

POST /2fa/disable

  • Auth Required: Yes
  • Body: None
  • Response: 200 OK { message: "2FA disabled" }

Regenerate Backup Codes

POST /2fa/regenerate

  • Auth Required: Yes
  • Body: None
  • Response: 200 OK
{
"message": "Backup codes regenerated",
"backup_codes": ["a1b2c3d4", "e5f6g7h8", ...]
}
  • Error: 400 Bad Request if 2FA not enabled.

Complete 2FA Login

POST /2fa/login

  • Auth Required: No (uses temp_token)
  • Content-Type: application/json
  • Body: Login2FARequest
{
"temp_token": "token_from_login_response",
"code": "123456"
}
  • Response: 200 OK User - Cookies set on success.
  • Error: 401 Unauthorized if code invalid or token expired (5 min).

6. Internal Endpoints

Validate Token (Nginx auth_request)

GET /validate

  • Cookies: access_token
  • Response:
    • 200 OK: Token valid, user active.
    • 401 Unauthorized: Token invalid or user inactive.
  • Note: Used by Nginx auth_request directive for protected routes.

Health Check

GET /health

  • Response: 200 OK HealthResponse
{
"status": "healthy",
"service": "auth-service",
"ready": true,
"database": "connected"
}