All files / src app.ts

100% Statements 24/24
80% Branches 4/5
100% Functions 1/1
100% Lines 24/24

Press n or j to go to the next uncovered block, b, p or k for the previous block.

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 421x                         26x 26x 26x 26x 26x 26x   26x   26x 26x 26x 26x 26x 26x 26x 26x 26x 26x 26x   26x   26x 26x   26x 26x  
import cors from "@fastify/cors";
import multipart from "@fastify/multipart";
import { registerErrorHandler } from "@ontrack/backend-common";
import Fastify from "fastify";
import type { AppConfig } from "./config.js";
import { createEmailVerifiedChecker } from "./lib/firebase-admin.js";
import {
  createIdTokenVerifier,
  setLiveEmailCheck,
  type IdTokenVerifier,
} from "./lib/firebase-auth.js";
import { registerRoutes } from "./routes/index.js";
 
export async function buildApp(config: AppConfig, deps: { verifyIdToken?: IdTokenVerifier } = {}) {
  const app = Fastify({
    logger: {
      level: config.nodeEnv === "production" ? "info" : "debug",
    },
  });
 
  registerErrorHandler(app);
  // Browser clients only: empty allowlist disables cross-origin (mobile/curl unaffected).
  await app.register(cors, {
    origin: config.corsOrigins.length > 0 ? config.corsOrigins : false,
    methods: ["GET", "POST", "PUT", "PATCH", "DELETE", "OPTIONS"],
    allowedHeaders: ["Content-Type", "Authorization"],
    maxAge: 86400,
  });
  await app.register(multipart, {
    limits: {
      fileSize: 52 * 1024 * 1024,
    },
  });
 
  const verifyIdToken = deps.verifyIdToken ?? createIdTokenVerifier(config.firebaseProjectId);
  // Живая сверка email_verified для протухших токенов (без Admin SDK — гейт по claim'у).
  setLiveEmailCheck(createEmailVerifiedChecker(config.firebaseServiceAccountPath));
  await registerRoutes(app, config, verifyIdToken);
 
  return app;
}