"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 swagger_2 = 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 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 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");
let AuthController = class AuthController {
    authService;
    passwordService;
    verificationService;
    constructor(authService, passwordService, verificationService) {
        this.authService = authService;
        this.passwordService = passwordService;
        this.verificationService = verificationService;
    }
    async signup(input) {
        const response = await this.authService.signup(input);
        return {
            ...response,
            message: 'Signup successful',
        };
    }
    async login(input) {
        const response = await this.authService.login(input);
        return {
            ...response,
            message: 'Login successful',
        };
    }
    async refreshToken(input) {
        const response = await this.authService.refreshToken(input.refreshToken);
        return {
            ...response,
            isRequiresMfa: false,
            message: 'Token refreshed successfully',
        };
    }
    async send2faCode(method) {
        const user = 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) {
        }
        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' };
    }
    async logoutAll(res) {
        const user = request_context_1.RequestContext.currentUser();
        if (!user) {
            throw new common_1.UnauthorizedException('User not found');
        }
        await this.authService.logoutAll(user.id);
        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 changePassword(input) {
        const response = await this.passwordService.changePassword(input);
        return {
            ...response,
            message: 'Password updated successfully',
        };
    }
    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 getUser() {
        return await this.authService.getUser();
    }
    async verifySession() {
        const user = request_context_1.RequestContext.currentUser();
        const session = request_context_1.RequestContext.currentSession();
        return {
            valid: true,
            userId: user?.id,
            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 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_2.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, common_1.HttpCode)(200),
    (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_2.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, 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_2.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, common_1.Post)('refresh-token'),
    (0, common_2.UseInterceptors)(token_response_interceptor_1.TokenResponseInterceptor),
    __param(0, (0, common_1.Body)()),
    __metadata("design:type", Function),
    __metadata("design:paramtypes", [refresh_token_request_dto_1.NestAuthRefreshTokenRequestDto]),
    __metadata("design:returntype", Promise)
], AuthController.prototype, "refreshToken", null);
__decorate([
    (0, swagger_2.ApiOperation)({ summary: 'Send MFA Code' }),
    (0, swagger_1.ApiResponse)({ status: 200, type: auth_messages_response_dto_1.NestAuthMfaCodeSentResponseDto }),
    (0, common_1.HttpCode)(200),
    (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_2.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, 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_2.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, 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_2.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 })),
    __metadata("design:type", Function),
    __metadata("design:paramtypes", [Object]),
    __metadata("design:returntype", Promise)
], AuthController.prototype, "logoutAll", null);
__decorate([
    (0, swagger_2.ApiOperation)({ summary: 'Change Password' }),
    (0, swagger_1.ApiResponse)({ status: 200, type: auth_response_dto_1.AuthWithTokensResponseDto }),
    (0, common_1.HttpCode)(200),
    (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_2.ApiOperation)({ summary: 'Forgot password' }),
    (0, swagger_1.ApiResponse)({ status: 200, type: auth_messages_response_dto_1.NestAuthPasswordResetLinkSentResponseDto }),
    (0, common_1.HttpCode)(200),
    (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_2.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, 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_2.ApiOperation)({ summary: 'Reset password' }),
    (0, swagger_1.ApiResponse)({ status: 200, type: auth_messages_response_dto_1.NestAuthPasswordResetResponseDto }),
    (0, common_1.HttpCode)(200),
    (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_2.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, common_1.Get)('user'),
    __metadata("design:type", Function),
    __metadata("design:paramtypes", []),
    __metadata("design:returntype", Promise)
], AuthController.prototype, "getUser", null);
__decorate([
    (0, swagger_2.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, common_1.Get)('verify-session'),
    __metadata("design:type", Function),
    __metadata("design:paramtypes", []),
    __metadata("design:returntype", Promise)
], AuthController.prototype, "verifySession", null);
__decorate([
    (0, swagger_2.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, 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_2.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, 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_2.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, 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, common_1.Controller)('auth'),
    (0, common_2.UseFilters)(auth_exception_filter_1.AuthExceptionFilter),
    __metadata("design:paramtypes", [auth_service_1.AuthService,
        password_service_1.PasswordService,
        verification_service_1.VerificationService])
], AuthController);
//# sourceMappingURL=auth.controller.js.map