config.ts
Raw
1// Runtime configuration, read once from the environment at startup.
2// Defaults are chosen to be secure-but-non-breaking; tighten them in production
3// (see README for the full list and the "run behind TLS" note).
4
5const env = process.env
6
7/** parseInt with a default that distinguishes "unset" from "explicit 0". */
8function intEnv(value: string | undefined, defaultValue: number): number {
9 if (value === undefined || value === "") return defaultValue;
10 const parsed = parseInt(value, 10);
11 return Number.isFinite(parsed) ? parsed : defaultValue;
12}
13
14/** Truthy only for "true"/"1"; anything else (incl. "false", "0", unset) is off. */
15function boolEnv(value: string | undefined): boolean {
16 return value === "true" || value === "1";
17}
18
19export const config = {
20 // Hard cap on a single upload, in bytes (default 100 MiB).
21 maxUploadBytes: intEnv(Bun.env.MAX_UPLOAD_BYTES, 100 * 1024 * 1024),
22 // Maximum retention in minutes. null = unlimited; when set, every upload's
23 // deletion time is clamped to at most now + maxAgeMinutes.
24 maxAgeMinutes: Bun.env.MAX_AGE_MINUTES
25 ? intEnv(Bun.env.MAX_AGE_MINUTES, 0) || null
26 : null,
27 // Minimum seconds between uploads from the same client IP. 0 = disabled.
28 uploadCooldownSeconds: intEnv(Bun.env.UPLOAD_COOLDOWN_SECONDS, 0),
29 // Set when running behind a trusted TLS-terminating reverse proxy (the usual
30 // production setup). Enables reading X-Forwarded-For / X-Real-IP for the
31 // client IP and adds the Secure flag to the password cookie. Leave off for
32 // direct/local HTTP, otherwise clients can spoof the cooldown key and the
33 // Secure cookie won't be sent over plain HTTP.
34 behindProxy: boolEnv(env.BEHIND_PROXY),
35};
36