"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.AuthController = void 0;
const common_1 = require("@nestjs/common");
const auth_service_1 = require("../services/auth.service");
const verify_2fa_request_dto_1 = require("../dto/requests/verify-2fa.request.dto");
const refresh_token_request_dto_1 = require("../dto/requests/refresh-token.request.dto");
const swagger_1 = require("@nestjs/swagger");
const auth_response_dto_1 = require("../dto/responses/auth.response.dto");
const auth_cookie_response_dto_1 = require("../dto/responses/auth-cookie.response.dto");
const signup_request_dto_1 = require("../dto/requests/signup.request.dto");
const auth_messages_response_dto_1 = require("../dto/responses/auth-messages.response.dto");
const login_request_dto_1 = require("../dto/requests/login.request.dto");
const request_context_1 = require("../../request-context/request-context");
const core_1 = require("../../core");
const invite_service_1 = require("../services/invite.service");
const invite_request_dto_1 = require("../dto/requests/invite.request.dto");
const nest_auth_contracts_1 = require("@ackplus/nest-auth-contracts");
const forgot_password_request_dto_1 = require("../dto/requests/forgot-password.request.dto");
const auth_guard_1 = require("../guards/auth.guard");
const verify_forgot_password_otp_request_dto_1 = require("../dto/requests/verify-forgot-password-otp-request-dto");
const reset_password_with_token_request_dto_1 = require("../dto/requests/reset-password-with-token.request.dto");
const verify_otp_response_dto_1 = require("../dto/responses/verify-otp.response.dto");
const change_password_request_dto_1 = require("../dto/requests/change-password.request.dto");
const send_email_verification_request_dto_1 = require("../dto/requests/send-email-verification.request.dto");
const verify_email_request_dto_1 = require("../dto/requests/verify-email.request.dto");
const send_phone_verification_request_dto_1 = require("../dto/requests/send-phone-verification.request.dto");
const verify_phone_request_dto_1 = require("../dto/requests/verify-phone.request.dto");
const switch_tenant_request_dto_1 = require("../dto/requests/switch-tenant.request.dto");
const auth_constants_1 = require("../../auth.constants");
const common_2 = require("@nestjs/common");
const password_service_1 = require("../services/password.service");
const verification_service_1 = require("../services/verification.service");
const token_response_interceptor_1 = require("../interceptors/token-response.interceptor");
const auth_exception_filter_1 = require("../filters/auth-exception.filter");
const auth_decorator_1 = require("../../core/decorators/auth.decorator");
const auth_config_service_1 = require("../../core/services/auth-config.service");
const tenant_service_1 = require("../../tenant/services/tenant.service");
const nest_auth_contracts_2 = require("@ackplus/nest-auth-contracts");
const passwordless_send_request_dto_1 = require("../dto/requests/passwordless-send.request.dto");
const cookie_helper_1 = require("../../utils/cookie.helper");
let AuthController = class AuthController {
    authService;
    passwordService;
    verificationService;
    authConfigService;
    tenantService;
    inviteService;
    constructor(authService, passwordService, verificationService, authConfigService, tenantService, inviteService) {
        this.authService = authService;
        this.passwordService = passwordService;
        this.verificationService = verificationService;
        this.authConfigService = authConfigService;
        this.tenantService = tenantService;
        this.inviteService = inviteService;
    }
    async signup(input) {
        const response = await this.authService.signup(input);
        return {
            ...response,
            message: 'Signup successful',
        };
    }
    async invite(input) {
        const invitedBy = await request_context_1.RequestContext.currentUserId();
        const { user, isNewUser } = await this.inviteService.inviteUser({
            email: input.email,
            phone: input.phone,
            tenantId: input.tenantId,
            metadata: input.metadata,
            invitedBy: invitedBy ?? undefined,
        });
        return { message: 'Invitation sent', userId: user.id, isNewUser };
    }
    async login(input) {
        const response = await this.authService.login(input);
        return {
            ...response,
            message: 'Login successful',
        };
    }
    async passwordlessSend(input) {
        return this.authService.passwordlessSend(input);
    }
    async refreshToken(input, req) {
        const headerTokenType = req.headers['x-access-token-type'];
        const accessTokenType = auth_config_service_1.AuthConfigService.getOptions().session?.accessTokenType ?? null;
        const isCookieMode = accessTokenType === 'cookie' || (!accessTokenType && headerTokenType === 'cookie');
        let refreshToken = input.refreshToken;
        if (!refreshToken && isCookieMode) {
            if (auth_config_service_1.AuthConfigService.getOptions().session?.allowMultipleAccounts === true) {
                const activeAccount = cookie_helper_1.CookieHelper.get(req, auth_constants_1.ACTIVE_ACCOUNT_COOKIE_NAME);
                if (activeAccount) {
                    refreshToken = cookie_helper_1.CookieHelper.get(req, (0, auth_constants_1.accountRefreshCookieName)(activeAccount));
                }
            }
            refreshToken = refreshToken || cookie_helper_1.CookieHelper.get(req, auth_constants_1.REFRESH_TOKEN_COOKIE_NAME);
        }
        if (!refreshToken) {
            throw new common_1.BadRequestException('refreshToken is required');
        }
        const response = await this.authService.refreshToken(refreshToken);
        return {
            ...response,
            isRequiresMfa: false,
            message: 'Token refreshed successfully',
        };
    }
    async send2faCode(method) {
        const user = await request_context_1.RequestContext.currentUser();
        if (!user) {
            throw new common_1.UnauthorizedException('User not found');
        }
        await this.authService.send2faCode(user.id, method);
        return { message: 'MFA code sent successfully' };
    }
    async verify2fa(input) {
        const response = await this.authService.verify2fa(input);
        return {
            ...response,
            message: '2FA verification successful',
        };
    }
    async logout(res, req) {
        try {
            if (req.user) {
                await this.authService.logout();
            }
        }
        catch (e) {
        }
        this.clearActiveAccountCookies(req, res);
        res.clearCookie(auth_constants_1.ACCESS_TOKEN_COOKIE_NAME, { path: '/' });
        res.clearCookie(auth_constants_1.REFRESH_TOKEN_COOKIE_NAME, { path: '/' });
        return { message: 'Logged out successfully' };
    }
    clearActiveAccountCookies(req, res) {
        if (this.authConfigService.getConfig().session?.allowMultipleAccounts !== true)
            return;
        const activeAccount = cookie_helper_1.CookieHelper.get(req, auth_constants_1.ACTIVE_ACCOUNT_COOKIE_NAME);
        if (!activeAccount)
            return;
        res.clearCookie((0, auth_constants_1.accountAccessCookieName)(activeAccount), { path: '/' });
        res.clearCookie((0, auth_constants_1.accountRefreshCookieName)(activeAccount), { path: '/' });
        const prefix = `${auth_constants_1.REFRESH_TOKEN_COOKIE_NAME}_`;
        const others = Object.keys(cookie_helper_1.CookieHelper.getAll(req))
            .filter((n) => n.startsWith(prefix))
            .map((n) => n.slice(prefix.length))
            .filter((k) => k && k !== activeAccount);
        if (others.length > 0) {
            res.cookie(auth_constants_1.ACTIVE_ACCOUNT_COOKIE_NAME, others[0], { path: '/', httpOnly: false, sameSite: 'lax' });
        }
        else {
            res.clearCookie(auth_constants_1.ACTIVE_ACCOUNT_COOKIE_NAME, { path: '/' });
        }
    }
    async logoutAll(res, req) {
        const user = await request_context_1.RequestContext.currentUser();
        if (!user) {
            throw new common_1.UnauthorizedException('User not found');
        }
        await this.authService.logoutAll(user.id);
        this.clearActiveAccountCookies(req, res);
        res.clearCookie(auth_constants_1.ACCESS_TOKEN_COOKIE_NAME, { path: '/' });
        res.clearCookie(auth_constants_1.REFRESH_TOKEN_COOKIE_NAME, { path: '/' });
        return { message: 'Logged out from all devices successfully' };
    }
    async switchTenant(input) {
        const response = await this.authService.switchTenant(input.tenantId);
        return {
            ...response,
            message: 'Tenant switched successfully',
        };
    }
    sessionUserData() {
        return this.authService.getSessionUserData();
    }
    changePassword(input) {
        return this.passwordService.changePassword(input);
    }
    async forgotPassword(input) {
        await this.passwordService.forgotPassword(input);
        return { message: 'If your email is registered, you will receive a password reset link' };
    }
    async verifyForgotPasswordOtp(input) {
        return await this.passwordService.verifyForgotPasswordOtp(input);
    }
    async resetPassword(input) {
        await this.passwordService.resetPasswordWithToken(input);
        return { message: 'Password has been reset successfully' };
    }
    async getClientConfig() {
        const config = this.authConfigService.getConfig();
        const defaultResponse = {
            tenants: {
                enabled: config.tenant?.enabled,
                mode: config.tenant.mode ?? nest_auth_contracts_2.TenantModeEnum.ISOLATED,
            },
            multipleAccounts: {
                enabled: config.session?.allowMultipleAccounts === true,
            },
            roleGuards: this.authConfigService.getRoleGuards(),
            emailAuth: { enabled: config.emailAuth?.enabled !== false },
            phoneAuth: { enabled: config.phoneAuth?.enabled === true },
            registration: {
                enabled: config.registration?.enabled !== false,
                requireInvitation: config.registration?.requireInvitation ?? false,
                collectProfileFields: config.registration?.collectProfileFields,
            },
            mfa: config.mfa
                ? {
                    enabled: config.mfa.enabled ?? false,
                    methods: config.mfa.methods,
                    allowUserToggle: config.mfa.allowUserToggle,
                    allowMethodSelection: config.mfa.allowMethodSelection,
                }
                : { enabled: false },
        };
        if (config.clientConfig?.factory) {
            return config.clientConfig.factory(defaultResponse, {
                configService: this.authConfigService,
                tenantService: this.tenantService,
            });
        }
        return defaultResponse;
    }
    async listAccounts(req) {
        if (this.authConfigService.getConfig().session?.allowMultipleAccounts !== true) {
            return { accounts: [] };
        }
        const all = cookie_helper_1.CookieHelper.getAll(req);
        const prefix = `${auth_constants_1.REFRESH_TOKEN_COOKIE_NAME}_`;
        const active = cookie_helper_1.CookieHelper.get(req, auth_constants_1.ACTIVE_ACCOUNT_COOKIE_NAME) || undefined;
        const accounts = Object.keys(all)
            .filter((name) => name.startsWith(prefix))
            .map((name) => {
            const accountId = name.slice(prefix.length);
            const payload = (0, auth_constants_1.jwtPayload)(all[name]) || {};
            return {
                accountId,
                email: payload.email,
                phone: payload.phone,
                tenantId: payload.tenantId,
                isActive: accountId === active,
            };
        });
        return { accounts };
    }
    async lookupTenant(slug) {
        const config = this.authConfigService.getConfig();
        if (!config.tenant?.enabled || !slug) {
            throw new common_1.NotFoundException({ message: 'Tenant not found', code: 'TENANT_NOT_FOUND' });
        }
        const tenant = await this.tenantService.getTenantBySlug(slug);
        if (!tenant || tenant.isActive === false) {
            throw new common_1.NotFoundException({ message: 'Tenant not found', code: 'TENANT_NOT_FOUND' });
        }
        return { id: tenant.id, slug: tenant.slug, name: tenant.name };
    }
    async getUser() {
        const user = await request_context_1.RequestContext.currentUser();
        if (!user) {
            throw new common_1.UnauthorizedException('User not found');
        }
        return user;
    }
    async verifySession() {
        const userId = await request_context_1.RequestContext.currentUserId();
        const session = request_context_1.RequestContext.currentSession();
        return {
            valid: true,
            userId: userId,
            expiresAt: session?.expiresAt?.toISOString(),
        };
    }
    async sendEmailVerification(input) {
        await this.verificationService.sendEmailVerification(input);
        return { message: 'Verification email sent' };
    }
    async verifyEmail(input) {
        await this.verificationService.verifyEmail(input);
        return { message: 'Email verified successfully' };
    }
    async sendPhoneVerification(input) {
        await this.verificationService.sendPhoneVerification(input);
        return { message: 'Verification SMS sent' };
    }
    async verifyPhone(input) {
        await this.verificationService.verifyPhone(input);
        return { message: 'Phone verified successfully' };
    }
    async ssoCallback(provider, data, res) {
        const jsonData = JSON.stringify(data);
        const escapedData = jsonData.replace(/</g, '\\u003c').replace(/>/g, '\\u003e');
        const html = `<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>SSO Callback</title>
    <style>
        body {
            font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Oxygen, Ubuntu, Cantarell, sans-serif;
            display: flex;
            justify-content: center;
            align-items: center;
            min-height: 100vh;
            margin: 0;
            background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
        }
        .container {
            background: white;
            padding: 2rem;
            border-radius: 8px;
            box-shadow: 0 4px 6px rgba(0, 0, 0, 0.1);
            text-align: center;
            max-width: 400px;
        }
        .spinner {
            border: 3px solid #f3f3f3;
            border-top: 3px solid #667eea;
            border-radius: 50%;
            width: 40px;
            height: 40px;
            animation: spin 1s linear infinite;
            margin: 0 auto 1rem;
        }
        @keyframes spin {
            0% { transform: rotate(0deg); }
            100% { transform: rotate(360deg); }
        }
        .message {
            color: #333;
            margin-top: 1rem;
        }
        .error {
            color: #dc3545;
        }
    </style>
</head>
<body>
    <div class="container">
        <div class="spinner"></div>
        <div class="message" id="message">Processing...</div>
    </div>
    <script>
        (function() {
            const data = ${escapedData};

            // Post message to parent window
            if (window.opener) {
                window.opener.postMessage({
                    type: 'nest-auth-sso-callback',
                    ...data
                }, '*');

                // Auto-close immediately
                window.close();
            } else if (window.parent && window.parent !== window) {
                // Iframe context
                window.parent.postMessage({
                    type: 'nest-auth-sso-callback',
                    ...data
                }, '*');
                // Note: Can't close iframe from inside
            } else {
                // No parent window, show message
                document.getElementById('message').textContent = data.success
                    ? 'Success! You can close this window.'
                    : 'Error: ' + (data.errorDescription || data.error);
                document.getElementById('message').className = data.success ? 'message' : 'message error';
            }
        })();
    </script>
</body>
</html>`;
        res.setHeader('Content-Type', 'text/html');
        res.status(200).send(html);
    }
};
exports.AuthController = AuthController;
__decorate([
    (0, swagger_1.ApiOperation)({
        summary: 'Signup',
        description: 'Register a new user. Response format depends on accessTokenType configuration:\n' +
            '- Header mode (default): Returns tokens in response body\n' +
            '- Cookie mode: Sets tokens in HTTP-only cookies and returns success message'
    }),
    (0, swagger_1.ApiResponse)({ status: 200, type: auth_response_dto_1.AuthWithTokensResponseDto, description: 'Header mode: Returns message + tokens in body' }),
    (0, swagger_1.ApiResponse)({ status: 200, type: auth_cookie_response_dto_1.AuthCookieResponseDto, description: 'Cookie mode: Returns message only, tokens in cookies' }),
    (0, core_1.ApiConflictError)('A user with this email or phone already exists.'),
    (0, common_1.HttpCode)(200),
    (0, core_1.Public)(),
    (0, common_1.Post)('signup'),
    (0, common_2.UseInterceptors)(token_response_interceptor_1.TokenResponseInterceptor),
    __param(0, (0, common_1.Body)()),
    __metadata("design:type", Function),
    __metadata("design:paramtypes", [signup_request_dto_1.NestAuthSignupRequestDto]),
    __metadata("design:returntype", Promise)
], AuthController.prototype, "signup", null);
__decorate([
    (0, swagger_1.ApiOperation)({
        summary: 'Invite a member (admin)',
        description: 'Create-or-link a user in the tenant and emit a `nest_auth.user_invited` event carrying a single-use set-password token, so YOUR listener can email the invite link (the token is intentionally NEVER returned in the response — that would leak a working credential). The member sets their password via POST /auth/reset-password { token, newPassword }, then signs in. Guarded by the `users.invite` permission — assign it to your admin roles, or call InviteService.inviteUser() directly from your own guarded controller.',
    }),
    (0, swagger_1.ApiResponse)({ status: 201, description: 'Invitation issued: { message, userId, isNewUser }' }),
    (0, auth_decorator_1.Auth)(),
    (0, core_1.NestAuthPermissions)(['users.invite']),
    (0, common_1.Post)('invite'),
    __param(0, (0, common_1.Body)()),
    __metadata("design:type", Function),
    __metadata("design:paramtypes", [invite_request_dto_1.NestAuthInviteRequestDto]),
    __metadata("design:returntype", Promise)
], AuthController.prototype, "invite", null);
__decorate([
    (0, swagger_1.ApiOperation)({
        summary: 'Login',
        description: 'Authenticate user. Response format depends on accessTokenType configuration:\n' +
            '- Header mode (default): Returns tokens in response body\n' +
            '- Cookie mode: Sets tokens in HTTP-only cookies and returns success message'
    }),
    (0, swagger_1.ApiResponse)({ status: 200, type: auth_response_dto_1.AuthWithTokensResponseDto, description: 'Header mode: Returns message + tokens in body' }),
    (0, swagger_1.ApiResponse)({ status: 200, type: auth_cookie_response_dto_1.AuthCookieResponseDto, description: 'Cookie mode: Returns message only, tokens in cookies' }),
    (0, common_1.HttpCode)(200),
    (0, core_1.Public)(),
    (0, common_1.Post)('login'),
    (0, common_2.UseInterceptors)(token_response_interceptor_1.TokenResponseInterceptor),
    __param(0, (0, common_1.Body)()),
    __metadata("design:type", Function),
    __metadata("design:paramtypes", [login_request_dto_1.NestAuthLoginRequestDto]),
    __metadata("design:returntype", Promise)
], AuthController.prototype, "login", null);
__decorate([
    (0, swagger_1.ApiOperation)({ summary: 'Passwordless — send login code (email or SMS)' }),
    (0, swagger_1.ApiResponse)({ status: 200, type: core_1.MessageResponseDto }),
    (0, common_1.HttpCode)(200),
    (0, core_1.Public)(),
    (0, common_1.Post)('passwordless/send'),
    (0, core_1.SkipMfa)(),
    __param(0, (0, common_1.Body)()),
    __metadata("design:type", Function),
    __metadata("design:paramtypes", [passwordless_send_request_dto_1.NestAuthPasswordlessSendRequestDto]),
    __metadata("design:returntype", Promise)
], AuthController.prototype, "passwordlessSend", null);
__decorate([
    (0, swagger_1.ApiOperation)({
        summary: 'Refresh Token',
        description: 'Refresh access token. Response format depends on accessTokenType configuration:\n' +
            '- Header mode (default): Returns new tokens in response body\n' +
            '- Cookie mode: Sets new tokens in HTTP-only cookies and returns success message'
    }),
    (0, swagger_1.ApiResponse)({ status: 200, type: auth_response_dto_1.AuthWithTokensResponseDto, description: 'Header mode: Returns message + tokens in body' }),
    (0, swagger_1.ApiResponse)({ status: 200, type: auth_cookie_response_dto_1.AuthCookieResponseDto, description: 'Cookie mode: Returns message only, tokens in cookies' }),
    (0, common_1.HttpCode)(200),
    (0, core_1.Public)(),
    (0, common_1.Post)('refresh-token'),
    (0, common_2.UseInterceptors)(token_response_interceptor_1.TokenResponseInterceptor),
    __param(0, (0, common_1.Body)()),
    __param(1, (0, common_1.Req)()),
    __metadata("design:type", Function),
    __metadata("design:paramtypes", [refresh_token_request_dto_1.NestAuthRefreshTokenRequestDto, Object]),
    __metadata("design:returntype", Promise)
], AuthController.prototype, "refreshToken", null);
__decorate([
    (0, swagger_1.ApiOperation)({ summary: 'Send MFA Code' }),
    (0, swagger_1.ApiResponse)({ status: 200, type: auth_messages_response_dto_1.NestAuthMfaCodeSentResponseDto }),
    (0, common_1.HttpCode)(200),
    (0, core_1.SkipMustChangePassword)(),
    (0, common_1.Post)('mfa/challenge'),
    (0, core_1.SkipMfa)(),
    (0, common_1.UseGuards)(auth_guard_1.NestAuthAuthGuard),
    __param(0, (0, common_1.Body)('method')),
    __metadata("design:type", Function),
    __metadata("design:paramtypes", [String]),
    __metadata("design:returntype", Promise)
], AuthController.prototype, "send2faCode", null);
__decorate([
    (0, swagger_1.ApiOperation)({
        summary: 'Verify MFA',
        description: 'Verify multi-factor authentication. Response format depends on accessTokenType configuration:\n' +
            '- Header mode (default): Returns tokens in response body\n' +
            '- Cookie mode: Sets tokens in HTTP-only cookies and returns success message'
    }),
    (0, swagger_1.ApiResponse)({ status: 200, type: auth_response_dto_1.Verify2faWithTokensResponseDto, description: 'Header mode: Returns message + tokens in body' }),
    (0, swagger_1.ApiResponse)({ status: 200, type: auth_cookie_response_dto_1.AuthCookieResponseDto, description: 'Cookie mode: Returns message only, tokens in cookies' }),
    (0, common_1.HttpCode)(200),
    (0, core_1.SkipMustChangePassword)(),
    (0, common_1.Post)('mfa/verify'),
    (0, core_1.SkipMfa)(),
    (0, common_1.UseGuards)(auth_guard_1.NestAuthAuthGuard),
    (0, common_2.UseInterceptors)(token_response_interceptor_1.TokenResponseInterceptor),
    __param(0, (0, common_1.Body)()),
    __metadata("design:type", Function),
    __metadata("design:paramtypes", [verify_2fa_request_dto_1.NestAuthVerify2faRequestDto]),
    __metadata("design:returntype", Promise)
], AuthController.prototype, "verify2fa", null);
__decorate([
    (0, swagger_1.ApiOperation)({ summary: 'Logout' }),
    (0, swagger_1.ApiResponse)({ status: 200, type: auth_messages_response_dto_1.NestAuthLogoutResponseDto }),
    (0, common_1.HttpCode)(200),
    (0, common_1.Post)('logout'),
    (0, core_1.SkipMfa)(),
    (0, core_1.SkipMustChangePassword)(),
    (0, auth_decorator_1.Auth)(true),
    __param(0, (0, common_1.Res)({ passthrough: true })),
    __param(1, (0, common_1.Req)()),
    __metadata("design:type", Function),
    __metadata("design:paramtypes", [Object, Object]),
    __metadata("design:returntype", Promise)
], AuthController.prototype, "logout", null);
__decorate([
    (0, swagger_1.ApiOperation)({ summary: 'Logout All' }),
    (0, swagger_1.ApiResponse)({ status: 200, type: auth_messages_response_dto_1.NestAuthLogoutAllResponseDto }),
    (0, common_1.HttpCode)(200),
    (0, common_1.Post)('logout-all'),
    (0, core_1.SkipMfa)(),
    (0, common_1.UseGuards)(auth_guard_1.NestAuthAuthGuard),
    __param(0, (0, common_1.Res)({ passthrough: true })),
    __param(1, (0, common_1.Req)()),
    __metadata("design:type", Function),
    __metadata("design:paramtypes", [Object, Object]),
    __metadata("design:returntype", Promise)
], AuthController.prototype, "logoutAll", null);
__decorate([
    (0, swagger_1.ApiOperation)({ summary: 'Switch Active Tenant' }),
    (0, swagger_1.ApiResponse)({ status: 200, type: auth_response_dto_1.AuthWithTokensResponseDto }),
    (0, common_1.HttpCode)(200),
    (0, common_1.Post)('switch-tenant'),
    (0, core_1.SkipMfa)(),
    (0, common_1.UseGuards)(auth_guard_1.NestAuthAuthGuard),
    (0, common_2.UseInterceptors)(token_response_interceptor_1.TokenResponseInterceptor),
    __param(0, (0, common_1.Body)()),
    __metadata("design:type", Function),
    __metadata("design:paramtypes", [switch_tenant_request_dto_1.NestAuthSwitchTenantRequestDto]),
    __metadata("design:returntype", Promise)
], AuthController.prototype, "switchTenant", null);
__decorate([
    (0, swagger_1.ApiOperation)({ summary: 'Get Session User Data and menage extra user data from config' }),
    (0, swagger_1.ApiResponse)({ status: 200, description: 'Current user data' }),
    (0, common_1.HttpCode)(200),
    (0, common_1.Get)('me'),
    (0, core_1.SkipMfa)(),
    (0, common_1.UseGuards)(auth_guard_1.NestAuthAuthGuard),
    (0, common_2.UseInterceptors)(token_response_interceptor_1.TokenResponseInterceptor),
    __metadata("design:type", Function),
    __metadata("design:paramtypes", []),
    __metadata("design:returntype", Promise)
], AuthController.prototype, "sessionUserData", null);
__decorate([
    (0, swagger_1.ApiOperation)({ summary: 'Change Password' }),
    (0, swagger_1.ApiResponse)({ status: 200, type: core_1.MessageResponseDto }),
    (0, common_1.HttpCode)(200),
    (0, core_1.SkipMustChangePassword)(),
    (0, common_1.Post)('change-password'),
    (0, core_1.SkipMfa)(),
    (0, common_1.UseGuards)(auth_guard_1.NestAuthAuthGuard),
    (0, common_2.UseInterceptors)(token_response_interceptor_1.TokenResponseInterceptor),
    __param(0, (0, common_1.Body)()),
    __metadata("design:type", Function),
    __metadata("design:paramtypes", [change_password_request_dto_1.NestAuthChangePasswordRequestDto]),
    __metadata("design:returntype", Promise)
], AuthController.prototype, "changePassword", null);
__decorate([
    (0, swagger_1.ApiOperation)({ summary: 'Forgot password' }),
    (0, swagger_1.ApiResponse)({ status: 200, type: auth_messages_response_dto_1.NestAuthPasswordResetLinkSentResponseDto }),
    (0, common_1.HttpCode)(200),
    (0, core_1.Public)(),
    (0, common_1.Post)('forgot-password'),
    (0, core_1.SkipMfa)(),
    __param(0, (0, common_1.Body)()),
    __metadata("design:type", Function),
    __metadata("design:paramtypes", [forgot_password_request_dto_1.NestAuthForgotPasswordRequestDto]),
    __metadata("design:returntype", Promise)
], AuthController.prototype, "forgotPassword", null);
__decorate([
    (0, swagger_1.ApiOperation)({ summary: 'Verify Forgot Password OTP and get reset token' }),
    (0, swagger_1.ApiResponse)({ status: 200, type: verify_otp_response_dto_1.VerifyOtpResponseDto }),
    (0, common_1.HttpCode)(200),
    (0, core_1.Public)(),
    (0, common_1.Post)('verify-forgot-password-otp'),
    (0, core_1.SkipMfa)(),
    __param(0, (0, common_1.Body)()),
    __metadata("design:type", Function),
    __metadata("design:paramtypes", [verify_forgot_password_otp_request_dto_1.NestAuthVerifyForgotPasswordOtpRequestDto]),
    __metadata("design:returntype", Promise)
], AuthController.prototype, "verifyForgotPasswordOtp", null);
__decorate([
    (0, swagger_1.ApiOperation)({ summary: 'Reset password' }),
    (0, swagger_1.ApiResponse)({ status: 200, type: auth_messages_response_dto_1.NestAuthPasswordResetResponseDto }),
    (0, common_1.HttpCode)(200),
    (0, core_1.Public)(),
    (0, common_1.Post)('reset-password'),
    (0, core_1.SkipMfa)(),
    __param(0, (0, common_1.Body)()),
    __metadata("design:type", Function),
    __metadata("design:paramtypes", [reset_password_with_token_request_dto_1.NestAuthResetPasswordWithTokenRequestDto]),
    __metadata("design:returntype", Promise)
], AuthController.prototype, "resetPassword", null);
__decorate([
    (0, swagger_1.ApiOperation)({
        summary: 'Client config',
        description: 'Public configuration for clients (tenant mode, auth methods, registration, MFA, etc.). No auth required.',
    }),
    (0, swagger_1.ApiResponse)({ status: 200, description: 'Client configuration' }),
    (0, core_1.Public)(),
    (0, common_1.Get)('client-config'),
    __metadata("design:type", Function),
    __metadata("design:paramtypes", []),
    __metadata("design:returntype", Promise)
], AuthController.prototype, "getClientConfig", null);
__decorate([
    (0, swagger_1.ApiOperation)({
        summary: 'List logged-in accounts (cookie multi-account)',
        description: 'Cookie-mode account switcher: lists the accounts this browser is logged into, derived from the per-account token cookies it holds (httpOnly tokens are never returned — only id/email/tenant + which is active). Empty unless session.allowMultipleAccounts is enabled.',
    }),
    (0, swagger_1.ApiResponse)({ status: 200, description: 'Logged-in accounts for this browser' }),
    (0, core_1.Public)(),
    (0, common_1.Get)('accounts'),
    __param(0, (0, common_1.Req)()),
    __metadata("design:type", Function),
    __metadata("design:paramtypes", [Object]),
    __metadata("design:returntype", Promise)
], AuthController.prototype, "listAccounts", null);
__decorate([
    (0, swagger_1.ApiOperation)({
        summary: 'Resolve a tenant by slug (public)',
        description: 'ISOLATED-mode login helper: resolve a tenant slug to its id so the login form can supply the right tenantId (the same email is a distinct account per tenant). Returns minimal public fields; 404 if not found. Broader name search/autocomplete is intentionally left to your app to avoid tenant enumeration.',
    }),
    (0, swagger_1.ApiResponse)({ status: 200, description: 'The resolved tenant: { id, slug, name }' }),
    (0, core_1.Public)(),
    (0, common_1.Get)('tenants/lookup'),
    __param(0, (0, common_1.Query)('slug')),
    __metadata("design:type", Function),
    __metadata("design:paramtypes", [String]),
    __metadata("design:returntype", Promise)
], AuthController.prototype, "lookupTenant", null);
__decorate([
    (0, swagger_1.ApiOperation)({ summary: 'Get Logged In User' }),
    (0, swagger_1.ApiResponse)({ status: 200, type: auth_response_dto_1.UserResponseDto }),
    (0, common_1.UseGuards)(auth_guard_1.NestAuthAuthGuard),
    (0, core_1.SkipMustChangePassword)(),
    (0, common_1.Get)('user'),
    __metadata("design:type", Function),
    __metadata("design:paramtypes", []),
    __metadata("design:returntype", Promise)
], AuthController.prototype, "getUser", null);
__decorate([
    (0, swagger_1.ApiOperation)({
        summary: 'Verify Session',
        description: 'Lightweight endpoint to verify if the current session is valid. Returns minimal information without fetching full user data.'
    }),
    (0, swagger_1.ApiResponse)({
        status: 200,
        schema: {
            properties: {
                valid: { type: 'boolean', example: true },
                userId: { type: 'string', example: '123e4567-e89b-12d3-a456-426614174000' },
                expiresAt: { type: 'string', example: '2024-01-01T12:00:00.000Z' }
            }
        }
    }),
    (0, common_1.UseGuards)(auth_guard_1.NestAuthAuthGuard),
    (0, core_1.SkipMfa)(),
    (0, core_1.SkipMustChangePassword)(),
    (0, common_1.Get)('verify-session'),
    __metadata("design:type", Function),
    __metadata("design:paramtypes", []),
    __metadata("design:returntype", Promise)
], AuthController.prototype, "verifySession", null);
__decorate([
    (0, swagger_1.ApiOperation)({ summary: 'Send email verification' }),
    (0, swagger_1.ApiResponse)({ status: 200, type: auth_messages_response_dto_1.NestAuthEmailVerificationSentResponseDto }),
    (0, common_1.HttpCode)(200),
    (0, common_1.Post)('send-email-verification'),
    (0, core_1.SkipMfa)(),
    (0, core_1.SkipMustChangePassword)(),
    (0, common_1.UseGuards)(auth_guard_1.NestAuthAuthGuard),
    __param(0, (0, common_1.Body)()),
    __metadata("design:type", Function),
    __metadata("design:paramtypes", [send_email_verification_request_dto_1.NestAuthSendEmailVerificationRequestDto]),
    __metadata("design:returntype", Promise)
], AuthController.prototype, "sendEmailVerification", null);
__decorate([
    (0, swagger_1.ApiOperation)({ summary: 'Verify Email' }),
    (0, swagger_1.ApiResponse)({ status: 200, type: auth_messages_response_dto_1.NestAuthEmailVerifiedResponseDto }),
    (0, common_1.HttpCode)(200),
    (0, common_1.Post)('verify-email'),
    (0, core_1.SkipMfa)(),
    (0, core_1.SkipMustChangePassword)(),
    (0, common_1.UseGuards)(auth_guard_1.NestAuthAuthGuard),
    __param(0, (0, common_1.Body)()),
    __metadata("design:type", Function),
    __metadata("design:paramtypes", [verify_email_request_dto_1.NestAuthVerifyEmailRequestDto]),
    __metadata("design:returntype", Promise)
], AuthController.prototype, "verifyEmail", null);
__decorate([
    (0, swagger_1.ApiOperation)({ summary: 'Send phone verification (SMS OTP)' }),
    (0, swagger_1.ApiResponse)({ status: 200, type: auth_messages_response_dto_1.NestAuthPhoneVerificationSentResponseDto }),
    (0, common_1.HttpCode)(200),
    (0, common_1.Post)('send-phone-verification'),
    (0, core_1.SkipMfa)(),
    (0, core_1.SkipMustChangePassword)(),
    (0, common_1.UseGuards)(auth_guard_1.NestAuthAuthGuard),
    __param(0, (0, common_1.Body)()),
    __metadata("design:type", Function),
    __metadata("design:paramtypes", [send_phone_verification_request_dto_1.NestAuthSendPhoneVerificationRequestDto]),
    __metadata("design:returntype", Promise)
], AuthController.prototype, "sendPhoneVerification", null);
__decorate([
    (0, swagger_1.ApiOperation)({ summary: 'Verify phone number with OTP' }),
    (0, swagger_1.ApiResponse)({ status: 200, type: auth_messages_response_dto_1.NestAuthPhoneVerifiedResponseDto }),
    (0, common_1.HttpCode)(200),
    (0, common_1.Post)('verify-phone'),
    (0, core_1.SkipMfa)(),
    (0, core_1.SkipMustChangePassword)(),
    (0, common_1.UseGuards)(auth_guard_1.NestAuthAuthGuard),
    __param(0, (0, common_1.Body)()),
    __metadata("design:type", Function),
    __metadata("design:paramtypes", [verify_phone_request_dto_1.NestAuthVerifyPhoneRequestDto]),
    __metadata("design:returntype", Promise)
], AuthController.prototype, "verifyPhone", null);
__decorate([
    (0, swagger_1.ApiOperation)({
        summary: 'SSO Callback',
        description: 'OAuth callback endpoint for SSO providers. Exchanges authorization code for access token and returns raw SSO user info. Returns HTML page that posts SSO data to parent window and auto-closes.',
    }),
    (0, core_1.Public)(),
    (0, common_1.Get)('callback/:provider'),
    __param(0, (0, common_1.Param)('provider')),
    __param(1, (0, common_1.Query)()),
    __param(2, (0, common_1.Res)()),
    __metadata("design:type", Function),
    __metadata("design:paramtypes", [String, Object, Object]),
    __metadata("design:returntype", Promise)
], AuthController.prototype, "ssoCallback", null);
exports.AuthController = AuthController = __decorate([
    (0, swagger_1.ApiTags)('Authentication'),
    (0, swagger_1.ApiBearerAuth)('access-token'),
    (0, core_1.ApiValidationError)(),
    (0, core_1.ApiUnauthorized)(),
    (0, common_1.Controller)(),
    (0, common_2.UseFilters)(auth_exception_filter_1.AuthExceptionFilter),
    __metadata("design:paramtypes", [auth_service_1.AuthService,
        password_service_1.PasswordService,
        verification_service_1.VerificationService,
        auth_config_service_1.AuthConfigService,
        tenant_service_1.TenantService,
        invite_service_1.InviteService])
], AuthController);
//# sourceMappingURL=auth.controller.js.map