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
JavaScript
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