Files
gashboard/apps/api/src/server.ts

88 lines
2.3 KiB
TypeScript

import express from "express";
import helmet from "helmet";
import cors from "cors";
import { pinoHttp } from "pino-http";
import path from "node:path";
import { fileURLToPath } from "node:url";
import fs from "node:fs";
import { config } from "./config.js";
import { logger } from "./logger.js";
import { authRouter } from "./auth/routes.js";
import { datumRouter } from "./datum/routes.js";
import { errorHandler } from "./errors.js";
export function buildApp() {
const app = express();
app.disable("x-powered-by");
app.set("trust proxy", 1);
app.use(
helmet({
contentSecurityPolicy: {
useDefaults: true,
directives: {
"default-src": ["'self'"],
"script-src": ["'self'"],
"style-src": ["'self'", "'unsafe-inline'"],
"img-src": ["'self'", "data:"],
"connect-src": ["'self'"],
"font-src": ["'self'", "data:"],
"frame-ancestors": ["'none'"],
"upgrade-insecure-requests": null,
},
},
crossOriginEmbedderPolicy: false,
crossOriginOpenerPolicy: false,
originAgentCluster: false,
}),
);
if (config.corsOrigin) {
app.use(cors({ origin: config.corsOrigin, credentials: false }));
}
app.use(express.json({ limit: "32kb" }));
app.use(
pinoHttp({
logger,
autoLogging: {
ignore: (req) =>
req.url === "/healthz" ||
req.url === "/favicon.ico" ||
req.url.startsWith("/assets/"),
},
}),
);
app.get("/healthz", (_req, res) => {
res.json({ ok: true });
});
app.use("/api/auth", authRouter);
app.use("/api/datum", datumRouter);
const staticDir = config.staticDir
? config.staticDir
: resolveDefaultStaticDir();
if (staticDir && fs.existsSync(staticDir)) {
logger.info({ staticDir }, "serving web assets");
app.use(express.static(staticDir, { index: false, maxAge: "1h" }));
app.get(/.*/, (_req, res, next) => {
const indexFile = path.join(staticDir, "index.html");
if (!fs.existsSync(indexFile)) return next();
res.sendFile(indexFile);
});
} else {
logger.warn({ staticDir }, "web assets directory not found");
}
app.use(errorHandler);
return app;
}
function resolveDefaultStaticDir(): string {
const here = path.dirname(fileURLToPath(import.meta.url));
return path.resolve(here, "../../web/dist");
}