"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 __param = (this && this.__param) || function (paramIndex, decorator) {
    return function (target, key) { decorator(target, key, paramIndex); }
};
var AuthConfigService_1;
Object.defineProperty(exports, "__esModule", { value: true });
exports.AuthConfigService = void 0;
const common_1 = require("@nestjs/common");
const crypto_1 = require("crypto");
const session_options_interface_1 = require("../interfaces/session-options.interface");
const nest_auth_contracts_1 = require("@ackplus/nest-auth-contracts");
let AuthConfigService = class AuthConfigService {
    static { AuthConfigService_1 = this; }
    static defaultOptions = {
        isGlobal: true,
        appName: 'Nest Auth',
        passwordResetOtpExpiresIn: '15m',
        passwordResetTokenExpiresIn: '1h',
        session: {
            storageType: session_options_interface_1.SessionStorageType.DATABASE,
            sessionExpiry: '1h',
            refreshTokenExpiry: '30d',
        },
        jwt: {
            secret: 'secret',
        },
        accessTokenType: null,
        cookieOptions: {
            httpOnly: true,
            secure: false,
        },
        emailAuth: {
            enabled: true,
        },
        phoneAuth: {
            enabled: false,
        },
        mfa: {
            enabled: false,
            methods: [nest_auth_contracts_1.NestAuthMFAMethodEnum.EMAIL, nest_auth_contracts_1.NestAuthMFAMethodEnum.TOTP],
            allowUserToggle: true,
            allowMethodSelection: true,
            otpLength: 6,
            otpExpiresIn: '15m',
        },
        defaultTenant: undefined,
        adminConsole: {
            enabled: true,
            basePath: '/api/auth/admin',
            sessionCookieName: 'nest_auth_admin',
            sessionDuration: '2h',
            allowAdminManagement: true,
            cookie: {
                httpOnly: true,
                secure: false,
                sameSite: 'lax',
            },
        },
        debug: {
            enabled: false,
            level: 'verbose',
            prefix: '[NestAuth]',
            includeTimestamp: true,
            includeContext: true
        }
    };
    static options;
    static instance;
    constructor(options) {
        if (options) {
            AuthConfigService_1.options = options;
        }
        if (!AuthConfigService_1.instance) {
            AuthConfigService_1.instance = this;
        }
    }
    static getOptions() {
        return this.options || this.defaultOptions;
    }
    static getDefaultOptions() {
        return this.defaultOptions;
    }
    static getInstance() {
        if (!AuthConfigService_1.instance) {
            AuthConfigService_1.instance = new AuthConfigService_1();
        }
        return AuthConfigService_1.instance;
    }
    static generateRandomKey(length = 32) {
        return (0, crypto_1.randomBytes)(length).toString('base64');
    }
    static resolveSecretKey(options) {
        const adminConsoleKey = options.adminConsole?.secretKey;
        if (adminConsoleKey) {
            return adminConsoleKey;
        }
        if (process.env.NODE_ENV !== 'production') {
            const generatedKey = this.generateRandomKey(32);
            console.warn('[NestAuth] Warning: adminConsole.secretKey not configured. ' +
                `Auto-generated key for development: ${generatedKey.slice(0, 20)}...\n` +
                '⚠️  This key will change on each restart. Configure adminConsole.secretKey in your AuthModuleOptions!');
            return generatedKey;
        }
        return undefined;
    }
    static setOptions(options) {
        const deepmerge = require('deepmerge');
        const mergedOptions = deepmerge(this.defaultOptions, options, { clone: false });
        if (mergedOptions.mfa?.methods) {
            mergedOptions.mfa.methods = [...new Set(mergedOptions.mfa.methods)];
        }
        if (!mergedOptions.adminConsole) {
            mergedOptions.adminConsole = {};
        }
        if (!mergedOptions.adminConsole.secretKey) {
            console.warn('Admin console secret key not configured. Please configure adminConsole.secretKey in AuthModuleOptions to enable admin console.');
            mergedOptions.adminConsole.enabled = false;
        }
        this.options = mergedOptions;
        this.validateSessionOptions(this.options);
        this.validateAdminConsoleOptions(this.options);
    }
    static validateAdminConsoleOptions(options) {
        if (options.adminConsole?.enabled !== false && options.adminConsole?.secretKey) {
            const secretKey = options.adminConsole.secretKey;
            const weakSecrets = ['change-me-admin-secret', 'default', 'secret', ''];
            if (weakSecrets.includes(secretKey)) {
                throw new Error('Admin console requires a secure secretKey. ' +
                    'Please set adminConsole.secretKey in your AuthModuleOptions (e.g., secretKey: process.env.ADMIN_CONSOLE_SESSION_SECRET) ' +
                    'with a 32+ byte random value. Store it securely in environment variables or a secrets manager. ' +
                    'Weak or default values are not allowed for security reasons. Rotate keys regularly.');
            }
        }
    }
    static validateSessionOptions(options) {
        const store = options.session?.storageType;
        if (store) {
            const normalized = String(store).toLowerCase();
            const allowedStores = Object.values(session_options_interface_1.SessionStorageType);
            if (!allowedStores.includes(normalized)) {
                throw new Error(`Invalid session store "${store}". ` +
                    `Allowed values: ${allowedStores.join(', ')}`);
            }
        }
        const ttlSeconds = options.session?.redis?.ttlSeconds;
        if (ttlSeconds !== undefined) {
            if (!Number.isFinite(ttlSeconds) || ttlSeconds <= 0) {
                throw new Error('session.redis.ttlSeconds must be a positive number of seconds.');
            }
        }
    }
    getConfig() {
        return AuthConfigService_1.getOptions();
    }
    setConfig(options) {
        AuthConfigService_1.setOptions(options);
    }
};
exports.AuthConfigService = AuthConfigService;
exports.AuthConfigService = AuthConfigService = AuthConfigService_1 = __decorate([
    (0, common_1.Injectable)(),
    __param(0, (0, common_1.Inject)('AUTH_MODULE_OPTIONS')),
    __param(0, (0, common_1.Optional)()),
    __metadata("design:paramtypes", [Object])
], AuthConfigService);
//# sourceMappingURL=auth-config.service.js.map