Skip to content

Commit

Permalink
Clear session storage on auto-logout & remove unused saml function (o…
Browse files Browse the repository at this point in the history
…pensearch-project#1872)

* clear session storage on auto-logout & remove unused saml function

Signed-off-by: Shenoy Pratik <[email protected]>

* remote openid unused function

Signed-off-by: Derek Ho <[email protected]>

---------

Signed-off-by: Shenoy Pratik <[email protected]>
Signed-off-by: Derek Ho <[email protected]>
Co-authored-by: Derek Ho <[email protected]>
  • Loading branch information
ps48 and derek-ho authored Apr 3, 2024
1 parent 28604fd commit aed7671
Show file tree
Hide file tree
Showing 3 changed files with 47 additions and 21 deletions.
43 changes: 40 additions & 3 deletions public/apps/account/test/plugin.test.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -13,15 +13,39 @@
* permissions and limitations under the License.
*/

import { LOGIN_PAGE_URI } from '../../../../common';
import { interceptError } from '../../../utils/logout-utils';
import { setShouldShowTenantPopup } from '../../../utils/storage-utils';
import { LOGIN_PAGE_URI } from '../../../../common';

jest.mock('../../../utils/storage-utils', () => ({
setShouldShowTenantPopup: jest.fn(),
}));

interface LooseObject {
[key: string]: any;
}

// Mock sessionStorage
const sessionStorageMock = (() => {
let store = {} as LooseObject;
return {
clear() {
store = {};
},
};
})();

Object.defineProperty(window, 'sessionStorage', { value: sessionStorageMock });

describe('Intercept error handler', () => {
beforeEach(() => {
jest.spyOn(window.sessionStorage, 'clear');
});

afterEach(() => {
jest.restoreAllMocks();
});

const fakeError401 = {
response: {
status: 401,
Expand All @@ -34,15 +58,28 @@ describe('Intercept error handler', () => {
},
};

it('Intercept error handler Should call setShouldShowTenantPopup on session timeout', () => {
it('Intercept error handler should call setShouldShowTenantPopup on session timeout', () => {
const sessionTimeoutFn = interceptError(LOGIN_PAGE_URI, window);
sessionTimeoutFn(fakeError401, null);
expect(setShouldShowTenantPopup).toBeCalledTimes(1);
expect(sessionStorage.clear).toBeCalledTimes(1);
});

it('Intercept error handler should clear the session', () => {
const sessionTimeoutFn = interceptError(LOGIN_PAGE_URI, window);
sessionTimeoutFn(fakeError401, null);
expect(sessionStorage.clear).toBeCalledTimes(1);
});

it('Intercept error handler Should not call setShouldShowTenantPopup on session timeout', () => {
it('Intercept error handler should not call setShouldShowTenantPopup on session timeout', () => {
const sessionTimeoutFn = interceptError(LOGIN_PAGE_URI, window);
sessionTimeoutFn(fakeError400, null);
expect(setShouldShowTenantPopup).toBeCalledTimes(0);
});

it('Intercept error handler should not clear the session', () => {
const sessionTimeoutFn = interceptError(LOGIN_PAGE_URI, window);
sessionTimeoutFn(fakeError400, null);
expect(sessionStorage.clear).toBeCalledTimes(0);
});
});
19 changes: 3 additions & 16 deletions public/apps/account/utils.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -14,11 +14,11 @@
*/

import { HttpStart } from 'opensearch-dashboards/public';
import { API_AUTH_LOGOUT, OPENID_AUTH_LOGOUT, SAML_AUTH_LOGOUT } from '../../../common';
import { API_AUTH_LOGOUT } from '../../../common';
import { setShouldShowTenantPopup } from '../../utils/storage-utils';
import { httpGet, httpGetWithIgnores, httpPost } from '../configuration/utils/request-utils';
import { API_ENDPOINT_ACCOUNT_INFO } from './constants';
import { AccountInfo } from './types';
import { httpGet, httpGetWithIgnores, httpPost } from '../configuration/utils/request-utils';
import { setShouldShowTenantPopup } from '../../utils/storage-utils';

export function fetchAccountInfo(http: HttpStart): Promise<AccountInfo> {
return httpGet(http, API_ENDPOINT_ACCOUNT_INFO);
Expand All @@ -40,19 +40,6 @@ export async function logout(http: HttpStart, logoutUrl?: string): Promise<void>
logoutUrl || `${http.basePath.serverBasePath}/app/login?nextUrl=${nextUrl}`;
}

export async function samlLogout(http: HttpStart): Promise<void> {
// This will ensure tenancy is picked up from local storage in the next login.
setShouldShowTenantPopup(null);
window.location.href = `${http.basePath.serverBasePath}${SAML_AUTH_LOGOUT}`;
}

export async function openidLogout(http: HttpStart): Promise<void> {
// This will ensure tenancy is picked up from local storage in the next login.
setShouldShowTenantPopup(null);
sessionStorage.clear();
window.location.href = `${http.basePath.serverBasePath}${OPENID_AUTH_LOGOUT}`;
}

export async function externalLogout(http: HttpStart, logoutEndpoint: string): Promise<void> {
// This will ensure tenancy is picked up from local storage in the next login.
setShouldShowTenantPopup(null);
Expand Down
6 changes: 4 additions & 2 deletions public/utils/logout-utils.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -13,19 +13,21 @@
* permissions and limitations under the License.
*/

import { setShouldShowTenantPopup } from './storage-utils';
import {
HttpInterceptorResponseError,
HttpStart,
IHttpInterceptController,
} from '../../../../src/core/public';
import { CUSTOM_ERROR_PAGE_URI, LOGIN_PAGE_URI, API_ENDPOINT_AUTHTYPE } from '../../common';
import { API_ENDPOINT_AUTHTYPE, CUSTOM_ERROR_PAGE_URI, LOGIN_PAGE_URI } from '../../common';
import { httpGet } from '../apps/configuration/utils/request-utils';
import { setShouldShowTenantPopup } from './storage-utils';

export function interceptError(logoutUrl: string, thisWindow: Window): any {
return (httpErrorResponse: HttpInterceptorResponseError, _: IHttpInterceptController) => {
if (httpErrorResponse.response?.status === 401) {
setShouldShowTenantPopup(null);
// Clear everything in the sessionStorage since they can contain sensitive information
sessionStorage.clear();
if (
!(
thisWindow.location.pathname.toLowerCase().includes(LOGIN_PAGE_URI) ||
Expand Down

0 comments on commit aed7671

Please sign in to comment.