Skip to content

v1.6.0

Choose a tag to compare

@github-actions github-actions released this 28 Jul 22:38
· 48 commits to main since this release
v1.6.0
2a0817e

Added

Custom branding

The product name, logo, page title and the Netresearch footer line were hardcoded. Five optional settings now cover them; a deployment that sets none looks exactly as before.

Setting Effect
BRANDING_PRODUCT_NAME the wordmark next to the logo (default GopherPass)
BRANDING_PAGE_TITLE the browser tab title of the start page
BRANDING_LOGO_ALT alternative text, used only while no wordmark is shown
BRANDING_SHOW_ATTRIBUTION the "Built by Netresearch" footer line (default true)
BRANDING_DIR a directory layered over the embedded static assets

BRANDING_DIR replaces assets file by file — logo.webp, logo-dark.webp, the favicon and home-screen icons, site.webmanifest, browserconfig.xml. Anything not supplied keeps its built-in version; styles.css and js/ are deliberately not replaceable. An unexpected filename, a file over 2 MiB or a non-regular file aborts startup rather than being ignored silently.

Two things worth knowing before you mount it: the runtime image is FROM scratch and declares no volumes, so the directory has to be bind-mounted explicitly (Kubernetes ConfigMap and Secret volumes work). And its files are served publicly under /static/ without authentication, so it must be operator-owned and mounted read-only — lookups go through os.Root with a stat after opening, so a symlink out of the directory or a FIFO swapped in after startup is rejected at serve time, not just at validation.

Clearing BRANDING_PRODUCT_NAME for a logo-only header requires setting BRANDING_LOGO_ALT; setting neither aborts startup, because a screen reader would otherwise announce the brand twice.

Fixed

Out-of-range numeric settings are rejected at startup instead of wrapping. SMTP_PORT, RESET_TOKEN_EXPIRY_MINUTES, RESET_RATE_LIMIT_WINDOW_MINUTES and RESET_RATE_LIMIT_REQUESTS are parsed as uint over the full 64-bit range but converted to int or time.Duration afterwards. A value above the target range wrapped: a window of 18446744073709551615 minutes became -1m, and a negative window makes the sliding-window limiter discard every timestamp and let every request through — on the password-reset endpoint, with no sign that limiting had stopped. A request count that large became -1, blocking all of them instead.

These values come from your own configuration, not from a request, so this is a footgun rather than a remotely exploitable flaw. Both are now config errors, as is an SMTP_PORT above 65535.

Changed

The per-IP rate limiter is now documented. Two independent in-memory limiters apply and only one is configurable: a hardcoded 10 requests per 60 minutes per IP across both endpoints, alongside the configurable per-identifier limit on reset requests. The README previously claimed a single configurable limit.

The Go toolchain is pinned to 1.26.5, clearing 15 standard-library advisories that govulncheck reports against 1.26.1.

Full changelog: v1.5.0...v1.6.0