/** * Lets a deployment configure the server through the `GERBEUR_*` environment * variables, which it reads once at import, and holds the fixed limits the * backend applies. The deno tasks load `.env` with `--env-file`, so changing a * setting needs a restart. * * @module */ import { BASE_STYLE, isStyleName, type StyleName } from "../shared/theme.ts"; import { isLocale, type Locale, SOURCE_LOCALE } from "../shared/locale.ts"; /** The port the server listens on (`GERBEUR_PORT`, default 8000). */ export const PORT: number = Number(Deno.env.get("GERBEUR_PORT")) || 8000; /** * The `smtps://` URL of the server `email-service.ts` sends mail through * (`GERBEUR_SMTPS_URL`). When it is empty, no email is sent: sign-up sends no * welcome, a password reset request does nothing, and there are no digests. */ export const SMTPS_URL: string = Deno.env.get("GERBEUR_SMTPS_URL")?.trim() || ""; /** * Whether the instance sends email, which is whether {@link SMTPS_URL} is * set. `email-service.ts` opens its transport by it, and index.html tells the * client, whose settings show the digest switches disabled without it. */ export const EMAIL_ENABLED: boolean = SMTPS_URL.length > 0; /** * The `From` address of every email (`GERBEUR_FROM_EMAIL`), as an address or * as `Name
`. `email-service.ts` refuses to load without it when * {@link SMTPS_URL} is set. */ export const FROM_EMAIL: string = Deno.env.get("GERBEUR_FROM_EMAIL")?.trim() || ""; /** * The Markdown of the welcome email sent on registration * (`GERBEUR_WELCOME_EMAIL_BODY`), or null for the built-in one in the * {@link EMAIL_LOCALE}. `api/mail/welcome.ts` replaces `{{site_name}}` and * `{{username}}` in it. */ export const WELCOME_EMAIL_BODY: string | null = Deno.env.get("GERBEUR_WELCOME_EMAIL_BODY")?.trim() || null; /** * The language of every email (`GERBEUR_EMAIL_LOCALE`). The interface picks * each visitor's language in their browser, which the server never learns, so * the emails take the instance's. A value that isn't a locale means the * source one, English. */ export const EMAIL_LOCALE: Locale = (() => { const locale = Deno.env.get("GERBEUR_EMAIL_LOCALE")?.trim(); return isLocale(locale) ? locale : SOURCE_LOCALE; })(); /** * The instance's style (`GERBEUR_DEFAULT_STYLE`). The site shows it until a * visitor or their account picks one, through index.html, and the emails that * aren't a user's own (the welcome and the password reset) are drawn in it. A * value that isn't a style means {@link BASE_STYLE}. */ export const DEFAULT_STYLE: StyleName = (() => { const style = Deno.env.get("GERBEUR_DEFAULT_STYLE")?.trim(); return isStyleName(style) ? style : BASE_STYLE; })(); /** * The key lib/jwt.ts signs and verifies tokens with (`GERBEUR_JWT_SECRET`). * The server refuses to start without it. */ export const JWT_SECRET: string = Deno.env.get("GERBEUR_JWT_SECRET")?.trim() || ""; /** * The interface the server binds to (`GERBEUR_LISTEN_HOST`). The default, * 0.0.0.0, lets Docker forward the port; 127.0.0.1 keeps it to loopback. */ export const LISTEN_HOST: string = Deno.env.get("GERBEUR_LISTEN_HOST") || "0.0.0.0"; /** * The URL visitors reach the server at (`GERBEUR_PUBLIC_URL`), without a * trailing slash. Behind a reverse proxy it must be the outside URL: it is an * allowed origin, it tells links to this site's own pages from other links, * and it prefixes the image URLs in their previews. */ export const PUBLIC_URL: string = Deno.env.get("GERBEUR_PUBLIC_URL")?.trim().replace(/\/$/, "") || `http://localhost:${PORT}`; /** * Points password reset links and the Open Graph tags' page URLs at the * frontend when it isn't served from {@link PUBLIC_URL}, as with a separate * Vite server, and allows it as an origin. It is `GERBEUR_FRONTEND_URL`, * without a trailing slash. */ export const FRONTEND_URL: string = Deno.env.get("GERBEUR_FRONTEND_URL")?.trim().replace(/\/$/, "") || PUBLIC_URL; /** * The SQLite database file (`GERBEUR_DB_PATH`). api/test/setup.ts points it at * a throwaway file before anything opens the database. */ export const DB_PATH: string = Deno.env.get("GERBEUR_DB_PATH") || "api/sql/gerbeur.db"; /** * The directory uploads are stored under (`GERBEUR_UPLOADS_DIR`). Each kind has * its subdirectory below, created by the first upload, and each file is named * after the id of what it belongs to. */ export const UPLOADS_DIR: string = Deno.env.get("GERBEUR_UPLOADS_DIR") || "api/uploads"; /** Holds the file of each file dump. */ export const DUMPS_DIR = `${UPLOADS_DIR}/dumps`; /** Holds each user's avatar. */ export const AVATARS_DIR = `${UPLOADS_DIR}/avatars`; /** Holds each playlist's cover. */ export const PLAYLIST_IMAGES_DIR = `${UPLOADS_DIR}/playlist-images`; /** * Holds the images pasted into chat messages, comments, dump notes and * descriptions. The startup tasks purge those nothing links to. */ export const ATTACHMENTS_DIR = `${UPLOADS_DIR}/attachments`; /** * Holds the thumbnails a poster uploads (`