Register the endpoints list without a trailing slash, and stop hiding its errors

This commit is contained in:
2026-08-28 17:48:21 -04:00
parent 765496a4cf
commit 6e72a157e8
7 changed files with 129 additions and 3 deletions

View File

@@ -131,6 +131,28 @@ def create_app(config_name: str = None) -> Flask:
if envname.startswith('COLLECTOR_API_KEY_') and envvalue:
app.config[envname] = envvalue
# Behind a reverse proxy (IIS at /shopdb, nginx, a load balancer), the app
# sees the PROXY's connection, not the browser's: scheme http even though
# the user is on https, the proxy's host, the proxy's IP. Anything Flask
# builds from that is wrong at the browser - an absolute redirect Location
# above all, which is how a trailing-slash redirect on the endpoints list
# sent an https page to an http URL the browser then refused to follow.
#
# OFF BY DEFAULT AND DELIBERATELY. ProxyFix makes the app TRUST
# X-Forwarded-* headers, and a client can send those itself. Enabled with no
# proxy in front, any caller can claim a different scheme or source IP -
# which matters here because the login rate limit and the lockout are keyed
# on the client address. Set TRUSTED_PROXY_COUNT to the number of proxies
# actually in front of this instance (1 for a single IIS or nginx), and only
# when one really is.
proxycount = app.config.get('TRUSTED_PROXY_COUNT', 0)
if proxycount:
from werkzeug.middleware.proxy_fix import ProxyFix
app.wsgi_app = ProxyFix(
app.wsgi_app,
x_for=proxycount, x_proto=proxycount,
x_host=proxycount, x_prefix=proxycount)
# Ensure instance folder exists
os.makedirs(app.instance_path, exist_ok=True)

View File

@@ -49,6 +49,15 @@ class Config:
seconds=int(os.environ.get('JWT_REFRESH_TOKEN_EXPIRES', 2592000))
)
# Number of reverse proxies in front of this instance. 0 (the default)
# means none, and the app reads the connection it actually receives.
# Set to 1 when IIS or nginx fronts it, so X-Forwarded-Proto/Host/Prefix are
# honoured and a generated absolute URL matches what the browser asked for.
# Do NOT set it without a proxy: it makes the app believe forwarded headers
# a client can send itself, and the login rate limit and account lockout are
# keyed on the client address.
TRUSTED_PROXY_COUNT = int(os.environ.get('TRUSTED_PROXY_COUNT', 0))
CORS_ORIGINS = [
origin.strip()
for origin in os.environ.get('CORS_ORIGINS', 'http://localhost:5173').split(',')