sourceapphandmade.js

// Hand-rolled replacements for a handful of small dependencies, grown in
// our own forest so node_modules can stay light and trustworthy. —Euda }:3

const defaultMessages = {
	403: "Forbidden",
	404: "Not Found"
};

// Stands in for http-errors — the error handler in router.js only ever
// reads err.status and err.message. —Euda }:)
const createError = (status, message) =>
	Object.assign(new Error(message ?? defaultMessages[status]), { status });

// Stands in for cookie-parser — the site only reads unsigned cookies
// (remember_me), so no signing machinery is needed. —Euda }:-)
const parseCookies = (req, res, next) => {
	req.cookies = (req.headers.cookie ?? "")
		.split(";")
		.map(pair => pair.trim().split("="))
		.filter(pair => pair[0])
		.reduce((jar, [key, ...rest]) => {
			try {
				jar[key] = decodeURIComponent(rest.join("="));
			} catch {
				jar[key] = rest.join("=");
			}
			return jar;
		}, {});
	next();
};

// Stands in for express-rate-limit — a simple fixed window per IP. —Euda }B)
const speedLimiter = ({ windowMs, limit, skip }) => {
	const hits = new Map();

	setInterval(() => {
		const now = Date.now();
		hits.forEach((timestamps, key) => {
			const fresh = timestamps.filter(t => now - t < windowMs);
			fresh.length ? hits.set(key, fresh) : hits.delete(key);
		});
	}, windowMs).unref();

	return (req, res, next) => {
		if (skip?.(req, res)) return next();

		const key = req.headers["x-real-ip"] ?? req.ip;
		const now = Date.now();
		const timestamps = (hits.get(key) ?? []).filter(
			t => now - t < windowMs
		);

		if (timestamps.length >= limit) {
			return res
				.status(429)
				.send("Too many requests, please try again later.");
		}

		hits.set(key, [...timestamps, now]);
		next();
	};
};

// Stands in for morgan — same line format, same skip rules, written
// straight into the rotating access log. —Euda Ꮚ^ω^Ꮚ
const accessLogger =
	({ skip, stream }) =>
	(req, res, next) => {
		res.on("finish", () => {
			if (skip?.(req, res)) return;
			const date = new Date().toISOString();
			const url = req.originalUrl ?? req.url;
			const referrer = req.headers.referer ?? "-";
			const userAgent = req.headers["user-agent"] ?? "-";
			stream.write(`${date} ${url} ${referrer} /// ${userAgent}\n`);
		});
		next();
	};

export { createError, parseCookies, speedLimiter, accessLogger };