Files
Kordant/packages/api/src/server.ts
Senior Engineer 91e4985a8e FRE-4474 Phase 5: Verify and resolve security review findings for SpamShield and Cross-Service Correlation
- FRE-4499 (SpamShield): Verified 6 security fixes (2 High, 4 Medium)
  - S01: Pre-compiled regex in RuleEngine (ReDoS fix)
  - S02: SmsClassifier accepts senderPhoneNumber context
  - S03: AlertServer JWT auth + origin validation
  - S04: SHA-256 phone hashing (PII protection)
  - S05: DecisionEngine timeout enforcement via Promise.race
  - S06: CarrierFactory.getAllCarriers properly async/await

- FRE-4500 (Correlation): Verified 7 security fixes (2 Critical, 2 High, 2 Medium, 1 Low)
  - C1: Ingest endpoints auth via request.user.id
  - C2: IDOR protection on group endpoints (userId filter)
  - H3: JWT middleware registered in server.ts
  - H4: Fastify schema validation on all routes
  - M6: Payload sanitization with depth limit and circular ref detection
  - L7: CORS origin restricted to env var

- Resolved liveness incidents FRE-4652 and FRE-4654
- All Phase 5 child issues now complete
2026-05-02 18:36:29 -04:00

50 lines
1.6 KiB
TypeScript

import Fastify from "fastify";
import cors from "@fastify/cors";
import helmet from "@fastify/helmet";
import sensible from "@fastify/sensible";
import { extractOrGenerateRequestId } from "@shieldai/types";
import { authMiddleware } from "./middleware/auth.middleware";
import { darkwatchRoutes } from "./routes/darkwatch.routes";
import { voiceprintRoutes } from "./routes/voiceprint.routes";
import { correlationRoutes } from "./routes/correlation.routes";
const app = Fastify({
logger: {
level: process.env.LOG_LEVEL || "info",
},
});
async function bootstrap() {
await app.register(cors, { origin: process.env.CORS_ORIGIN || "http://localhost:5173" });
await app.register(helmet);
await app.register(sensible);
// Register auth middleware to populate request.user
await app.register(authMiddleware);
app.addHook("onRequest", async (request, _reply) => {
const requestId = extractOrGenerateRequestId(request.headers);
request.id = requestId;
const pinoLog = request.log as typeof request.log & { bindings?: Record<string, string>; bindActive?: () => void };
pinoLog.bindings = { requestId };
pinoLog.bindActive?.();
request.headers["x-request-id"] = requestId;
});
await app.register(darkwatchRoutes);
await app.register(voiceprintRoutes);
await app.register(correlationRoutes);
app.get("/health", async () => ({ status: "ok", timestamp: new Date().toISOString() }));
try {
await app.listen({ port: parseInt(process.env.PORT || "3000", 10), host: "0.0.0.0" });
app.log.info(`Server listening on port ${process.env.PORT || 3000}`);
} catch (err) {
app.log.error(err);
process.exit(1);
}
}
bootstrap();