import helmet from "helmet"; import type { Request, Response, NextFunction } from "express"; // Strict security headers via Helmet. export const securityHeaders = helmet({ contentSecurityPolicy: { directives: { defaultSrc: ["'none'"], frameAncestors: ["'none'"], }, }, hsts: { maxAge: 31_536_000, includeSubDomains: true, preload: true }, frameguard: { action: "deny" }, noSniff: true, referrerPolicy: { policy: "no-referrer" }, hidePoweredBy: true, // This is a public API accessed cross-origin — must be cross-origin not same-origin crossOriginResourcePolicy: { policy: "cross-origin" }, // Allow cross-origin opener for Stripe Identity redirect flows crossOriginOpenerPolicy: { policy: "unsafe-none" }, }); // Attach normalised client IP to req (handles IPv6-mapped IPv4). declare global { namespace Express { interface Request { clientIp?: string; } } } export function extractClientIp(req: Request, _res: Response, next: NextFunction): void { let ip = (req.headers["x-forwarded-for"] as string)?.split(",")[0]?.trim() || req.ip || ""; // Normalise ::ffff:127.0.0.1 → 127.0.0.1 if (ip.startsWith("::ffff:")) ip = ip.slice(7); req.clientIp = ip; next(); }