Files
CLProject/src/routes/authRoutes.js
T
2026-04-22 22:39:26 +02:00

236 lines
5.6 KiB
JavaScript

/**
* @openapi
* /api/v1/auth:
* post:
* summary: Admin login
* tags:
* - Authentication
* requestBody:
* required: true
* content:
* application/json:
* schema:
* type: object
* required:
* - username
* - password
* properties:
* username:
* type: string
* password:
* type: string
* responses:
* 200:
* description: Login successful
* 401:
* description: Invalid credentials
* get:
* summary: Check session
* tags:
* - Authentication
* responses:
* 200:
* description: Session valid
* 401:
* description: Session invalid
*/
/*
* Authentication routes for the PoC application.
*
* Provides endpoints for:
* - POST /auth/admin/login - Admin login
* - POST /auth/user/login - User login
* - POST /auth/logout - Logout (both admin and user)
* - GET /auth/check - Check current session validity
*/
import { Router } from 'express';
import { asyncHandler } from '../utils/asyncHandler.js';
import {
verifyAdminCredentials,
verifyUserCredentials,
generateSessionToken,
createSession,
removeSession,
validateSession
} from '../services/authService.js';
const router = Router();
/**
* @openapi
* /api/v1/auth/admin/login:
* post:
* summary: Admin login
* tags:
* - Authentication
* requestBody:
* required: true
* content:
* application/json:
* schema:
* type: object
* required:
* - username
* - password
* properties:
* username:
* type: string
* password:
* type: string
* responses:
* 200:
* description: Login successful
* 401:
* description: Invalid credentials
*/
router.post(
'/admin/login',
asyncHandler(async (req, res) => {
const { username, password } = req.body;
console.log(`PUBLIC: POST /api/v1/auth/admin/login - user: ${username}`);
if (!username || !password) {
return res.status(400).json({ success: false, message: 'Username and password required.' });
}
const result = await verifyAdminCredentials(username, password);
if (!result.valid) {
return res.status(401).json({ success: false, message: 'Invalid credentials.' });
}
const token = generateSessionToken();
createSession(token, { type: 'admin', ...result.admin });
/* Set cookie for browser-based auth */
res.cookie('auth_token', token, {
httpOnly: true,
maxAge: 24 * 60 * 60 * 1000, // 24 hours
sameSite: 'lax'
});
return res.json({ success: true, token, admin: result.admin });
})
);
/**
* @openapi
* /api/v1/auth/user/login:
* post:
* summary: User login
* tags:
* - Authentication
* requestBody:
* required: true
* content:
* application/json:
* schema:
* type: object
* required:
* - email
* - password
* properties:
* email:
* type: string
* password:
* type: string
* responses:
* 200:
* description: Login successful
* 401:
* description: Invalid credentials
*/
router.post(
'/user/login',
asyncHandler(async (req, res) => {
const { email, password } = req.body;
console.log(`PUBLIC: POST /api/v1/auth/user/login - email: ${email}`);
if (!email || !password) {
return res.status(400).json({ success: false, message: 'Email and password required.' });
}
const result = await verifyUserCredentials(email, password);
if (!result.valid) {
return res.status(401).json({ success: false, message: 'Invalid credentials.' });
}
const token = generateSessionToken();
createSession(token, { type: 'user', ...result.user });
/* Set cookie for browser-based auth */
res.cookie('auth_token', token, {
httpOnly: true,
maxAge: 24 * 60 * 60 * 1000, // 24 hours
sameSite: 'lax'
});
return res.json({ success: true, token, user: result.user });
})
);
/**
* @openapi
* /api/v1/auth/logout:
* post:
* summary: Logout
* tags:
* - Authentication
* responses:
* 200:
* description: Logged out
*/
router.post('/logout', (req, res) => {
const token = req.cookies?.auth_token || req.headers.authorization?.replace('Bearer ', '');
console.log(`PUBLIC: POST /api/v1/auth/logout`);
if (token) {
removeSession(token);
}
res.clearCookie('auth_token');
return res.json({ success: true, message: 'Logged out.' });
});
/**
* @openapi
* /api/v1/auth/check:
* get:
* summary: Check session validity
* tags:
* - Authentication
* security:
* - cookieAuth: []
* responses:
* 200:
* description: Session valid
* 401:
* description: Session invalid
*/
router.get('/check', (req, res) => {
const token = req.cookies?.auth_token || req.headers.authorization?.replace('Bearer ', '');
console.log(`PUBLIC: GET /api/v1/auth/check`);
if (!token) {
return res.status(401).json({ authenticated: false, message: 'No session token.' });
}
const session = validateSession(token);
if (!session) {
res.clearCookie('auth_token');
return res.status(401).json({ authenticated: false, message: 'Session expired or invalid.' });
}
return res.json({ authenticated: true, session });
});
export default router;