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
-
Desktop Browser Requests QR Code
- POST
/auth/qr/generatewith desktop device info - Backend creates session in database
- Returns QR code image
- POST
-
Frontend Starts Polling
- Every 2 seconds: GET
/auth/qr/status/:sessionId - Backend returns
{ authenticated: false }
- Every 2 seconds: GET
-
Mobile App Scans QR
- Parse QR code to get sessionId
- POST
/auth/qr/scanwith mobile device info - Backend authenticates user
- Backend updates session as authenticated
- Returns JWT token
-
Desktop Polling Detects Auth
- Next poll returns
{ authenticated: true, token: "..." } - Frontend stores token
- Redirects to application
- Next poll returns
📊 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
projectare optional - Send
nullfor 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
- QR Code Expiration: 60 seconds (configurable)
- JWT Token Expiration: 24 hours (configurable)
- Polling Interval: 2 seconds
- Rate Limiting: 60 requests/minute per IP
- CORS: Allow all project domains
- 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:
- Email: backend@dx-projects.com
- Slack: #backend-auth
- Documentation: https://docs.dx-projects.com/auth