feat(F-078): completed feature
This commit is contained in:
@@ -9,12 +9,14 @@ import { errorSchema } from '../../../shared/swagger.js';
|
||||
import { parseJson } from '../../../shared/http-input.js';
|
||||
import { AuditLogger } from '../application/audit-logger.js';
|
||||
import { RateLimiter } from '../application/rate-limiter.js';
|
||||
import type { LogBroadcaster } from '../../../infrastructure/logging/log-broadcaster.js';
|
||||
|
||||
export interface SecurityRoutesDeps {
|
||||
pool: pg.Pool;
|
||||
authenticate: Authenticate;
|
||||
rateLimiter: RateLimiter;
|
||||
auditLogger: AuditLogger;
|
||||
broadcaster?: LogBroadcaster;
|
||||
}
|
||||
|
||||
// ── Schema definitions ─────────────────────────────────────────────────────────
|
||||
@@ -150,6 +152,24 @@ export async function registerSecurityRoutes(
|
||||
return reply.send(decision);
|
||||
});
|
||||
|
||||
// ── Server log stream (SSE) ─────────────────────────────────────────────
|
||||
app.get('/admin/logs/stream', async (request, reply) => {
|
||||
const user = await deps.authenticate(request);
|
||||
requireRole(user, 'admin');
|
||||
|
||||
if (!deps.broadcaster) {
|
||||
throw new AppError(500, 'BROADCASTER_UNAVAILABLE', 'Log broadcaster not available');
|
||||
}
|
||||
|
||||
const stream = deps.broadcaster.registerClient();
|
||||
return reply
|
||||
.header('Content-Type', 'text/event-stream')
|
||||
.header('Cache-Control', 'no-cache, no-store, must-revalidate')
|
||||
.header('Connection', 'keep-alive')
|
||||
.header('X-Accel-Buffering', 'no')
|
||||
.send(stream);
|
||||
});
|
||||
|
||||
// ── Admin user management ──────────────────────────────────────────────────
|
||||
const listAdminUsersSchema: FastifySchema = {
|
||||
tags: ['Admin'],
|
||||
|
||||
Reference in New Issue
Block a user