"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); }
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.SessionTokenService = void 0;
const common_1 = require("@nestjs/common");
const typeorm_1 = require("@nestjs/typeorm");
const typeorm_2 = require("typeorm");
const user_entity_1 = require("../../user/entities/user.entity");
const user_access_entity_1 = require("../../user/entities/user-access.entity");
const platform_access_entity_1 = require("../../user/entities/platform-access.entity");
const jwt_service_1 = require("../../core/services/jwt.service");
const auth_config_service_1 = require("../../core/services/auth-config.service");
const user_service_1 = require("../../user/services/user.service");
const tenant_service_1 = require("../../tenant/services/tenant.service");
const mfa_service_1 = require("./mfa.service");
const session_manager_service_1 = require("../../session/services/session-manager.service");
const has_token_1 = require("../../utils/has-token");
let SessionTokenService = class SessionTokenService {
    userRepository;
    jwtService;
    authConfigService;
    userService;
    tenantService;
    mfaService;
    sessionManager;
    constructor(userRepository, jwtService, authConfigService, userService, tenantService, mfaService, sessionManager) {
        this.userRepository = userRepository;
        this.jwtService = jwtService;
        this.authConfigService = authConfigService;
        this.userService = userService;
        this.tenantService = tenantService;
        this.mfaService = mfaService;
        this.sessionManager = sessionManager;
    }
    getRefreshHashSecret() {
        return this.authConfigService.getConfig().session?.jwt?.secret ?? '';
    }
    getUserWithRoles(userId, relations = []) {
        return this.userRepository.findOne({
            where: { id: userId },
            relations: ['userAccesses', 'userAccesses.roles', ...relations],
        });
    }
    async getUserWithAccess(userId, tenantId, isPlatformAccess = false) {
        const user = await this.userRepository.findOne({
            where: {
                id: userId,
                ...(tenantId ? { userAccesses: { tenantId } } : {}),
            },
        });
        if (isPlatformAccess) {
            const platformAccess = await platform_access_entity_1.NestAuthPlatformAccess.findOne({
                where: { userId, isActive: true },
                relations: ['roles', 'roles.rolePermissions', 'roles.rolePermissions.permission'],
            });
            return { user, platformAccess };
        }
        const userAccess = await user_access_entity_1.NestAuthUserAccess.findOne({
            where: {
                userId,
                isActive: true,
                tenantId: tenantId ? (0, typeorm_2.Equal)(tenantId) : (0, typeorm_2.IsNull)(),
            },
            relations: ['roles', 'roles.rolePermissions', 'roles.rolePermissions.permission'],
        });
        return { user, userAccess };
    }
    async generateTokensPayload(session, otherPayload = {}) {
        let payload = {
            id: session.userId,
            sub: session.userId,
            sessionId: session.id,
            email: session.data?.user?.email,
            phone: session.data?.user?.phone,
            emailVerifiedAt: session.data?.user?.emailVerifiedAt,
            phoneVerifiedAt: session.data?.user?.phoneVerifiedAt,
            roles: session.data?.roles || [],
            tenantId: session.data?.tenantId,
            isMfaEnabled: session.data?.user?.isMfaEnabled,
            isMfaVerified: session.data?.isMfaVerified,
            ...otherPayload,
        };
        const config = this.authConfigService.getConfig();
        if (config.session?.customizeTokenPayload) {
            payload = await config.session.customizeTokenPayload(payload, session);
        }
        return payload;
    }
    async generateTokensFromSession(session) {
        const payload = await this.generateTokensPayload(session);
        const tokens = await this.jwtService.generateTokens(payload);
        if (session?.id && tokens.refreshToken) {
            await this.sessionManager.updateSession(session.id, {
                refreshToken: (0, has_token_1.hmacSha256Hex)(this.getRefreshHashSecret(), tokens.refreshToken),
            });
        }
        return tokens;
    }
    async generateAuthResponse(user, session, tokens, isRequiresMfa, trustToken) {
        const config = this.authConfigService.getConfig();
        const activeTenantId = session?.data?.tenantId;
        let tenants = await this.userService.getUserTenants(user.id);
        if (!tenants.length && activeTenantId) {
            const fallbackTenant = await this.tenantService.getTenantById(activeTenantId);
            if (fallbackTenant) {
                tenants = [fallbackTenant];
            }
        }
        let response = {
            accessToken: tokens.accessToken,
            refreshToken: tokens.refreshToken,
            isRequiresMfa: isRequiresMfa,
        };
        if (isRequiresMfa) {
            const enabledMethods = await this.mfaService.getEnabledMethods(user.id);
            response.mfaMethods = enabledMethods;
            response.defaultMfaMethod = this.mfaService.mfaConfig?.defaultMethod || enabledMethods[0];
        }
        if (config.auth?.transformResponse) {
            response = await config.auth.transformResponse(response, user, session);
        }
        if (trustToken) {
            response.trustToken = trustToken;
        }
        return response;
    }
};
exports.SessionTokenService = SessionTokenService;
exports.SessionTokenService = SessionTokenService = __decorate([
    (0, common_1.Injectable)(),
    __param(0, (0, typeorm_1.InjectRepository)(user_entity_1.NestAuthUser)),
    __metadata("design:paramtypes", [typeorm_2.Repository,
        jwt_service_1.JwtService,
        auth_config_service_1.AuthConfigService,
        user_service_1.UserService,
        tenant_service_1.TenantService,
        mfa_service_1.MfaService,
        session_manager_service_1.SessionManagerService])
], SessionTokenService);
//# sourceMappingURL=session-token.service.js.map