Merge pull request #3754 from SillyTavern/fix-openrouter-oauth OpenRouter: Fix OAuth flow with enabled accounts
Signed| @@ -189,14 +189,17 @@ export async function findSecret(key) { | |||
| 189 | } | 189 | } |
| 190 | 190 | ||
| 191 | function authorizeOpenRouter() { | 191 | function authorizeOpenRouter() { |
| 192 | const openRouterUrl = `https://openrouter.ai/auth?callback_url=${encodeURIComponent(location.origin)}`; | 192 | const redirectUrl = new URL('/callback/openrouter', window.location.origin); |
| 193 | const openRouterUrl = `https://openrouter.ai/auth?callback_url=${encodeURIComponent(redirectUrl.toString())}`; | ||
| 193 | location.href = openRouterUrl; | 194 | location.href = openRouterUrl; |
| 194 | } | 195 | } |
| 195 | 196 | ||
| 196 | async function checkOpenRouterAuth() { | 197 | async function checkOpenRouterAuth() { |
| 197 | const params = new URLSearchParams(location.search); | 198 | const params = new URLSearchParams(location.search); |
| 198 | if (params.has('code')) { | 199 | const source = params.get('source'); |
| 199 | const code = params.get('code'); | 200 | if (source === 'openrouter') { |
| 201 | const query = new URLSearchParams(params.get('query')); | ||
| 202 | const code = query.get('code'); | ||
| 200 | try { | 203 | try { |
| 201 | const response = await fetch('https://openrouter.ai/api/v1/auth/keys', { | 204 | const response = await fetch('https://openrouter.ai/api/v1/auth/keys', { |
| 202 | method: 'POST', | 205 | method: 'POST', |
| @@ -150,7 +150,7 @@ if (cliArgs.enableCorsProxy) { | |||
| 150 | 150 | ||
| 151 | app.use(cookieSession({ | 151 | app.use(cookieSession({ |
| 152 | name: getCookieSessionName(), | 152 | name: getCookieSessionName(), |
| 153 | sameSite: 'strict', | 153 | sameSite: 'lax', |
| 154 | httpOnly: true, | 154 | httpOnly: true, |
| 155 | maxAge: getSessionCookieAge(), | 155 | maxAge: getSessionCookieAge(), |
| 156 | secret: getCookieSecret(globalThis.DATA_ROOT), | 156 | secret: getCookieSecret(globalThis.DATA_ROOT), |
| @@ -213,6 +213,17 @@ app.get('/', getCacheBusterMiddleware(), (request, response) => { | |||
| 213 | return response.sendFile('index.html', { root: path.join(process.cwd(), 'public') }); | 213 | return response.sendFile('index.html', { root: path.join(process.cwd(), 'public') }); |
| 214 | }); | 214 | }); |
| 215 | 215 | ||
| 216 | // Callback endpoint for OAuth PKCE flows (e.g. OpenRouter) | ||
| 217 | app.get('/callback/:source?', (request, response) => { | ||
| 218 | const source = request.params.source; | ||
| 219 | const query = request.url.split('?')[1]; | ||
| 220 | const searchParams = new URLSearchParams(); | ||
| 221 | source && searchParams.set('source', source); | ||
| 222 | query && searchParams.set('query', query); | ||
| 223 | const path = `/?${searchParams.toString()}`; | ||
| 224 | return response.redirect(307, path); | ||
| 225 | }); | ||
| 226 | |||
| 216 | // Host login page | 227 | // Host login page |
| 217 | app.get('/login', loginPageMiddleware); | 228 | app.get('/login', loginPageMiddleware); |
| 218 | 229 | ||