diff --git a/changelog/unreleased/fix-logout b/changelog/unreleased/fix-logout new file mode 100644 index 00000000000..5124aa60746 --- /dev/null +++ b/changelog/unreleased/fix-logout @@ -0,0 +1,6 @@ +Bugfix: OIDC logout + +We've fixed the bug that the user sometimes got immediately logged back into the web UI after clicking on logout. + +https://github.com/owncloud/product/issues/266 +https://github.com/owncloud/phoenix/pull/4211 \ No newline at end of file diff --git a/src/components/UserMenu.vue b/src/components/UserMenu.vue index 5bfad131d96..38a6ab65754 100644 --- a/src/components/UserMenu.vue +++ b/src/components/UserMenu.vue @@ -135,7 +135,10 @@ export default { methods: { logout() { this.visible = false - this.$store.dispatch('logout') + // Use timeout to leave enough time for the dropdown to be hidden + setTimeout(() => { + this.$store.dispatch('logout') + }) }, focusFirstLink() { /* diff --git a/src/services/auth.js b/src/services/auth.js index 136917575e7..694b9dd3d71 100644 --- a/src/services/auth.js +++ b/src/services/auth.js @@ -94,8 +94,13 @@ export function initVueAuthenticate(config) { isAuthenticated() { return this.getToken() !== null }, - logout() { - return mgr.signoutRedirect() + createSignoutRequest(idToken) { + return new Promise((resolve, reject) => { + mgr + .createSignoutRequest(idToken) + .then(signoutRequest => resolve(signoutRequest.url)) + .catch(error => reject(error)) + }) }, clearLoginState() { return mgr.removeUser() diff --git a/src/store/user.js b/src/store/user.js index 4912b4bcbff..130a14b33a0 100644 --- a/src/store/user.js +++ b/src/store/user.js @@ -26,25 +26,34 @@ const actions = { // clear oidc client state vueAuthInstance.clearLoginState() }, - logout(context) { - const logoutFinalizer = () => { - context.dispatch('cleanUpLoginState') - context.dispatch('loadSettingsValues') - // force redirect to login page after logout - router.push({ name: 'login' }) + async logout({ dispatch }) { + const logoutFinalizier = (forceRedirect = false) => { + // Remove signed in user + dispatch('cleanUpLoginState') + dispatch('loadSettingsValues') + + // Force redirect to login + if (forceRedirect) { + router.push({ name: 'login' }) + } } - // TODO: only call logout if we still have the id token - const u = vueAuthInstance.getStoredUserObject() + const u = await vueAuthInstance.getStoredUserObject() + if (u && u.id_token) { vueAuthInstance - .logout() - .then(logoutFinalizer) + .createSignoutRequest({ id_token_hint: u.id_token }) + .then(signoutRequestUrl => { + logoutFinalizier() + + // Navigate to signout URL + window.open(signoutRequestUrl, '_self') + }) .catch(error => { console.error(error) - logoutFinalizer() }) } else { - logoutFinalizer() + // Oauth2 logout + logoutFinalizier(true) } }, initAuth(context, payload = { autoRedirect: false }) {