Files
Reactive-Resume/turbo.json
T
Santhi PrakashandAmruth Pillai 7eb6d3bdbf fix(auth): use loopback URL for MCP OAuth JWKS verification (#3297)
* fix(auth): use loopback URL for MCP OAuth JWKS verification

Fetch the JWKS endpoint over the internal loopback address instead of the public APP_URL, so token verification works under Docker port-mapping, reverse proxies, and other deployments where the public URL does not loop back to the Node process.

Also log the specific MCP OAuth verification error instead of swallowing it with a bare catch.

Fixes #3077

* fix(auth): normalize internal JWKS URL and throttle MCP OAuth warnings

 - Problem: default loopback JWKS URL used PORT in dev where the server
   listens on SERVER_PORT (3001), and trailing-slash overrides produced
   //api/auth/jwks; unthrottled warn logs could flood on bad bearer tokens.
 - Fix: resolveInternalBaseUrl trims/normalizes BETTER_AUTH_INTERNAL_URL,
   mirrors apps/server listen-port selection, and MCP OAuth warnings are
   throttled to once per minute.
 - Verification: pnpm exec biome check on changed files; pnpm typecheck.

* fix(auth): declare BETTER_AUTH_INTERNAL_URL in turbo globalEnv

- Problem: Turborepo strict env mode strips undeclared BETTER_AUTH_INTERNAL_URL under pnpm dev, so the JWKS override silently falls back to loopback.
- Fix: add BETTER_AUTH_INTERNAL_URL to turbo.json globalEnv (required for any new env var per CLAUDE.md).
- Verification: python3 JSON parse of turbo.json; confirmed var was absent from globalEnv before this change.

---------

Co-authored-by: Amruth Pillai <im.amruth@gmail.com>
2026-08-13 22:51:02 +02:00

129 lines
2.5 KiB
JSON

{
"$schema": "https://v2-10-7.turborepo.dev/schema.json",
"ui": "stream",
"boundaries": {
"dependencies": {
"deny": ["web", "server"]
},
"implicitDependencies": [
"vitest",
"@testing-library/jest-dom",
"@testing-library/react",
"@testing-library/user-event"
],
"tags": {
"app:server": {
"dependencies": {
"deny": ["app:web", "runtime:browser"]
}
},
"runtime:server": {
"dependencies": {
"deny": ["app:web", "runtime:browser"]
}
},
"runtime:browser": {
"dependencies": {
"deny": ["app:server", "runtime:server"]
}
},
"runtime:universal": {
"dependencies": {
"deny": ["app:web", "app:server", "runtime:server"]
}
},
"role:domain": {
"dependencies": {
"deny": ["app:web", "app:server", "role:adapter", "role:infra"]
}
},
"role:ui": {
"dependencies": {
"deny": ["app:web", "app:server", "runtime:server", "role:infra"]
}
}
}
},
"globalEnv": [
"PORT",
"SERVER_PORT",
"APP_URL",
"DATABASE_URL",
"AUTH_SECRET",
"BETTER_AUTH_API_KEY",
"BETTER_AUTH_INTERNAL_URL",
"GOOGLE_CLIENT_ID",
"GOOGLE_CLIENT_SECRET",
"GITHUB_CLIENT_ID",
"GITHUB_CLIENT_SECRET",
"LINKEDIN_CLIENT_ID",
"LINKEDIN_CLIENT_SECRET",
"OAUTH_PROVIDER_NAME",
"OAUTH_CLIENT_ID",
"OAUTH_CLIENT_SECRET",
"OAUTH_DISCOVERY_URL",
"OAUTH_AUTHORIZATION_URL",
"OAUTH_TOKEN_URL",
"OAUTH_USER_INFO_URL",
"OAUTH_SCOPES",
"SMTP_HOST",
"SMTP_PORT",
"SMTP_USER",
"SMTP_PASS",
"SMTP_FROM",
"SMTP_SECURE",
"LOCAL_STORAGE_PATH",
"S3_ACCESS_KEY_ID",
"S3_SECRET_ACCESS_KEY",
"S3_REGION",
"S3_ENDPOINT",
"S3_BUCKET",
"S3_FORCE_PATH_STYLE",
"REDIS_URL",
"ENCRYPTION_SECRET",
"FLAG_DISABLE_SIGNUPS",
"FLAG_DISABLE_EMAIL_AUTH",
"FLAG_DISABLE_IMAGE_PROCESSING",
"FLAG_DISABLE_API_RATE_LIMIT",
"FLAG_SHOW_SPONSORS",
"FLAG_ALLOW_UNSAFE_OAUTH_REDIRECT_URI",
"FLAG_ALLOW_UNSAFE_AI_BASE_URL"
],
"tasks": {
"build": {
"inputs": ["$TURBO_DEFAULT$", "$TURBO_ROOT$/.env*"],
"outputs": ["dist/**", ".vercel/**"]
},
"check": {},
"typecheck": {},
"test": {},
"test:coverage": {},
"test:ci": {},
"test:e2e": {
"cache": false
},
"test:agent": {},
"dev": {
"cache": false,
"persistent": true
},
"start": {
"cache": false,
"persistent": true
},
"db:generate": {
"cache": false
},
"db:migrate": {
"cache": false
},
"db:studio": {
"cache": false,
"persistent": true
},
"lingui:extract": {
"cache": false
}
}
}