From 5c23a3e60b8bcdb29932e7776f6ff9b872da3e7c Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Thu, 19 Feb 2026 09:04:27 +0000 Subject: [PATCH 1/5] Initial plan From 852b29387336cd3e1eb7106dbc5c8ddf496490e4 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Thu, 19 Feb 2026 09:17:48 +0000 Subject: [PATCH 2/5] feat: Add nginx proxy rule for OAuth callbacks on web domain Co-authored-by: BENZOOgataga <50145143+BENZOOgataga@users.noreply.github.com> --- docs/project/corpsim.altitude.nginx.conf | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/docs/project/corpsim.altitude.nginx.conf b/docs/project/corpsim.altitude.nginx.conf index d3dd68d6..f5b03acf 100644 --- a/docs/project/corpsim.altitude.nginx.conf +++ b/docs/project/corpsim.altitude.nginx.conf @@ -20,6 +20,16 @@ server { ssl_certificate /etc/ssl/cloudflare/altitude_pubkey.pem; ssl_certificate_key /etc/ssl/cloudflare/altitude_privkey.key; + # Proxy OAuth callback routes to API server + location /api/auth/ { + proxy_pass http://10.7.0.3:4310; + proxy_http_version 1.1; + proxy_set_header Host $host; + proxy_set_header X-Real-IP $remote_addr; + proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; + proxy_set_header X-Forwarded-Proto $scheme; + } + location / { proxy_pass http://10.7.0.3:4311; proxy_http_version 1.1; From 89e76633aff53250858717e7e933cc05a5ccddc8 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Thu, 19 Feb 2026 09:18:42 +0000 Subject: [PATCH 3/5] docs: Update deployment docs and env example for OAuth callback configuration Co-authored-by: BENZOOgataga <50145143+BENZOOgataga@users.noreply.github.com> --- .env.example | 3 +++ ...219091824-fix-github-oauth-redirect-url.md | 10 +++++++++ docs/project/DOKPLOY_DOCKERFILE.md | 22 +++++++++++++++++-- 3 files changed, 33 insertions(+), 2 deletions(-) create mode 100644 .releases/unreleased/20260219091824-fix-github-oauth-redirect-url.md diff --git a/.env.example b/.env.example index adb9dcee..7404303c 100644 --- a/.env.example +++ b/.env.example @@ -43,6 +43,9 @@ JWT_SECRET=change_me_dev_only SESSION_SECRET=change_me_dev_only BETTER_AUTH_SECRET=replace_with_at_least_32_random_chars ADMIN_PASSWORD= +# BETTER_AUTH_URL: Base URL for Better Auth endpoints and OAuth callbacks +# In production, set this to the main web domain (e.g., https://corpsim.altitude-interactive.com) +# NOT the API subdomain. The nginx proxy will forward /api/auth/* to the API server. BETTER_AUTH_URL=http://localhost:4310 GOOGLE_CLIENT_ID= GOOGLE_CLIENT_SECRET= diff --git a/.releases/unreleased/20260219091824-fix-github-oauth-redirect-url.md b/.releases/unreleased/20260219091824-fix-github-oauth-redirect-url.md new file mode 100644 index 00000000..701bc9df --- /dev/null +++ b/.releases/unreleased/20260219091824-fix-github-oauth-redirect-url.md @@ -0,0 +1,10 @@ +--- +type: patch +area: api, web, infra +summary: Fix OAuth callback redirect URLs for GitHub, Microsoft, and Discord by configuring nginx proxy and BETTER_AUTH_URL +--- + +- Updated nginx configuration to proxy `/api/auth/*` requests from web domain to API server +- Added documentation for configuring `BETTER_AUTH_URL` to use the main web domain in production +- Fixed OAuth callback URL issues that caused "redirect_uri is not associated with this application" errors +- Ensures all OAuth providers (GitHub, Microsoft, Discord) redirect to the correct domain diff --git a/docs/project/DOKPLOY_DOCKERFILE.md b/docs/project/DOKPLOY_DOCKERFILE.md index 936640d0..9c16d884 100644 --- a/docs/project/DOKPLOY_DOCKERFILE.md +++ b/docs/project/DOKPLOY_DOCKERFILE.md @@ -38,6 +38,8 @@ Create separate Dokploy apps from the same repository and Dockerfile: - `API_PORT=4310` - expose/public port `4310` - `CORS_ORIGIN=https://corpsim.altitude-interactive.com` + - `BETTER_AUTH_URL=https://corpsim.altitude-interactive.com` + - ⚠️ **IMPORTANT**: Set `BETTER_AUTH_URL` to the main web domain (not the API subdomain) so OAuth callbacks redirect to the correct domain 3. `corpsim-worker` - `APP_ROLE=worker` @@ -89,11 +91,27 @@ pnpm sim:seed ## Nginx upstream mapping -- `corpsim.altitude-interactive.com` -> `10.7.0.3:4311` -- `corpsim-api.altitude-interactive.com` -> `10.7.0.3:4310` +- `corpsim.altitude-interactive.com` -> `10.7.0.3:4311` (web app) +- `corpsim-api.altitude-interactive.com` -> `10.7.0.3:4310` (API server) + +**IMPORTANT**: The nginx configuration for `corpsim.altitude-interactive.com` must proxy `/api/auth/*` requests to the API server at port 4310. This allows OAuth callbacks to work correctly on the main web domain. See `docs/project/corpsim.altitude.nginx.conf` for the complete configuration. ## Troubleshooting +### OAuth failing with "redirect_uri is not associated with this application" + +**Symptom:** When clicking "Continue with GitHub" (or other OAuth providers), you get: +- Error from OAuth provider: "The redirect_uri is not associated with this application" +- Failed OAuth authentication + +**Cause:** The `BETTER_AUTH_URL` environment variable for the API service is not configured correctly, or the nginx proxy is not set up to forward `/api/auth/*` requests from the web domain to the API server. + +**Solution:** +1. Ensure `BETTER_AUTH_URL=https://corpsim.altitude-interactive.com` is set for the API service (use the main web domain, NOT the API subdomain) +2. Verify the nginx configuration includes a proxy rule for `/api/auth/*` (see `docs/project/corpsim.altitude.nginx.conf`) +3. Restart the API service and nginx after making changes +4. Configure OAuth apps (GitHub, Google, Microsoft, Discord) to allow callback URLs like `https://corpsim.altitude-interactive.com/api/auth/callback/{provider}` + ### Authentication failing with "Provider not found" or 404 errors **Symptom:** When clicking "Continue with Google" (or other OAuth providers), you get: From 7291faf499f483c832cc9e5131d94d70707e185a Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Thu, 19 Feb 2026 09:19:49 +0000 Subject: [PATCH 4/5] docs: Add deployment guide for OAuth callback redirect URL fix Co-authored-by: BENZOOgataga <50145143+BENZOOgataga@users.noreply.github.com> --- docs/project/OAUTH_CALLBACK_FIX.md | 116 +++++++++++++++++++++++++++++ 1 file changed, 116 insertions(+) create mode 100644 docs/project/OAUTH_CALLBACK_FIX.md diff --git a/docs/project/OAUTH_CALLBACK_FIX.md b/docs/project/OAUTH_CALLBACK_FIX.md new file mode 100644 index 00000000..05114f96 --- /dev/null +++ b/docs/project/OAUTH_CALLBACK_FIX.md @@ -0,0 +1,116 @@ +# OAuth Callback Redirect URL Fix - Deployment Guide + +## Problem +When users try to sign in/sign up with GitHub (or other OAuth providers) on production at `https://corpsim.altitude-interactive.com`, they receive an error: + +> "The redirect_uri is not associated with this application." + +## Root Cause +The OAuth flow in better-auth works as follows: +1. User clicks "Continue with GitHub" on the web app +2. Browser sends request to API server (via `NEXT_PUBLIC_API_URL`) +3. API server redirects to GitHub with a `redirect_uri` parameter +4. The `redirect_uri` is constructed from `BETTER_AUTH_URL` environment variable +5. GitHub redirects back to that `redirect_uri` after user authorization +6. API server processes the callback + +The issue occurs because: +- The GitHub OAuth App is configured to allow callbacks to `https://corpsim.altitude-interactive.com/api/auth/callback/github` +- But `BETTER_AUTH_URL` is set to `https://corpsim-api.altitude-interactive.com` +- This causes GitHub to reject the callback URL as unauthorized + +## Solution +To fix this issue, we need to: + +### 1. Update Nginx Configuration +Apply the updated `docs/project/corpsim.altitude.nginx.conf` to the production nginx server: + +```nginx +server { + listen 443 ssl http2; + listen [::]:443 ssl http2; + server_name corpsim.altitude-interactive.com; + + ssl_certificate /etc/ssl/cloudflare/altitude_pubkey.pem; + ssl_certificate_key /etc/ssl/cloudflare/altitude_privkey.key; + + # Proxy OAuth callback routes to API server + location /api/auth/ { + proxy_pass http://10.7.0.3:4310; + proxy_http_version 1.1; + proxy_set_header Host $host; + proxy_set_header X-Real-IP $remote_addr; + proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; + proxy_set_header X-Forwarded-Proto $scheme; + } + + location / { + proxy_pass http://10.7.0.3:4311; + proxy_http_version 1.1; + proxy_set_header Host $host; + proxy_set_header X-Real-IP $remote_addr; + proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; + proxy_set_header X-Forwarded-Proto $scheme; + } +} +``` + +This adds a specific proxy rule for `/api/auth/*` requests that forwards them to the API server. + +### 2. Update API Service Environment Variable +In Dokploy (or your deployment platform), update the `corpsim-api` service environment variables: + +Add: +``` +BETTER_AUTH_URL=https://corpsim.altitude-interactive.com +``` + +This tells better-auth to construct OAuth callback URLs using the main web domain instead of the API subdomain. + +### 3. Reload/Restart Services +1. Reload nginx configuration: `sudo nginx -s reload` +2. Restart the API service in Dokploy (or redeploy with the new environment variable) + +### 4. Update OAuth Provider Configurations +Ensure the OAuth apps on each provider's developer portal have the correct callback URL registered: + +**GitHub**: https://github.com/settings/developers +- Callback URL: `https://corpsim.altitude-interactive.com/api/auth/callback/github` + +**Google**: https://console.cloud.google.com/apis/credentials +- Authorized redirect URI: `https://corpsim.altitude-interactive.com/api/auth/callback/google` + +**Microsoft**: https://portal.azure.com/#blade/Microsoft_AAD_IAM/ActiveDirectoryMenuBlade/RegisteredApps +- Redirect URI: `https://corpsim.altitude-interactive.com/api/auth/callback/microsoft` + +**Discord**: https://discord.com/developers/applications +- Redirect URI: `https://corpsim.altitude-interactive.com/api/auth/callback/discord` + +## How It Works After the Fix +1. User clicks "Continue with GitHub" on `https://corpsim.altitude-interactive.com` +2. Browser calls `https://corpsim-api.altitude-interactive.com/api/auth/sign-in/social` +3. API server (with `BETTER_AUTH_URL=https://corpsim.altitude-interactive.com`) redirects to GitHub with `redirect_uri=https://corpsim.altitude-interactive.com/api/auth/callback/github` +4. User authorizes on GitHub +5. GitHub redirects to `https://corpsim.altitude-interactive.com/api/auth/callback/github` +6. Nginx proxies this request to the API server at port 4310 +7. API server processes the callback and redirects to success page + +## Testing +After applying the fix: +1. Go to `https://corpsim.altitude-interactive.com` +2. Navigate to `/sign-in` or `/sign-up` +3. Click "Continue with GitHub" (or another OAuth provider) +4. Verify you're redirected to the provider's authorization page +5. Authorize the application +6. Verify you're redirected back to the app successfully +7. Check browser network tab to confirm callbacks go to the correct domain + +## Alternative Solution (Not Recommended) +Instead of updating nginx and environment variables, you could update each OAuth provider's configuration to allow callbacks to both domains: +- `https://corpsim.altitude-interactive.com/api/auth/callback/{provider}` +- `https://corpsim-api.altitude-interactive.com/api/auth/callback/{provider}` + +However, this is not recommended because: +- It's confusing to have callbacks on two different domains +- It's harder to manage and update OAuth provider configurations +- Users might see inconsistent domain behavior From 2fa00750c6c7aaf87a6399496bc51631c5846a83 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Thu, 19 Feb 2026 09:37:45 +0000 Subject: [PATCH 5/5] fix: Address PR review feedback - update release area, nginx comments, and use RFC 5737 IP ranges Co-authored-by: BENZOOgataga <50145143+BENZOOgataga@users.noreply.github.com> --- ...260219091824-fix-github-oauth-redirect-url.md | 2 +- docs/project/DOKPLOY_DOCKERFILE.md | 6 ++++-- docs/project/OAUTH_CALLBACK_FIX.md | 12 ++++++------ docs/project/corpsim.altitude.nginx.conf | 16 ++++++++-------- 4 files changed, 19 insertions(+), 17 deletions(-) diff --git a/.releases/unreleased/20260219091824-fix-github-oauth-redirect-url.md b/.releases/unreleased/20260219091824-fix-github-oauth-redirect-url.md index 701bc9df..62f24ac6 100644 --- a/.releases/unreleased/20260219091824-fix-github-oauth-redirect-url.md +++ b/.releases/unreleased/20260219091824-fix-github-oauth-redirect-url.md @@ -1,6 +1,6 @@ --- type: patch -area: api, web, infra +area: web summary: Fix OAuth callback redirect URLs for GitHub, Microsoft, and Discord by configuring nginx proxy and BETTER_AUTH_URL --- diff --git a/docs/project/DOKPLOY_DOCKERFILE.md b/docs/project/DOKPLOY_DOCKERFILE.md index 9c16d884..adeed8af 100644 --- a/docs/project/DOKPLOY_DOCKERFILE.md +++ b/docs/project/DOKPLOY_DOCKERFILE.md @@ -91,11 +91,13 @@ pnpm sim:seed ## Nginx upstream mapping -- `corpsim.altitude-interactive.com` -> `10.7.0.3:4311` (web app) -- `corpsim-api.altitude-interactive.com` -> `10.7.0.3:4310` (API server) +- `corpsim.altitude-interactive.com` -> `192.0.2.10:4311` (web app) +- `corpsim-api.altitude-interactive.com` -> `192.0.2.10:4310` (API server) **IMPORTANT**: The nginx configuration for `corpsim.altitude-interactive.com` must proxy `/api/auth/*` requests to the API server at port 4310. This allows OAuth callbacks to work correctly on the main web domain. See `docs/project/corpsim.altitude.nginx.conf` for the complete configuration. +**Note**: Replace the example IP address `192.0.2.10` (from RFC 5737 documentation range) with your actual server IP address. + ## Troubleshooting ### OAuth failing with "redirect_uri is not associated with this application" diff --git a/docs/project/OAUTH_CALLBACK_FIX.md b/docs/project/OAUTH_CALLBACK_FIX.md index 05114f96..dc8f57ba 100644 --- a/docs/project/OAUTH_CALLBACK_FIX.md +++ b/docs/project/OAUTH_CALLBACK_FIX.md @@ -31,12 +31,12 @@ server { listen [::]:443 ssl http2; server_name corpsim.altitude-interactive.com; - ssl_certificate /etc/ssl/cloudflare/altitude_pubkey.pem; - ssl_certificate_key /etc/ssl/cloudflare/altitude_privkey.key; + ssl_certificate /etc/letsencrypt/live/example.com/fullchain.pem; + ssl_certificate_key /etc/letsencrypt/live/example.com/privkey.pem; - # Proxy OAuth callback routes to API server + # Proxy Better Auth routes (/api/auth/*) to API server location /api/auth/ { - proxy_pass http://10.7.0.3:4310; + proxy_pass http://192.0.2.10:4310; proxy_http_version 1.1; proxy_set_header Host $host; proxy_set_header X-Real-IP $remote_addr; @@ -45,7 +45,7 @@ server { } location / { - proxy_pass http://10.7.0.3:4311; + proxy_pass http://192.0.2.10:4311; proxy_http_version 1.1; proxy_set_header Host $host; proxy_set_header X-Real-IP $remote_addr; @@ -55,7 +55,7 @@ server { } ``` -This adds a specific proxy rule for `/api/auth/*` requests that forwards them to the API server. +This adds a specific proxy rule for `/api/auth/*` requests that forwards them to the API server. Replace the example IP addresses and SSL certificate paths with your production values. ### 2. Update API Service Environment Variable In Dokploy (or your deployment platform), update the `corpsim-api` service environment variables: diff --git a/docs/project/corpsim.altitude.nginx.conf b/docs/project/corpsim.altitude.nginx.conf index f5b03acf..764249b2 100644 --- a/docs/project/corpsim.altitude.nginx.conf +++ b/docs/project/corpsim.altitude.nginx.conf @@ -17,12 +17,12 @@ server { listen [::]:443 ssl http2; server_name corpsim.altitude-interactive.com; - ssl_certificate /etc/ssl/cloudflare/altitude_pubkey.pem; - ssl_certificate_key /etc/ssl/cloudflare/altitude_privkey.key; + ssl_certificate /etc/letsencrypt/live/example.com/fullchain.pem; + ssl_certificate_key /etc/letsencrypt/live/example.com/privkey.pem; - # Proxy OAuth callback routes to API server + # Proxy Better Auth routes (/api/auth/*) to API server location /api/auth/ { - proxy_pass http://10.7.0.3:4310; + proxy_pass http://192.0.2.10:4310; proxy_http_version 1.1; proxy_set_header Host $host; proxy_set_header X-Real-IP $remote_addr; @@ -31,7 +31,7 @@ server { } location / { - proxy_pass http://10.7.0.3:4311; + proxy_pass http://192.0.2.10:4311; proxy_http_version 1.1; proxy_set_header Host $host; proxy_set_header X-Real-IP $remote_addr; @@ -45,11 +45,11 @@ server { listen [::]:443 ssl http2; server_name corpsim-api.altitude-interactive.com; - ssl_certificate /etc/ssl/cloudflare/altitude_pubkey.pem; - ssl_certificate_key /etc/ssl/cloudflare/altitude_privkey.key; + ssl_certificate /etc/letsencrypt/live/example.com/fullchain.pem; + ssl_certificate_key /etc/letsencrypt/live/example.com/privkey.pem; location / { - proxy_pass http://10.7.0.3:4310; + proxy_pass http://192.0.2.10:4310; proxy_http_version 1.1; proxy_set_header Host $host; proxy_set_header X-Real-IP $remote_addr;