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

@@ -325,6 +325,11 @@ namespace AyaNova
//Store a reference to the dependency injection service for static classes
ServiceProviderProvider.Provider = app.ApplicationServices;
//case 4632: inside IIS the report page's API calls are relayed (ReportApiRelay)
ServerBootConfig.HOSTED_IN_IIS = app.ApplicationServices.GetService<Microsoft.AspNetCore.Hosting.Server.IServer>()?.GetType().FullName?.Contains(".IIS.", StringComparison.Ordinal) == true;
if (ServerBootConfig.HOSTED_IN_IIS)
_newLog.LogInformation("Running inside IIS: report API calls are relayed to the address of the users' requests");
//Enable ability to handle reverse proxy
//case 4732: a proxy on this computer (loopback) is always trusted; proxies on other computers only when named in AYANOVA_TRUSTED_PROXIES
var forwardedHeadersOptions = new ForwardedHeadersOptions
@@ -472,23 +477,21 @@ namespace AyaNova
{
//It may be a local report render request from a job
//case 4632: from this machine only; the host name is no longer required to be 127.0.0.1, inside IIS the
//request is relayed to the site's own address and host name (ReportApiRelay)
bool bLocalReportRenderRequest = false;
if (context.Request.Host.Host == "127.0.0.1")
if (context.Request.IsLocal())
{
//check if token has j value set
if (context.Request.IsLocal())
//if this is a generate report internal token this will be the override language set
//and it's existance is enough to indicate it was set internally by this server
var rpl = context.User.Claims.FirstOrDefault(c => c.Type == "rpl");
if (rpl != null)
{
//if this is a generate report internal token this will be the override language set
//and it's existance is enough to indicate it was set internally by this server
var rpl = context.User.Claims.FirstOrDefault(c => c.Type == "rpl");
if (rpl != null)
{
//it's a local request, the jwt already passed earlier so we issued it and it has the correct claim set so allow it
bLocalReportRenderRequest = true;
//set override language
context.Request.HttpContext.Items["AY_TRANSLATION_ID"] = Convert.ToInt64(rpl.Value);
await next.Invoke();
}
//it's a local request, the jwt already passed earlier so we issued it and it has the correct claim set so allow it
bLocalReportRenderRequest = true;
//set override language
context.Request.HttpContext.Items["AY_TRANSLATION_ID"] = Convert.ToInt64(rpl.Value);
await next.Invoke();
}
}
if (!bLocalReportRenderRequest)
@@ -517,6 +520,8 @@ namespace AyaNova
}));
return;
}
//case 4632: inside IIS, where this signed-in request arrived is where notification reports send their API calls
ReportApiRelay.Remember(context);
await next.Invoke();
}
}