Files
auth-service/BACKEND_API.md
2026-01-26 16:21:23 +04:00

11 KiB

Backend API Documentation - Auth Service

Complete API documentation for implementing the backend for the DX Authentication Service.

📋 Overview

This authentication service provides QR code-based authentication with comprehensive device tracking for all DX projects (Dexar, Novo Markets, FastCheck, BackOffice).

Base URL:

  • Development: http://localhost:3000/api
  • Production: https://api.dx-projects.com/api

🔐 Endpoints

1. Generate QR Code

Generate a new QR code session for authentication.

Endpoint: POST /auth/qr/generate

Request Body:

{
  "project": "dexar",
  "deviceInfo": {
    "deviceType": "desktop",
    "deviceOS": "windows",
    "context": "browser",
    "project": "dexar",
    "userAgent": "Mozilla/5.0...",
    "screenResolution": "1920x1080",
    "browserName": "Chrome",
    "browserVersion": "120.0.0"
  }
}

Request Schema:

Field Type Required Description
project string Yes Project ID: dexar, novo, fastcheck, backoffice
deviceInfo.deviceType string|null No mobile, desktop, tablet
deviceInfo.deviceOS string|null No android, ios, windows, macos, linux
deviceInfo.context string|null No browser, application, telegram
deviceInfo.project string Yes Same as root project
deviceInfo.userAgent string No Browser user agent
deviceInfo.screenResolution string No e.g. "1920x1080"
deviceInfo.browserName string No Browser name
deviceInfo.browserVersion string No Browser version

Response: 200 OK

{
  "sessionId": "550e8400-e29b-41d4-a716-446655440000",
  "qrCode": "data:image/png;base64,iVBORw0KGgo...",
  "expiresAt": "2026-01-26T15:30:00.000Z",
  "expiresIn": 60
}

QR Code Content Should Be:

{
  "sessionId": "550e8400-e29b-41d4-a716-446655440000",
  "apiUrl": "https://api.dx-projects.com/api"
}

2. Scan QR Code (Mobile Auth)

Scan and authenticate using a QR code session.

Endpoint: POST /auth/qr/scan

Request Body:

{
  "sessionId": "550e8400-e29b-41d4-a716-446655440000",
  "deviceInfo": {
    "deviceType": "mobile",
    "deviceOS": "android",
    "context": "application",
    "project": "dexar",
    "userAgent": "Mozilla/5.0...",
    "screenResolution": "1080x2400",
    "browserName": "Chrome Mobile",
    "browserVersion": "120.0.0"
  }
}

Response: 200 OK

{
  "success": true,
  "token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...",
  "userId": "user-123",
  "expiresAt": "2026-01-27T14:30:00.000Z",
  "message": "Authentication successful",
  "userInfo": {
    "username": "john_doe",
    "email": "john@example.com",
    "role": "admin"
  }
}

3. Check Auth Status (Polling)

Check if a QR session has been authenticated. Used for polling every 2 seconds.

Endpoint: GET /auth/qr/status/:sessionId

Response (Not Authenticated): 200 OK

{
  "authenticated": false
}

Response (Authenticated): 200 OK

{
  "authenticated": true,
  "token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...",
  "userId": "user-123",
  "expiresAt": "2026-01-27T14:30:00.000Z",
  "userInfo": {
    "username": "john_doe",
    "email": "john@example.com",
    "role": "admin"
  }
}

4. Traditional Login

Username/password authentication (alternative to QR).

Endpoint: POST /auth/login

Request Body:

{
  "username": "john_doe",
  "password": "secure_password_123",
  "deviceInfo": {
    "deviceType": "desktop",
    "deviceOS": "windows",
    "context": "browser",
    "project": "backoffice"
  }
}

Response: 200 OK

{
  "success": true,
  "token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...",
  "userId": "user-123",
  "expiresAt": "2026-01-27T14:30:00.000Z",
  "message": "Login successful",
  "userInfo": {
    "username": "john_doe",
    "email": "john@example.com",
    "role": "admin"
  }
}

5. Validate Session

Validate an existing JWT token.

Endpoint: POST /auth/validate

Headers:

Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...

Request Body:

{
  "deviceInfo": {
    "deviceType": "desktop",
    "deviceOS": "windows",
    "context": "browser",
    "project": "dexar"
  }
}

Response: 200 OK

{
  "valid": true,
  "userId": "user-123",
  "expiresAt": "2026-01-27T14:30:00.000Z",
  "userInfo": {
    "username": "john_doe",
    "email": "john@example.com",
    "role": "admin"
  }
}

6. Logout

Invalidate current session.

Endpoint: POST /auth/logout

Headers:

Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...

Request Body:

{
  "deviceInfo": {
    "deviceType": "desktop",
    "deviceOS": "windows",
    "context": "browser",
    "project": "dexar"
  }
}

Response: 200 OK

{
  "success": true,
  "message": "Logged out successfully"
}

💾 Database Schema

Sessions Table

CREATE TABLE auth_sessions (
  id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
  session_id VARCHAR(255) UNIQUE NOT NULL,
  project VARCHAR(50) NOT NULL,
  device_type VARCHAR(20),
  device_os VARCHAR(20),
  context VARCHAR(20),
  user_agent TEXT,
  screen_resolution VARCHAR(20),
  browser_name VARCHAR(50),
  browser_version VARCHAR(20),
  authenticated BOOLEAN DEFAULT FALSE,
  user_id UUID,
  ip_address VARCHAR(45),
  created_at TIMESTAMP DEFAULT NOW(),
  expires_at TIMESTAMP NOT NULL,
  authenticated_at TIMESTAMP,
  INDEX idx_session_id (session_id),
  INDEX idx_expires_at (expires_at),
  INDEX idx_user_id (user_id)
);

