# Demo Proxy Upstream and Trusted Origins

This document explains how the Next.js demo resolves auth upstream targets and how origin allowlisting works.

## Why this matters

Two different concerns often get mixed up:

- `ATHENA_AUTH_ORIGIN` and `ATHENA_AUTH_ORIGIN_MAP` decide where the demo proxy forwards auth API requests.
- `TRUSTED_ORIGINS` decides which browser origins are allowed for CORS/preflight.

If `TRUSTED_ORIGINS` is correct but upstream is wrong, login still fails with upstream errors.

## Environment variables

### Upstream resolution

- `ATHENA_AUTH_ORIGIN`: single concrete upstream URL.
  - Example: `https://auth.athena-cluster.com`
  - Must be concrete. No `*` wildcard.
  - Forwarding is root-based: `/api/auth/<path>` is sent to upstream as `/<path>` for the primary request.
  - The proxy only retries `/api/auth/<path>` as a fallback when the primary upstream route returns `404`.
- `ATHENA_AUTH_ORIGIN_MAP`: optional host-pattern map for multi-domain deployments.
  - Format: `<incoming-host-glob>=<upstream-url>,<incoming-host-glob>=<upstream-url>`
  - The left side matches the incoming request host only. It can be a bare host pattern or a URL-shaped value; URL paths, queries, fragments, and schemes are normalized away before matching.
  - Example:
    - `ATHENA_AUTH_ORIGIN_MAP=athena-auth-*-suits-finance.vercel.app=https://auth.athena-cluster.com`
    - `ATHENA_AUTH_ORIGIN_MAP=https://athena-auth-*-suits-finance.vercel.app/api/auth=https://auth.athena-cluster.com`

Resolution order:

1. `ATHENA_AUTH_ORIGIN_MAP` match for current request host (if set)
2. `ATHENA_AUTH_ORIGIN`
3. `NEXT_PUBLIC_AUTH_BASE_URL`
4. Local dev fallback (`http://localhost:3000`) outside production only

### Origin allowlisting

- `TRUSTED_ORIGINS`: allowlist for CORS/preflight checks.
  - Exact origins, wildcard origins, and bare host patterns are supported here.
  - Bare non-local host patterns infer `https://`, so `*.vercel.app` is treated as `https://*.vercel.app`.
  - URL-shaped values are normalized to their origin before matching, so paths and queries do not affect CORS decisions.
  - Examples:
    - `https://athena-auth-*-suits-finance.vercel.app`
    - `*.vercel.app`
    - `https://app.formations.company`
    - `https://speedrun-formations.vercel.app`

Set the same trusted-origin patterns in both:

- `apps/demo` environment (Next.js proxy preflight)
- Rust `athena-auth` server environment (server-side origin checks)

## Recommended setup for preview domains

Use this for the demo app (Preview environment):

```env
ATHENA_AUTH_ORIGIN_MAP=athena-auth-*-suits-finance.vercel.app=https://auth.athena-cluster.com
ATHENA_AUTH_ORIGIN=https://auth.athena-cluster.com
TRUSTED_ORIGINS=https://athena-auth-*-suits-finance.vercel.app,https://app.formations.company,https://speedrun-formations.vercel.app
```

Rust server:

```env
TRUSTED_ORIGINS=https://athena-auth-*-suits-finance.vercel.app,https://app.formations.company,https://speedrun-formations.vercel.app
```

## Diagnostics

Call:

- `/api/auth/diagnostics`

Look at:

- `proxyUpstream.ok`
- `proxyUpstream.source`
- `proxyUpstream.resolved`
- `proxyOriginMap.requestHost`
- `proxyOriginMap.entries[].hostPattern`
- `proxyOriginMap.entries[].matchesRequestHost`
- `trustedOriginDiagnostics.trustedOrigins`
- `trustedOriginDiagnostics.allowed`

If `proxyUpstream.ok` is `false`, the proxy config is invalid before any upstream call is attempted.
If wildcard origins are failing, compare the request origin to `trustedOriginDiagnostics.trustedOrigins`; the diagnostics output shows the normalized patterns that the proxy actually matched against.

## Error codes and meanings

- `UPSTREAM_CONFIG_MISSING`
  - No valid upstream config was provided.
- `UPSTREAM_CONFIG_INVALID`
  - Upstream value is malformed, wildcard in upstream URL, or invalid production host (like `localhost` / private IP ranges).
- `UPSTREAM_UNREACHABLE`
  - Upstream target looked valid but could not be reached at runtime.
- `ORIGIN_NOT_TRUSTED`
  - Request origin failed `TRUSTED_ORIGINS` allowlist.

## Common failure pattern

If you see upstream attempts to `http://localhost:4000/...` in a Vercel deployment, upstream config is wrong for that environment.

Fix by setting a concrete public upstream URL or using `ATHENA_AUTH_ORIGIN_MAP` for the preview host pattern.
