diff --git a/frontend/src/stores/auth.ts b/frontend/src/stores/auth.ts index 7a444acc7..14e93d2c5 100644 --- a/frontend/src/stores/auth.ts +++ b/frontend/src/stores/auth.ts @@ -28,6 +28,11 @@ import {TIME_FORMAT} from '@/constants/timeFormat' import {RELATION_KIND} from '@/types/IRelationKind' import type {IProvider} from '@/types/IProvider' +// Set on explicit logout so the login page won't immediately bounce the user +// back to the OIDC provider. Lives in sessionStorage so it survives the +// round-trip to the IdP within the tab and isn't wiped by localStorage.clear(). +export const JUST_LOGGED_OUT_KEY = 'justLoggedOut' + function redirectToSpecifiedProvider() { const {auth} = useConfigStore() @@ -560,6 +565,8 @@ export const useAuthStore = defineStore('auth', () => { await router.push({name: 'user.login'}) await checkAuth() + sessionStorage.setItem(JUST_LOGGED_OUT_KEY, 'true') + // Redirect to the OIDC provider to end its session too. Prefer the // server-built RP-Initiated Logout URL, falling back to the static one. if (oidcLogoutUrl) { diff --git a/frontend/src/views/user/Login.vue b/frontend/src/views/user/Login.vue index c4564982c..b6a131468 100644 --- a/frontend/src/views/user/Login.vue +++ b/frontend/src/views/user/Login.vue @@ -136,7 +136,7 @@ import {redirectToProvider} from '@/helpers/redirectToProvider' import {useRedirectToLastVisited} from '@/composables/useRedirectToLastVisited' import {isDesktopApp} from '@/helpers/desktopAuth' -import {useAuthStore} from '@/stores/auth' +import {useAuthStore, JUST_LOGGED_OUT_KEY} from '@/stores/auth' import {useConfigStore} from '@/stores/config' import {useTitle} from '@/composables/useTitle' @@ -181,6 +181,25 @@ onBeforeMount(() => { // route before the submit() handler gets a chance to use it. if (authenticated.value) { router.push({name: 'home'}) + return + } + + // Don't auto-redirect right after an explicit logout, otherwise we'd + // immediately re-authenticate the user we just logged out. + if (sessionStorage.getItem(JUST_LOGGED_OUT_KEY)) { + sessionStorage.removeItem(JUST_LOGGED_OUT_KEY) + return + } + + // When the login page offers nothing but a single OIDC provider, skip it + // and send the user straight there. + if ( + !localAuthEnabled.value && + !ldapAuthEnabled.value && + hasOpenIdProviders.value && + openidConnect.value.providers.length === 1 + ) { + redirectToProvider(openidConnect.value.providers[0]) } })