import { Controller, Get, Post, Param, UseGuards, Query, BadRequestException, } from "@nestjs/common"; import { ApiTags, ApiOperation, ApiResponse, ApiBearerAuth } from "@nestjs/swagger"; import { AdminGuard } from "./guards/admin.guard"; import { AuditService, AuditAction } from "@bff/infra/audit/audit.service"; import { UsersService } from "@bff/modules/users/users.service"; @ApiTags("auth-admin") @ApiBearerAuth() @UseGuards(AdminGuard) @Controller("auth/admin") export class AuthAdminController { constructor( private auditService: AuditService, private usersService: UsersService ) {} @Get("audit-logs") @ApiOperation({ summary: "Get audit logs (admin only)" }) @ApiResponse({ status: 200, description: "Audit logs retrieved" }) async getAuditLogs( @Query("page") page: string = "1", @Query("limit") limit: string = "50", @Query("action") action?: AuditAction, @Query("userId") userId?: string ) { const pageNum = parseInt(page, 10); const limitNum = parseInt(limit, 10); if (Number.isNaN(pageNum) || Number.isNaN(limitNum) || pageNum < 1 || limitNum < 1) { throw new BadRequestException("Invalid pagination parameters"); } const { logs, total } = await this.auditService.getAuditLogs({ page: pageNum, limit: limitNum, action, userId, }); return { logs, pagination: { page: pageNum, limit: limitNum, total, totalPages: Math.ceil(total / limitNum), }, }; } @Post("unlock-account/:userId") @ApiOperation({ summary: "Unlock user account (admin only)" }) @ApiResponse({ status: 200, description: "Account unlocked" }) async unlockAccount(@Param("userId") userId: string) { const user = await this.usersService.findById(userId); if (!user) { throw new BadRequestException("User not found"); } await this.usersService.update(userId, { failedLoginAttempts: 0, lockedUntil: null, }); await this.auditService.log({ userId, action: AuditAction.ACCOUNT_UNLOCKED, resource: "auth", details: { adminAction: true, email: user.email }, success: true, }); return { message: "Account unlocked successfully" }; } @Get("security-stats") @ApiOperation({ summary: "Get security statistics (admin only)" }) @ApiResponse({ status: 200, description: "Security stats retrieved" }) async getSecurityStats() { return this.auditService.getSecurityStats(); } }