Auth Logs Table

CREATE TABLE auth_logs (
  id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
  user_id UUID,
  project VARCHAR(50) NOT NULL,
  action VARCHAR(50) NOT NULL, -- login, logout, qr_scan, validate, qr_generate
  device_type VARCHAR(20),
  device_os VARCHAR(20),
  context VARCHAR(20),
  user_agent TEXT,
  ip_address VARCHAR(45),
  success BOOLEAN,
  error_message TEXT,
  created_at TIMESTAMP DEFAULT NOW(),
  INDEX idx_user_id (user_id),
  INDEX idx_created_at (created_at),
  INDEX idx_project (project)
);

🔒 Security Implementation

Password Hashing

const bcrypt = require('bcrypt');
const saltRounds = 12;

// Hash password
const hashedPassword = await bcrypt.hash(password, saltRounds);

// Verify password
const isValid = await bcrypt.compare(password, hashedPassword);

JWT Token Generation

const jwt = require('jsonwebtoken');

const token = jwt.sign(
  {
    userId: user.id,
    project: deviceInfo.project,
    deviceType: deviceInfo.deviceType
  },
  process.env.JWT_SECRET,
  { expiresIn: '24h' }
);

QR Code Generation

const QRCode = require('qrcode');

const qrData = {
  sessionId: sessionId,
  apiUrl: process.env.API_URL
};

const qrCodeImage = await QRCode.toDataURL(JSON.stringify(qrData));

🚀 Implementation Flow

QR Authentication Flow

  1. Desktop Browser Requests QR Code

    • POST /auth/qr/generate with desktop device info
    • Backend creates session in database
    • Returns QR code image
  2. Frontend Starts Polling

    • Every 2 seconds: GET /auth/qr/status/:sessionId
    • Backend returns { authenticated: false }
  3. Mobile App Scans QR

    • Parse QR code to get sessionId
    • POST /auth/qr/scan with mobile device info
    • Backend authenticates user
    • Backend updates session as authenticated
    • Returns JWT token
  4. Desktop Polling Detects Auth

    • Next poll returns { authenticated: true, token: "..." }
    • Frontend stores token
    • Redirects to application

📊 Device Info Tracking

When to Send Device Info

Send device info on:

  • QR code generation (desktop)
  • QR code scanning (mobile)
  • Traditional login
  • Session validation
  • Logout

Device Info Rules:

  • All fields except project are optional
  • Send null for unknown values
  • Never fail request if device info is incomplete
  • Log all device info for analytics

⚠️ Error Handling

Error Response Format

{
  "error": true,
  "message": "Invalid credentials",
  "code": "INVALID_CREDENTIALS"
}

Error Codes

Code HTTP Status Description
INVALID_PROJECT 400 Unknown project identifier
INVALID_SESSION 401 Session not found or expired
INVALID_CREDENTIALS 401 Wrong username/password
INVALID_TOKEN 401 JWT token invalid or expired
SESSION_EXPIRED 401 QR code session expired
RATE_LIMIT_EXCEEDED 429 Too many requests
SERVER_ERROR 500 Internal server error

🧪 Testing

Test Data

Test User:

{
  "username": "test_user",
  "password": "Test123!",
  "email": "test@dx-projects.com",
  "role": "user"
}

Example cURL Commands

Generate QR Code:

curl -X POST http://localhost:3000/api/auth/qr/generate \
  -H "Content-Type: application/json" \
  -d '{
    "project": "dexar",
    "deviceInfo": {
      "deviceType": "desktop",
      "deviceOS": "windows",
      "context": "browser",
      "project": "dexar"
    }
  }'

Check Status:

curl http://localhost:3000/api/auth/qr/status/{sessionId}

Login:

curl -X POST http://localhost:3000/api/auth/login \
  -H "Content-Type: application/json" \
  -d '{
    "username": "test_user",
    "password": "Test123!",
    "deviceInfo": {
      "deviceType": "desktop",
      "deviceOS": "windows",
      "context": "browser",
      "project": "dexar"
    }
  }'

📌 Important Notes

  1. QR Code Expiration: 60 seconds (configurable)
  2. JWT Token Expiration: 24 hours (configurable)
  3. Polling Interval: 2 seconds
  4. Rate Limiting: 60 requests/minute per IP
  5. CORS: Allow all project domains
  6. Session Cleanup: Delete expired sessions every hour

🔧 Environment Variables

# API Configuration
PORT=3000
API_URL=http://localhost:3000/api
NODE_ENV=development

# JWT
JWT_SECRET=your-super-secret-jwt-key-change-this
JWT_EXPIRATION=24h

# Database
DB_HOST=localhost
DB_PORT=5432
DB_NAME=dx_auth
DB_USER=postgres
DB_PASSWORD=your-password

# QR Code
QR_EXPIRATION=60
QR_SIZE=240

# CORS
CORS_ORIGINS=http://localhost:4200,http://localhost:4300,http://localhost:4400

# Rate Limiting
RATE_LIMIT_WINDOW=60000
RATE_LIMIT_MAX_REQUESTS=60

📚 Additional Resources

  • Frontend Integration: See HOW_TO_USE.md
  • Project Setup: See README.md
  • FastCheck APIs: Reference similar implementation in FastCheck project

🆘 Support

For backend implementation questions: