/**
 * Authentication Middleware
 * Generic authentication utilities for Express applications
 */
import { createLogger } from "../core/index.js";
let logger; // Will be initialized when needed
function ensureLogger() {
    if (!logger) {
        logger = createLogger("AuthMiddleware");
    }
    return logger;
}
/**
 * Creates authentication middleware with configuration
 */
export function createAuthMiddleware(config = {}) {
    const { loginPath = "/login", apiPrefix = "/api/", excludePaths = [], onUnauthorized, } = config;
    return function requireAuth(req, res, next) {
        // Check if path is excluded
        if (excludePaths.some((path) => req.path.startsWith(path))) {
            return next();
        }
        // Check if user is authenticated
        if (req.session && req.session.authenticated) {
            // Attach user to request
            req.user = {
                id: req.session.userId || "",
                username: req.session.username || "",
                roles: req.session.roles || [],
            };
            return next();
        }
        // Handle unauthorized access
        if (onUnauthorized) {
            return onUnauthorized(req, res);
        }
        // Default behavior
        if (req.path.startsWith(apiPrefix)) {
            // For API routes, return JSON error
            res.status(401).json({
                success: false,
                error: "Authentication required",
                message: "Please log in to access this resource",
            });
        }
        else {
            // For web routes, redirect to login
            res.redirect(loginPath);
        }
    };
}
export function createLoginHandler(authService) {
    return async (req, res) => {
        try {
            const { username, password } = req.body;
            if (!username || !password) {
                res.status(400).json({
                    success: false,
                    error: "Missing credentials",
                    message: "Username and password are required",
                });
                return;
            }
            const result = await authService.validateCredentials({
                username,
                password,
            });
            if (result.valid && result.user) {
                // Set session
                req.session.authenticated = true;
                req.session.username = result.user.username;
                req.session.userId = result.user.id;
                req.session.roles = result.user.roles;
                ensureLogger().info(`User logged in: ${username}`);
                res.json({
                    success: true,
                    user: {
                        username: result.user.username,
                        roles: result.user.roles,
                    },
                });
            }
            else {
                ensureLogger().warn(`Failed login attempt for user: ${username}`);
                res.status(401).json({
                    success: false,
                    error: "Invalid credentials",
                    message: result.error || "Invalid username or password",
                });
            }
        }
        catch (_error) {
            ensureLogger().error("Login error:", _error);
            res.status(500).json({
                success: false,
                error: "Login failed",
                message: "An error occurred during login",
            });
        }
    };
}
/**
 * Logout handler factory
 */
export function createLogoutHandler() {
    return (req, res) => {
        const username = req.session?.username;
        req.session.destroy((err) => {
            if (err) {
                ensureLogger().error("Error destroying session:", err);
                res.status(500).json({
                    success: false,
                    error: "Logout failed",
                });
                return;
            }
            if (username) {
                ensureLogger().info(`User logged out: ${username}`);
            }
            res.json({ success: true });
        });
    };
}
/**
 * Auth check handler
 */
export function createAuthCheckHandler() {
    return (req, res) => {
        if (req.session?.authenticated) {
            res.json({
                authenticated: true,
                user: {
                    username: req.session.username,
                    roles: req.session.roles,
                },
            });
        }
        else {
            res.status(401).json({
                authenticated: false,
            });
        }
    };
}
/**
 * Role-based access control middleware
 */
export function requireRole(roles) {
    const requiredRoles = Array.isArray(roles) ? roles : [roles];
    return (req, res, next) => {
        if (!req.user) {
            res.status(401).json({
                success: false,
                error: "Authentication required",
            });
            return;
        }
        const userRoles = req.user.roles || [];
        const hasRole = requiredRoles.some((role) => userRoles.includes(role));
        if (!hasRole) {
            res.status(403).json({
                success: false,
                error: "Insufficient permissions",
                message: `This action requires one of the following roles: ${requiredRoles.join(", ")}`,
            });
            return;
        }
        next();
    };
}
/**
 * Simple in-memory auth service for development
 */
export class SimpleAuthService {
    users;
    constructor(users = []) {
        this.users = new Map();
        // Add default admin user if no users provided
        if (users.length === 0) {
            users = [
                {
                    username: "admin",
                    password: "admin",
                    id: "admin-1",
                    roles: ["admin"],
                },
            ];
        }
        users.forEach((user) => {
            this.users.set(user.username, {
                password: user.password,
                id: user.id || `user-${user.username}`,
                roles: user.roles,
            });
        });
    }
    async validateCredentials(credentials) {
        const user = this.users.get(credentials.username);
        if (!user || user.password !== credentials.password) {
            return {
                valid: false,
                error: "Invalid username or password",
            };
        }
        return {
            valid: true,
            user: {
                id: user.id,
                username: credentials.username,
                roles: user.roles,
            },
        };
    }
    addUser(username, password, roles) {
        this.users.set(username, {
            password,
            id: `user-${username}`,
            roles,
        });
    }
}
export default {
    createAuthMiddleware,
    createLoginHandler,
    createLogoutHandler,
    createAuthCheckHandler,
    requireRole,
    SimpleAuthService,
};
//# sourceMappingURL=auth.js.map