Backend hardening: structured logging, timeouts, memory leak fixes, compression, XSS fix
Some checks failed
Deploy to Production / Deploy to Server (push) Failing after 20s
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:
parent
4833edf44c
commit
9541ae1826
20 changed files with 319 additions and 74 deletions
|
|
@ -1,4 +1,5 @@
|
|||
import { randomBytes, randomInt } from "crypto";
|
||||
import logger from "./logger.js";
|
||||
import pool from "./db.js";
|
||||
|
||||
export interface Verification {
|
||||
|
|
@ -63,6 +64,17 @@ export async function loadVerifications(): Promise<void> {
|
|||
createdAt: r.created_at instanceof Date ? r.created_at.toISOString() : r.created_at,
|
||||
verifiedAt: r.verified_at ? (r.verified_at instanceof Date ? r.verified_at.toISOString() : r.verified_at) : null,
|
||||
}));
|
||||
|
||||
// Cleanup expired entries every 15 minutes
|
||||
setInterval(() => {
|
||||
const cutoff = Date.now() - 24 * 60 * 60 * 1000;
|
||||
const before = verificationsCache.length;
|
||||
verificationsCache = verificationsCache.filter(
|
||||
(v) => v.verifiedAt || new Date(v.createdAt).getTime() > cutoff
|
||||
);
|
||||
const removed = before - verificationsCache.length;
|
||||
if (removed > 0) logger.info({ removed }, "Cleaned expired verification cache entries");
|
||||
}, 15 * 60 * 1000);
|
||||
}
|
||||
|
||||
function verifyTokenSync(token: string): { status: "ok"; verification: Verification } | { status: "invalid" | "expired" | "already_verified"; verification?: Verification } {
|
||||
|
|
@ -73,7 +85,7 @@ function verifyTokenSync(token: string): { status: "ok"; verification: Verificat
|
|||
if (age > TOKEN_EXPIRY_MS) return { status: "expired" };
|
||||
v.verifiedAt = new Date().toISOString();
|
||||
// Update DB async
|
||||
pool.query("UPDATE verifications SET verified_at = $1 WHERE token = $2", [v.verifiedAt, token]).catch(console.error);
|
||||
pool.query("UPDATE verifications SET verified_at = $1 WHERE token = $2", [v.verifiedAt, token]).catch((err) => logger.error({ err }, "Failed to update verification"));
|
||||
return { status: "ok", verification: v };
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue