UNPKG

neo4j-client-sso

Version:

Single sign-on client (frontend) library for Neo4j products

181 lines (180 loc) 9.47 kB
"use strict"; /* * Copyright (c) "Neo4j" * Neo4j Sweden AB [http://neo4j.com] * * This file is part of Neo4j. * * Licensed 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 __importDefault = (this && this.__importDefault) || function (mod) { return (mod && mod.__esModule) ? mod : { "default": mod }; }; Object.defineProperty(exports, "__esModule", { value: true }); exports.restoreSearchAndHashParams = exports.wasRedirectedBackFromSSOServer = exports.getSSOServerIdIfShouldRedirect = exports.clearRefreshTokenData = exports.retrieveRefreshTokenData = exports.storeRefreshTokenData = exports.temporarilyStoreUrlSearchParams = exports.getCredentialsFromAuthResult = exports.getValidSSOProviders = exports.getInitialisationParameters = void 0; const jwt_decode_1 = __importDefault(require("jwt-decode")); const lodash_pick_1 = __importDefault(require("lodash.pick")); const utils_1 = require("./utils"); const constants_1 = require("./constants"); const helpers_1 = require("./helpers"); const settings_1 = require("./settings"); const getInitialisationParameters = () => { const urlSearchParams = window.location.search; const urlHashParamsAsSearchParams = '?' + window.location.hash.substring(1); const initParams = {}; new URLSearchParams(urlSearchParams).forEach((value, key) => { initParams[key] = value; }); new URLSearchParams(urlHashParamsAsSearchParams).forEach((value, key) => { initParams[key] = value; }); return initParams; }; exports.getInitialisationParameters = getInitialisationParameters; const getValidSSOProviders = (discoveredSSOProviders) => { if (!discoveredSSOProviders) { return []; } if (!Array.isArray(discoveredSSOProviders)) { (0, helpers_1.authLog)(`Discovered SSO providers should be a list, got ${discoveredSSOProviders}`, 'warn'); } if (discoveredSSOProviders.length === 0) { (0, helpers_1.authLog)('List of discovered SSO providers was empty'); return []; } const validSSOProviders = discoveredSSOProviders.filter(provider => { const missingKeys = settings_1.mandatoryKeysForSSOProviders.filter(key => !provider.hasOwnProperty(key)); if (missingKeys.length !== 0) { (0, helpers_1.authLog)(`Dropping invalid discovered sso provider with id: "${provider.id}", missing key(s) ${missingKeys.join(', ')} `); return false; } const missingParamKeys = settings_1.mandatoryKeysForSSOProviderParams.filter(key => !provider.params.hasOwnProperty(key)); if (missingParamKeys.length !== 0) { (0, helpers_1.authLog)(`Dropping invalid discovered SSO provider with id: "${provider.id}", missing params key(s) ${missingParamKeys.join(', ')}`); return false; } return true; }); (0, helpers_1.authLog)('Checked SSO providers'); return validSSOProviders.map(ssoProvider => (Object.assign({ // visibility was introduced in 5.14.0 and defaults to true visible: true }, ssoProvider))); }; exports.getValidSSOProviders = getValidSSOProviders; const getCredentialsFromAuthResult = (result, selectedSSOProvider) => { var _a, _b, _c; (0, helpers_1.authLog)(`Attempting to assemble credentials for idp_id: ${selectedSSOProvider.id}`); if (!selectedSSOProvider) { throw new Error('No SSO provider passed'); } if (!result) { throw new Error('Missing result in auth result handler'); } const tokenTypePrincipal = ((_a = selectedSSOProvider.config) === null || _a === void 0 ? void 0 : _a['token_type_principal']) || settings_1.defaultTokenTypePrincipal; (0, helpers_1.authLog)(`Credentials, using token type "${tokenTypePrincipal}" to retrieve principal`); let parsedJWT; try { parsedJWT = (0, jwt_decode_1.default)(result[tokenTypePrincipal]); } catch (err) { } if (!parsedJWT) { throw new Error(`Could not parse JWT of type "${tokenTypePrincipal}" for idp_id "${selectedSSOProvider.id}", aborting`); } (0, helpers_1.authDebug)('Credentials, parsed JWT', parsedJWT); const principal = (_b = selectedSSOProvider.config) === null || _b === void 0 ? void 0 : _b.principal; if (principal) { (0, helpers_1.authLog)(`Credentials, provided principal in config: ${principal}`); } else { (0, helpers_1.authLog)(`Credentials, no principal provided in config, falling back to 'email' then 'sub'`); } const credsPrincipal = parsedJWT[principal] || parsedJWT.email || parsedJWT.sub; (0, helpers_1.authLog)(`Credentials assembly with username: ${credsPrincipal}`); const configuredTokenType = (_c = selectedSSOProvider.config) === null || _c === void 0 ? void 0 : _c['token_type_authentication']; const tokenTypeAuthentication = configuredTokenType || settings_1.defaultTokenTypeAuthentication; if (!configuredTokenType) { (0, helpers_1.authLog)(`token_type_authentication not configured, using default token type "${settings_1.defaultTokenTypeAuthentication}".`); } (0, helpers_1.authLog)(`Credentials assembled with token type "${tokenTypeAuthentication}" as password. If connection still does not succeed, make sure 'neo4j.conf' is set up correctly`); return { username: credsPrincipal, password: result[tokenTypeAuthentication] }; }; exports.getCredentialsFromAuthResult = getCredentialsFromAuthResult; const temporarilyStoreUrlSearchParams = () => { const currentBrowserURLParams = (0, exports.getInitialisationParameters)(); (0, helpers_1.authLog)(`Temporarily storing the url search params. data: "${JSON.stringify(currentBrowserURLParams)}"`); window.sessionStorage.setItem(constants_1.AUTH_STORAGE_URL_SEARCH_PARAMS, JSON.stringify(currentBrowserURLParams)); }; exports.temporarilyStoreUrlSearchParams = temporarilyStoreUrlSearchParams; const storeRefreshTokenData = (refreshToken, selectedSSOProviderId) => { (0, helpers_1.authLog)('Storing refresh data'); window.sessionStorage.setItem(constants_1.AUTH_STORAGE_REFRESH_DATA, JSON.stringify({ refreshToken, selectedSSOProviderId })); }; exports.storeRefreshTokenData = storeRefreshTokenData; const retrieveRefreshTokenData = () => { const emptyResponse = { refreshToken: null, selectedSSOProviderId: null }; try { const data = window.sessionStorage.getItem(constants_1.AUTH_STORAGE_REFRESH_DATA); if (!data) return emptyResponse; return JSON.parse(data); } catch (err) { (0, helpers_1.authLog)(`Parsing of refresh token data failed, err: ${err}`); return emptyResponse; } }; exports.retrieveRefreshTokenData = retrieveRefreshTokenData; const clearRefreshTokenData = () => window.sessionStorage.removeItem(constants_1.AUTH_STORAGE_REFRESH_DATA); exports.clearRefreshTokenData = clearRefreshTokenData; const getSSOServerIdIfShouldRedirect = () => { const { searchParams } = new URL(window.location.href); return searchParams.get(constants_1.SSO_REDIRECT); }; exports.getSSOServerIdIfShouldRedirect = getSSOServerIdIfShouldRedirect; const wasRedirectedBackFromSSOServer = () => { const { auth_flow_step: authFlowStep } = (0, exports.getInitialisationParameters)(); return (authFlowStep || '').toLowerCase() === constants_1.REDIRECT_URI; }; exports.wasRedirectedBackFromSSOServer = wasRedirectedBackFromSSOServer; const restoreSearchAndHashParams = (toRetrieveParams = [], isClearStore = true) => { (0, helpers_1.authLog)(`Retrieving temporarily stored url search params, params to retrieve: "${toRetrieveParams}"`); try { const storedParams = JSON.parse(window.sessionStorage.getItem(constants_1.AUTH_STORAGE_URL_SEARCH_PARAMS)); if (isClearStore) { (0, helpers_1.authLog)('Clearing temporarily stored url search params.'); window.sessionStorage.removeItem(constants_1.AUTH_STORAGE_URL_SEARCH_PARAMS); } if (!(0, utils_1.isObject)(storedParams)) { throw new Error(`Stored search params were ${storedParams}, expected an object.`); } let parameters = storedParams; if (toRetrieveParams === null || toRetrieveParams === void 0 ? void 0 : toRetrieveParams.length) { parameters = (0, lodash_pick_1.default)(storedParams, toRetrieveParams); } const crntHashParams = window.location.hash || undefined; (0, helpers_1.addSearchParamsInBrowserHistory)(parameters); const newUrl = `${window.location.href}${crntHashParams || ''}`; window.history.replaceState({}, '', newUrl); return parameters; } catch (err) { (0, helpers_1.authLog)(`Error when parsing temporarily stored url search params, err: ${err}. Clearing.`); window.sessionStorage.removeItem(constants_1.AUTH_STORAGE_URL_SEARCH_PARAMS); return null; } }; exports.restoreSearchAndHashParams = restoreSearchAndHashParams;