"use strict";
var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
    var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
    if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
    else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
    return c > 3 && r && Object.defineProperty(target, key, r), r;
};
var __metadata = (this && this.__metadata) || function (k, v) {
    if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
};
var __importDefault = (this && this.__importDefault) || function (mod) {
    return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.TokenResponseInterceptor = void 0;
const common_1 = require("@nestjs/common");
const operators_1 = require("rxjs/operators");
const auth_config_service_1 = require("../../core/services/auth-config.service");
const auth_constants_1 = require("../../auth.constants");
const ms_1 = __importDefault(require("ms"));
const lodash_1 = require("lodash");
const cookie_helper_1 = require("../../utils/cookie.helper");
const debug_logger_service_1 = require("../../core/services/debug-logger.service");
let TokenResponseInterceptor = class TokenResponseInterceptor {
    debugLogger;
    options;
    constructor(debugLogger) {
        this.debugLogger = debugLogger;
        this.options = auth_config_service_1.AuthConfigService.getOptions();
    }
    isUsingCookies(req) {
        const headerTokenType = req.headers['x-access-token-type'];
        if (!this.options.accessTokenType && headerTokenType === 'cookie') {
            this.debugLogger.debug('Using cookies mode (from x-access-token-type header)', 'TokenResponseInterceptor', { headerTokenType });
            return true;
        }
        else if (this.options.accessTokenType === 'cookie') {
            this.debugLogger.debug('Using cookies mode (from config)', 'TokenResponseInterceptor', { configTokenType: this.options.accessTokenType });
            return true;
        }
        this.debugLogger.debug('Using header mode for tokens', 'TokenResponseInterceptor', { configTokenType: this.options.accessTokenType, headerTokenType });
        return false;
    }
    async intercept(context, next) {
        const ctx = context.switchToHttp();
        const req = ctx.getRequest();
        const res = ctx.getResponse();
        const isUsingCookies = await this.isUsingCookies(req);
        this.debugLogger.logFunctionEntry('intercept', 'TokenResponseInterceptor', {
            method: req.method,
            url: req.url,
            isUsingCookies
        });
        return next.handle().pipe((0, operators_1.map)(data => {
            if (!data) {
                this.debugLogger.debug('No data to process', 'TokenResponseInterceptor');
                return data;
            }
            if (isUsingCookies) {
                this.debugLogger.debug('Setting tokens in cookies and removing from response body', 'TokenResponseInterceptor', {
                    hasAccessToken: !!data.accessToken,
                    hasRefreshToken: !!data.refreshToken,
                    hasTrustToken: !!data.trustToken
                });
                this.setTokens(res, data);
                return (0, lodash_1.omit)(data, ['accessToken', 'refreshToken', 'trustToken']);
            }
            this.debugLogger.debug('Returning tokens in response body (header mode)', 'TokenResponseInterceptor', {
                hasAccessToken: !!data.accessToken,
                hasRefreshToken: !!data.refreshToken
            });
            return data;
        }));
    }
    setTokens(response, tokens) {
        if (tokens.accessToken) {
            this.debugLogger.debug(`Setting access token cookie: ${auth_constants_1.ACCESS_TOKEN_COOKIE_NAME}`, 'TokenResponseInterceptor');
            this.setCookie(response, auth_constants_1.ACCESS_TOKEN_COOKIE_NAME, tokens.accessToken);
        }
        if (tokens.refreshToken) {
            this.debugLogger.debug(`Setting refresh token cookie: ${auth_constants_1.REFRESH_TOKEN_COOKIE_NAME}`, 'TokenResponseInterceptor');
            this.setCookie(response, auth_constants_1.REFRESH_TOKEN_COOKIE_NAME, tokens.refreshToken);
        }
        if (tokens.trustToken) {
            const trustCookieName = auth_config_service_1.AuthConfigService.getOptions().mfa?.trustDeviceStorageName || auth_constants_1.NEST_AUTH_TRUST_DEVICE_KEY;
            const duration = auth_config_service_1.AuthConfigService.getOptions().mfa?.trustedDeviceDuration || '30d';
            const maxAge = typeof duration === 'string' ? (0, ms_1.default)(duration) : duration;
            this.debugLogger.debug(`Setting trust device cookie: ${trustCookieName}`, 'TokenResponseInterceptor', { duration, maxAge });
            this.setCookie(response, trustCookieName, tokens.trustToken, {
                maxAge,
            });
        }
    }
    setCookie(response, name, token, options) {
        const cookieOptions = {
            httpOnly: true,
            path: '/',
            secure: this.options.cookieOptions?.secure,
            ...this.options.cookieOptions?.domain ? { domain: this.options.cookieOptions?.domain } : {},
            sameSite: this.options.cookieOptions?.sameSite,
            maxAge: (0, ms_1.default)(this.options.session?.sessionExpiry || '7d'),
            ...options,
        };
        this.debugLogger.verbose(`Setting cookie: ${name}`, 'TokenResponseInterceptor', {
            cookieName: name,
            ...cookieOptions
        });
        cookie_helper_1.CookieHelper.set(response, name, token, cookieOptions);
    }
};
exports.TokenResponseInterceptor = TokenResponseInterceptor;
exports.TokenResponseInterceptor = TokenResponseInterceptor = __decorate([
    (0, common_1.Injectable)(),
    __metadata("design:paramtypes", [debug_logger_service_1.DebugLoggerService])
], TokenResponseInterceptor);
//# sourceMappingURL=token-response.interceptor.js.map