eduverse-backend / src /modules /security /controllers /security.controller.ts
amirhamdi's picture
sprint 4 dev a endpoints works
828d8a4
Raw
History Blame Contribute Delete
6.73 kB
import {
Controller,
Get,
Post,
Delete,
Body,
Param,
Query,
UseGuards,
ParseIntPipe,
Request,
} from '@nestjs/common';
import {
ApiTags,
ApiBearerAuth,
ApiOperation,
ApiResponse,
ApiParam,
} from '@nestjs/swagger';
import { JwtAuthGuard } from '../../auth/guards/jwt-auth.guard';
import { RolesGuard } from '../../auth/guards/roles.guard';
import { Roles } from '../../../common/decorators/roles.decorator';
import { RoleName } from '../../auth/entities/role.entity';
import { SecurityService } from '../services/security.service';
import { IpBlockerService } from '../services/ip-blocker.service';
import { SecurityLogQueryDto } from '../dto/security-log-query.dto';
import { BlockIpDto } from '../dto/block-ip.dto';
import { ExportLogsDto } from '../dto/export-logs.dto';
@ApiTags('πŸ”’ Security')
@ApiBearerAuth('JWT-auth')
@Controller('api/security')
@UseGuards(JwtAuthGuard, RolesGuard)
export class SecurityController {
constructor(
private readonly securityService: SecurityService,
private readonly ipBlockerService: IpBlockerService,
) {}
// ── Static routes first ────────────────────────────────────
@Get('logs')
@Roles(RoleName.ADMIN, RoleName.IT_ADMIN)
@ApiOperation({
summary: 'Get security logs (paginated, filterable)',
description: 'Retrieves a paginated list of security events. Access rules: ADMIN, IT_ADMIN. Uses table: `security_logs`.',
})
@ApiResponse({ status: 200, description: 'Security logs returned' })
async getSecurityLogs(@Query() query: SecurityLogQueryDto) {
return this.securityService.getSecurityLogs(query);
}
@Get('logs/stats')
@Roles(RoleName.ADMIN, RoleName.IT_ADMIN)
@ApiOperation({
summary: 'Get security log statistics',
description: 'Retrieves security statistics (recent logs, categorization). Access rules: ADMIN, IT_ADMIN. Uses table: `security_logs`.',
})
@ApiResponse({ status: 200, description: 'Security stats returned' })
async getSecurityLogStats() {
return this.securityService.getSecurityLogStats();
}
@Post('logs/export')
@Roles(RoleName.IT_ADMIN)
@ApiOperation({
summary: 'Export security logs',
description: 'Exports security logs in CSV or JSON format. Access rules: IT_ADMIN. Uses table: `security_logs`.',
})
@ApiResponse({ status: 200, description: 'Export data returned' })
async exportLogs(@Body() dto: ExportLogsDto) {
return this.securityService.exportLogs(dto);
}
@Get('dashboard')
@Roles(RoleName.ADMIN, RoleName.IT_ADMIN)
@ApiOperation({
summary: 'Get security dashboard',
description: 'Fetches aggregated security data for dashboards. Access rules: ADMIN, IT_ADMIN. Uses tables: `security_logs`, `sessions`, `blocked_ips`, `login_attempts`.',
})
@ApiResponse({ status: 200, description: 'Dashboard data returned' })
async getDashboard() {
return this.securityService.getDashboard();
}
@Get('threats')
@Roles(RoleName.IT_ADMIN)
@ApiOperation({
summary: 'Get active threats',
description: 'Retrieves a list of currently active threats, blocked IPs, and multiple failures. Access rules: IT_ADMIN. Uses tables: `security_logs`, `login_attempts`, `blocked_ips`.',
})
@ApiResponse({ status: 200, description: 'Threats data returned' })
async getThreats() {
return this.securityService.getThreats();
}
@Get('sessions')
@Roles(RoleName.ADMIN, RoleName.IT_ADMIN)
@ApiOperation({
summary: 'Get active sessions',
description: 'List all currently active sessions on the server. Access rules: ADMIN, IT_ADMIN. Uses table: `sessions`.',
})
@ApiResponse({ status: 200, description: 'Active sessions returned' })
async getActiveSessions() {
return this.securityService.getActiveSessions();
}
@Get('blocked-ips')
@Roles(RoleName.IT_ADMIN)
@ApiOperation({
summary: 'Get blocked IPs',
description: 'Retrieves complete list of blocked IP addresses. Access rules: IT_ADMIN. Uses table: `blocked_ips`.',
})
@ApiResponse({ status: 200, description: 'Blocked IPs returned' })
async getBlockedIps() {
return this.ipBlockerService.getBlockedIps();
}
@Post('block-ip')
@Roles(RoleName.IT_ADMIN)
@ApiOperation({
summary: 'Block an IP address',
description: 'Blocks a specific IPv4/IPv6 address permanently or temporarily. Access rules: IT_ADMIN. Uses table: `blocked_ips`.',
})
@ApiResponse({ status: 201, description: 'IP blocked' })
async blockIp(@Body() dto: BlockIpDto) {
return this.ipBlockerService.blockIp(dto);
}
@Get('login-attempts')
@Roles(RoleName.ADMIN, RoleName.IT_ADMIN)
@ApiOperation({
summary: 'Get login attempts',
description: 'Queries login attempts log base including failures and successes. Access rules: ADMIN, IT_ADMIN. Uses table: `login_attempts`.',
})
@ApiResponse({ status: 200, description: 'Login attempts returned' })
async getLoginAttempts(@Query() query: SecurityLogQueryDto) {
return this.securityService.getLoginAttempts(query);
}
// ── Parameter routes ───────────────────────────────────────
@Delete('sessions/user/:userId')
@Roles(RoleName.ADMIN, RoleName.IT_ADMIN)
@ApiOperation({
summary: 'Revoke all sessions for a user',
description: 'Force purges all active tokens rendering existing sessions invalid. Access rules: ADMIN, IT_ADMIN. Uses table: `sessions`.',
})
@ApiParam({ name: 'userId', type: Number })
@ApiResponse({ status: 200, description: 'User sessions revoked' })
async revokeUserSessions(@Param('userId', ParseIntPipe) userId: number) {
return this.securityService.revokeUserSessions(userId);
}
@Delete('sessions/:id')
@Roles(RoleName.ADMIN, RoleName.IT_ADMIN)
@ApiOperation({
summary: 'Revoke a specific session',
description: 'Terminates a single specific session instance by ID. Access rules: ADMIN, IT_ADMIN. Uses table: `sessions`.',
})
@ApiParam({ name: 'id', type: Number })
@ApiResponse({ status: 200, description: 'Session revoked' })
async revokeSession(@Param('id', ParseIntPipe) id: number) {
return this.securityService.revokeSession(id);
}
@Delete('blocked-ips/:id')
@Roles(RoleName.IT_ADMIN)
@ApiOperation({
summary: 'Unblock an IP address',
description: 'Removes an IP block restoring connection to the target server point. Access rules: IT_ADMIN. Uses table: `blocked_ips`.',
})
@ApiParam({ name: 'id', type: Number })
@ApiResponse({ status: 200, description: 'IP unblocked' })
async unblockIp(@Param('id', ParseIntPipe) id: number) {
return this.ipBlockerService.unblockIp(id);
}
}