diff --git a/public/scripts/secrets.js b/public/scripts/secrets.js index 8d95d62cc..d0dff1e4e 100644 --- a/public/scripts/secrets.js +++ b/public/scripts/secrets.js @@ -189,14 +189,17 @@ export async function findSecret(key) { } function authorizeOpenRouter() { - const openRouterUrl = `https://openrouter.ai/auth?callback_url=${encodeURIComponent(location.origin)}`; + const redirectUrl = new URL('/callback/openrouter', window.location.origin); + const openRouterUrl = `https://openrouter.ai/auth?callback_url=${encodeURIComponent(redirectUrl.toString())}`; location.href = openRouterUrl; } async function checkOpenRouterAuth() { const params = new URLSearchParams(location.search); - if (params.has('code')) { - const code = params.get('code'); + const source = params.get('source'); + if (source === 'openrouter') { + const query = new URLSearchParams(params.get('query')); + const code = query.get('code'); try { const response = await fetch('https://openrouter.ai/api/v1/auth/keys', { method: 'POST', diff --git a/server.js b/server.js index 847aa9881..3e5c5a1d7 100644 --- a/server.js +++ b/server.js @@ -150,7 +150,7 @@ if (cliArgs.enableCorsProxy) { app.use(cookieSession({ name: getCookieSessionName(), - sameSite: 'strict', + sameSite: 'lax', httpOnly: true, maxAge: getSessionCookieAge(), secret: getCookieSecret(globalThis.DATA_ROOT), @@ -213,6 +213,17 @@ app.get('/', getCacheBusterMiddleware(), (request, response) => { return response.sendFile('index.html', { root: path.join(process.cwd(), 'public') }); }); +// Callback endpoint for OAuth PKCE flows (e.g. OpenRouter) +app.get('/callback/:source?', (request, response) => { + const source = request.params.source; + const query = request.url.split('?')[1]; + const searchParams = new URLSearchParams(); + source && searchParams.set('source', source); + query && searchParams.set('query', query); + const path = `/?${searchParams.toString()}`; + return response.redirect(307, path); +}); + // Host login page app.get('/login', loginPageMiddleware);