The LAN/IIS and Linux templates shipped a placeholder secret printed in the
manual, and installs that kept it signed logins with a public key; any setting
also invited short or reused values (security review F1). The setting is now
ignored (one warning at boot if still present): the server generates a key once
(48 random bytes) into jwt-signing.key in the data folder (beside the app if
there is none; owner-only on Linux) and reuses it, so sign-ins also survive a
restart where the server used to make a new key each boot (standalone, Linux
desktop). If the file cannot be used, a temporary key is used for that run.
Templates and dev launch configs drop the setting; manual updated (key page
rewritten, setting steps removed from install pages); changelog line.
Checked locally: token forged with the old placeholder 401; key file created
and reused after restart (old token 200); auth and 2FA tests pass.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The 2FA step matched the user by temp token alone, and the token was left
empty after a successful 2FA login (null right after turning 2FA on), so an
empty or missing token skipped the password step (security review F5).
Now: an empty or missing temp token is refused before the lookup; the token is
cleared to null after success; after 5 wrong codes the token is cleared, so the
password must be entered again (counted in memory per user).
Changelog: general security notice for self-hosted upgrades, and the one
behaviour change users can see. SECURITY-REVIEW.md: F5 fixed.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Full Chrome 155 would not start under a Linux service user with no writable
home (chrome_crashpad_handler: --database is required). chrome-headless-shell
starts, and measured on a 1 GB droplet is 3-4x faster and smaller per render.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Roles and every numeric type (Decimal, Currency, Integer, InternalId, Enum,
MemorySize) now parse the filter value as an invariant decimal or long and
append the re-formatted number. An invalid value throws ArgumentException
before any SQL runs. Covers the types Sockeye's fix (3427cd8) missed.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>