UNPKG

@brionmario-experimental/asgardeo-auth-spa

Version:

Asgardeo Auth SPA SDK to be used in Single-Page Applications.

252 lines 13.1 kB
/** * Copyright (c) 2020, WSO2 Inc. (http://www.wso2.org) All Rights Reserved. * * WSO2 Inc. licenses this file to you under the Apache License, * Version 2.0 (the "License"); you may not use this file except * in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) { function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); } return new (P || (P = Promise))(function (resolve, reject) { function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } } function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } } function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); } step((generator = generator.apply(thisArg, _arguments || [])).next()); }); }; import { AsgardeoAuthClient, SESSION_STATE } from "@asgardeo/auth-js"; import { CHECK_SESSION_SIGNED_IN, CHECK_SESSION_SIGNED_OUT, INITIALIZED_SILENT_SIGN_IN, OP_IFRAME, PROMPT_NONE_IFRAME, RP_IFRAME, SET_SESSION_STATE_FROM_IFRAME, SILENT_SIGN_IN_STATE, STATE, STATE_QUERY, Storage } from "../constants"; import { SPAUtils } from "../utils"; export const SessionManagementHelper = (() => { let _clientID; let _checkSessionEndpoint; let _sessionState; let _interval; let _redirectURL; let _sessionRefreshInterval; let _signOut; let _sessionRefreshIntervalTimeout; let _checkSessionIntervalTimeout; let _storage; let _setSessionState; let _getAuthorizationURL; const initialize = (clientID, checkSessionEndpoint, getSessionState, interval, sessionRefreshInterval, redirectURL, getAuthorizationURL) => { _clientID = clientID; _checkSessionEndpoint = checkSessionEndpoint; _sessionState = getSessionState; _interval = interval; _redirectURL = redirectURL; _sessionRefreshInterval = sessionRefreshInterval; _getAuthorizationURL = getAuthorizationURL; if (_interval > -1) { initiateCheckSession(); } if (_sessionRefreshInterval > -1) { sessionRefreshInterval = setInterval(() => { sendPromptNoneRequest(); }, _sessionRefreshInterval * 1000); } }; const initiateCheckSession = () => __awaiter(void 0, void 0, void 0, function* () { var _a; if (!_checkSessionEndpoint || !_clientID || !_redirectURL) { return; } const OP_IFRAME = "opIFrame"; function checkSession() { var _a; return __awaiter(this, void 0, void 0, function* () { const sessionState = yield _sessionState(); if (Boolean(_clientID) && Boolean(sessionState)) { const message = `${_clientID} ${sessionState}`; const rpIFrame = document.getElementById(RP_IFRAME); const opIframe = (_a = rpIFrame === null || rpIFrame === void 0 ? void 0 : rpIFrame.contentDocument) === null || _a === void 0 ? void 0 : _a.getElementById(OP_IFRAME); const win = opIframe.contentWindow; win === null || win === void 0 ? void 0 : win.postMessage(message, _checkSessionEndpoint); } }); } const rpIFrame = document.getElementById(RP_IFRAME); const opIframe = (_a = rpIFrame === null || rpIFrame === void 0 ? void 0 : rpIFrame.contentDocument) === null || _a === void 0 ? void 0 : _a.getElementById(OP_IFRAME); opIframe.src = _checkSessionEndpoint + "?client_id=" + _clientID + "&redirect_uri=" + _redirectURL; _checkSessionIntervalTimeout = setInterval(checkSession, _interval * 1000); listenToResponseFromOPIFrame(); }); /** * Destroys session intervals. */ const reset = () => { clearInterval(_checkSessionIntervalTimeout); clearInterval(_sessionRefreshIntervalTimeout); }; const listenToResponseFromOPIFrame = () => { function receiveMessage(e) { var _a; return __awaiter(this, void 0, void 0, function* () { const targetOrigin = _checkSessionEndpoint; if (!targetOrigin || (targetOrigin === null || targetOrigin === void 0 ? void 0 : targetOrigin.indexOf(e.origin)) < 0 || ((_a = e === null || e === void 0 ? void 0 : e.data) === null || _a === void 0 ? void 0 : _a.type) === SET_SESSION_STATE_FROM_IFRAME) { return; } if (e.data === "unchanged") { // [RP] session state has not changed } else if (e.data === "error") { window.location.href = yield _signOut(); } else if (e.data === "changed") { // [RP] session state has changed. Sending prompt=none request... sendPromptNoneRequest(); } }); } window === null || window === void 0 ? void 0 : window.addEventListener("message", receiveMessage, false); }; const sendPromptNoneRequest = () => __awaiter(void 0, void 0, void 0, function* () { var _b; const rpIFrame = document.getElementById(RP_IFRAME); const promptNoneIFrame = (_b = rpIFrame === null || rpIFrame === void 0 ? void 0 : rpIFrame.contentDocument) === null || _b === void 0 ? void 0 : _b.getElementById(PROMPT_NONE_IFRAME); if (SPAUtils.canSendPromptNoneRequest()) { SPAUtils.setPromptNoneRequestSent(true); const receiveMessageListener = (e) => { var _a, _b, _c; if (((_a = e === null || e === void 0 ? void 0 : e.data) === null || _a === void 0 ? void 0 : _a.type) === SET_SESSION_STATE_FROM_IFRAME) { _setSessionState((_c = (_b = e === null || e === void 0 ? void 0 : e.data) === null || _b === void 0 ? void 0 : _b.data) !== null && _c !== void 0 ? _c : ""); window === null || window === void 0 ? void 0 : window.removeEventListener("message", receiveMessageListener); } }; if (_storage === Storage.BrowserMemory || _storage === Storage.WebWorker) { window === null || window === void 0 ? void 0 : window.addEventListener("message", receiveMessageListener); } const promptNoneURL = yield _getAuthorizationURL({ prompt: "none", response_mode: "query", state: STATE }); promptNoneIFrame.src = promptNoneURL; } }); /** * This contains the logic to process the response of a prompt none request. * * @param setSessionState The method that sets the session state. * on the output of the content of the redirect URL */ const receivePromptNoneResponse = (setSessionState) => __awaiter(void 0, void 0, void 0, function* () { var _c, _d; const state = new URL(window.location.href).searchParams.get(STATE_QUERY); const sessionState = new URL(window.location.href).searchParams.get(SESSION_STATE); const parent = window.parent.parent; if (state !== null && (state.includes(STATE) || state.includes(SILENT_SIGN_IN_STATE))) { // Prompt none response. const code = new URL(window.location.href).searchParams.get("code"); if (code !== null && code.length !== 0) { if (state.includes(SILENT_SIGN_IN_STATE)) { const message = { data: { code, sessionState: sessionState !== null && sessionState !== void 0 ? sessionState : "", state }, type: CHECK_SESSION_SIGNED_IN }; sessionStorage.setItem(INITIALIZED_SILENT_SIGN_IN, "false"); parent.postMessage(message, parent.origin); SPAUtils.setPromptNoneRequestSent(false); window.location.href = "about:blank"; yield SPAUtils.waitTillPageRedirect(); return true; } const newSessionState = new URL(window.location.href).searchParams.get("session_state"); if (_storage === Storage.LocalStorage || _storage === Storage.SessionStorage) { setSessionState && (yield setSessionState(newSessionState)); } else { const message = { data: newSessionState !== null && newSessionState !== void 0 ? newSessionState : "", type: SET_SESSION_STATE_FROM_IFRAME }; (_d = (_c = window === null || window === void 0 ? void 0 : window.parent) === null || _c === void 0 ? void 0 : _c.parent) === null || _d === void 0 ? void 0 : _d.postMessage(message); } SPAUtils.setPromptNoneRequestSent(false); window.location.href = "about:blank"; yield SPAUtils.waitTillPageRedirect(); return true; } else { if (state.includes(SILENT_SIGN_IN_STATE)) { const message = { type: CHECK_SESSION_SIGNED_OUT }; window.parent.parent.postMessage(message, parent.origin); SPAUtils.setPromptNoneRequestSent(false); window.location.href = "about:blank"; yield SPAUtils.waitTillPageRedirect(); return true; } SPAUtils.setPromptNoneRequestSent(false); const signOutURL = yield _signOut(); // Clearing user session data before redirecting to the signOutURL because user has been already logged // out by the initial logout request in the single logout flow. yield AsgardeoAuthClient.clearUserSessionData(); parent.location.href = signOutURL; window.location.href = "about:blank"; yield SPAUtils.waitTillPageRedirect(); return true; } } return false; }); return (signOut, storage, setSessionState) => __awaiter(void 0, void 0, void 0, function* () { var _e; let rpIFrame = document.createElement("iframe"); rpIFrame.setAttribute("id", RP_IFRAME); rpIFrame.style.display = "none"; let rpIframeLoaded = false; rpIFrame.onload = () => { var _a, _b, _c, _d; rpIFrame = document.getElementById(RP_IFRAME); const rpDoc = rpIFrame === null || rpIFrame === void 0 ? void 0 : rpIFrame.contentDocument; const opIFrame = rpDoc === null || rpDoc === void 0 ? void 0 : rpDoc.createElement("iframe"); if (opIFrame) { opIFrame.setAttribute("id", OP_IFRAME); opIFrame.style.display = "none"; } const promptNoneIFrame = rpDoc === null || rpDoc === void 0 ? void 0 : rpDoc.createElement("iframe"); if (promptNoneIFrame) { promptNoneIFrame.setAttribute("id", PROMPT_NONE_IFRAME); promptNoneIFrame.style.display = "none"; } opIFrame && ((_b = (_a = rpIFrame === null || rpIFrame === void 0 ? void 0 : rpIFrame.contentDocument) === null || _a === void 0 ? void 0 : _a.body) === null || _b === void 0 ? void 0 : _b.appendChild(opIFrame)); promptNoneIFrame && ((_d = (_c = rpIFrame === null || rpIFrame === void 0 ? void 0 : rpIFrame.contentDocument) === null || _c === void 0 ? void 0 : _c.body) === null || _d === void 0 ? void 0 : _d.appendChild(promptNoneIFrame)); rpIframeLoaded = true; }; (_e = document === null || document === void 0 ? void 0 : document.body) === null || _e === void 0 ? void 0 : _e.appendChild(rpIFrame); _signOut = signOut; _storage = storage; _setSessionState = setSessionState; const sleep = () => { return new Promise((resolve) => setTimeout(resolve, 1)); }; while (rpIframeLoaded === false) { yield sleep(); } return { initialize, receivePromptNoneResponse, reset }; }); })(); //# sourceMappingURL=session-management-helper.js.map