import { Request, Response } from 'express'; import { DyNTS_AuthService } from '../../../_services/core/auth.service'; import { DyFM_Error } from '@futdevpro/fsm-dynamo'; import { DyNTS_global_settings } from '../../../_collections/global-settings.const'; /** * Default Authentication Service * Basic token-based authentication * Can be extended for custom auth logic */ export class DyNTS_Default_AuthService extends DyNTS_AuthService { static getInstance(): DyNTS_Default_AuthService { return DyNTS_Default_AuthService.getSingletonInstance(); } /** * Extract user ID from request * Override for custom logic */ getUserIdFromRequest(req: Request): string { // Default: extract from auth header or query param const userId = req.headers['x-user-id'] as string || req.query.userId as string; if (!userId) { throw new DyFM_Error({ message: 'User ID not found in request', errorCode: `${DyNTS_global_settings.systemShortCodeName}|DyNTS-DEF-AUTH-GUID`, userMessage: 'Authentication required.', }); } return userId; } /** * Extract username from request * Override for custom logic */ getUsernameFromRequest(req: Request): string { const username = req.headers['x-username'] as string || req.query.username as string; if (!username) { return 'anonymous'; } return username; } /** * Validate user token * Override for custom token validation */ async validateToken(token: string): Promise { // Default: basic validation (can be extended) return token && token.length > 0; } /** * Get user roles from request * Override for custom role extraction */ getUserRolesFromRequest(req: Request): string[] { const roles = req.headers['x-user-roles'] as string || req.query.roles as string; if (!roles) { return ['user']; // Default role } try { return JSON.parse(roles); } catch { return [roles]; // Single role as string } } /** * Extract issuer from request * Required abstract method implementation */ getIssuerFromRequest(req: Request): string { return this.getUserIdFromRequest(req); } /** * Authenticate token * Required abstract method implementation */ authenticate_token = async (req: Request, res: Response): Promise => { try { const token = req.headers.authorization?.replace('Bearer ', '') || req.query.token as string; if (!token) { res.status(401).json({ error: 'Token required' }); return; } const isValid = await this.validateToken(token); if (!isValid) { res.status(401).json({ error: 'Invalid token' }); return; } // Token is valid, continue res.status(200).json({ success: true }); } catch (error) { res.status(500).json({ error: 'Authentication failed' }); } }; /** * Authenticate token for self operations * Required abstract method implementation */ authenticate_tokenSelf = async (req: Request, res: Response): Promise => { try { const userId = this.getUserIdFromRequest(req); const token = req.headers.authorization?.replace('Bearer ', '') || req.query.token as string; if (!token) { res.status(401).json({ error: 'Token required' }); return; } const isValid = await this.validateToken(token); if (!isValid) { res.status(401).json({ error: 'Invalid token' }); return; } // Add user ID to request for downstream use (req as any).authenticatedUserId = userId; res.status(200).json({ success: true, userId }); } catch (error) { res.status(500).json({ error: 'Authentication failed' }); } }; /** * Authenticate token with permission and usage data * Required abstract method implementation */ authenticate_tokenPerm_accUsageData = async (req: Request, res: Response): Promise => { try { const userId = this.getUserIdFromRequest(req); const token = req.headers.authorization?.replace('Bearer ', '') || req.query.token as string; if (!token) { res.status(401).json({ error: 'Token required' }); return; } const isValid = await this.validateToken(token); if (!isValid) { res.status(401).json({ error: 'Invalid token' }); return; } // Add user data to request for downstream use (req as any).authenticatedUserId = userId; (req as any).userRoles = this.getUserRolesFromRequest(req); (req as any).usageData = { timestamp: new Date(), endpoint: req.path, method: req.method, }; res.status(200).json({ success: true, userId, roles: this.getUserRolesFromRequest(req) }); } catch (error) { res.status(500).json({ error: 'Authentication failed' }); } }; }