UNPKG

adpa-enterprise-framework-automation

Version:

Modular, standards-compliant Node.js/TypeScript automation framework for enterprise requirements, project, and data management. Provides CLI and API for BABOK v3, PMBOK 7th Edition, and DMBOK 2.0 (in progress). Production-ready Express.js API with TypeSpe

121 lines 4.89 kB
import * as jwt from 'jsonwebtoken'; import { logger } from '../../config/logger.js'; // Simple API key authentication for development export const authMiddleware = async (req, res, next) => { try { const authHeader = req.headers.authorization; const apiKey = req.headers['x-api-key']; // Skip auth for health checks and development if (req.path.includes('/health') || process.env.NODE_ENV === 'development' && process.env.SKIP_AUTH === 'true') { return next(); } // Check for API key first (simpler authentication) if (apiKey) { const validApiKeys = process.env.API_KEYS?.split(',') || ['dev-api-key-123']; if (validApiKeys.includes(apiKey)) { req.user = { id: 'api-user', email: 'api@adpa.io', role: 'service', permissions: ['read', 'write', 'admin'] }; req.apiKey = apiKey; logger.debug(`API key authentication successful for ${req.method} ${req.path}`); return next(); } else { logger.warn(`Invalid API key attempted: ${apiKey.substring(0, 8)}...`); return res.status(401).json({ error: true, message: 'Invalid API key', code: 'INVALID_API_KEY' }); } } // Check for JWT token if (authHeader && authHeader.startsWith('Bearer ')) { const token = authHeader.substring(7); const jwtSecret = process.env.JWT_SECRET || 'development-secret-key'; try { const decoded = jwt.verify(token, jwtSecret); req.user = { id: decoded.sub || decoded.id, email: decoded.email, role: decoded.role || 'user', permissions: decoded.permissions || ['read'] }; logger.debug(`JWT authentication successful for user ${req.user.email}`); return next(); } catch (jwtError) { logger.warn(`Invalid JWT token: ${jwtError.message}`); return res.status(401).json({ error: true, message: 'Invalid or expired token', code: 'INVALID_TOKEN' }); } } // No authentication provided logger.warn(`No authentication provided for ${req.method} ${req.path}`); return res.status(401).json({ error: true, message: 'Authentication required. Provide either X-API-Key header or Authorization Bearer token.', code: 'AUTHENTICATION_REQUIRED', hint: process.env.NODE_ENV === 'development' ? 'Use X-API-Key: dev-api-key-123 for development' : undefined }); } catch (error) { logger.error('Authentication error:', error); return res.status(500).json({ error: true, message: 'Authentication service error', code: 'AUTH_SERVICE_ERROR' }); } }; // Role-based authorization middleware export const requireRole = (roles) => { return (req, res, next) => { if (!req.user) { return res.status(401).json({ error: true, message: 'Authentication required', code: 'AUTHENTICATION_REQUIRED' }); } if (!roles.includes(req.user.role)) { logger.warn(`Access denied for user ${req.user.email} with role ${req.user.role}. Required: ${roles.join(', ')}`); return res.status(403).json({ error: true, message: `Access denied. Required role: ${roles.join(' or ')}`, code: 'INSUFFICIENT_PERMISSIONS' }); } next(); }; }; // Permission-based authorization middleware export const requirePermission = (permission) => { return (req, res, next) => { if (!req.user) { return res.status(401).json({ error: true, message: 'Authentication required', code: 'AUTHENTICATION_REQUIRED' }); } if (!req.user.permissions.includes(permission) && !req.user.permissions.includes('admin')) { logger.warn(`Access denied for user ${req.user.email}. Missing permission: ${permission}`); return res.status(403).json({ error: true, message: `Access denied. Required permission: ${permission}`, code: 'INSUFFICIENT_PERMISSIONS' }); } next(); }; }; // Alias for backward compatibility export const apiKeyAuth = authMiddleware; //# sourceMappingURL=auth.js.map