import { useExtendContext } from 'graphql-yoga';
import { handleDevBypassAuth } from '../modules/auth/providers/auth-context.provider.js';
import { BUSINESS_SCOPE_HEADER, parseBusinessScopeHeader } from './business-scope-header.js';
/**
 * AuthPlugin - Extracts authentication credentials from request headers.
 *
 * This plugin is part of the Auth0 authentication system.
 * It ONLY handles credential extraction. Verification and context creation
 * are delegated to the AuthContextProvider.
 *
 * Responsibilities:
 * 1. Extract `X-Dev-Auth: <user-id>` (Dev Bypass, gated by ALLOW_DEV_AUTH=1)
 * 1. Extract `Authorization: Bearer <token>` (JWT)
 * 2. Extract `X-API-Key: <key>` (API Key)
 * 3. Add `rawAuth` object to Yoga context
 */
export const authPlugin = () => {
    const allowDevAuth = process.env.ALLOW_DEV_AUTH === '1';
    if (allowDevAuth) {
        // eslint-disable-next-line no-console
        console.warn('⚠️ DEV AUTH BYPASS ENABLED');
    }
    return useExtendContext(async (yogaContext) => {
        const request = yogaContext.request;
        const devAuthHeader = request.headers.get('x-dev-auth');
        const authHeader = request.headers.get('authorization');
        const apiKeyHeader = request.headers.get('x-api-key');
        const gatewayCpTokenHeader = request.headers.get('x-gateway-cp-token');
        // Parse the requested read scope once. Attach it only when the header was
        // actually sent, so requests without it keep the original rawAuth shape.
        const parsedScope = parseBusinessScopeHeader(request.headers.get(BUSINESS_SCOPE_HEADER));
        const scopeFields = parsedScope.kind === 'absent' ? {} : { requestedBusinessScope: parsedScope };
        // Dev bypass takes precedence when explicitly enabled and user is resolvable.
        if (allowDevAuth && devAuthHeader) {
            const userId = devAuthHeader.trim();
            if (userId.length > 0) {
                const pool = yogaContext.pool;
                if (pool) {
                    const db = {
                        query: async (queryStatement, values) => {
                            const result = await pool.query(queryStatement, values);
                            return {
                                ...result,
                                rowCount: typeof result.rowCount === 'number'
                                    ? result.rowCount
                                    : 0,
                            };
                        },
                    };
                    const context = await handleDevBypassAuth(db, userId);
                    if (context) {
                        return {
                            rawAuth: {
                                authType: 'devBypass',
                                token: userId,
                                ...scopeFields,
                            },
                        };
                    }
                }
            }
        }
        // Gateway control-plane service identity (no tenant context)
        if (gatewayCpTokenHeader) {
            const token = gatewayCpTokenHeader.trim();
            if (token.length > 0) {
                return {
                    rawAuth: {
                        authType: 'gatewayControlPlane',
                        token,
                        ...scopeFields,
                    },
                };
            }
        }
        // JWT takes precedence (e.g., user operations)
        if (authHeader?.startsWith('Bearer ')) {
            const token = authHeader.substring(7).trim();
            if (token.length > 0) {
                return {
                    rawAuth: {
                        authType: 'jwt',
                        token,
                        ...scopeFields,
                    },
                };
            }
        }
        // Fallback to API key (e.g., automated tools)
        if (apiKeyHeader) {
            const token = apiKeyHeader.trim();
            if (token.length > 0) {
                return {
                    rawAuth: {
                        authType: 'apiKey',
                        token,
                        ...scopeFields,
                    },
                };
            }
        }
        // Unauthenticated or malformed headers
        return {
            rawAuth: {
                authType: null,
                token: null,
                ...scopeFields,
            },
        };
    });
};
//# sourceMappingURL=auth-plugin.js.map