Backend hardening: structured logging, timeouts, memory leak fixes, compression, XSS fix
Some checks failed
Deploy to Production / Deploy to Server (push) Failing after 20s

- Add pino structured logging with request IDs (X-Request-Id header)
- Add 30s timeout to acquirePage() and renderPdf/renderUrlPdf
- Add verification cache cleanup (every 15min) and rate limit cleanup (every 60s)
- Read version from package.json in health endpoint
- Add compression middleware
- Escape currency in templates (XSS fix)
- Add static asset caching (1h maxAge)
- Remove deprecated docker-compose version field
- Replace all console.log/error with pino logger
This commit is contained in:
OpenClaw 2026-02-16 08:27:42 +00:00
parent 4833edf44c
commit 9541ae1826
20 changed files with 319 additions and 74 deletions

View file

@ -1,4 +1,7 @@
import express from "express";
import { randomUUID } from "crypto";
import compression from "compression";
import logger from "./services/logger.js";
import helmet from "helmet";
import path from "path";
import { fileURLToPath } from "url";
@ -24,6 +27,17 @@ const PORT = parseInt(process.env.PORT || "3100", 10);
app.use(helmet({ crossOriginResourcePolicy: { policy: "cross-origin" } }));
// Request ID middleware
app.use((req, res, next) => {
const requestId = (req.headers["x-request-id"] as string) || randomUUID();
(req as any).requestId = requestId;
res.setHeader("X-Request-Id", requestId);
next();
});
// Compression
app.use(compression());
// Differentiated CORS middleware
app.use((req, res, next) => {
const isAuthBillingRoute = req.path.startsWith('/v1/signup') ||
@ -145,7 +159,7 @@ ${apiKey ? `
// Landing page
const __dirname = path.dirname(fileURLToPath(import.meta.url));
app.use(express.static(path.join(__dirname, "../public")));
app.use(express.static(path.join(__dirname, "../public"), { maxAge: "1h", etag: true }));
// Docs page (clean URL)
app.get("/docs", (_req, res) => {
@ -179,11 +193,11 @@ async function start() {
await loadUsageData();
await initBrowser();
console.log(`Loaded ${getAllKeys().length} API keys`);
app.listen(PORT, () => console.log(`DocFast API running on :${PORT}`));
logger.info(`Loaded ${getAllKeys().length} API keys`);
app.listen(PORT, () => logger.info(`DocFast API running on :${PORT}`));
const shutdown = async () => {
console.log("Shutting down...");
logger.info("Shutting down...");
await closeBrowser();
process.exit(0);
};
@ -192,7 +206,7 @@ async function start() {
}
start().catch((err) => {
console.error("Failed to start:", err);
logger.error({ err }, "Failed to start");
process.exit(1);
});