import { Controller, Post, Body, Req, UseGuards, Get, HttpCode, HttpStatus, } from '@nestjs/common'; import { ApiTags, ApiOperation, ApiBearerAuth } from '@nestjs/swagger'; import type { Request } from 'express'; import { TwoFactorAuthService } from './two-factor-auth.service'; import { SuperAdminAuthGuard } from '../auth/guards/super-admin-auth.guard'; import { EnableEmail2FADto, SendEmail2FACodeDto, VerifyEmail2FADto, } from './dto/email-2fa.dto'; import { InitTotp2FADto, VerifyTotpSetupDto, VerifyTotp2FADto, } from './dto/totp-2fa.dto'; import { VerifyRecoveryCodeDto, RegenerateRecoveryCodesDto, } from './dto/recovery-code.dto'; import { LogToDiscord } from 'src/shared/decorators/log-to-discord.decorator'; @ApiTags('Super Admin - Two Factor Authentication') @Controller('super-admin/2fa') @LogToDiscord() export class TwoFactorAuthController { constructor(private readonly twoFactorAuthService: TwoFactorAuthService) {} // ==================== EMAIL 2FA ==================== @Post('email/enable') @UseGuards(SuperAdminAuthGuard) @ApiBearerAuth() @ApiOperation({ summary: 'Enable Email 2FA' }) async enableEmail2FA(@Body() dto: EnableEmail2FADto) { return this.twoFactorAuthService.enableEmail2FA(dto.email); } @Post('email/send-code') @HttpCode(HttpStatus.OK) @ApiOperation({ summary: 'Send Email 2FA Code' }) async sendEmail2FACode( @Body() dto: SendEmail2FACodeDto, @Req() request: Request, ) { return this.twoFactorAuthService.sendEmail2FACode( dto.pending2faToken, request, ); } @Post('email/verify') @HttpCode(HttpStatus.OK) @ApiOperation({ summary: 'Verify Email 2FA Code' }) async verifyEmail2FACode( @Body() dto: VerifyEmail2FADto, @Req() request: Request, ) { return this.twoFactorAuthService.verifyEmail2FACode( dto.pending2faToken, dto.code, dto.trustDevice || false, request, ); } // ==================== TOTP/AUTHENTICATOR 2FA ==================== @Post('totp/init') @UseGuards(SuperAdminAuthGuard) @ApiBearerAuth() @ApiOperation({ summary: 'Initialize TOTP Setup' }) async initTotp2FA(@Body() dto: InitTotp2FADto) { return this.twoFactorAuthService.initTotp2FA(dto.email); } @Post('totp/verify-setup') @UseGuards(SuperAdminAuthGuard) @ApiBearerAuth() @ApiOperation({ summary: 'Verify TOTP Setup' }) async verifyTotpSetup(@Body() dto: VerifyTotpSetupDto, @Req() request: any) { return this.twoFactorAuthService.verifyTotpSetup( request.user.email, dto.code, ); } @Post('totp/verify') @HttpCode(HttpStatus.OK) @ApiOperation({ summary: 'Verify TOTP Code' }) async verifyTotp2FACode( @Body() dto: VerifyTotp2FADto, @Req() request: Request, ) { return this.twoFactorAuthService.verifyTotp2FACode( dto.pending2faToken, dto.code, dto.trustDevice || false, request, ); } // ==================== RECOVERY CODES ==================== @Post('recovery/verify') @HttpCode(HttpStatus.OK) @ApiOperation({ summary: 'Verify Recovery Code' }) async verifyRecoveryCode( @Body() dto: VerifyRecoveryCodeDto, @Req() request: Request, ) { return this.twoFactorAuthService.verifyRecoveryCode( dto.pending2faToken, dto.code, dto.trustDevice || false, request, ); } @Post('recovery/regenerate') @UseGuards(SuperAdminAuthGuard) @ApiBearerAuth() @ApiOperation({ summary: 'Regenerate Recovery Codes' }) async regenerateRecoveryCodes(@Body() dto: RegenerateRecoveryCodesDto) { return this.twoFactorAuthService.regenerateRecoveryCodes(dto.email); } // ==================== INFO/STATUS ==================== @Get('status') @UseGuards(SuperAdminAuthGuard) @ApiBearerAuth() @ApiOperation({ summary: 'Get 2FA Status' }) async get2FAStatus(@Req() request: any) { return this.twoFactorAuthService.get2FAStatus(request.user.email); } }