From d955a0c08093508d884672a6e7b63c663fd50692 Mon Sep 17 00:00:00 2001 From: Seefs Date: Thu, 19 Mar 2026 12:57:39 +0800 Subject: [PATCH] fix: redirect OAuth login in current page --- web/src/helpers/api.js | 56 ++++++++++++++++++++++++++++-------------- 1 file changed, 38 insertions(+), 18 deletions(-) diff --git a/web/src/helpers/api.js b/web/src/helpers/api.js index 361d7e09..9381968e 100644 --- a/web/src/helpers/api.js +++ b/web/src/helpers/api.js @@ -36,6 +36,20 @@ export let API = axios.create({ }, }); + +function redirectToOAuthUrl(url, options = {}) { + const { openInNewTab = false } = options; + const targetUrl = typeof url === 'string' ? url : url.toString(); + + if (openInNewTab) { + window.open(targetUrl, '_blank'); + return; + } + + window.location.assign(targetUrl); +} + + function patchAPIInstance(instance) { const originalGet = instance.get.bind(instance); const inFlightGetRequests = new Map(); @@ -249,7 +263,7 @@ export async function onDiscordOAuthClicked(client_id, options = {}) { const redirect_uri = `${window.location.origin}/oauth/discord`; const response_type = 'code'; const scope = 'identify+openid'; - window.open( + redirectToOAuthUrl( `https://discord.com/oauth2/authorize?client_id=${client_id}&redirect_uri=${redirect_uri}&response_type=${response_type}&scope=${scope}&state=${state}`, ); } @@ -268,17 +282,13 @@ export async function onOIDCClicked( url.searchParams.set('response_type', 'code'); url.searchParams.set('scope', 'openid profile email'); url.searchParams.set('state', state); - if (openInNewTab) { - window.open(url.toString(), '_blank'); - } else { - window.location.href = url.toString(); - } + redirectToOAuthUrl(url, { openInNewTab }); } export async function onGitHubOAuthClicked(github_client_id, options = {}) { const state = await prepareOAuthState(options); if (!state) return; - window.open( + redirectToOAuthUrl( `https://github.com/login/oauth/authorize?client_id=${github_client_id}&state=${state}&scope=user:email`, ); } @@ -289,7 +299,7 @@ export async function onLinuxDOOAuthClicked( ) { const state = await prepareOAuthState(options); if (!state) return; - window.open( + redirectToOAuthUrl( `https://connect.linux.do/oauth2/authorize?response_type=code&client_id=${linuxdo_client_id}&state=${state}`, ); } @@ -307,29 +317,39 @@ export async function onLinuxDOOAuthClicked( export async function onCustomOAuthClicked(provider, options = {}) { const state = await prepareOAuthState(options); if (!state) return; - + try { const redirect_uri = `${window.location.origin}/oauth/${provider.slug}`; - + // Check if authorization_endpoint is a full URL or relative path let authUrl; - if (provider.authorization_endpoint.startsWith('http://') || - provider.authorization_endpoint.startsWith('https://')) { + if ( + provider.authorization_endpoint.startsWith('http://') || + provider.authorization_endpoint.startsWith('https://') + ) { authUrl = new URL(provider.authorization_endpoint); } else { // Relative path - this is a configuration error, show error message - console.error('Custom OAuth authorization_endpoint must be a full URL:', provider.authorization_endpoint); - showError('OAuth 配置错误:授权端点必须是完整的 URL(以 http:// 或 https:// 开头)'); + console.error( + 'Custom OAuth authorization_endpoint must be a full URL:', + provider.authorization_endpoint, + ); + showError( + 'OAuth 配置错误:授权端点必须是完整的 URL(以 http:// 或 https:// 开头)', + ); return; } - + authUrl.searchParams.set('client_id', provider.client_id); authUrl.searchParams.set('redirect_uri', redirect_uri); authUrl.searchParams.set('response_type', 'code'); - authUrl.searchParams.set('scope', provider.scopes || 'openid profile email'); + authUrl.searchParams.set( + 'scope', + provider.scopes || 'openid profile email', + ); authUrl.searchParams.set('state', state); - - window.open(authUrl.toString()); + + redirectToOAuthUrl(authUrl); } catch (error) { console.error('Failed to initiate custom OAuth:', error); showError('OAuth 登录失败:' + (error.message || '未知错误'));