From d72e2a7506c9649da44ff2e4ab7a3e53de07dcd1 Mon Sep 17 00:00:00 2001 From: Jacob Overgaard <752371+iOvergaard@users.noreply.github.com> Date: Fri, 19 Jan 2024 16:24:57 +0100 Subject: [PATCH] signout on server by first revoking all known tokens, then clear local cache of tokens, and finally redirect user to signout endpoint to clear the cookies on the server --- .../src/shared/auth/auth-flow.ts | 48 +++++++++++-------- 1 file changed, 28 insertions(+), 20 deletions(-) diff --git a/src/Umbraco.Web.UI.Client/src/shared/auth/auth-flow.ts b/src/Umbraco.Web.UI.Client/src/shared/auth/auth-flow.ts index 0cf116b1cb..b3e80000e2 100644 --- a/src/Umbraco.Web.UI.Client/src/shared/auth/auth-flow.ts +++ b/src/Umbraco.Web.UI.Client/src/shared/auth/auth-flow.ts @@ -238,34 +238,42 @@ export class UmbAuthFlow { * This method will sign the user out of the application. */ async signOut() { - // forget all cached token state - await this.#storageBackend.removeItem(TOKEN_RESPONSE_NAME); + const signOutPromises: Promise[] = []; + // revoke the access token if it exists if (this.#accessTokenResponse) { - // TODO: Enable this when the server supports it - // const tokenRevokeRequest = new RevokeTokenRequest({ - // token: this.#accessTokenResponse.accessToken, - // client_id: this.#clientId, - // token_type_hint: 'access_token', - // }); + const tokenRevokeRequest = new RevokeTokenRequest({ + token: this.#accessTokenResponse.accessToken, + client_id: this.#clientId, + token_type_hint: 'access_token', + }); - // await this.#tokenHandler.performRevokeTokenRequest(this.#configuration, tokenRevokeRequest); - - this.#accessTokenResponse = undefined; + signOutPromises.push(this.#tokenHandler.performRevokeTokenRequest(this.#configuration, tokenRevokeRequest)); } + // revoke the refresh token if it exists if (this.#refreshToken) { - // TODO: Enable this when the server supports it - // const tokenRevokeRequest = new RevokeTokenRequest({ - // token: this.#refreshToken, - // client_id: this.#clientId, - // token_type_hint: 'refresh_token', - // }); + const tokenRevokeRequest = new RevokeTokenRequest({ + token: this.#refreshToken, + client_id: this.#clientId, + token_type_hint: 'refresh_token', + }); - // await this.#tokenHandler.performRevokeTokenRequest(this.#configuration, tokenRevokeRequest); - - this.#refreshToken = undefined; + signOutPromises.push(this.#tokenHandler.performRevokeTokenRequest(this.#configuration, tokenRevokeRequest)); } + + // clear the internal token state + signOutPromises.push(this.clearTokenStorage()); + + // wait for all promises to settle before continuing + await Promise.allSettled(signOutPromises); + + // clear the session on the server as well + // this will redirect the user to the end session endpoint of the server + // which will redirect the user back to the client + // and the client will then try and log in again (if the user is not logged in) + // which will redirect the user to the login page + location.href = `${this.#configuration.endSessionEndpoint}?post_logout_redirect_uri=${this.#redirectUri}`; } /**