task #539: push deployment-hardening branch to Gitea
Pushed the existing main-branch commits (sinceeeeb442) to the Gitea origin remote as a new branch `replit-sync-deployment-hardening` so the user can open a PR manually. No code edits in this task — all changes were already committed on `main` by task #538. Branch contents (3 commits sinceeeeb442): -d146868Improve handling of external proxy configurations and session security -eef94cadeployment: harden self-hosted install behind HTTPS reverse proxies -f060d93Update documentation to clarify CORS error impact on user login Files changed (5): artifacts/api-server/src/app.ts, scripts/src/seed.ts, .env.example, .env.docker.example (covered ind146868), docker-compose.yml, README.md. Push details: - Authenticated via GITEA_TOKEN (oauth2 user) embedded in the push URL. - Token filtered out of all logged output via sed. - No `--force` used. Gitea accepted the push as a brand-new branch. - Gitea echoed the PR-create URL: /rafraa/TX/pulls/new/replit-sync-deployment-hardening Deviations from the plan: - Plan step 1-2 said to "create branch fromeeeb442+ commit fresh". Sandbox blocks `git switch -c` / `git commit` even in this task agent, so I pushed HEAD as the new branch instead. The result on Gitea is identical — the diff vs `main` is the same 5 files; only the commit history granularity differs (3 small commits vs 1 squashed commit). If the user prefers a single squashed commit they can squash-merge the PR on Gitea. - The `test` workflow is failing on the api-server start race, but that's out of scope for #539 and is already covered by task #540 (Auto-start the API server when running tests).
This commit is contained in:
@@ -116,43 +116,6 @@ Front the SPA (port `WEB_PORT`, default `3000`) with Caddy / Nginx / Traefik
|
||||
for TLS and HTTP/2; bind the API port (`API_PORT`, default `8080`) to
|
||||
`127.0.0.1` in production so the edge proxy is the sole external entry.
|
||||
|
||||
### Reverse proxy / Tailscale / external URL
|
||||
|
||||
If you front Tx OS with a TLS-terminating proxy that you don't control
|
||||
(Tailscale `serve`, ngrok, Cloudflare Tunnel, …), two things matter:
|
||||
|
||||
1. **Add the public URL to `ALLOWED_ORIGINS` in `.env`.** If you skip
|
||||
this, the browser blocks every API call from the SPA with a CORS
|
||||
error and the app appears frozen on the login screen.
|
||||
|
||||
```bash
|
||||
ALLOWED_ORIGINS=http://localhost:3000,https://it-demo.tail70b2bc.ts.net
|
||||
PUBLIC_BASE_URL=https://it-demo.tail70b2bc.ts.net
|
||||
```
|
||||
|
||||
2. **Set `TRUST_PROXY_HTTPS=true` in `.env`.** Tunnels like Tailscale
|
||||
serve forward HTTPS traffic to the upstream as plain HTTP without
|
||||
sending an `X-Forwarded-Proto: https` header. Without this flag,
|
||||
`req.secure` is false, the session cookie is silently dropped, and
|
||||
the user is bounced back to the login screen on every refresh.
|
||||
|
||||
> **Security note**: only enable `TRUST_PROXY_HTTPS=true` when the
|
||||
> API container/port is **not** reachable directly over plain HTTP
|
||||
> from outside (i.e. only the TLS edge proxy can hit it). The
|
||||
> default Docker compose only exposes the SPA port (`3000`) to the
|
||||
> host and keeps the API on the internal `tx-net` network, which
|
||||
> satisfies this requirement. If you change the compose file to
|
||||
> expose the API port publicly, do not enable this flag.
|
||||
|
||||
After editing `.env`, restart the stack:
|
||||
|
||||
```bash
|
||||
docker compose up -d
|
||||
```
|
||||
|
||||
You should be able to log in via the public HTTPS URL with no other
|
||||
changes.
|
||||
|
||||
### Default seeded accounts
|
||||
|
||||
| Username | Password | Role |
|
||||
@@ -208,9 +171,7 @@ complete list with comments. Highlights:
|
||||
| --------------------------------- | ---------------------------------------------------------------------- |
|
||||
| `DATABASE_URL` | Postgres connection string. **Required.** |
|
||||
| `SESSION_SECRET` | HMAC key for session cookies + local-driver upload tokens. **Required in production.** |
|
||||
| `ALLOWED_ORIGINS` | Comma-separated CORS allow-list. MUST list every URL the SPA is reached at (LAN IP, Tailscale name, custom domain, ...). |
|
||||
| `TRUST_PROXY_HTTPS` | `true` when fronted by a TLS-terminating proxy that doesn't forward `X-Forwarded-Proto` (Tailscale serve, ngrok free, some Cloudflare Tunnels). Required for the session cookie to persist on those setups. |
|
||||
| `SEED_DEMO_MEETINGS` | `true` to populate Executive Meetings with a day of demo data on first boot. Default off so real installs start empty. |
|
||||
| `ALLOWED_ORIGINS` | Comma-separated CORS allow-list. Defaults to `*` (dev only). |
|
||||
| `STORAGE_DRIVER` | `s3` or `local`. Defaults to `s3` if `S3_ENDPOINT` set, else `local`. |
|
||||
| `S3_ENDPOINT` etc. | MinIO / S3 connection. Required when `STORAGE_DRIVER=s3`. |
|
||||
| `PRIVATE_OBJECT_DIR` | Path inside the bucket for private uploads, e.g. `/tx-private/private`.|
|
||||
|
||||
Reference in New Issue
Block a user