@hmcts/rpx-xui-node-lib
Version:
Common nodejs library components for XUI
665 lines • 32.2 kB
JavaScript
"use strict";
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
if (k2 === undefined) k2 = k;
var desc = Object.getOwnPropertyDescriptor(m, k);
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
desc = { enumerable: true, get: function() { return m[k]; } };
}
Object.defineProperty(o, k2, desc);
}) : (function(o, m, k, k2) {
if (k2 === undefined) k2 = k;
o[k2] = m[k];
}));
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
Object.defineProperty(o, "default", { enumerable: true, value: v });
}) : function(o, v) {
o["default"] = v;
});
var __importStar = (this && this.__importStar) || (function () {
var ownKeys = function(o) {
ownKeys = Object.getOwnPropertyNames || function (o) {
var ar = [];
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
return ar;
};
return ownKeys(o);
};
return function (mod) {
if (mod && mod.__esModule) return mod;
var result = {};
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
__setModuleDefault(result, mod);
return result;
};
})();
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());
});
};
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.Strategy = void 0;
const events = __importStar(require("events"));
const passport_1 = __importDefault(require("passport"));
const auth_constants_1 = require("../auth.constants");
const common_1 = require("../../common");
const joi_1 = __importDefault(require("joi"));
const URL = __importStar(require("url"));
const openid_client_1 = require("openid-client");
const csurf_1 = __importDefault(require("@dr.pogodin/csurf"));
const jwt_decode_1 = __importDefault(require("jwt-decode"));
class Strategy extends events.EventEmitter {
constructor(strategyName, router, logger = (0, common_1.getLogger)('auth:strategy')) {
super();
this.options = {
authorizationURL: '',
tokenURL: '',
clientID: '',
clientSecret: '',
callbackURL: '',
scope: '',
logoutURL: '',
useRoutes: true,
sessionKey: '',
//openID options
discoveryEndpoint: '',
issuerURL: '',
responseTypes: [''],
tokenEndpointAuthMethod: '',
allowRolesRegex: '.',
useCSRF: true,
routeCredential: undefined,
serviceOverride: false,
};
this.redactingLogReplacer = (key, value) => {
if (key && Strategy.SENSITIVE_LOG_KEY_PATTERN.test(key)) {
return Strategy.REDACTED_LOG_VALUE;
}
return value;
};
/* istanbul ignore next */
this.initialiseStrategy = (options) => __awaiter(this, void 0, void 0, function* () {
this.options = options;
this.logger.log('initialising strategy, options:');
this.logger.log(JSON.stringify(options, this.redactingLogReplacer));
});
/**
* The login route handler will attempt to setup security state param and redirect user if not authenticated
* @param req Request
* @param res Response
* @param next NextFunction
*/
/* istanbul ignore next */
this.loginHandler = (req, res, next) => __awaiter(this, void 0, void 0, function* () {
this.logger.log('Base loginHandler Hit');
const reqSession = req.session;
const { promise, state } = this.saveStateInSession(reqSession);
/* istanbul ignore next */
try {
/* istanbul ignore next */
yield promise;
/* istanbul ignore next */
this.logger.log('calling passport authenticate with state ' + state);
/* istanbul ignore next */
return passport_1.default.authenticate(this.strategyName, {
redirect_uri: reqSession === null || reqSession === void 0 ? void 0 : reqSession.callbackURL,
state,
keepSessionInfo: false,
}, (error, user, info) => {
var _a;
/* istanbul ignore next */
if (error) {
this.logger.error('passport authenticate error ', JSON.stringify(error, this.redactingLogReplacer));
}
/* istanbul ignore next */
if (info) {
this.logger.info('passport authenticate info', JSON.stringify(info, this.redactingLogReplacer));
}
/* istanbul ignore next */
if (!user) {
const message = 'No user details returned by the authentication service, redirecting to login';
this.logger.log(message);
}
else {
this.logger.log('User details from passport.authenticate ' + ((_a = user.userInfo) === null || _a === void 0 ? void 0 : _a.email));
}
})(req, res, next);
/* istanbul ignore next */
}
catch (error) {
this.logger.error('Exception in passport.authenticate', error, this.strategyName);
next(error);
return Promise.reject(error);
}
});
/* istanbul ignore next */
this.setCallbackURL = (req, _res, next) => {
var _a;
const reqSession = req.session;
// Always ensure callbackURL is set to a non-empty string
const hasValidSessionCallback = typeof reqSession.callbackURL === 'string' &&
reqSession.callbackURL.trim().length > 0;
const hasValidOptionCallback = typeof this.options.callbackURL === 'string' &&
this.options.callbackURL.trim().length > 0;
if (!hasValidSessionCallback) {
req.app.set('trust proxy', true);
const pathname = hasValidOptionCallback ? this.options.callbackURL.trim() : req.originalUrl;
reqSession.callbackURL = URL.format({
protocol: req.protocol,
host: req.get('host'),
pathname,
});
}
// 🔍 Log current config and session key status
this.logger.log(`setCallbackURL, options.callbackurl: ${this.options.callbackURL}`);
if (this.options.sessionKey) {
const sessionKey = this.options.sessionKey;
this.logger.log(`sessionKey: ${sessionKey}`);
this.logger.log(`state from session = ${(_a = reqSession[sessionKey]) === null || _a === void 0 ? void 0 : _a.state}`);
}
else {
this.logger.log('sessionKey not set');
}
next();
};
/* istanbul ignore next */
this.logout = (req, res, next) => __awaiter(this, void 0, void 0, function* () {
const reqSession = req.session;
try {
this.logger.log('logout start');
const { accessToken, refreshToken } = (reqSession === null || reqSession === void 0 ? void 0 : reqSession.passport.user.tokenset) || null;
const auth = this.getAuthorization(this.options.clientID, this.options.clientSecret);
yield common_1.http.delete(this.urlFromToken(this.options.logoutURL, accessToken), {
headers: {
Authorization: auth,
},
});
yield common_1.http.delete(this.urlFromToken(this.options.logoutURL, refreshToken), {
headers: {
Authorization: auth,
},
});
//passport provides this method on request object
req.logout({ keepSessionInfo: false }, (err) => __awaiter(this, void 0, void 0, function* () {
if (err) {
console.error(err);
return next(err);
}
yield this.destroySession(req);
/* istanbul ignore next */
if (req.query.noredirect) {
res.status(200).send({ message: 'You have been logged out!' });
return Promise.resolve();
}
const redirectUrl = URL.format({
protocol: req.protocol,
host: req.get('host'),
});
const params = new URLSearchParams({ post_logout_redirect_uri: redirectUrl });
const finalSSOLogoutUrl = `${this.options.ssoLogoutURL}?${params.toString()}`;
const redirect = finalSSOLogoutUrl ? finalSSOLogoutUrl : auth_constants_1.AUTH.ROUTE.LOGIN;
this.logger.log('redirecting to => ', redirect);
// 401 is when no accessToken
res.redirect(redirect);
/* istanbul ignore next */
}));
}
catch (e) {
this.logger.error('error => ', e);
res.status(401).redirect(auth_constants_1.AUTH.ROUTE.DEFAULT_REDIRECT);
}
this.logger.log('logout end');
});
/* istanbul ignore next */
this.authRouteHandler = (req, res) => {
return res.send(req.isAuthenticated());
};
/* istanbul ignore next */
this.destroySession = (req) => __awaiter(this, void 0, void 0, function* () {
return new Promise((resolve, reject) => {
var _a;
(_a = req.session) === null || _a === void 0 ? void 0 : _a.destroy((err) => {
if (err) {
reject(err);
}
this.logger.log('session destroyed');
resolve(true);
});
});
});
/* istanbul ignore next */
this.keepAliveHandler = (_req, _res, next) => {
next();
};
/* istanbul ignore next */
this.configure = (options) => {
const configuredOptions = Object.assign(Object.assign({}, this.options), options);
this.validateOptions(configuredOptions);
this.options = configuredOptions;
this.serializeUser();
this.deserializeUser();
(() => __awaiter(this, void 0, void 0, function* () {
yield this.initialiseStrategy(this.options);
}))();
// ensure trust proxy is always enabled before any other middleware executes
this.initializeTrustProxy();
this.initializePassport();
this.initializeSession();
this.initializeKeepAlive();
this.initialiseCSRF();
if (options.useRoutes) {
this.router.get(auth_constants_1.AUTH.ROUTE.DEFAULT_AUTH_ROUTE, this.authRouteHandler);
this.router.get(auth_constants_1.AUTH.ROUTE.KEEPALIVE_ROUTE, this.authRouteHandler);
this.router.get(auth_constants_1.AUTH.ROUTE.LOGIN, this.setCallbackURL, this.loginHandler);
this.router.get(auth_constants_1.AUTH.ROUTE.OAUTH_CALLBACK, this.callbackHandler);
this.router.get(auth_constants_1.AUTH.ROUTE.LOGOUT, this.logout);
}
this.addHeaders();
this.emit(`${this.strategyName}.bootstrap.success`);
return this.router;
};
/* istanbul ignore next */
this.callbackHandler = (req, res, next) => __awaiter(this, void 0, void 0, function* () {
var _a;
this.logger.log('in callbackHandler for url ' + req.url);
const reqSession = req.session;
const qstate = typeof req.query.state == 'string' ? req.query.state : undefined;
const INVALID_STATE_ERROR = 'Invalid authorization request state.';
if (!qstate) {
this.logger.log('Missing callback state in authorization response, rejecting request');
res.locals = res.locals || {};
res.locals.message = INVALID_STATE_ERROR;
this.emit(auth_constants_1.AUTH.EVENT.AUTHENTICATE_FAILURE, req, res, next);
res.redirect(auth_constants_1.AUTH.ROUTE.EXPIRED_LOGIN_LINK);
return;
}
if (this.options.sessionKey) {
const sessionKey = this.options.sessionKey;
this.logger.log(`sessionKey: ${sessionKey}`);
this.logger.log(`state from session = ${(_a = reqSession[sessionKey]) === null || _a === void 0 ? void 0 : _a.state}`);
}
else {
this.logger.log('sessionKey not set');
}
const LOGIN_BOOKMARK_ERROR = 'LoginBookmarkUsed :';
const emitAuthenticationFailure = (logMessages) => {
this.logger.log(`inside emitAuthenticationFailure, message count ${logMessages.length}`);
if (!logMessages.length)
return;
this.logger.log(`emitAuthenticationFailure logMessages ${logMessages.join('\n')}`);
res.locals.message = logMessages.join('\n');
this.emit(auth_constants_1.AUTH.EVENT.AUTHENTICATE_FAILURE, req, res, next);
};
const redirectWithFailure = (errorMessages, INVALID_STATE_ERROR, uri) => {
errorMessages.push(INVALID_STATE_ERROR);
emitAuthenticationFailure(errorMessages);
return res.redirect(uri);
};
this.logger.log(`calling passport authenticate with ${this.strategyName} strategy`);
passport_1.default.authenticate(this.strategyName, {
redirect_uri: reqSession === null || reqSession === void 0 ? void 0 : reqSession.callbackURL,
keepSessionInfo: false,
failureMessage: true,
}, (error, user, info) => {
var _a, _b, _c;
if (info) {
this.logger.log(`in passport authenticate callback info: ${info}`);
}
let errorMessages = [];
if ((_a = this.options) === null || _a === void 0 ? void 0 : _a.sessionKey) {
const sessState = (_b = reqSession[this.options.sessionKey]) === null || _b === void 0 ? void 0 : _b.state;
this.logger.log(`in passport authenticate callback, strategy ${this.strategyName}, state ${sessState}`);
}
if (error) {
this.logger.log(`in passport authenticate error: ${error}`);
switch (error.name) {
case 'TimeoutError':
const timeoutErrorMessage = `${error.name}: timeout awaiting ${error.url} for ${error.gotOptions.gotTimeout.request}ms`;
errorMessages.push(timeoutErrorMessage);
this.logger.error(error);
break;
default:
errorMessages.push(error);
this.logger.error(error);
break;
}
}
if (!user) {
const MISMATCH_NONCE = 'nonce mismatch';
const MISMATCH_STATE = 'state mismatch';
if ((info === null || info === void 0 ? void 0 : info.message) === INVALID_STATE_ERROR) {
if (!qstate) { // if state is not in query, then we can ignore
this.logger.log('Invalid state error, redirecting to default');
return res.redirect(auth_constants_1.AUTH.ROUTE.DEFAULT_REDIRECT);
}
else {
errorMessages.push(LOGIN_BOOKMARK_ERROR);
return redirectWithFailure(errorMessages, INVALID_STATE_ERROR, auth_constants_1.AUTH.ROUTE.EXPIRED_LOGIN_LINK);
}
}
else if ((info === null || info === void 0 ? void 0 : info.message.includes(MISMATCH_NONCE)) || (info === null || info === void 0 ? void 0 : info.message.includes(MISMATCH_STATE))) {
errorMessages.push(LOGIN_BOOKMARK_ERROR);
return redirectWithFailure(errorMessages, info.message, auth_constants_1.AUTH.ROUTE.EXPIRED_LOGIN_LINK);
}
else if (error === null || error === void 0 ? void 0 : error.message.includes('did not find expected authorization request details in session')) {
errorMessages = [LOGIN_BOOKMARK_ERROR];
return redirectWithFailure(errorMessages, error.message, auth_constants_1.AUTH.ROUTE.EXPIRED_LOGIN_LINK);
}
else {
const message = 'No user details returned by the authentication service, redirecting to login';
this.logger.log(message);
return redirectWithFailure(errorMessages, message, auth_constants_1.AUTH.ROUTE.LOGIN);
}
}
else {
this.logger.log('User id from passport.authenticate ' + ((_c = user === null || user === void 0 ? void 0 : user.userInfo) === null || _c === void 0 ? void 0 : _c.id));
}
emitAuthenticationFailure(errorMessages);
this.verifyLogin(req, user, next, res);
})(req, res, next);
});
/* istanbul ignore next */
this.isTokenExpired = (token) => {
const jwtData = (0, jwt_decode_1.default)(token);
return this.jwTokenExpired(jwtData);
};
/* istanbul ignore next */
this.authenticate = (req, _res, next) => {
var _a, _b, _c;
if (req.isUnauthenticated() || !((_c = (_b = (_a = req === null || req === void 0 ? void 0 : req.session) === null || _a === void 0 ? void 0 : _a.passport) === null || _b === void 0 ? void 0 : _b.user) === null || _c === void 0 ? void 0 : _c.userinfo)) {
this.logger.log('unauthenticated');
return _res.status(401).send({ message: 'Unauthorized' });
}
next();
};
/* istanbul ignore next */
this.makeAuthorization = (passport) => `Bearer ${passport.user.tokenset.accessToken}`;
/* istanbul ignore next */
this.setHeaders = (req, _res, next) => __awaiter(this, void 0, void 0, function* () {
var _a;
const reqSession = req.session;
if ((_a = reqSession === null || reqSession === void 0 ? void 0 : reqSession.passport) === null || _a === void 0 ? void 0 : _a.user) {
if (this.isRouteCredentialNeeded(req.path, this.options)) {
yield this.setCredentialToken(req);
}
else {
req.headers['user-roles'] = reqSession.passport.user.userinfo.roles.join();
req.headers.Authorization = this.makeAuthorization(reqSession.passport);
}
}
else if (this.isRouteCredentialNeeded(req.path, this.options)) {
yield this.setCredentialToken(req);
}
next();
});
/* istanbul ignore next */
this.isRouteCredentialNeeded = (url, options) => {
return options.routeCredential && options.routeCredential.routes && options.routeCredential.routes.includes(url);
};
/* istanbul ignore next */
this.setCredentialToken = (req) => __awaiter(this, void 0, void 0, function* () {
let routeCredentialToken;
const cachedToken = req.app.get('routeCredentialToken');
if (cachedToken && cachedToken.access_token && !this.isTokenExpired(cachedToken.access_token)) {
routeCredentialToken = cachedToken;
}
else {
routeCredentialToken = yield this.generateToken();
req.app.set('routeCredentialToken', routeCredentialToken);
}
if (routeCredentialToken && routeCredentialToken.access_token) {
req.headers.Authorization = `Bearer ${routeCredentialToken.access_token}`;
}
});
/* istanbul ignore next */
this.generateToken = () => __awaiter(this, void 0, void 0, function* () {
const url = this.getUrlFromOptions(this.options);
try {
const axiosConfig = {
headers: { 'content-type': 'application/x-www-form-urlencoded' },
};
const body = this.getRequestBody(this.options);
const response = yield common_1.http.post(url, body, axiosConfig);
return response.data;
}
catch (error) {
this.logger.error('error generating authentication token => ', error);
}
});
/* istanbul ignore next */
this.verifyLogin = (req, user, next, res) => {
req.logIn(user, (err) => {
const roles = user.userinfo.roles;
if (err) {
this.logger.error('verifyLogin error', err);
return next(err);
}
if (this.options.allowRolesRegex && !(0, common_1.arrayPatternMatch)(roles, this.options.allowRolesRegex)) {
this.logger.info(JSON.stringify(user.userInfo));
this.logger.error(`User has no application access, as they do not have a role that matches ${this.options.allowRolesRegex}.`);
return this.logout(req, res, next);
}
if (!this.listenerCount(auth_constants_1.AUTH.EVENT.AUTHENTICATE_SUCCESS)) {
this.logger.log(`redirecting, no listener count: ${auth_constants_1.AUTH.EVENT.AUTHENTICATE_SUCCESS}, user: ${user.email}`);
res.redirect(auth_constants_1.AUTH.ROUTE.DEFAULT_REDIRECT);
}
else {
req.isRefresh = false;
this.emit(auth_constants_1.AUTH.EVENT.AUTHENTICATE_SUCCESS, req, res, next);
}
});
};
/* istanbul ignore next */
this.initializePassport = () => {
this.router.use(passport_1.default.initialize());
};
/* istanbul ignore next */
this.initializeSession = () => {
this.router.use(passport_1.default.session());
};
/* istanbul ignore next */
this.initializeKeepAlive = () => {
this.router.use(this.keepAliveHandler);
};
/* istanbul ignore next */
this.initializeTrustProxy = () => {
this.router.use((req, _res, next) => {
if (req.app.get('trust proxy') !== true) {
req.app.set('trust proxy', true);
this.logger.log('trust proxy enabled');
}
next();
});
};
/**
* helper method to store csrf token into session
*/
/* istanbul ignore next */
this.initialiseCSRF = () => {
if (this.options.useCSRF) {
this.logger.log('initialising CSRF middleware');
const csrfProtection = (0, csurf_1.default)({
value: this.getCSRFValue,
});
// cookie options added via EXUI-986, fortify issues
const cookieOptions = {
sameSite: 'strict',
secure: true,
};
/* istanbul ignore next */
this.router.use(csrfProtection, (req, res, next) => {
res.cookie('XSRF-TOKEN', req.csrfToken(), cookieOptions);
next();
});
}
};
/**
* retrieve the csrf token value, lastly from sent cookies
* @param req
* @return string
*/
/* istanbul ignore next */
this.getCSRFValue = (req) => {
return ((req.body && req.body._csrf) ||
(req.query && req.query._csrf) ||
req.headers['csrf-token'] ||
req.headers['xsrf-token'] ||
req.headers['x-csrf-token'] ||
req.headers['x-xsrf-token'] ||
req.cookies['XSRF-TOKEN']);
};
/* istanbul ignore next */
this.addHeaders = () => {
this.router.use(this.setHeaders);
};
/* istanbul ignore next */
this.serializeUser = () => {
passport_1.default.serializeUser((user, done) => {
this.logger.log(`${this.strategyName} serializeUser`);
this.emitIfListenersExist(auth_constants_1.AUTH.EVENT.SERIALIZE_USER, user, done);
});
};
/* istanbul ignore next */
this.deserializeUser = () => {
passport_1.default.deserializeUser((id, done) => {
this.emitIfListenersExist(auth_constants_1.AUTH.EVENT.DESERIALIZE_USER, id, done);
});
};
/* istanbul ignore next */
this.jwTokenExpired = (jwtData) => {
const expires = new Date(jwtData.exp * 1000).getTime();
const now = new Date().getTime();
return expires < now;
};
/**
* Get session URL
* @return {string}
*/
/* istanbul ignore next */
this.urlFromToken = (url, token) => {
return `${url}/session/${token}`;
};
/**
* Get authorization from ClientID and secret
* @return {string}
*/
/* istanbul ignore next */
this.getAuthorization = (clientID, clientSecret, encoding = 'base64') => {
return `Basic ${Buffer.from(`${clientID}:${clientSecret}`).toString(encoding)}`;
};
/**
* Get all the events that this strategy emits
* @return {string[]} - ['auth.authenticate.success']
*/
/* istanbul ignore next */
this.getEvents = () => {
return Object.values(auth_constants_1.AUTH.EVENT);
};
/**
* emit Events if any subscriptions available
*/
/* istanbul ignore next */
this.emitIfListenersExist = (eventName, eventObject, done) => {
if (!this.listenerCount(eventName)) {
done(null, eventObject);
}
else {
this.emit(eventName, eventObject, done);
}
};
/* istanbul ignore next */
this.getRequestBody = (options) => {
var _a;
if (options.routeCredential) {
const userName = options.routeCredential.userName;
const userPassword = encodeURIComponent(options.routeCredential.password);
const scope = (_a = options.routeCredential) === null || _a === void 0 ? void 0 : _a.scope;
const clientSecret = options.clientSecret;
const idamClient = options.clientID;
return `grant_type=password&password=${userPassword}&username=${userName}&scope=${scope}&client_id=${idamClient}&client_secret=${clientSecret}`;
}
const msg = 'options.routeCredential missing values';
throw new Error(msg);
};
/* istanbul ignore next */
this.getUrlFromOptions = (options) => {
if (options.routeCredential) {
return `${options.logoutURL}/o/token`;
}
const msg = 'missing routeCredential in options';
this.logger.error('msg');
throw new Error(msg);
};
this.strategyName = strategyName;
this.router = router;
this.logger = logger;
}
validateOptions(options) {
const schema = joi_1.default.object({
authorizationURL: joi_1.default.string().required(),
tokenURL: joi_1.default.string().required(),
clientID: joi_1.default.string().required(),
clientSecret: joi_1.default.string().required(),
callbackURL: joi_1.default.string().required(),
discoveryEndpoint: joi_1.default.string(),
issuerURL: joi_1.default.string(),
logoutURL: joi_1.default.string().required(),
scope: joi_1.default.string().required(),
scopeSeparator: joi_1.default.any(),
sessionKey: joi_1.default.any(),
useRoutes: joi_1.default.bool(),
skipUserProfile: joi_1.default.any(),
responseTypes: joi_1.default.array(),
tokenEndpointAuthMethod: joi_1.default.string(),
pkce: joi_1.default.any(),
proxy: joi_1.default.any(),
store: joi_1.default.any(),
state: joi_1.default.any(),
customHeaders: joi_1.default.any(),
allowRolesRegex: joi_1.default.string(),
useCSRF: joi_1.default.bool(),
serviceOverride: joi_1.default.bool(),
routeCredential: joi_1.default.any(),
ssoLogoutURL: joi_1.default.string(),
});
const { error } = schema.validate(options);
if (error) {
throw error;
}
return true;
}
saveStateInSession(reqSession, state) {
if (!state) {
state = openid_client_1.generators.state();
this.logger.log(`state not found, generating new state ${state}`);
}
const p = new Promise((resolve) => {
var _a, _b;
if (reqSession && ((_a = this.options) === null || _a === void 0 ? void 0 : _a.sessionKey)) {
// add the state to the current session object, this will then contain both nonce and state
reqSession[(_b = this.options) === null || _b === void 0 ? void 0 : _b.sessionKey] = Object.assign(Object.assign({}, reqSession[this.options.sessionKey]), { state });
this.logger.log(`saving state ${state} in session`);
reqSession.save(() => {
this.logger.log(`state ${state} saved in session`);
resolve(true);
});
}
else {
this.logger.log('sessionKey not available state not saved');
resolve(false);
}
});
return { promise: p, state: state };
}
}
exports.Strategy = Strategy;
Strategy.REDACTED_LOG_VALUE = '[REDACTED]';
Strategy.SENSITIVE_LOG_KEY_PATTERN = /(clientSecret|client_secret|password|token|authorization)/i;
//# sourceMappingURL=strategy.class.js.map