Skip to content

Commit

Permalink
Merge pull request #130 from adrienne-deriv/remove-user-state
Browse files Browse the repository at this point in the history
Adrienne / Added function to remove user state
  • Loading branch information
adrienne-deriv authored Dec 31, 2024
2 parents 995ba95 + 7d50561 commit 9aff97a
Show file tree
Hide file tree
Showing 2 changed files with 37 additions and 2 deletions.
1 change: 1 addition & 0 deletions src/oidc/error.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ export enum OIDCErrorType {
LegacyTokenRequestFailed = 'LegacyTokenRequestFailed',
UserManagerCreationFailed = 'UserManagerCreationFailed',
OneTimeCodeMissing = 'OneTimeCodeMissing',
FailedToRemoveSession = 'FailedToRemoveSession',
}

export class OIDCError extends Error {
Expand Down
38 changes: 36 additions & 2 deletions src/oidc/oidc.ts
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,17 @@ type CreateUserManagerOptions = {
postLogoutRedirectUri?: string;
};

type OAuth2LogoutOptions = {
WSLogoutAndRedirect: () => void;
redirectCallbackUri: string;
postLogoutRedirectUri: string;
};

type ClearOIDCStorageOptions = {
redirectCallbackUri: string;
postLogoutRedirectUri: string;
};

/**
* Fetches the OIDC configuration for the given serverUrl.
* @returns {Promise<object>} - A promise resolving to the OIDC configuration.
Expand Down Expand Up @@ -268,14 +279,19 @@ export const createUserManager = async (options: CreateUserManagerOptions) => {
* Logs out the user from the auth server and calls the callback function when the logout is complete.
* @param WSLogoutAndRedirect - The callback function to call after the logout is complete
*/
export const OAuth2Logout = (WSLogoutAndRedirect: () => void) => {
export const OAuth2Logout = (options: OAuth2LogoutOptions) => {
const oidcEndpoints = localStorage.getItem('config.oidc_endpoints') || '{}';

const logoutUrl = getOAuthLogoutUrl() || JSON.parse(oidcEndpoints).end_session_endpoint;

const cleanup = () => {
const iframe = document.getElementById('logout-iframe') as HTMLIFrameElement;
if (iframe) iframe.remove();
// NOTE: this will resolve issues where once you are logged out, OIDC may reuse the previous user's OIDC ID token / session data
clearOIDCStorage({
redirectCallbackUri: options.redirectCallbackUri,
postLogoutRedirectUri: options.postLogoutRedirectUri,
});
};
const onMessage = (event: MessageEvent) => {
if (event.data === 'logout_complete') {
Expand All @@ -289,7 +305,7 @@ export const OAuth2Logout = (WSLogoutAndRedirect: () => void) => {
secure: true,
});
}
WSLogoutAndRedirect();
options.WSLogoutAndRedirect();
cleanup();
window.removeEventListener('message', onMessage);
}
Expand Down Expand Up @@ -351,6 +367,24 @@ export const oidcLogout = async (options: RequestOidcAuthenticationOptions): Pro
}
};

/**
* Clears any OIDC-related storage (localStorage, sessionStorage, etc) about the current user.
* There's 2 types of storage `oidc-client-ts` uses: state store, and user store
* User store is used for storing the access token and ID token
* Use this function when your application has logged out successfully but the session data is still there, otherwise use `OAuth2Logout` function which already handles this scenario
*
*/
export const clearOIDCStorage = async (options: ClearOIDCStorageOptions) => {
try {
const userManager = await createUserManager(options);

await userManager.removeUser();
} catch (error) {
if (error instanceof Error) throw new OIDCError(OIDCErrorType.FailedToRemoveSession, error.message);
throw new OIDCError(OIDCErrorType.FailedToRemoveSession, 'unable to remove OIDC session');
}
};

/**
* Checks if the user has completed the logout flow and calls the callback function from the consumer.
* At this point the user is already logged out from the auth server. This function is just to clear the FE session.
Expand Down

0 comments on commit 9aff97a

Please sign in to comment.