Skip to content

Commit 0c25fc4

Browse files
authored
fix(auth): resolve CORS errors for self-hosted deployments behind reverse proxies (#4369)
* fix(auth): resolve CORS errors for self-hosted deployments behind reverse proxies - auth client now uses browser origin first, falling back to NEXT_PUBLIC_APP_URL - socket client falls back to page origin when served from non-localhost (assumes /socket.io is proxied) - add TRUSTED_ORIGINS env var to extend Better Auth trustedOrigins (apex+www, alias hostnames) - warn at startup when NEXT_PUBLIC_APP_URL is localhost in production - preprocess empty NEXT_PUBLIC_SOCKET_URL so docker-compose ${VAR:-} works - migrate remaining uuid/nanoid/randomUUID usages to @sim/utils generateId/generateShortId - extend generateShortId with optional alphabet param (rejection sampling) - document TRUSTED_ORIGINS in .env.example, docker-compose.prod.yml, and helm values.yaml Fixes #1243 * fix(auth): address PR review comments * chore(env): drop unnecessary NEXT_PUBLIC_SOCKET_URL preprocess (skipValidation is true) * fix(docker): include @sim/utils in migrations image Migration scripts now import generateId from @sim/utils/id; without copying packages/utils into the image, bun install fails to resolve the workspace dep at build time and the import fails at runtime. * fix(helm): remove unused NEXT_PUBLIC_SOCKET_URL from realtime sections The realtime service never reads NEXT_PUBLIC_SOCKET_URL — its env schema only includes BETTER_AUTH_URL, NEXT_PUBLIC_APP_URL, ALLOWED_ORIGINS, BETTER_AUTH_SECRET, INTERNAL_API_SECRET, DATABASE_URL, and REDIS_URL. Remove the dead config from all helm values files and the values schema. * fix(helm): allow empty NEXT_PUBLIC_SOCKET_URL in values schema The default in values.yaml is now "" (empty string), which falls back to the page origin at runtime. The schema previously required a valid URI, which would reject the default. Mirror the INTERNAL_API_BASE_URL pattern using anyOf with const "". Also add TRUSTED_ORIGINS to the schema. * docs(self-hosting): mark NEXT_PUBLIC_SOCKET_URL as optional The page-origin fallback in getSocketUrl() means self-hosters no longer need to set NEXT_PUBLIC_SOCKET_URL when realtime is on the same origin as the app. Update docs to reflect this: - Remove NEXT_PUBLIC_SOCKET_URL from .env scaffolding examples in docker.mdx, platforms.mdx, environment-variables.mdx - Mark the variable as Optional in the env vars table with the new default behavior described - Update troubleshooting to point at reverse-proxy /socket.io routing rather than the env var - Flip dev docker-compose defaults (local, ollama, devcontainer) from http://localhost:3002 to empty for consistency with prod.yml; the in-code localhost fallback handles the dev case identically Applied across all 6 documentation languages (en/fr/de/ja/es/zh). * chore: untrack and ignore .claude/scheduled_tasks.lock
1 parent 6080489 commit 0c25fc4

57 files changed

Lines changed: 341 additions & 91 deletions

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

.devcontainer/docker-compose.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@ services:
2121
- COPILOT_API_KEY=${COPILOT_API_KEY}
2222
- SIM_AGENT_API_URL=${SIM_AGENT_API_URL}
2323
- OLLAMA_URL=${OLLAMA_URL:-http://localhost:11434}
24-
- NEXT_PUBLIC_SOCKET_URL=${NEXT_PUBLIC_SOCKET_URL:-http://localhost:3002}
24+
- NEXT_PUBLIC_SOCKET_URL=${NEXT_PUBLIC_SOCKET_URL:-}
2525
- BUN_INSTALL_CACHE_DIR=/home/bun/.bun/cache
2626
depends_on:
2727
db:

.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -80,3 +80,4 @@ i18n.cache
8080
## Claude Code
8181
.claude/launch.json
8282
.claude/worktrees/
83+
.claude/scheduled_tasks.lock

apps/docs/content/docs/de/self-hosting/docker.mdx

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,6 @@ ENCRYPTION_KEY=$(openssl rand -hex 32)
2929
INTERNAL_API_SECRET=$(openssl rand -hex 32)
3030
NEXT_PUBLIC_APP_URL=https://sim.yourdomain.com
3131
BETTER_AUTH_URL=https://sim.yourdomain.com
32-
NEXT_PUBLIC_SOCKET_URL=https://sim.yourdomain.com
3332
EOF
3433
```
3534

apps/docs/content/docs/de/self-hosting/environment-variables.mdx

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ import { Callout } from 'fumadocs-ui/components/callout'
1515
| `ENCRYPTION_KEY` | Verschlüsselungsschlüssel (32 Hex-Zeichen): `openssl rand -hex 32` |
1616
| `INTERNAL_API_SECRET` | Internes API-Secret (32 Hex-Zeichen): `openssl rand -hex 32` |
1717
| `NEXT_PUBLIC_APP_URL` | Öffentliche App-URL |
18-
| `NEXT_PUBLIC_SOCKET_URL` | WebSocket-URL (Standard: `http://localhost:3002`) |
18+
| `NEXT_PUBLIC_SOCKET_URL` | Optional. WebSocket-URL — verwendet standardmäßig den Seitenursprung; nur setzen, wenn Realtime auf einem separaten Host läuft. |
1919

2020
## KI-Anbieter
2121

@@ -80,7 +80,6 @@ BETTER_AUTH_URL=https://sim.yourdomain.com
8080
ENCRYPTION_KEY=<openssl rand -hex 32>
8181
INTERNAL_API_SECRET=<openssl rand -hex 32>
8282
NEXT_PUBLIC_APP_URL=https://sim.yourdomain.com
83-
NEXT_PUBLIC_SOCKET_URL=https://sim.yourdomain.com
8483
OPENAI_API_KEY=sk-...
8584
```
8685

apps/docs/content/docs/de/self-hosting/platforms.mdx

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -77,7 +77,6 @@ ENCRYPTION_KEY=$(openssl rand -hex 32)
7777
INTERNAL_API_SECRET=$(openssl rand -hex 32)
7878
NEXT_PUBLIC_APP_URL=https://sim.yourdomain.com
7979
BETTER_AUTH_URL=https://sim.yourdomain.com
80-
NEXT_PUBLIC_SOCKET_URL=https://sim.yourdomain.com
8180
EOF
8281

8382
# Start

apps/docs/content/docs/de/self-hosting/troubleshooting.mdx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,7 @@ OLLAMA_URL=http://192.168.1.x:11434 # Linux (use actual IP)
2727

2828
## WebSocket/Echtzeit funktioniert nicht
2929

30-
1. Prüfen Sie, ob `NEXT_PUBLIC_SOCKET_URL` mit Ihrer Domain übereinstimmt
30+
1. Stellen Sie sicher, dass der Reverse Proxy `/socket.io` an den Realtime-Service (Standardport 3002) weiterleitet. `NEXT_PUBLIC_SOCKET_URL` ist nur erforderlich, wenn Realtime auf einem separaten Host läuft.
3131
2. Überprüfen Sie, ob der Echtzeit-Dienst läuft: `docker compose ps realtime`
3232
3. Stellen Sie sicher, dass der Reverse-Proxy WebSocket-Upgrades weiterleitet (siehe [Docker-Anleitung](/self-hosting/docker))
3333

apps/docs/content/docs/en/self-hosting/docker.mdx

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,6 @@ ENCRYPTION_KEY=$(openssl rand -hex 32)
3030
INTERNAL_API_SECRET=$(openssl rand -hex 32)
3131
NEXT_PUBLIC_APP_URL=https://sim.yourdomain.com
3232
BETTER_AUTH_URL=https://sim.yourdomain.com
33-
NEXT_PUBLIC_SOCKET_URL=https://sim.yourdomain.com
3433
EOF
3534
```
3635

apps/docs/content/docs/en/self-hosting/environment-variables.mdx

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ import { Callout } from 'fumadocs-ui/components/callout'
1515
| `ENCRYPTION_KEY` | Encryption key (32 hex chars): `openssl rand -hex 32` |
1616
| `INTERNAL_API_SECRET` | Internal API secret (32 hex chars): `openssl rand -hex 32` |
1717
| `NEXT_PUBLIC_APP_URL` | Public app URL |
18-
| `NEXT_PUBLIC_SOCKET_URL` | WebSocket URL (default: `http://localhost:3002`) |
18+
| `NEXT_PUBLIC_SOCKET_URL` | Optional. WebSocket URL — defaults to the page origin; set only if realtime is on a separate host. |
1919

2020
## AI Providers
2121

@@ -80,7 +80,6 @@ BETTER_AUTH_URL=https://sim.yourdomain.com
8080
ENCRYPTION_KEY=<openssl rand -hex 32>
8181
INTERNAL_API_SECRET=<openssl rand -hex 32>
8282
NEXT_PUBLIC_APP_URL=https://sim.yourdomain.com
83-
NEXT_PUBLIC_SOCKET_URL=https://sim.yourdomain.com
8483
OPENAI_API_KEY=sk-...
8584
```
8685

apps/docs/content/docs/en/self-hosting/platforms.mdx

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -70,7 +70,6 @@ ENCRYPTION_KEY=$(openssl rand -hex 32)
7070
INTERNAL_API_SECRET=$(openssl rand -hex 32)
7171
NEXT_PUBLIC_APP_URL=https://sim.yourdomain.com
7272
BETTER_AUTH_URL=https://sim.yourdomain.com
73-
NEXT_PUBLIC_SOCKET_URL=https://sim.yourdomain.com
7473
EOF
7574

7675
# Start

apps/docs/content/docs/en/self-hosting/troubleshooting.mdx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,7 @@ OLLAMA_URL=http://192.168.1.x:11434 # Linux (use actual IP)
2727

2828
## WebSocket/Realtime Not Working
2929

30-
1. Check `NEXT_PUBLIC_SOCKET_URL` matches your domain
30+
1. Verify reverse proxy routes `/socket.io` to the realtime service (default port 3002). `NEXT_PUBLIC_SOCKET_URL` is only needed if realtime is on a separate host.
3131
2. Verify realtime service is running: `docker compose ps realtime`
3232
3. Ensure reverse proxy passes WebSocket upgrades (see [Docker guide](/self-hosting/docker))
3333

0 commit comments

Comments
 (0)