Commit Graph

4888 Commits

Author SHA1 Message Date
bd4494abac case 4712 - customer contacts reach only their own customer's work orders
Step 2 of 4712 (security review F13). The customer work-order rights checked
only tag-based feature switches, never which customer a work order belongs to.
New UserBiz.CustomerContactOwnsCustomerAsync (own customer, or for a head
office contact a customer of its head office), used by:
- workorder/customer/{id}: another customer's work order is not found (404);
- customer work order report (-100): exactly one work order, which must be the
  contact's (the renderer used every id it was given);
- work order attachment list and download for contacts; other attachment types
  are refused to contacts (the customer screens show them only on work orders).

Checked: other customer's work order 404 (was 200); report on another's or on
two work orders not found; own customer report still accepted (202).

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-24 13:52:31 -07:00
2b1adaa496 case 4712 - customer contacts limited to the routes the customer screens use
Customer contacts had the Customer role's Select and read rights on most record
types and could call any route whose staff role check they passed, including
several with no role check (security review F13 to F17). Step 1 of 4712: the
token middleware now answers 403 (same body as other 403s) to Customer and
HeadOffice users for any route not in CustomerContactRoutes, the routes the
customer screens use (read from raven-client). Anonymous routes are always
allowed. New routes stay closed to contacts unless added on purpose.
Ownership of the records these routes return follows in the next steps.

