Assist_Design/apps/bff/src/modules/auth/auth-admin.controller.ts

90 lines
2.5 KiB
TypeScript
Raw Normal View History

2025-08-21 15:24:40 +09:00
import {
Controller,
Get,
Post,
Param,
UseGuards,
Query,
2025-08-22 17:02:49 +09:00
BadRequestException,
2025-08-21 15:24:40 +09:00
} from "@nestjs/common";
2025-08-22 17:02:49 +09:00
import { ApiTags, ApiOperation, ApiResponse, ApiBearerAuth } from "@nestjs/swagger";
2025-08-21 15:24:40 +09:00
import { AdminGuard } from "./guards/admin.guard";
import { AuditService, AuditAction } from "@bff/infra/audit/audit.service";
import { UsersService } from "@bff/modules/users/users.service";
2025-08-21 15:24:40 +09:00
@ApiTags("auth-admin")
@ApiBearerAuth()
2025-08-28 16:57:57 +09:00
@UseGuards(AdminGuard)
2025-08-21 15:24:40 +09:00
@Controller("auth/admin")
export class AuthAdminController {
constructor(
private auditService: AuditService,
2025-08-22 17:02:49 +09:00
private usersService: UsersService
) {}
2025-08-21 15:24:40 +09:00
@Get("audit-logs")
@ApiOperation({ summary: "Get audit logs (admin only)" })
@ApiResponse({ status: 200, description: "Audit logs retrieved" })
async getAuditLogs(
2025-08-21 15:24:40 +09:00
@Query("page") page: string = "1",
@Query("limit") limit: string = "50",
@Query("action") action?: AuditAction,
2025-08-22 17:02:49 +09:00
@Query("userId") userId?: string
) {
const pageNum = parseInt(page, 10);
const limitNum = parseInt(limit, 10);
2025-08-22 17:02:49 +09:00
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),
},
};
}
2025-08-21 15:24:40 +09:00
@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) {
2025-08-22 17:02:49 +09:00
throw new BadRequestException("User not found");
}
await this.usersService.update(userId, {
failedLoginAttempts: 0,
lockedUntil: null,
});
await this.auditService.log({
userId,
action: AuditAction.ACCOUNT_UNLOCKED,
2025-08-21 15:24:40 +09:00
resource: "auth",
details: { adminAction: true, email: user.email },
success: true,
});
2025-08-21 15:24:40 +09:00
return { message: "Account unlocked successfully" };
}
2025-08-21 15:24:40 +09:00
@Get("security-stats")
@ApiOperation({ summary: "Get security statistics (admin only)" })
@ApiResponse({ status: 200, description: "Security stats retrieved" })
async getSecurityStats() {
return this.auditService.getSecurityStats();
}
}