1 Configuration
Emily edited this page 2026-11-04 23:26:39 +01:00
This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

Configuration

Configuration is read from environment variables. loadConfig() validates critical values and fails fast instead of starting in an insecure or broken state.

Required

Variable Description
JWT_SECRET Required. At least 32 characters. Used to sign HS256 access tokens.

If no database URL or PostgreSQL credentials are supplied, the backend uses SQLite at DATABASE_PATH.

Server

Variable Default Description
NODE_ENV development Runtime mode label
HOST 0.0.0.0 Listen address
PORT 6767 HTTP port
PUBLIC_BASE_URL https://account.games.emilyh.de Public backend base URL used in e-mail links
APP_PUBLIC_URL https://games.emilyh.de Public web app base URL used in password-reset links
CORS_ORIGINS * Comma-separated allowed origins
REQUEST_LOGGING true Log one line per request (no bodies, tokens or query strings)

Database

Variable Default Description
DATABASE_URL — Optional explicit PostgreSQL URL. Overrides POSTGRES_*
POSTGRES_HOST db PostgreSQL host
POSTGRES_PORT 5432 PostgreSQL port
POSTGRES_DB — Database name
POSTGRES_USER — Database user
POSTGRES_PASSWORD — Database password
DATABASE_PATH ./data/accounts.db SQLite file when PostgreSQL is not configured

DATABASE_URL is normally built by the backend from POSTGRES_* with encodeURIComponent, so passwords containing @, :, /, ?, # or % work correctly. An explicit DATABASE_URL remains available as an override.

Changing POSTGRES_PASSWORD only initializes a new volume. It does not alter an existing PostgreSQL role. Use ALTER ROLE against the running database, then update the environment. Never delete the data directory to "fix" authentication.

Authentication

Variable Default Allowed Description
JWT_TTL_SECONDS 2592000 (30 days) 300–31536000 Access-token lifetime
BCRYPT_ROUNDS 12 10–15 bcrypt cost factor
REGISTRATION_ENABLED true boolean Allow new accounts
PASSWORD_RESET_TTL_MINUTES 30 5–1440 Password-reset link lifetime

Passwords must be 8–128 characters. They are pre-hashed with SHA-256 and then hashed with bcrypt, so the full password is used rather than being silently truncated at bcrypt's 72-byte limit.

Features

Variable Default Description
LEADERBOARD_ENABLED true Enable competitive leaderboard routes
CHESS_ENABLED true Enable online chess routes
EMAIL_CONFIRMATION_ENABLED true Mark new e-mail addresses unverified and send confirmation mail
UPDATE_ENABLED true Enable the release proxy
UPDATE_SOURCE_URL Gitea releases API for the app Upstream release feed
UPDATE_CACHE_SECONDS 300 Release cache lifetime, 30–3600

E-mail confirmation is opt-in at deployment level and never blocks account use. If SMTP is not configured, accounts still work and addresses remain unconfirmed.

SMTP

Variable Default Description
SMTP_HOST — SMTP server; enables e-mail when set with SMTP_FROM
SMTP_PORT 587 SMTP port
SMTP_SECURE inferred Implicit TLS. Defaults to true only on port 465
SMTP_REQUIRE_TLS inferred Require STARTTLS. Defaults to true on 25, 587 and 2525
SMTP_USER — SMTP username
SMTP_PASSWORD — SMTP password
SMTP_FROM — From address; required to enable e-mail

TLS rules

  • Port 465 → implicit TLS (secure=true).
  • Ports 25, 587, 2525 → STARTTLS (secure=false, requireTls=true).
  • SMTP_SECURE can override the inferred mode, but setting SMTP_SECURE=true on a STARTTLS port is automatically corrected to STARTTLS with a warning.
  • The server logs [mail] SMTP host=… port=… secure=… requireTLS=… at startup.

A mismatch here is the usual cause of tls_validate_record_header: wrong version number.

Management panel

Variable Default Description
MANAGEMENT_ENABLED true Enable the panel when a password is set
MANAGEMENT_USER admin Basic-auth username
MANAGEMENT_PASSWORD — Basic-auth password; empty disables the panel

The panel is a read-only HTML page at /management. It is disabled unless MANAGEMENT_PASSWORD is non-empty. Store the password in a root-only file outside Git.

Proxies and client IPs

Variable Default Description
TRUSTED_PROXIES — Comma-separated IPs, CIDR ranges or presets
TRUST_PROXY false Legacy Express trust-proxy fallback

Accepted TRUSTED_PROXIES entries:

  • IPv4 or IPv6 addresses.
  • CIDR ranges such as 10.0.0.0/8 or 2001:db8::/32.
  • Presets: loopback, linklocal, uniquelocal.

Invalid entries fail startup. When TRUSTED_PROXIES is set, it takes precedence over TRUST_PROXY.

Correct proxy configuration is required for rate limits and request logs to see the real client IP. Do not trust all proxies on a public server.

Example production environment

NODE_ENV=production
PORT=6767
PUBLIC_BASE_URL=https://account.example.com
APP_PUBLIC_URL=https://games.example.com
CORS_ORIGINS=https://games.example.com

JWT_SECRET=<at-least-32-random-characters>
JWT_TTL_SECONDS=2592000
BCRYPT_ROUNDS=12

POSTGRES_HOST=db
POSTGRES_PORT=5432
POSTGRES_DB=universal_gaming
POSTGRES_USER=universal_gaming
POSTGRES_PASSWORD=<strong-password>

REGISTRATION_ENABLED=true
LEADERBOARD_ENABLED=true
CHESS_ENABLED=true
EMAIL_CONFIRMATION_ENABLED=true
PASSWORD_RESET_TTL_MINUTES=30

SMTP_HOST=mail.example.com
SMTP_PORT=587
SMTP_SECURE=false
SMTP_REQUIRE_TLS=true
SMTP_USER=noreply@example.com
SMTP_PASSWORD=<smtp-password>
SMTP_FROM=noreply@example.com

TRUSTED_PROXIES=10.0.0.0/8
MANAGEMENT_ENABLED=true
MANAGEMENT_USER=admin
MANAGEMENT_PASSWORD=<strong-password>

REQUEST_LOGGING=true

Generate secrets with:

openssl rand -base64 48

Never commit .env, SMTP passwords, the management password or the JWT secret.