Checked: full integration suite 103 passed, 5 skipped, the same 2 known
failures as the baseline.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-24 13:44:02 -07:00
445f9b0d0a case 4717 - KPI interval accepted only as a known date unit
Six KPIs put the request's interval criterion into the query as
DATE_TRUNC('<interval>', ...) unchecked, reachable by staff down to
TechRestricted (security review F26). New KPIFetcher.DateTruncUnitOrNull
accepts only PostgreSQL's date_trunc unit names (any case); the seven KPIs that
read interval refuse anything else with "Invalid 'interval' criteria", the same
form as their existing missing-criteria errors. The client only sends day or
month. (WorkOrderByStatusList reads interval without using it; checked too.)

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-24 12:36:52 -07:00
b1944b7ca3 case 4716 - pick-list search text passed as SQL parameters
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>
2026-10-24 12:28:43 -07:00
e58ab2c100 case 4715 - download file names checked
report/download and export/download (any download key), the log-file routes and
backup download built a path from the file name in the URL with Path.Combine
and no check, so on Windows a name with a folder part or an absolute path could
reach files outside the folder (security review F21). New helper
FileUtil.FullPathInFolderOrNull accepts only a bare file name that resolves
directly inside the folder; TemporaryFileExists and BackupFileExists use it
(the download routes already call them first), and so do both log routes.
A refused name gets the same 404 as a missing file.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-24 12:20:25 -07:00
705a54f9d8 case 4718 - report and translation import need create rights
report/upload and translation/upload had no role check, so any login, customer
contacts included, could import a report template (whose JavaScript runs in the
server's browser at render time) or a translation (security review F19, F24).
Both now require the same right as creating one, checked before the upload is
read. The import screens are already limited to those roles.

Checked locally: customer contact and Service 403, BizAdmin 202.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-24 12:10:00 -07:00
a843bd3132 case 4711 - JWT signing key generated by the server; AYANOVA_JWT_SECRET removed
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>
2026-10-24 12:01:08 -07:00
141bdeb89c case 4710 - 2FA step requires the temp token from the password step
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>
2026-10-24 11:28:17 -07:00
bf0555fb31 case 4690 - report browser: launch chrome-headless-shell; writable config/cache folders for the browser; Ubuntu 24.04 droplet results
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>
2026-10-23 08:12:21 -07:00
9af1034a88 case 4690 - data-list date filters: >= and < from the start of the minute, != excludes the whole minute; null check first
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-22 20:38:23 -07:00
892ef59608 case 4690 - report browser download/launch failures: logged at Error, specific error returned to the client
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-22 20:31:29 -07:00
a34e012eee case 4690 - report browser downloads under the data path, not beside the app; manual updated
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-22 20:25:00 -07:00
e8e7a2ec40 case 4690 - erase database: check CREATEDB before dropping, so a failed create can't leave no database
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-22 20:15:13 -07:00
78f5863947 case 4690 - backup: run pg_dump without a shell, password in PGPASSWORD, failures detected by exit code
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-22 20:00:52 -07:00
6db7c12c49 case 4690 - appsettings.json: Debug/Console log levels Trace -> Warning
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-22 19:47:31 -07:00
86ac9a2b96 case 4690 - remaining packages to current releases (Bogus, jose-jwt, QRCoder); Newtonsoft.Json direct reference
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-22 19:47:31 -07:00
77b825a064 case 4690 - CA2022: read the PE header with ReadAtLeast for the licence build date
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-22 19:39:11 -07:00
76dab8d865 case 4690 - remove MiniProfiler (never used): packages, wiring, profiler auth workaround, credits entry
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-22 18:49:28 -07:00
e55e0d6707 case 4690 - Asp.Versioning 10.2.1 with explicit AddMvc()
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-22 18:45:40 -07:00
f3e8026501 case 4690 - PuppeteerSharp 25.15.0; launch arguments as separate elements; --lang keeps the server locale as browser default
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-22 18:12:49 -07:00
91f59d8554 case 4690 - NLog 6.2.2: archive suffix keeps log-ayanova-N.txt names and cleans up old archives; log viewer sorted by date
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-22 17:31:01 -07:00
4098cd4922 case 4690 - Swashbuckle 10.3.1 / OpenAPI.NET 2: namespace and security requirement changes; drop explicit Microsoft.OpenApi
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-22 16:46:49 -07:00
230222f8a7 case 4690 - MailKit/MimeKit 4.18.1, BouncyCastle 2.7.0; pin System.Security.Cryptography.Pkcs 10.0.13
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-22 15:43:45 -07:00
6d6d4d9a5b case 4690 - retarget net10.0; framework-matched Microsoft.* 10.0.13, Npgsql EF 10.0.3
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-22 14:50:47 -07:00
ab1a636ecb case 4690 - AdminConnectionString: swap only the database via NpgsqlConnectionStringBuilder
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-22 14:43:03 -07:00
1ca07f1321 case 4676 - data-list numeric and roles filters: parse values, never append client text
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>
2026-10-22 14:36:28 -07:00
c2f2f92236 case 4690 - version bump and confirmation of choices for net10-port 2026-10-22 12:38:37 -07:00
2077ac445f reverted to non local sockeye server for testing against destination sockeye droplet 2026-10-19 18:35:21 -07:00
b41de9a57a case 4670 2026-09-22 12:10:21 -07:00
be7034b079 4642 2026-02-14 19:44:28 -08:00
880f4802a4 case 4642 2026-02-13 09:13:54 -08:00
d96942a296 case 4640 2025-11-24 14:19:27 +00:00
15933c0b1c case 4632 2025-04-03 21:05:18 +00:00
ff1ce4d483 prepare for next release 2025-02-18 21:50:30 +00:00
9d7c575dd1 case 4632 2025-02-18 21:08:56 +00:00
2efbd2e428 prepare for next release 2024-10-24 00:29:57 +00:00
1602b9680d 2024-10-23 23:40:31 +00:00
f06a23475b 2024-10-23 23:38:19 +00:00
e394b98882 case 4615 2024-10-23 23:10:16 +00:00
7b341fe8f5 case 4615 2024-10-23 22:05:28 +00:00
092059eefe Prepare for next release 2024-08-29 00:54:46 +00:00
2548ba53d3 case 4610 2024-08-28 23:00:00 +00:00
e0f57fb1ee case 4610 2024-08-28 22:44:54 +00:00
b9a29a23bc 2024-08-28 21:58:30 +00:00
985baef4f5 2024-08-28 21:51:00 +00:00
6e60c3becb case 4610 2024-08-28 21:48:19 +00:00
210df92358 case 4610 2024-08-28 21:45:38 +00:00
97574f837e case 4610 2024-08-28 21:15:30 +00:00
d502787c37 prepare for next release 2024-06-03 18:32:08 +00:00
4cc125aae7 case 4597 2024-05-13 23:10:34 +00:00