/** * @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;