From 89ed62780069f35f76ab37f7f2f0a44f541e5b0a Mon Sep 17 00:00:00 2001 From: Weijie Zhao Date: Mon, 8 Jun 2026 13:09:57 +0800 Subject: [PATCH] fix(auth): remove stale OIDC callback lock The OpenID callback view used a localStorage "authenticating" flag to avoid submitting the same authorization code twice when the route was remounted during an auth layout swap. That layout swap is now guarded by AUTH_ROUTE_NAMES, so openid.auth stays in the unauthenticated shell until redirectIfSaved() navigates away. The persistent flag can instead get stranded when the page is refreshed, closed, or interrupted during the callback, making future OIDC callbacks silently return before exchanging the code. Remove the flag so each valid callback URL is processed normally while keeping the existing state validation and TOTP retry handling. --- frontend/src/views/user/OpenIdAuth.vue | 17 ----------------- 1 file changed, 17 deletions(-) diff --git a/frontend/src/views/user/OpenIdAuth.vue b/frontend/src/views/user/OpenIdAuth.vue index b163ba4e5..3d41c4f0f 100644 --- a/frontend/src/views/user/OpenIdAuth.vue +++ b/frontend/src/views/user/OpenIdAuth.vue @@ -90,25 +90,11 @@ function findProvider(providerKey: string): IProvider | undefined { } async function authenticateWithCode() { - // This component gets mounted twice: The first time when the actual auth request hits the frontend, - // the second time after that auth request succeeded and the outer component "content-no-auth" isn't used - // but instead the "content-auth" component is used. Because this component is just a route and thus - // gets mounted as part of a which both the content-auth and content-no-auth components have, - // this re-mounts the component, even if the user is already authenticated. - // To make sure we only try to authenticate the user once, we set this "authenticating" lock in localStorage - // which ensures only one auth request is done at a time. We don't simply check if the user is already - // authenticated to not prevent the whole authentication if some user is already logged in. - if (localStorage.getItem('authenticating')) { - return - } - localStorage.setItem('authenticating', 'true') - errorMessage.value = '' const providerKey = route.params.provider as string if (typeof route.query.error !== 'undefined') { - localStorage.removeItem('authenticating') sessionStorage.removeItem(pendingTotpKey(providerKey)) errorMessage.value = typeof route.query.message !== 'undefined' ? route.query.message as string @@ -118,7 +104,6 @@ async function authenticateWithCode() { const state = localStorage.getItem('state') if (typeof route.query.state === 'undefined' || route.query.state !== state) { - localStorage.removeItem('authenticating') sessionStorage.removeItem(pendingTotpKey(providerKey)) errorMessage.value = t('user.auth.openIdStateError') return @@ -145,8 +130,6 @@ async function authenticateWithCode() { return } errorMessage.value = getErrorText(e) - } finally { - localStorage.removeItem('authenticating') } }