Inside IIS (in-process) AyaNova has no port of its own, so the report page
could not reach the API: user reports called http://127.0.0.1:<request port>
(reset on https), notification reports 127.0.0.1:7575 (refused). Under IIS the
page's requests under the API URL are now intercepted and made by the server
(util/ReportApiRelay.cs) to the local address and port a user's request
arrived on, with its host name and scheme; notification reports use the
latest signed-in request, else the override. Outside IIS nothing changes.
The notification token check requires a request from this machine, no longer
host 127.0.0.1. Manual (IIS install, override page) and changelog updated.
Deferred: emailed PDF content type application/pdf/pdf.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Both installers drop users-modify from the program folder (and local-postgres
in the single-user installer) and run icacls to remove the Users group's own
grants (by SID) from the program folder after copying files, so upgrades over
8.2.4 lose them too. The data folder keeps users-modify and config.json stays
readable by local users (the running account is not known at install time);
both documented in the single-user and LAN install pages. Changelog updated.
F2 fixed (write access), the rest accepted. Deferred: report on a missing
record fails with a generic error.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
New config setting AYANOVA_TRUSTED_PROXIES (IP addresses or CIDR networks)
for reverse proxies on another computer: their X-Forwarded-For is used, a
chain of trusted proxies is followed, invalid entries are warned at boot.
X-Forwarded-For from a proxy that is not trusted logs one warning per server
start naming the proxy's address. Without the setting nothing changes (only
a loopback proxy is trusted). Shown in server info; manual page, Linux install
note, changelog. F6 follow-up recorded.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The anonymous page at /api/v8/ shows the version and its links only: the
licence block is removed and the support link no longer carries the DB
ID and licensee. F11 fixed (4727 step 2).
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Logo upload and delete need change rights on Global (was read rights,
which BizAdminRestricted has). The image type is taken from the bytes:
PNG, JPEG, GIF, WebP or SVG, anything else refused; the claimed type is
not stored. Downloads send nosniff and a sandbox Content-Security-Policy,
so an SVG opened by its URL runs no script. F23 fixed (4727 step 1).
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
FormFieldReferenceList and FormFieldKeys built their static lists lazily
and published them before filling them, so requests arriving during the
first build after a restart saw a half-filled list ("is not valid").
Both are now built in a local and published when complete (volatile).
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Failed logins are counted in memory (util/LoginThrottle.cs): 10 per login
name or 50 per client address within 15 minutes, then attempts are refused
with 429 for the rest of the window without checking the password. A
correct password clears the login's count; loopback is not counted per
address. Each lockout is logged. F6 fixed (2FA part in case 4710).
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
A password set by someone else (reset code, administrator) or a disabled
login replaces the user's session token and download key; changing one's
own password keeps the session. PasswordResetCodeExpire is cleared (was
DlKeyExpire). The token middleware exempts only the exact login and
notify/hello routes and refuses inactive users and users who may not log
in. With a purchased licence, notify/hello no longer offers the default
SuperUser login and a SuperUser with the default password may only change
it (SuperUserDefaultPasswordRoutes). F7, F8 and F9 fixed. Manual and
changelog updated.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Mailer checks the SMTP server's certificate (trust and name; no revocation
check). New config setting AYANOVA_SMTP_ACCEPT_ANY_CERTIFICATE accepts any
certificate (boot warning, shown in server info, manual page).
The notification settings GET returns ******** instead of the SMTP
password; a PUT with ******** or empty keeps the stored password.
F30 and F31 fixed. Changelog and manual updated.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
PickListSqlBuilder put the search text and the tag search text into the SQL
inside quotes with no escaping, reachable by any login (security review F18);
an apostrophe in a search also made the query fail. The builder now writes
@plq / @pltag and PickListFetcher adds them as Npgsql parameters (same %text%
match; wildcards typed by the user still apply).
Changelog: searching selection lists for text with an apostrophe now works.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
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>
Also removes the server-only /var/ayanova chown/chmod lines from the Linux desktop upgrade page.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>