Skip to content

Commit d9c9dde

Browse files
committed
chore: proxy backend paths in the vite dev server for single-origin OAuth testing
The OAuth browser flow needs the SPA and API on one origin. Forward the backend-owned paths to VITE_DEV_PROXY_TARGET while keeping /oauth2/consent and /oauth2/bootstrap as SPA routes, so a split local dev setup can run the flow. Inert unless VITE_APP_API_URL is empty.
1 parent 5f17068 commit d9c9dde

2 files changed

Lines changed: 36 additions & 0 deletions

File tree

.gitignore

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -94,3 +94,6 @@ ngrok.local.yml
9494
# mcp-publisher auth tokens
9595
/.mcpregistry_github_token
9696
/.mcpregistry_registry_token
97+
98+
# local mkcert certs for OAuth browser-extension https testing (webapp/vite.config.ts)
99+
/webapp/localhost*.pem

webapp/vite.config.ts

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,15 @@ import { sentryVitePlugin } from '@sentry/vite-plugin';
1414
const billingFrontendDir = resolve(__dirname, '../../billing/frontend');
1515
const hasBilling = existsSync(billingFrontendDir);
1616

17+
// Optional trusted HTTPS for local OAuth browser-extension testing (chrome.identity requires HTTPS).
18+
// Generate with `mkcert localhost` in webapp/; without the files the dev server stays plain http.
19+
const localCert = resolve(__dirname, 'localhost.pem');
20+
const localCertKey = resolve(__dirname, 'localhost-key.pem');
21+
const devHttps =
22+
existsSync(localCert) && existsSync(localCertKey)
23+
? { cert: localCert, key: localCertKey }
24+
: undefined;
25+
1726
export default defineConfig(({ mode }) => {
1827
process.env = { ...process.env, ...loadEnv(mode, process.cwd()) };
1928

@@ -78,11 +87,35 @@ export default defineConfig(({ mode }) => {
7887
exclude: ['@tginternal/library'],
7988
},
8089
server: {
90+
https: devHttps,
8191
// this ensures that the browser opens upon server start
8292
open: true,
8393
host: process.env.VITE_HOST || undefined,
8494
// this sets a default port to 3000
8595
port: Number(process.env.VITE_PORT) || 3000,
96+
// These backend paths must be proxied so the OAuth browser flow stays single-origin (the session-bootstrap
97+
// cookie). See docs/oauth/README.md for the full dev-server setup.
98+
proxy: Object.fromEntries(
99+
[
100+
'/v2',
101+
'/api',
102+
'/oauth2/authorize',
103+
'/oauth2/token',
104+
'/oauth2/jwks',
105+
'/.well-known',
106+
].map((path) => [
107+
path,
108+
{
109+
target:
110+
process.env.VITE_DEV_PROXY_TARGET || 'http://localhost:8080',
111+
changeOrigin: false,
112+
// Forward X-Forwarded-Proto/Host so the backend (forward-headers-strategy: framework) builds https URLs
113+
// for the /oauth2/authorize -> /oauth2/bootstrap redirect; otherwise it emits http and the https-only dev
114+
// server can't load it.
115+
xfwd: true,
116+
},
117+
])
118+
),
86119
// this enables direct access to library sources
87120
fs: {
88121
allow: [

0 commit comments

Comments
 (0)