UNPKG

@okta-dfuhriman/okta-auth-js

Version:
86 lines (78 loc) 3.69 kB
import { IdxResponse } from "@okta/okta-auth-js"; import CookieUtil from '../../util/CookieUtil'; import AppState from '../models/AppState'; import sessionStorageHelper from './sessionStorageHelper'; import { interactionCodeFlow } from './interactionCodeFlow'; import { FORMS } from "../ion/RemediationConstants"; import transformIdxResponse from '../ion/transformIdxResponse'; function hasAuthenticationSucceeded(idxResponse: IdxResponse) { // Check whether authentication has succeeded. This is done by checking the server response // and seeing if either the 'success' or 'successWithInteractionCode' objects are present. return idxResponse?.rawIdxState?.success || idxResponse?.rawIdxState?.successWithInteractionCode; } /** * When "Remember My Username" is enabled, we save the identifier in a cookie * so that the next time the user visits the SIW, the identifier field can be * pre-filled with this value. */ function updateIdentifierCookie(appState: AppState, idxResponse: IdxResponse) { const settings = appState.settings; if (settings.get('features.rememberMe')) { // Update the cookie with the identifier const user = idxResponse?.context?.user; const { identifier } = user?.value || {}; if (identifier) { CookieUtil.setUsernameCookie(identifier); } } else { // We remove the cookie explicitly if this feature is disabled. CookieUtil.removeUsernameCookie(); } } export async function updateAppState(appState: AppState, idxResponse: IdxResponse): Promise<void> { const settings = appState.settings; // Only update the cookie when the user has successfully authenticated themselves // to avoid incorrect/unnecessary updates. if (hasAuthenticationSucceeded(idxResponse) && settings.get('features.rememberMyUsernameOnOIE')) { updateIdentifierCookie(appState, idxResponse); } const lastResponse = appState.get('idx'); const useInteractionCodeFlow = settings.get('oauth2Enabled'); if (useInteractionCodeFlow) { if (idxResponse.interactionCode) { // Although session.stateHandle isn't used by interation flow, // it's better to clean up at the end of the flow. sessionStorageHelper.removeStateHandle(); // This is the end of the IDX flow, now entering OAuth const tokens = await interactionCodeFlow(settings, idxResponse); // reset terminal view in case the were OAuth errors prior to successful token retrieval if (appState.get('currentFormName') === FORMS.TERMINAL) { appState.unset('currentFormName', { silent: true }); } return tokens; } } else { // Do not save state handle for the first page loads. // Because there shall be no difference between following behavior // 1. bootstrap widget // -> save state handle to session storage // -> refresh page // -> introspect using sessionStorage.stateHandle // 2. bootstrap widget // -> do not save state handle to session storage // -> refresh page // -> introspect using options.stateHandle if (lastResponse) { sessionStorageHelper.setStateHandle(idxResponse?.context?.stateHandle); } // Login flows that mimic step up (moving forward in login pipeline) via internal api calls, // need to clear stored stateHandles. // This way the flow can maintain the latest state handle. For eg. Device probe calls if (appState.get('currentFormName') === FORMS.CANCEL_TRANSACTION) { sessionStorageHelper.removeStateHandle(); } } // transform response const ionResponse = transformIdxResponse(settings, idxResponse, lastResponse); await appState.setIonResponse(ionResponse); }