// 🤠 Heady Authentication Status Endpoint - System Health & Stats /** * Returns authentication system status and statistics * Used for health checks, monitoring, and admin dashboards */ import type { APIRoute } from 'astro'; import { getSessionManager } from '../../../lib/auth/session-manager.js'; import { getRoleMappingConfig, loadAuthentikConfig, validateAuthentikConfig, } from '../../../lib/config/authentik.js'; // Force SSR — this route reads env vars and must not be prerendered export const prerender = false; export const GET: APIRoute = async ({ url, cookies }) => { try { // Load configuration const config = loadAuthentikConfig(); const validation = validateAuthentikConfig(); const roleMappingConfig = getRoleMappingConfig(); // Check if detailed stats are requested (requires admin access) const includeStats = url.searchParams.get('stats') === 'true'; // Basic status available to everyone const basicStatus = { service: 'Heady Authentication', status: validation.valid ? 'healthy' : 'configuration_error', version: '1.0.0', authentik_configured: !!config.issuer, authentication: { provider: 'Authentik OIDC', issuer: config.issuer, redirect_uri: config.redirectUri, }, timestamp: new Date().toISOString(), }; if (!validation.valid) { return new Response( JSON.stringify({ ...basicStatus, errors: validation.errors, }), { status: 503, // Service Unavailable headers: { 'Content-Type': 'application/json' }, }, ); } // If detailed stats not requested, return basic status if (!includeStats) { return new Response(JSON.stringify(basicStatus), { status: 200, headers: { 'Content-Type': 'application/json' }, }); } // Detailed stats require authentication const sessionMgr = getSessionManager(); const validationResult = await sessionMgr.validateSession({ cookies }); if (!validationResult.valid || !validationResult.user) { return new Response( JSON.stringify({ ...basicStatus, error: 'Authentication required for detailed statistics', login_url: '/api/auth/login', }), { status: 401, headers: { 'Content-Type': 'application/json' }, }, ); } const user = validationResult.user; // Check if user can view statistics (admin/auditor roles) const canViewStats = ['owner', 'admin', 'auditor'].includes(user.role); if (!canViewStats) { return new Response( JSON.stringify({ ...basicStatus, error: 'Insufficient permissions for detailed statistics', required_roles: ['owner', 'admin', 'auditor'], user_role: user.role, }), { status: 403, headers: { 'Content-Type': 'application/json' }, }, ); } // Get session statistics (simplified for now) const activeSessionCount = await sessionMgr.getActiveCount(); const detailedStatus = { ...basicStatus, configuration: { scopes: config.scopes, role_mapping: { environment_configured: Object.values(roleMappingConfig).some( (groups) => groups.length > 0, ), owner_groups: roleMappingConfig.ownerGroups, admin_groups: roleMappingConfig.adminGroups, network_admin_groups: roleMappingConfig.networkGroups, it_admin_groups: roleMappingConfig.itGroups, auditor_groups: roleMappingConfig.auditorGroups, }, }, sessions: { total_active: activeSessionCount, // Additional session stats would go here }, system: { uptime: process.uptime(), memory_usage: process.memoryUsage(), node_version: process.version, environment: process.env.NODE_ENV || 'unknown', }, }; console.log(`✓ Auth status requested by ${user.email} (${user.role})`); console.log(` Active sessions: ${activeSessionCount}`); return new Response(JSON.stringify(detailedStatus), { status: 200, headers: { 'Content-Type': 'application/json' }, }); } catch (error) { console.error('❌ Auth status error:', error); return new Response( JSON.stringify({ service: 'Heady Authentication', status: 'error', error: 'Status check failed', message: error instanceof Error ? error.message : 'Unknown error', timestamp: new Date().toISOString(), }), { status: 500, headers: { 'Content-Type': 'application/json' }, }, ); } };