case 4632 - reports render under IIS: the report page's API calls are relayed by the server

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>
This commit is contained in:
2026-10-25 19:04:24 -07:00
parent ce5fb9e11c
commit a6447ecb37
10 changed files with 227 additions and 24 deletions

View File

@@ -221,7 +221,7 @@ John's "next release" cases for AyaNova (exported 2026-10-24). Each is its own s
| 4636 | Docs: turn off 2FA before v7 to v8 migration | 1, docs |
| 4634 | Docs: custom checkbox shows nothing for older records | 1, docs |
| 4633 | Docs: pg_dump path quoting on Windows (likely fixed by the port; confirm) | 1, docs |
| 4632 | AYANOVA_REPORT_RENDER_API_URL_OVERRIDE breaks customer notification reports (do before or with 4719) | 1, investigate. **Moved to the end with 4719** (John, 2026-10-24): needs an IIS + TLS test setup to reproduce; behaves differently for customers with apparently the same setup, so a thorough investigation on a real IIS install |
| 4632 | AYANOVA_REPORT_RENDER_API_URL_OVERRIDE breaks customer notification reports (do before or with 4719) | 1. **Done.** Cause, reproduced on a Windows Server 2025 Hyper-V VM (IIS, https-only site with a host name, as for internet access): AyaNova runs inside IIS (in-process), so nothing listens on `AYANOVA_USE_URLS`; user reports called `http://127.0.0.1:<port of the request>` (443 over https: connection reset), notification reports `127.0.0.1:7575` (refused); the override only fixed user reports, and only where the server reaches itself by its public name. Fix: under IIS the report page's requests under the API URL are intercepted (PuppeteerSharp request interception) 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 (IIS binding and certificate match, no DNS/router hairpin); notification reports use the latest signed-in request, else the override; the page is opened at the API origin so its calls are same-origin; outside IIS nothing changes. The notification token check no longer requires host `127.0.0.1`, only a request from this machine. Proof: VM before (both fail) and after (user report 1.6 s and notification email with PDF, https-only with and without the override); locally 22 stock reports identical with the relay forced on (temporary switch, removed); integration suite = baseline. Manual: IIS install page and override page; changelog |
| 4628 | Deleting a work order tied to a CSR gives a raw server error | 1, bug |
| 4623 | Docs: migration, what is erased and what is kept | 1, docs |
| 4602 | Logo upload UI: hide Upload and Delete until usable | 1, client |
@@ -275,6 +275,7 @@ Found during the port, out of scope. One line each.
- **Own case after the port (John):** the subscription server setup script is hard-coded in `biz-subscription-server.vue`, so every change needs a new Sockeye client build. Make it editable without a rebuild
- **Improvement, own case after the port (John to create):** bring back logging of JavaScript error details from report page console errors, as Sockeye's port did. AyaNova logs only `ERROR: {message text}`; the per-argument detail (`arg instanceof Error ? arg.message : arg`) is commented out at `biz/ReportBiz.cs:873-876` since case 4586, because `IJSHandle.ExecutionContext` was removed. Sockeye 8.1.0 (`server/biz/ReportBiz.cs:575`) evaluates on the handle instead: `args.Message.Args.Select(arg => arg.EvaluateFunctionAsync("(arg) => arg instanceof Error ? arg.message : arg"))`, which also needs the console handler to be `async` again
- Pre-existing, same in 8.2.4 (found in the 4579 sandbox test, John: Deferred): rendering a report for a record that does not exist (e.g. work order ids 1 and 2 in a trial without sample data) fails the job with a generic `ArgumentNullException` ("Value cannot be null. (Parameter 'o')") from `JObject.FromObject` in `WorkOrderBiz.GetReportData` (`WorkOrderBiz.cs:1030`), instead of skipping the missing record or saying it is not found. Other object types' `GetReportData` likely do the same
- Pre-existing (found in the 4632 IIS test, John: Deferred): emailed report attachments have the content type `application/pdf/pdf`, because `Mailer.cs:51` builds `new MimePart("application/pdf", "pdf")` (media type and subtype) instead of `new MimePart("application", "pdf")`. Mail programs still open the file by its `.pdf` name
## Log