From 1bd610e154e914108207a89067220c38a08fafd4 Mon Sep 17 00:00:00 2001 From: melodiebutz Date: Thu, 7 Mar 2024 12:56:53 -0800 Subject: [PATCH 1/3] copy over latest auth module + keep is decoupled --- README.md | 179 +++++- environment.js | 59 ++ index.js | 466 +++++++++------ moduleLogger.js | 72 +++ package-lock.json | 1424 +++++++++++++++++++++++++++++++++++++-------- package.json | 28 +- samlConfigs.js | 6 +- samlStrategy.js | 45 +- 8 files changed, 1795 insertions(+), 484 deletions(-) create mode 100644 environment.js create mode 100644 moduleLogger.js diff --git a/README.md b/README.md index a4cf06f..c2760d3 100644 --- a/README.md +++ b/README.md @@ -1,32 +1,151 @@ -## Env Variables -* REDIS_URL - -* PG_USER -* PG_PASSWORD -* PG_HOST -* PG_UM_DB - -* TLS_KEY_FILEPATH -* TLS_KEY_PASSPHRASE -* APPROVED_API_CALLERS -* COOKIE_DOMAIN -* SECURE_SESSION -* DISABLE_SSO -* EXPRESS_SESSION_SECRET JSON array of strings used as secrets like +## Configuration + +**NOTE: For working with encrypted TLS/SSL connections to RDS (PostgreSQL) and ElastiCache (Redis) in the CSN AWS dev and test environments, you will need to include the Amazon Root CA and RDS us-east-1 certificates in your CA bundle (`TLS_CERT_CA` or `TLS_CERT_CA_FILEPATH`): [csn-aws.pem](./csn-aws.pem)** + +| Environment Variable | Default Value | Description | +| --- | --- | --- | +| `AD_ENABLED` | | Set to `true` to query Active Directory for user permissions. | +| `API_AUTH_LOG_LEVEL` | `${LOG_LEVEL}` or `info` | The name of the lowest level of log messages to record from the module in development/testing environments. If this value is not set, it will inherit the value of the `LOG_LEVEL` setting if available or fall back to `info`. To disable log messages from the module, set this variable to `silent`. +| `APPROVED_API_CALLERS` | | A space-delimited list of URLs to use in generating the [`Access-Control-Allow-Origin` HTTP response header](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Access-Control-Allow-Origin) in the `getAllowedOriginMiddleware`, also used to enforce safe client redirection in the SSO workflow. | +| `COOKIE_DOMAIN` | | The session cookie's [`Domain` attribute](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Set-Cookie#domaindomain-value) in the `redisSession` middleware. | +| `DISABLE_SSO` | | Set to `true` to disable SSO in development/testing environments. When `true`, the user will be defined by the value of the `SSL_CLIENT_S_DN_CN` HTTP request header. | +| `EXPRESS_SESSION_MAX_AGE` | `43200000` (12 hours) | The maximum session age (in milliseconds) allowed by the `redisSession` middleware. | +| `EXPRESS_SESSION_SECRET` | | A string that can be parsed as a JSON array for values to be used as the session secret for the `redisSession` middleware. | +| `LDAP_CERT` | | The certificate for the Active Directory server. | +| `LDAP_PASSWORD` | | The password for authenticating to the Active Directory server. | +| `LDAP_URL` | | The URL of the Active Directory server. | +| `LDAP_USER_FOLDER_CN` | | The root DN to search for users on the Active Directory server. | +| `LDAP_USERNAME` | | The username for authenticating to the Active Directory server. | +| `PG_HOST` | | The host name of the PostgreSQL database server where user data is stored. | +| `PG_PASSWORD` | | The password for authenticating to the PostgreSQL database server. | +| `PG_SSL_REQUIRE` | `true` | Set to `false` to connect to a local PostgreSQL server without SSL. Setting this to false will log a warning message when connecting to the `PG_UM_DB` database. | +| `PG_UM_DB` | | The name of the PostgreSQL database where user data is stored. | +| `PG_USER` | | The username for authenticating to the PostgreSQL database server. | +| `REDIS_PASSWORD` | | The password to use for authenticating to the Redis server. | +| `REDIS_URL` | `redis://localhost` | The URL of the Redis server that stores user session data by the `redisSession` middleware. | +| `REDIS_USER` | | The username to use for authenticating to the Redis server. | +| `SAML_CALLBACK_URL` | | The full callback URL for the identity provider's single sign-on (SSO) service. | +| `SAML_CERT` | | The public signing certificate for the identity provider used to validate signatures of incoming SAML responses. | +| `SAML_ENTRYPOINT` | | The identity provider's single sign-on (SSO) service entrypoint. | +| `SAML_ISSUER` | | The issuer string for the identity provider. | +| `SAML_LOGOUT_CALLBACK_URL` | | The value for the `Location` attribute in the identity provider's single logout (SLO) service configuration. | +| `SAML_LOGOUT_URL` | | The full URL for the identity provider's single logout (SLO) service). | +| `SECURE_SESSION` | | Boolean value determining how to secure the session cookie in the `redisSession` middleware. Set to *true* to set the session cookie's [`Secure` attibute](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Set-Cookie#secure) to `true` and the [`SameSite` attibute](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Set-Cookie#samesitesamesite-value) to `none`. Otherwise, these attributes will be set to `false` and `lax`, respectively. | +| `TLS_CERT_CA` | | The serialized certificate authority bundle for establishing encrypted TLS/SSL connections to PostgreSQL and Redis. | +| `TLS_CERT_CA_FILEPATH` | | The file path of the certificate authority bundle for establishing encrypted TLS/SSL connections to PostgreSQL and Redis, if `TLS_CERT_CA` is not defined. | +| `TLS_KEY` | | The private certificate for signing JWT tokens for client-side session management. | +| `TLS_KEY_FILEPATH` | | The file path of the private certificate for signing JWT tokens, if `TLS_KEY` is not defined. | +| `TLS_KEY_PASSPHRASE` | | The passphrase for decrypting the private certificate for signing JWT tokens. | + +## Usage + +### `getAllowedOriginMiddleware` middleware + +The `getAllowedOriginMiddleware` middleware configures your Express.js application to send [CORS](https://developer.mozilla.org/en-US/docs/Web/HTTP/CORS) response headers. The middleware is configured using the `APPROVED_API_CALLERS` environment variable. + +```javascript +import Express from 'express'; +import AAA from '@advana/api-auth'; + +const app = Express(); +app.use(AAA.getAllowedOriginMiddleware); +``` + +### `redisSession` middleware + +The `redisSession` middleware configures your Express.js application to use the centralized Redis-backed storage for authenticated user sessions. The middleware is configured using the `REDIS_URL` (and `REDIS_USER`, `REDIS_PASSWORD`, and `TLS_CERT_CA` or `TLS_CERT_CA_FILEPATH`), `SECURE_SESSION`, `COOKIE_DOMAIN`, `EXPRESS_SESSION_SECRET`, and `EXPRESS_SESSION_MAX_AGE` environment variables. + +```javascript +import Express from 'express'; +import AAA from '@advana/api-auth'; + +const app = Express(); +app.use(AAA.redisSession()); +``` + +### `setupSaml` + +The `setupSaml` function configures your Express.js application to use the Advana single sign-on (SSO) provider using SAML-based authentication. This is configured using the `SSO_DISABLED`, `APPROVED_API_CALLERS`, `PG_HOST`, `PG_USER`, `PG_PASSWORD`, `PG_UM_DB`, `AD_ENABLED`, `LDAP_URL`, `LDAP_CERT`, `LDAP_USERNAME`, `LDAP_PASSWORD`, `LDAP_USER_FOLDER_CN`, `SAML_ISSUER`, `SAML_CALLBACK_URL`, `SAML_ENTRYPOINT`, `SAML_LOGOUT_URL`, `SAML_LOGOUT_CALLBACK_URL`, and `SAML_CERT` environment variables. + +This function also registers the following routes in your application: + +* GET /login +* POST /login/callback +* GET /login/fail +* GET /logout +* POST /logout/callback +* GET /setUserSession + +```javascript +import Express from 'express'; +import AAA from '@advana/api-auth'; + +const app = Express(); +AAA.setupSaml(app); +``` + +### `ensureAuthenticated` middleware + +The `ensureAuthenticated` middleware configures your Express.js application to ensure the current user is authenticated via the centralized Redis-backed storage for authenticated user sessions. The middleware is configured using the `SSO_DISABLED` environment variable, but also requires the `redisSession` middleware to be configured and in use. + +```javascript +import Express from 'express'; +import AAA from '@advana/api-auth'; + +const app = Express(); +app.use(AAA.redisSession()); +app.use(AAA.ensureAuthenticated); +``` + +### `getToken` POST request handler + +The `getToken` request handler responds to HTTP POST requests to the configured route (usually /api/auth/token) in your Express.js application with a JSON Web Token (JWT) to link the Redis-backed authenticated user session to your client application. The request handler is configured using the `TLS_KEY` or `TLS_KEY_FILEPATH`, and `TLS_PASSPHRASE` environment variables, but also requires the `redisSession` middleware to be configured and in use. + +```javascript +import Express from 'express'; +import AAA from '@advana/api-auth'; + +const app = Express(); +app.use(AAA.redisSession()); +app.post('/api/auth/token', AAA.getToken); ``` -'["new secret first", "older secrets later"]' + +### `permCheck` middleware + +The `permCheck` middleware configures your Express.js application to authorize the current user session against an array of permissions. If the user has any of the specified permissions - or the WebApp Super Admin or Tier 3 Support permissions - the middleware returns `next()`. Otherwise, the middleware sends an HTTP 403 error and prevents access to any routes in the chain. This middleware requires the `redisSession` middleware to be configured and in use. + +```javascript +import Express from 'express'; +import AAA from '@advana/api-auth'; + +const app = Express(); +app.use(AAA.redisSession()); + +app.use((req, res, next) => + AAA.permCheck(req, res, next, [SPECIAL_PERMISSION]) +); + +// this route will not be served to the user unless he or she has +// the "SPECIAL_PERMISSION" permission. +app.get('/api/special/route', (req, res) => { + specialRouteHandler(req, res); +}); ``` -* EXPRESS_SESSION_MAX_AGE session cookie max age in seconds -* SAML_ISSUER -* SAML_CALLBACK_URL -* SAML_ENTRYPOINT -* SAML_LOGOUT_URL -* SAML_LOGOUT_CALLBACK_URL -* SAML_CERT - -* AD_ENABLED (true/false) This one turns on and off pulling permissions from AD. -* LDAP_URL (ldaps://ldap.example.com) -* LDAP_USERNAME (dev.team.da@DRCED) -* LDAP_PASSWORD (password) -* LDAP_CERT (Cert for LDAP) -* LDAP_USER_FOLDER_CN (DC=drced,DC=local) + +### `fetchActiveDirectoryPermissions` + +The `fetchActiveDirectoryPermissions` function returns an array of permissions from Active Directory based on the specified user ID (typically found in `req.session.user.id`, but the value can come from elsewhere). The Active Directory connection must be configured using the `LDAP_URL`, `LDAP_CERT`, `LDAP_USERNAME`, `LDAP_PASSWORD`, and `LDAP_USER_FOLDER_CN` environment variables. + +```javascript +import Express from 'express'; +import AAA from '@advana/api-auth'; + +const app = Express(); +app.use(AAA.redisSession()); + +// please don't do this... +app.get('/example/route', (req, res, next) => { + const permissions = AAA.fetchActiveDirectoryPermissions(req.session.user.id); + return next(); +}); +``` \ No newline at end of file diff --git a/environment.js b/environment.js new file mode 100644 index 0000000..f64c95b --- /dev/null +++ b/environment.js @@ -0,0 +1,59 @@ +const fs = require('fs'); +const RSAkeyDecrypt = require('ssh-key-decrypt'); + +/** + * The log level for the api-auth library to use. + * @since 2.6.0 + * @internal + */ +const API_AUTH_LOG_LEVEL = process.env.API_AUTH_LOG_LEVEL; + +const PG_HOST = process.env.PG_UOT_HOST || process.env.PG_HOST; +const PG_DATABASE = process.env.PG_UM_DB; +const PG_USERNAME = process.env.PG_UOT_USER || process.env.PG_USER; +const PG_PASSWORD = process.env.PG_UOT_PASSWORD || process.env.PG_PASSWORD; + +/** + * Boolean flag indicating whether SSL/TLS should be used for connecting to + * PostgreSQL. The default value is `true`. + * @since 2.7.0 + * @internal + */ +const PG_SSL_REQUIRE = process.env.PG_SSL_REQUIRE !== 'false'; + +const SSO_DISABLED = process.env.DISABLE_SSO === 'true'; + +const readCert = (value, filePath) => { + if (value) { + return value.replace(/\\n/g, '\n'); + } else { + // eslint-disable-next-line security/detect-non-literal-fs-filename + return fs.readFileSync(filePath, 'ascii'); + } +}; + +const TLS_CERT_CA = readCert( + process.env.TLS_CERT_CA, + process.env.TLS_CERT_CA_FILEPATH +); + +const TLS_KEY = readCert(process.env.TLS_KEY, process.env.TLS_KEY_FILEPATH); + +const TLS_PRIVATE_KEY = + '-----BEGIN RSA PRIVATE KEY-----\n' + + RSAkeyDecrypt(TLS_KEY, process.env.TLS_KEY_PASSPHRASE, 'base64') + .match(/.{1,64}/g) + .join('\n') + + '\n-----END RSA PRIVATE KEY-----'; + +module.exports = { + API_AUTH_LOG_LEVEL, + PG_DATABASE, + PG_HOST, + PG_PASSWORD, + PG_SSL_REQUIRE, + PG_USERNAME, + SSO_DISABLED, + TLS_CERT_CA, + TLS_PRIVATE_KEY, +}; diff --git a/index.js b/index.js index 99b7a44..a47b7f2 100644 --- a/index.js +++ b/index.js @@ -1,23 +1,28 @@ -const fs = require('fs'); const CryptoJS = require('crypto-js'); const jwt = require('jsonwebtoken'); -const RSAkeyDecrypt = require('ssh-key-decrypt'); const secureRandom = require('secure-random'); const { Pool } = require('pg'); - const session = require('express-session'); -const redis = require('redis'); const RedisStore = require('connect-redis').default; - const passport = require('passport'); - const ldap = require('ldapjs'); -const logger = require('@dod-advana/advana-logger'); -const samlStrategy = require('./samlStrategy'); const AD = require('activedirectory2').promiseWrapper; const SSO_DISABLED = process.env.DISABLE_SSO === 'true'; -const IS_DECOUPLED = process.env.IS_DECOUPLED && process.env.IS_DECOUPLED === 'true' +const IS_DECOUPLED = process.env.IS_DECOUPLED && process.env.IS_DECOUPLED === 'true'; + +const { + createRedisClient, + exponentialBackoffReconnect, +} = require('@advana/redis-client'); + +const env = require('./environment'); +const { + createLoggingContext, + getRequestLogger, + moduleLogger, +} = require('./moduleLogger'); +const samlStrategy = require('./samlStrategy'); const getMaxAge = () => { const MAX_MAX_AGE = 43200000; // 12 hours @@ -31,77 +36,77 @@ const getMaxAge = () => { } return MAX_AGE; -} +}; const pool = new Pool({ - user: process.env.PG_USER, - password: process.env.PG_PASSWORD, - host: process.env.PG_HOST, - database: process.env.PG_UM_DB, + host: env.PG_HOST, + database: env.PG_DATABASE, + ssl: env.PG_SSL_REQUIRE ? { ca: env.TLS_CERT_CA } : null, + user: env.PG_USERNAME, + password: env.PG_PASSWORD, + application_name: `@advana/api-auth`, }); -const retry_strategy = (options) => { - if(options.attempt > 75){ - return new Error('Redis connection attempts timed out'); - } - - // square number of retries to get an exponential curve of retries - // return number of milleseconds to wait before retrying again - logger.info('Redis attempting to retry connection. Try number: ', options.attempt); - return options.attempt * options.attempt *100; -} -const client = redis.createClient({url: process.env.REDIS_URL, retry_strategy: retry_strategy}); -let keyFileData; -if (process.env.TLS_KEY) { - keyFileData = process.env.TLS_KEY.replace(/\\n/g, '\n'); +if (!env.PG_SSL_REQUIRE) { + moduleLogger.warn( + `SSL disabled for PostgreSQL '${env.PG_DATABASE}' database connection` + ); } else { - keyFileData = fs.readFileSync(process.env.TLS_KEY_FILEPATH, 'ascii'); + moduleLogger.trace( + `connected to PostgreSQL '${env.PG_DATABASE}' database via SSL` + ); } -const private_key = - '-----BEGIN RSA PRIVATE KEY-----\n' + - RSAkeyDecrypt(keyFileData, process.env.TLS_KEY_PASSPHRASE, 'base64') - .match(/.{1,64}/g) - .join('\n') + - '\n-----END RSA PRIVATE KEY-----'; +const generateToken = (claims) => { + claims['csrf-token'] = CryptoJS.SHA256(secureRandom(10)).toString( + CryptoJS.enc.Hex + ); + return jwt.sign(claims, env.TLS_PRIVATE_KEY, { algorithm: 'RS256' }); +}; - const generateToken = (claims) => { - claims['csrf-token'] = CryptoJS.SHA256(secureRandom(10)).toString(CryptoJS.enc.Hex); - return jwt.sign(claims, private_key, { algorithm: 'RS256' }); - } - const getToken = (req, res) => { - try { + const requestLogger = getRequestLogger(req); + const loggingContext = createLoggingContext(req); + try { if (req.method === 'POST' && !!req.body?.consent) { req.session.consent = req.body.consent; req.session.user.consent = req.body.consent; } const token = generateToken(req.session.user); - - res.status(200).send({ token }); - } catch (error) { - console.info(error); + } catch (err) { + requestLogger.error({ err, ...loggingContext }); res.sendStatus(400); } }; const getAllowedOriginMiddleware = (req, res, next) => { + const requestLogger = getRequestLogger(req); + const loggingContext = createLoggingContext(req); + try { - if (req && req.headers && process.env.APPROVED_API_CALLERS.split(' ').includes(req.hostname)) { + if ( + req && + req.headers && + process.env.APPROVED_API_CALLERS.split(' ').includes(req.hostname) + ) { res.setHeader('Access-Control-Allow-Origin', req.hostname); - } else if (req && req.headers && process.env.APPROVED_API_CALLERS.split(' ').includes(req.headers.origin)) { + } else if ( + req && + req.headers && + process.env.APPROVED_API_CALLERS.split(' ').includes(req.headers.origin) + ) { res.setHeader('Access-Control-Allow-Origin', req.headers.origin); } - } catch (e) { + } catch (err) { //this error happens in docker where origin is undefined - logger.error(e); + requestLogger.error({ err, ...loggingContext }); } res.header('Access-Control-Allow-Methods', 'GET, PUT, POST, DELETE, OPTIONS'); res.header( - 'Access-Control-Allow-Headers', + 'Access-Control-Allow-Headers', 'Accept, Origin, Content-Encoding, Content-Type, Authorization, Content-Length, X-Requested-With, Accept-Language, SSL_CLIENT_S_DN_CN, X-UA-SIGNATURE, permissions' ); res.header('Access-Control-Allow-Credentials', true); @@ -114,39 +119,37 @@ const getAllowedOriginMiddleware = (req, res, next) => { } }; -const redisSession = () => { +const redisClient = createRedisClient({ + name: '@advana/api-auth', + socket: { + reconnectStrategy: exponentialBackoffReconnect, + }, +}); - let redisOptions = { - host: process.env.REDIS_URL, - port: '6379', - client: client - }; - const secureSession = (process.env.SECURE_SESSION.toLowerCase() === 'true'); +const redisSession = () => { + const secureSession = process.env.SECURE_SESSION.toLowerCase() === 'true'; const sessionCookie = { maxAge: getMaxAge(), sameSite: secureSession ? 'none' : 'lax', secure: secureSession, httpOnly: true, }; - if (process.env.COOKIE_DOMAIN) { sessionCookie.domain = process.env.COOKIE_DOMAIN; } - let secret = 'keyboard cat'; - if (process.env.EXPRESS_SESSION_SECRET){ - secret = process.env.EXPRESS_SESSION_SECRET?.includes('|') ? process.env.EXPRESS_SESSION_SECRET?.split('|') : JSON.parse(process.env.EXPRESS_SESSION_SECRET) || 'keyboard cat'; - } + redisClient.connect(); return session({ - store: new RedisStore(redisOptions), - secret: secret, + store: new RedisStore({ client: redisClient }), + secret: JSON.parse(process.env.EXPRESS_SESSION_SECRET), resave: false, saveUninitialized: true, cookie: sessionCookie, }); }; +/* const ensureAuthenticated = async (req, res, next) => { // If Decoupled then we need to make the userId off of the cn then create the req.user objects if (IS_DECOUPLED) { @@ -213,11 +216,73 @@ const ensureAuthenticated = async (req, res, next) => { } } }; +*/ + +const ensureAuthenticated = async (req, res, next) => { + const requestLogger = getRequestLogger(req); + const loggingContext = createLoggingContext(req); + + // If Decoupled then we need to make the userId off of the cn then create the req.user objects + if (IS_DECOUPLED) { + if (!req?.session?.user || !req?.session?.user?.session_id) { + let cn = req.get('x-env-ssl_client_certificate'); + cn = cn?.split('=') || []; + if (cn.length > 1) { + cn = cn[1]; + } else { + cn = cn[0]; + } + if (!cn) { + if (req.get('SSL_CLIENT_S_DN_CN')==='ml-api'){ + next(); + } else { + return res.status(403).send('Unauthorized'); + } + } else { + const cnSplit = cn.split('.'); + const userID = `${cnSplit[cnSplit.length - 1]}@mil`; + const modifiedReq = {user: {}, ...req}; + modifiedReq.user.id = userID; + modifiedReq.user.cn = cn; + + req.user = await fetchUserInfo(modifiedReq); + req.session.user = req.user; + req.session.user.session_id = req.sessionID; + req.headers['SSL_CLIENT_S_DN_CN'] = userID; + next(); + } + } else { + next(); + } + } else if (!env.SSO_DISABLED && req.isAuthenticated()) { + if (req.session?.user?.disabled) { + requestLogger.warn(loggingContext, 'not authenticated: user disabled'); + return res.status(403).send(); + } + requestLogger.trace(loggingContext, 'authenticated'); + return next(); + } else if (env.SSO_DISABLED) { + req.session.user = await fetchUserInfo(req); + requestLogger.trace(loggingContext, 'authenticated'); + return next(); + } else { + requestLogger.warn(loggingContext, 'not authenticated'); + return res.status(401).send(); + } +}; -const fetchUserInfo = async (userid, cn, reqPerms=[]) => { +const fetchUserInfo = async (req) => { + const requestLogger = getRequestLogger(req); + const loggingContext = createLoggingContext(req); + + let userid; - if (!userid && !cn) { - return false; + if (IS_DECOUPLED) { + userid = req.user.id; + } else if (env.SSO_DISABLED && req.user.id) { + userid = req.get('SSL_CLIENT_S_DN_CN'); + } else { + userid = req.user.id; } let dbClient = await pool.connect(); @@ -243,13 +308,15 @@ const fetchUserInfo = async (userid, cn, reqPerms=[]) => { const t0 = new Date().getTime(); adUser = await fetchActiveDirectoryUserInfo(userid); const t1 = new Date().getTime(); - console.log(`Call to fetchActiveDirectoryUserInfo took ${(t1 - t0) / 1000} seconds.`); + requestLogger.trace( + loggingContext, + `Call to fetchActiveDirectoryUserInfo took ${(t1 - t0) / 1000} seconds.` + ); } let cn = req?.user?.cn || adUser.cn; let displayName = getDisplayName(req, user, adUser, cn); - // Create a new user if they don't exist in the database let perms = []; if (!user.id) { @@ -266,14 +333,17 @@ const fetchUserInfo = async (userid, cn, reqPerms=[]) => { new Date(), adUser?.mail || '', ]); - } catch (e) { - logger.error(e); + } catch (err) { + requestLogger.error({ err, ...loggingContext }); } } else { if (!user.displayName) { // user object in postgres has a blank display name; update it if (displayName) { - await dbClient.query(`UPDATE users SET displayname = $1 WHERE username = $2`, [displayName, userid]); + await dbClient.query( + `UPDATE users SET displayname = $1 WHERE username = $2`, + [displayName, userid] + ); } else { // what to do? we can't get the display name from anywhere... } @@ -286,16 +356,19 @@ const fetchUserInfo = async (userid, cn, reqPerms=[]) => { return { id: userid, displayName, - perms: perms.concat(adUser?.perms || [], !SSO_DISABLED ? reqPerms : []), + perms: perms.concat( + adUser?.perms || [], + !env.SSO_DISABLED ? req?.user?.perms : [] + ), sandboxId: user.sandbox_id || adUser.sandboxId, disabled: user.disabled || adUser.disabled, cn, - email: user?.email || adUser?.email, + email: req?.user?.email || adUser.email, retrievedADPerms: adUser?.perms?.length > 0, consent: req?.session?.consent, }; } catch (err) { - console.error(err); + requestLogger.error({ err, ...loggingContext }); return {}; } finally { dbClient.release(); @@ -319,14 +392,14 @@ const fetchActiveDirectoryUserInfo = async (userId) => { const userObj = await ad.findUser(userId.split('@')[0]); if (!userObj) { - console.log('User: ' + userId + ' not found.'); + moduleLogger.warn('user: ' + userId + ' not found.'); return {}; } const groups = await ad.getGroupMembershipForUser(userId.split('@')[0]); const groupPerms = []; if (!groups) { - console.log('User: ' + userId + ' not found.'); + moduleLogger.warn('user: ' + userId + ' not found.'); } else { groups.forEach((group) => { groupPerms.push(group.cn); @@ -344,7 +417,7 @@ const fetchActiveDirectoryUserInfo = async (userId) => { email: userObj.mail, }; } catch (err) { - logger.error(err); + moduleLogger.error(err); return {}; } }; @@ -367,7 +440,7 @@ const fetchActiveDirectoryPermissions = async (userId) => { const groups = await ad.getGroupMembershipForUser(userId.split('@')[0]); const groupPerms = []; if (!groups) { - console.log('User: ' + userId + ' not found.'); + moduleLogger.warn('User: ' + userId + ' not found.'); } else { groups.forEach((group) => { groupPerms.push(group.cn); @@ -376,7 +449,7 @@ const fetchActiveDirectoryPermissions = async (userId) => { return groupPerms; } catch (err) { - logger.error(err); + moduleLogger.error(err); return []; } }; @@ -396,9 +469,9 @@ function addUserToGroup(groupname, userToAddDn) { ldapclient.modify(groupname, change, function (err) { if (err) { - console.log('err in add user in a group ' + err); + moduleLogger.error(err); } else { - console.log('added user in a group'); + moduleLogger.info('added user in a group'); } }); } @@ -417,9 +490,9 @@ function removeUserFromGroup(groupname, userToRemoveDn) { ldapclient.modify(groupname, change, function (err) { if (err) { - console.log('err in remove user from a group ' + err); + moduleLogger.error(err); } else { - console.log('removed user from a group'); + moduleLogger.info('removed user from a group'); } }); } @@ -440,14 +513,20 @@ const hasPerm = (desiredPermission = '', permissions = []) => { }; const permCheck = (req, res, next, permissionToCheckFor = []) => { + const requestLogger = getRequestLogger(req); + const loggingContext = createLoggingContext(req); + try { - let permissions = req.session.user && req.session.user.perms ? req.session.user.perms : []; + let permissions = + req.session.user && req.session.user.perms ? req.session.user.perms : []; for (let p of permissionToCheckFor) { if (hasPerm(p, permissions)) return next(); } } catch (err) { - console.error('Error reading request permissions.'); - console.error(err); + requestLogger.error( + { err, ...loggingContext }, + 'Error reading request permissions.' + ); return res.status(403).send(); } return res.status(403).send(); @@ -456,8 +535,12 @@ const permCheck = (req, res, next, permissionToCheckFor = []) => { // SAML PORTION const updateLoginTime = async (req, res) => { + const requestLogger = getRequestLogger(req); + const loggingContext = createLoggingContext(req); + let userid; - if (SSO_DISABLED) { + + if (env.SSO_DISABLED) { userid = req.get('SSL_CLIENT_S_DN_CN'); } else { userid = req.user.id; @@ -465,24 +548,34 @@ const updateLoginTime = async (req, res) => { let dbClient = await pool.connect(); - try{ + try { let loginTimeSQL = 'UPDATE users SET lastlogin=NOW() WHERE username=$1'; await dbClient.query(loginTimeSQL, [userid]); } catch (err) { - logger.error(err) + requestLogger.error({ err, ...loggingContext }); } finally { dbClient.release(); } -} +}; const setUserSession = async (req, res) => { + const requestLogger = getRequestLogger(req); + const loggingContext = createLoggingContext(req); + try { - req.session.user = await fetchUserInfo(req.user.id, req.user?.cn || req.get('x-env-ssl_client_certificate'), req?.user?.perms); - req.session.user.session_id = req.sessionID; - logger.info(`Setting user session: user - ${req.user.id}, session id - ${req.sessionID}, IP - ${req.ip}`) + if (IS_DECOUPLED) { + const modifiedReq = {user: {}, ...req}; + modifiedReq.user.cn = req?.user?.cn || req.get('x-env-ssl_client_certificate'); + req.session.user = await fetchUserInfo(modifiedReq); + req.session.user.session_id = req.sessionID; + } else { + req.session.user = await fetchUserInfo(req); + req.session.user.session_id = req.sessionID; + } + requestLogger.info(loggingContext, 'session started'); SSORedirect(req, res); } catch (err) { - console.error(err); + requestLogger.error({ err, ...loggingContext }); } }; @@ -497,86 +590,116 @@ const SSORedirect = (req, res) => { }; const setupSaml = (app) => { + passport.serializeUser((user, done) => { + done(null, user); + }); + passport.deserializeUser((user, done) => { + done(null, user); + }); - if (!SSO_DISABLED) { - passport.serializeUser((user, done) => { - done(null, user); - }); - passport.deserializeUser((user, done) => { - done(null, user); - }); - - passport.use(samlStrategy); - - app.use(passport.initialize()); - app.use(passport.session()); - - app.get( - '/login', - (req, res, next) => { - const referer = req.get('Referer'); - if (referer) { - try { - const parsedReferer = new URL(referer); - const refererOrigin = parsedReferer.origin.replace('www.', ''); - const approvedClients = process.env.APPROVED_API_CALLERS.split(' '); - // store referer origin in session in order to redirect to correct domain after SAML auth - if (approvedClients.includes(refererOrigin) && refererOrigin !== approvedClients[0]) { - req.session.AlternateSsoOrigin = refererOrigin; - } - } catch (error) { - logger.info(error); + passport.use(samlStrategy); + + app.use(passport.initialize()); + app.use(passport.session()); + + app.get( + '/login', + (req, res, next) => { + const requestLogger = getRequestLogger(req); + const loggingContext = createLoggingContext(req); + + const referer = req.get('Referer'); + if (referer) { + try { + const parsedReferer = new URL(referer); + const refererOrigin = parsedReferer.origin.replace('www.', ''); + const approvedClients = process.env.APPROVED_API_CALLERS.split(' '); + // store referer origin in session in order to redirect to correct domain after SAML auth + if ( + approvedClients.includes(refererOrigin) && + refererOrigin !== approvedClients[0] + ) { + req.session.AlternateSsoOrigin = refererOrigin; } + } catch (err) { + requestLogger.error({ err, ...loggingContext }); } - passport.authenticate('saml', { failureRedirect: '/login/fail' })(req, res, next); - }, - (req, res) => { - SSORedirect(req, res); } - ); + passport.authenticate('saml', { failureRedirect: '/login/fail' })( + req, + res, + next + ); + }, + (req, res) => { + SSORedirect(req, res); + } + ); - app.post('/login/callback', passport.authenticate('saml', { failureRedirect: '/login/fail' }), (_req, res) => { + app.post( + '/login/callback', + passport.authenticate('saml', { failureRedirect: '/login/fail' }), + (_req, res) => { res.redirect('/api/setUserSession'); - }); + } + ); - app.get('/login/fail', (_req, res) => { - res.status(401).send('Login failed'); - }); + app.get('/login/fail', (_req, res) => { + res.status(401).send('Login failed'); + }); + + app.get('/logout', function (req, res) { + const requestLogger = getRequestLogger(req); + const loggingContext = createLoggingContext(req); - app.get('/logout', function(req, res) { - if (req.user == null) { + if (req.user == null) { return res.redirect('/'); + } + samlStrategy.logout(req, function (err, uri) { + if (!err) { + return res.redirect('/login'); + } + if (err) { + requestLogger.error({ err, ...loggingContext }); } - samlStrategy.logout(req, function(err, uri) { - if(!err){ - return res.redirect("/login") - } - if(err){ - logger.info(err) - } - }); }); + }); - app.post('/logout/callback', function(req, res){ - req.logout(); - res.redirect('/login'); - }); + app.post('/logout/callback', function (req, res) { + req.logout(); + res.redirect('/login'); + }); - app.get( - '/api/setUserSession', - (req, res, next) => { - if (req.isAuthenticated()) { - updateLoginTime(req, res) - return next(); - } - else return res.redirect('/login'); - }, - setUserSession - ); - } + app.get( + '/api/setUserSession', + (req, res, next) => { + if (req.isAuthenticated()) { + updateLoginTime(req, res); + return next(); + } else return res.redirect('/login'); + }, + setUserSession + ); +}; + +// END SAML PORTION + +module.exports = { + getAllowedOriginMiddleware, + getToken, + ensureAuthenticated, + permCheck, + redisSession, + setUserSession, + setupSaml, + fetchActiveDirectoryPermissions, + getMaxAge, }; -const getDisplayName = (req, user, adUser, userid) => { +const getDisplayName = (req, user, adUser, cn) => { + const requestLogger = getRequestLogger(req); + const loggingContext = createLoggingContext(req); + let ret = ''; try { if (req?.user?.displayName) { @@ -589,32 +712,17 @@ const getDisplayName = (req, user, adUser, userid) => { // next check user in AD ret = adUser.displayName; } else { - // finally, try to parse userid - let parts = userid.split('.'); + // finally, try to parse cn + let parts = cn.split('.'); if (parts.length >= 2) { - // userid is in LAST.FIRST.MI.EDIPI format + // cn is in LAST.FIRST.MI.EDIPI format // we want display name to be FIRST LAST ret = `${parts[1]} ${parts[0]}`; } } } catch (err) { - logger.error(err); + requestLogger.error({ err, ...loggingContext }); } finally { return ret; } -} - - -// END SAML PORTION - -module.exports = { - getAllowedOriginMiddleware, - getToken, - ensureAuthenticated, - permCheck, - redisSession, - setUserSession, - setupSaml, - fetchActiveDirectoryPermissions, - getMaxAge }; diff --git a/moduleLogger.js b/moduleLogger.js new file mode 100644 index 0000000..a2325e5 --- /dev/null +++ b/moduleLogger.js @@ -0,0 +1,72 @@ +const { createChildLogger, hashValue, logger } = require('@advana/logger'); +const { API_AUTH_LOG_LEVEL, SSO_DISABLED } = require('./environment'); + +const loggerOptions = { + source: 'api-auth', + level: API_AUTH_LOG_LEVEL ?? logger.level, +}; + +/** + * A child instance of the default logger for logging module events. + * @internal + * @since 2.6.0 + */ +const moduleLogger = createChildLogger(logger, loggerOptions); + +/** + * Gets a child instance of the request logger for logging module events. + * @internal + * @since 2.6.0 + */ +const getRequestLogger = (req) => { + if (!req.log) { + return moduleLogger; + } + return createChildLogger(req.log, loggerOptions); +}; + +/** + * Creates an `auth` logging context with basic information, and adds the req + * logging context if not provided by httpLogger. + * @returns The logging context + * @internal + * @since 2.6.0 + */ +const createLoggingContext = (req) => { + const context = { + auth: { + authenticated: SSO_DISABLED + ? SSO_DISABLED + : req.isAuthenticated && req.isAuthenticated(), + }, + }; + + if (SSO_DISABLED) context.auth.sso = 'disabled'; + + // if req.log exists, it means we're using httpLogger, which should already + // log all of this data. use the same structure for consistency, but don't + // create a duplicate req object. + if (!req.log) { + const sessionID = hashValue(req.sessionID); + context.req = { + id: req.id, + remoteAddress: req.remoteAddress, + sessionID, + session: { + id: sessionID, + user: { + id: req.session?.user?.id, + disabled: req.session?.user?.disabled, + }, + }, + }; + } + + return context; +}; + +module.exports = { + createLoggingContext, + getRequestLogger, + moduleLogger, +}; diff --git a/package-lock.json b/package-lock.json index c5159f2..d1d4fb8 100644 --- a/package-lock.json +++ b/package-lock.json @@ -10,23 +10,26 @@ "hasInstallScript": true, "license": "ISC", "dependencies": { - "activedirectory2": "2.1.0", + "@advana/logger": "1.0.1", + "@advana/redis-client": "4.3.0", + "@node-saml/passport-saml": "4.0.4", + "activedirectory2": "2.2.0", "connect-redis": "7.1.0", "crypto-js": "4.1.1", - "express-session": "1.17.3", - "jsonwebtoken": "9.0.0", + "express-session": "1.18.0", + "jsonwebtoken": "9.0.2", "ldapjs": "2.3.1", - "passport": "0.6.0", - "passport-saml": "3.2.4", - "pg": "8.11.0", - "redis": "4.6.7", + "passport": "0.7.0", + "pg": "8.11.3", "secure-random": "1.1.2", "ssh-key-decrypt": "0.1.2" - }, - "peerDependencies": { - "@dod-advana/advana-logger": "0.2.1" } }, + "node_modules/quick-format-unescaped": { + "version": "4.0.4", + "resolved": "https://registry.npmjs.org/quick-format-unescaped/-/quick-format-unescaped-4.0.4.tgz", + "integrity": "sha512-tYC1Q1hgyRuHgloV/YXs2w15unPVh8qfu/qCTfhTYamaw7fyhumKa2yGpdSo87vY32rIclj+4fWYQXUMs9EHvg==" + }, "node_modules/pg-pool": { "version": "3.6.1", "resolved": "https://registry.npmjs.org/pg-pool/-/pg-pool-3.6.1.tgz", @@ -46,6 +49,27 @@ "safe-buffer": "^5.0.1" } }, + "node_modules/@node-saml/node-saml": { + "version": "4.0.5", + "resolved": "https://registry.npmjs.org/@node-saml/node-saml/-/node-saml-4.0.5.tgz", + "integrity": "sha512-J5DglElbY1tjOuaR1NPtjOXkXY5bpUhDoKVoeucYN98A3w4fwgjIOPqIGcb6cQsqFq2zZ6vTCeKn5C/hvefSaw==", + "dependencies": { + "@types/debug": "^4.1.7", + "@types/passport": "^1.0.11", + "@types/xml-crypto": "^1.4.2", + "@types/xml-encryption": "^1.2.1", + "@types/xml2js": "^0.4.11", + "@xmldom/xmldom": "^0.8.6", + "debug": "^4.3.4", + "xml-crypto": "^3.0.1", + "xml-encryption": "^3.0.2", + "xml2js": "^0.5.0", + "xmlbuilder": "^15.1.1" + }, + "engines": { + "node": ">= 14" + } + }, "node_modules/@redis/bloom": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/@redis/bloom/-/bloom-1.2.0.tgz", @@ -54,6 +78,20 @@ "@redis/client": "^1.0.0" } }, + "node_modules/pino-abstract-transport": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/pino-abstract-transport/-/pino-abstract-transport-1.1.0.tgz", + "integrity": "sha512-lsleG3/2a/JIWUtf9Q5gUNErBqwIu1tUKTT3dUzaf5DySw9ra1wcqKjJjLX1VTY64Wk1eEOYsVGSaGfCK85ekA==", + "dependencies": { + "readable-stream": "^4.0.0", + "split2": "^4.0.0" + } + }, + "node_modules/@node-saml/node-saml/node_modules/ms": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", + "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==" + }, "node_modules/packet-reader": { "version": "1.0.0", "resolved": "http://10.194.9.122/packet-reader/-/packet-reader-1.0.0.tgz", @@ -70,14 +108,14 @@ } }, "node_modules/pg": { - "version": "8.11.0", - "resolved": "https://registry.npmjs.org/pg/-/pg-8.11.0.tgz", - "integrity": "sha512-meLUVPn2TWgJyLmy7el3fQQVwft4gU5NGyvV0XbD41iU9Jbg8lCH4zexhIkihDzVHJStlt6r088G6/fWeNjhXA==", + "version": "8.11.3", + "resolved": "https://registry.npmjs.org/pg/-/pg-8.11.3.tgz", + "integrity": "sha512-+9iuvG8QfaaUrrph+kpF24cXkH1YOOUeArRNYIxq1viYHZagBxrTno7cecY1Fa44tJeZvaoG+Djpkc3JwehN5g==", "dependencies": { "buffer-writer": "2.0.0", "packet-reader": "1.0.0", - "pg-connection-string": "^2.6.0", - "pg-pool": "^3.6.0", + "pg-connection-string": "^2.6.2", + "pg-pool": "^3.6.1", "pg-protocol": "^1.6.0", "pg-types": "^2.1.0", "pgpass": "1.x" @@ -86,7 +124,7 @@ "node": ">= 8.0.0" }, "optionalDependencies": { - "pg-cloudflare": "^1.1.0" + "pg-cloudflare": "^1.1.1" }, "peerDependencies": { "pg-native": ">=3.0.1" @@ -103,13 +141,49 @@ "integrity": "sha512-iAB+JbDEGXhyIUavoDl9WP/Jj106Kz9DEn1DPgYw5ruDn0e3Wgi3sKFm55sASdGBNOQB8F59d9qQ7deqrHA8wQ==" }, "node_modules/@redis/json": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/@redis/json/-/json-1.0.4.tgz", - "integrity": "sha512-LUZE2Gdrhg0Rx7AN+cZkb1e6HjoSKaeeW8rYnt89Tly13GBI5eP4CwDVr+MY8BAYfCg4/N15OUrtLoona9uSgw==", + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/@redis/json/-/json-1.0.6.tgz", + "integrity": "sha512-rcZO3bfQbm2zPRpqo82XbW8zg4G/w4W3tI7X8Mqleq9goQjAGLL7q/1n1ZX4dXEAmORVZ4s1+uKLaUOg7LrUhw==", "peerDependencies": { "@redis/client": "^1.0.0" } }, + "node_modules/lodash.isstring": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/lodash.isstring/-/lodash.isstring-4.0.1.tgz", + "integrity": "sha512-0wJxfxH1wgO3GrbuP+dTTk7op+6L41QCXbGINEmD+ny/G/eCqGzxyCsh7159S+mgDDcoarnBw6PC1PS5+wUGgw==" + }, + "node_modules/on-exit-leak-free": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/on-exit-leak-free/-/on-exit-leak-free-2.1.2.tgz", + "integrity": "sha512-0eJJY6hXLGf1udHwfNftBqH+g73EU4B504nZeKpz1sYRKafAghwxEJunB2O7rDZkL4PGfsMVnTXZ2EjibbqcsA==", + "engines": { + "node": ">=14.0.0" + } + }, + "node_modules/buffer": { + "version": "6.0.3", + "resolved": "https://registry.npmjs.org/buffer/-/buffer-6.0.3.tgz", + "integrity": "sha512-FTiCpNxtwiZZHEZbcbTIcZjERVICn9yq/pDFkTl95/AxzD1naBctN7YO68riM/gLSDY7sdrMby8hofADYuuqOA==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ], + "dependencies": { + "base64-js": "^1.3.1", + "ieee754": "^1.2.1" + } + }, "node_modules/postgres-array": { "version": "2.0.0", "resolved": "http://10.194.9.122/postgres-array/-/postgres-array-2.0.0.tgz", @@ -128,6 +202,11 @@ "split2": "^4.1.0" } }, + "node_modules/lodash.isboolean": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/lodash.isboolean/-/lodash.isboolean-3.0.3.tgz", + "integrity": "sha512-Bz5mupy2SVbPHURB98VAcw+aHh4vRV5IPNhILUCsOzRmsTmSQ17jIuqopAentWoehktxGd9e/hbIXq980/1QJg==" + }, "node_modules/uid-safe": { "version": "2.1.5", "resolved": "http://10.194.9.122/uid-safe/-/uid-safe-2.1.5.tgz", @@ -140,6 +219,11 @@ "node": ">= 0.8" } }, + "node_modules/@types/mime": { + "version": "1.3.5", + "resolved": "https://registry.npmjs.org/@types/mime/-/mime-1.3.5.tgz", + "integrity": "sha512-/pyBZWSLD2n0dcHE3hq8s8ZvcETHtEuF+3E7XVt0Ig2nvsVQXdghHVcEkIWjy9A0wKfTn97a/PSDYohKIlnP/w==" + }, "node_modules/utils-merge": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/utils-merge/-/utils-merge-1.0.1.tgz", @@ -156,6 +240,14 @@ "node": ">=0.10.0" } }, + "node_modules/@types/debug": { + "version": "4.1.12", + "resolved": "https://registry.npmjs.org/@types/debug/-/debug-4.1.12.tgz", + "integrity": "sha512-vIChWdVG3LG1SMxEvI/AK+FWJthlrqlTu7fbrlywTkkaONwk/UAGaULXRlf8vkzFBLVm0zkMdCquhL5aOjhXPQ==", + "dependencies": { + "@types/ms": "*" + } + }, "node_modules/ldapjs": { "version": "2.3.1", "resolved": "https://registry.npmjs.org/ldapjs/-/ldapjs-2.3.1.tgz", @@ -174,22 +266,25 @@ "node": ">=10.13.0" } }, - "node_modules/passport-saml": { - "version": "3.2.4", - "resolved": "https://registry.npmjs.org/passport-saml/-/passport-saml-3.2.4.tgz", - "integrity": "sha512-JSgkFXeaexLNQh1RrOvJAgjLnZzH/S3HbX/mWAk+i7aulnjqUe7WKnPl1NPnJWqP7Dqsv0I2Xm6KIFHkftk0HA==", - "deprecated": "For versions >= 4, please use scopped package @node-saml/passport-saml", - "dependencies": { - "@xmldom/xmldom": "^0.7.6", - "debug": "^4.3.2", - "passport-strategy": "^1.0.0", - "xml-crypto": "^2.1.3", - "xml-encryption": "^2.0.0", - "xml2js": "^0.4.23", - "xmlbuilder": "^15.1.1" - }, + "node_modules/fast-redact": { + "version": "3.4.0", + "resolved": "https://registry.npmjs.org/fast-redact/-/fast-redact-3.4.0.tgz", + "integrity": "sha512-2gwPvyna0zwBdxKnng1suu/dTL5s8XEy2ZqH8mwDUwJdDkV8w5kp+JV26mupdK68HmPMbm6yjW9m7/Ys/BHEHg==", "engines": { - "node": ">= 12" + "node": ">=6" + } + }, + "node_modules/lodash.isplainobject": { + "version": "4.0.6", + "resolved": "https://registry.npmjs.org/lodash.isplainobject/-/lodash.isplainobject-4.0.6.tgz", + "integrity": "sha512-oSXzaWypCMHkPC3NvBEaPHf0KsA5mvPrOPgQWDsbg8n7orZ290M0BmC/jgRZ4vcJ6DTAhjrsSYgdsW/F+MFOBA==" + }, + "node_modules/@types/xml2js": { + "version": "0.4.14", + "resolved": "https://registry.npmjs.org/@types/xml2js/-/xml2js-0.4.14.tgz", + "integrity": "sha512-4YnrRemBShWRO2QjvUin8ESA41rH+9nQGLUGZV/1IDhi3SL9OhdpNC/MrulTWuptXKwhx/aDxE7toV0f/ypIXQ==", + "dependencies": { + "@types/node": "*" } }, "node_modules/ldap-filter": { @@ -212,11 +307,35 @@ "node": ">= 10.x" } }, + "node_modules/string_decoder": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.3.0.tgz", + "integrity": "sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA==", + "dependencies": { + "safe-buffer": "~5.2.0" + } + }, "node_modules/crypto-js": { "version": "4.1.1", "resolved": "https://registry.npmjs.org/crypto-js/-/crypto-js-4.1.1.tgz", "integrity": "sha512-o2JlM7ydqd3Qk9CA0L4NL6mTzU2sdx96a+oOfPu8Mkl/PK51vSyoi8/rQ8NknZtk44vq15lmhAj9CIAGwgeWKw==" }, + "node_modules/@node-saml/node-saml/node_modules/debug": { + "version": "4.3.4", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz", + "integrity": "sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==", + "dependencies": { + "ms": "2.1.2" + }, + "engines": { + "node": ">=6.0" + }, + "peerDependenciesMeta": { + "supports-color": { + "optional": true + } + } + }, "node_modules/pg-types": { "version": "2.2.0", "resolved": "http://10.194.9.122/pg-types/-/pg-types-2.2.0.tgz", @@ -254,13 +373,13 @@ } }, "node_modules/activedirectory2": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/activedirectory2/-/activedirectory2-2.1.0.tgz", - "integrity": "sha512-HaccG+/mf5NpHL1mAcLzXed4+gGlO6l7mkBi8vNIo6sTJvLoJjHgvJg12F4cy5CNcRqvPS48++s5tfdSiafn4Q==", + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/activedirectory2/-/activedirectory2-2.2.0.tgz", + "integrity": "sha512-uGbw74xttFG6hgocU8T1a0oDofLsyTp44BPTn42JN5C2QlyO5kRl2E7ZoUdfpFzV+yxhaQTKI+8QqRB5HONYvA==", "dependencies": { "abstract-logging": "^2.0.0", "async": "^3.1.0", - "ldapjs": "^2.1.0", + "ldapjs": "^2.3.3", "merge-options": "^2.0.0" }, "engines": { @@ -284,12 +403,28 @@ "wrappy": "1" } }, + "node_modules/safe-stable-stringify": { + "version": "2.4.3", + "resolved": "https://registry.npmjs.org/safe-stable-stringify/-/safe-stable-stringify-2.4.3.tgz", + "integrity": "sha512-e2bDA2WJT0wxseVd4lsDP4+3ONX6HpMXQa1ZhFQ7SU+GjvORCmShbCMltrtIDfkYhVHrOcPtj+KhmDBdPdZD1g==", + "engines": { + "node": ">=10" + } + }, "node_modules/ssh-key-decrypt": { "version": "0.1.2", "resolved": "http://10.194.9.122/ssh-key-decrypt/-/ssh-key-decrypt-0.1.2.tgz", "integrity": "sha1-8e3lsMezI7AA6TgF3+VPHwUBDtk=", "license": "ISC" }, + "node_modules/fast-url-parser": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/fast-url-parser/-/fast-url-parser-1.1.3.tgz", + "integrity": "sha512-5jOCVXADYNuRkKFzNJ0dCCewsZiYo0dz8QNYljkOpFC6r2U4OBmKtvm/Tsuh4w1YYdDqDb31a8TVhBJ2OJKdqQ==", + "dependencies": { + "punycode": "^1.3.2" + } + }, "node_modules/parseurl": { "version": "1.3.3", "resolved": "http://10.194.9.122/parseurl/-/parseurl-1.3.3.tgz", @@ -299,11 +434,37 @@ "node": ">= 0.8" } }, - "node_modules/passport-saml/node_modules/ms": { - "version": "2.1.2", - "resolved": "http://10.194.9.122/ms/-/ms-2.1.2.tgz", - "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", - "license": "MIT" + "node_modules/real-require": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/real-require/-/real-require-0.2.0.tgz", + "integrity": "sha512-57frrGM/OCTLqLOAh0mhVA9VBMHd+9U7Zb2THMGdBUoZVOtGbJzjxsYGDJ3A9AYYCP4hn6y1TVbaOfzWtm5GFg==", + "engines": { + "node": ">= 12.13.0" + } + }, + "node_modules/@types/express": { + "version": "4.17.21", + "resolved": "https://registry.npmjs.org/@types/express/-/express-4.17.21.tgz", + "integrity": "sha512-ejlPM315qwLpaQlQDTjPdsUFSc6ZsP4AN6AlWnogPjQ7CVi7PYF3YVz+CY3jE2pwYf7E/7HlDAN0rV2GxTG0HQ==", + "dependencies": { + "@types/body-parser": "*", + "@types/express-serve-static-core": "^4.17.33", + "@types/qs": "*", + "@types/serve-static": "*" + } + }, + "node_modules/atomic-sleep": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/atomic-sleep/-/atomic-sleep-1.0.0.tgz", + "integrity": "sha512-kNOjDqAh7px0XWNI+4QbzoiR/nTkHAWNud2uvnJquD1/x5a7EQZMJT0AczqK0Qn67oY/TTQ1LbUKajZpp3I9tQ==", + "engines": { + "node": ">=8.0.0" + } + }, + "node_modules/@types/http-errors": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/@types/http-errors/-/http-errors-2.0.4.tgz", + "integrity": "sha512-D0CFMMtydbJAegzOyHjtiKPLlvnm3iTZyZRSZoLq2mRhDdmLfIWOCYPfQJ4cu2erKghU++QvjcUjp/5h7hESpA==" }, "node_modules/xml2js/node_modules/xmlbuilder": { "version": "11.0.1", @@ -313,6 +474,25 @@ "node": ">=4.0" } }, + "node_modules/base64-js": { + "version": "1.5.1", + "resolved": "https://registry.npmjs.org/base64-js/-/base64-js-1.5.1.tgz", + "integrity": "sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ] + }, "node_modules/postgres-interval": { "version": "1.2.0", "resolved": "http://10.194.9.122/postgres-interval/-/postgres-interval-1.2.0.tgz", @@ -325,6 +505,32 @@ "node": ">=0.10.0" } }, + "node_modules/@types/express-serve-static-core": { + "version": "4.17.43", + "resolved": "https://registry.npmjs.org/@types/express-serve-static-core/-/express-serve-static-core-4.17.43.tgz", + "integrity": "sha512-oaYtiBirUOPQGSWNGPWnzyAFJ0BP3cwvN4oWZQY+zUBwpVIGsKUkpBpSztp74drYcjavs7SKFZ4DX1V2QeN8rg==", + "dependencies": { + "@types/node": "*", + "@types/qs": "*", + "@types/range-parser": "*", + "@types/send": "*" + } + }, + "node_modules/@types/serve-static": { + "version": "1.15.5", + "resolved": "https://registry.npmjs.org/@types/serve-static/-/serve-static-1.15.5.tgz", + "integrity": "sha512-PDRk21MnK70hja/YF8AHfC7yIsiQHn1rcXx7ijCFBX/k+XQJhQT/gw3xekXKJvx+5SXaMMS8oqQy09Mzvz2TuQ==", + "dependencies": { + "@types/http-errors": "*", + "@types/mime": "*", + "@types/node": "*" + } + }, + "node_modules/lodash.once": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/lodash.once/-/lodash.once-4.1.1.tgz", + "integrity": "sha512-Sb487aTOCr9drQVL8pIxOzVhafOjZN9UU54hiN8PU3uAiSV7lx1yYNpbNmex2PK6dSJoNTSJUUswT651yww3Mg==" + }, "node_modules/postgres-bytea": { "version": "1.0.0", "resolved": "http://10.194.9.122/postgres-bytea/-/postgres-bytea-1.0.0.tgz", @@ -343,27 +549,57 @@ "node": ">= 0.8" } }, + "node_modules/@types/node": { + "version": "20.11.25", + "resolved": "https://registry.npmjs.org/@types/node/-/node-20.11.25.tgz", + "integrity": "sha512-TBHyJxk2b7HceLVGFcpAUjsa5zIdsPWlR6XHfyGzd0SFu+/NFgQgMAl96MSDZgQDvJAvV6BKsFOrt6zIL09JDw==", + "dependencies": { + "undici-types": "~5.26.4" + } + }, "node_modules/pause": { "version": "0.0.1", "resolved": "http://10.194.9.122/pause/-/pause-0.0.1.tgz", "integrity": "sha1-HUCLP9t2kjuVQ9lvtMnf1TXZy10=" }, + "node_modules/@advana/logger": { + "version": "1.0.1", + "resolved": "http://10.194.9.122/@advana%2flogger/-/logger-1.0.1.tgz", + "integrity": "sha512-ryl8NhAd86tzIz/DS2ubAZAQ++j1739nq8qd6N+uNYpAt8BftZ2lyVtf4mpDh2LrBc928g/cCTFbHZpAoiNAUw==", + "dependencies": { + "pino": "8.16.1", + "pino-http": "8.3.1" + }, + "engines": { + "node": ">=18" + } + }, "node_modules/@redis/graph": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/@redis/graph/-/graph-1.1.0.tgz", - "integrity": "sha512-16yZWngxyXPd+MJxeSr0dqh2AIOi8j9yXKcKCwVaKDbH3HTuETpDVPcLujhFYVPtYrngSco31BUcSa9TH31Gqg==", + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/@redis/graph/-/graph-1.1.1.tgz", + "integrity": "sha512-FEMTcTHZozZciLRl6GiiIB4zGm5z5F3F6a6FZCyrfxdKOhFlGkiAqlexWMBzCi4DcRoyiOsuLfW+cjlGWyExOw==", "peerDependencies": { "@redis/client": "^1.0.0" } }, "node_modules/cookie": { - "version": "0.4.2", - "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.4.2.tgz", - "integrity": "sha512-aSWTXFzaKWkvHO1Ny/s+ePFpvKsPnjc551iI41v3ny/ow6tBG5Vd+FuqGNhh1LxOmVzOlGUriIlOaokOvhaStA==", + "version": "0.6.0", + "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.6.0.tgz", + "integrity": "sha512-U71cyTamuh1CRNCfpGY6to28lxvNwPG4Guz/EVjgf3Jmzv0vlDp1atT9eS5dDjMYHucpHbWns6Lwf3BKz6svdw==", "engines": { "node": ">= 0.6" } }, + "node_modules/lodash.includes": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/lodash.includes/-/lodash.includes-4.3.0.tgz", + "integrity": "sha512-W3Bx6mdkRTGtlJISOvVD/lbqjTlPPUDTMnlXZFnVwi9NKJ6tiAk6LVdlhZMm17VZisqhKcgzpO5Wz91PCt5b0w==" + }, + "node_modules/@types/qs": { + "version": "6.9.12", + "resolved": "https://registry.npmjs.org/@types/qs/-/qs-6.9.12.tgz", + "integrity": "sha512-bZcOkJ6uWrL0Qb2NAWKa7TBU+mJHPzhx9jjLL1KHF+XpzEcR7EXHvjbHlGtR/IsP1vyPrehuS6XqkmaePy//mg==" + }, "node_modules/backoff": { "version": "2.5.0", "resolved": "https://registry.npmjs.org/backoff/-/backoff-2.5.0.tgz", @@ -383,6 +619,11 @@ "node": ">= 0.4.0" } }, + "node_modules/punycode": { + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/punycode/-/punycode-1.4.1.tgz", + "integrity": "sha512-jmYNElW7yvO7TV33CjSmvSiE2yco3bV2czu/OzDKdMNVZQWfxCblURLhf+47syQRBntjfLdd/H0egrzIG+oaFQ==" + }, "node_modules/extsprintf": { "version": "1.4.1", "resolved": "https://registry.npmjs.org/extsprintf/-/extsprintf-1.4.1.tgz", @@ -391,6 +632,19 @@ "node >=0.6.0" ] }, + "node_modules/@node-saml/node-saml/node_modules/xml-encryption": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/xml-encryption/-/xml-encryption-3.0.2.tgz", + "integrity": "sha512-VxYXPvsWB01/aqVLd6ZMPWZ+qaj0aIdF+cStrVJMcFj3iymwZeI0ABzB3VqMYv48DkSpRhnrXqTUkR34j+UDyg==", + "dependencies": { + "@xmldom/xmldom": "^0.8.5", + "escape-html": "^1.0.3", + "xpath": "0.0.32" + }, + "engines": { + "node": ">=12" + } + }, "node_modules/buffer-equal-constant-time": { "version": "1.0.1", "resolved": "http://10.194.9.122/buffer-equal-constant-time/-/buffer-equal-constant-time-1.0.1.tgz", @@ -406,42 +660,56 @@ "safe-buffer": "^5.0.1" } }, + "node_modules/ieee754": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/ieee754/-/ieee754-1.2.1.tgz", + "integrity": "sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ] + }, "node_modules/@redis/time-series": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/@redis/time-series/-/time-series-1.0.4.tgz", - "integrity": "sha512-ThUIgo2U/g7cCuZavucQTQzA9g9JbDDY2f64u3AbAoz/8vE2lt2U37LamDUVChhaDA3IRT9R6VvJwqnUfTJzng==", + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/@redis/time-series/-/time-series-1.0.5.tgz", + "integrity": "sha512-IFjIgTusQym2B5IZJG3XKr5llka7ey84fw/NOYqESP5WUfQs9zz1ww/9+qoz4ka/S6KcGBodzlCeZ5UImKbscg==", "peerDependencies": { "@redis/client": "^1.0.0" } }, + "node_modules/lodash.isnumber": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/lodash.isnumber/-/lodash.isnumber-3.0.3.tgz", + "integrity": "sha512-QYqzpfwO3/CWf3XP+Z+tkQsfaLL/EnUlXWVkIk5FUPc4sBdTehEqZONuyRt2P67PXAk+NXmTBcc97zw9t1FQrw==" + }, "node_modules/core-util-is": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.2.tgz", "integrity": "sha512-3lqz5YjWTYnW6dlDa5TLaTCcShfar1e40rmcJVwCBJC6mWlFuj0eCHIElmG1g5kyuJ/GD+8Wn4FFCcz4gJPfaQ==" }, - "node_modules/xml-crypto": { - "version": "2.1.3", - "resolved": "http://10.194.9.122/xml-crypto/-/xml-crypto-2.1.3.tgz", - "integrity": "sha512-MpXZwnn9JK0mNPZ5mnFIbNnQa+8lMGK4NtnX2FlJMfMWR60sJdFO9X72yO6ji068pxixzk53O7x0/iSKh6IhyQ==", - "license": "MIT", - "dependencies": { - "@xmldom/xmldom": "^0.7.0", - "xpath": "0.0.32" - }, - "engines": { - "node": ">=0.4.0" - } - }, "node_modules/ms": { "version": "2.0.0", "resolved": "http://10.194.9.122/ms/-/ms-2.0.0.tgz", "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=", "license": "MIT" }, - "node_modules/lodash": { - "version": "4.17.21", - "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz", - "integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==" + "node_modules/get-caller-file": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-2.0.5.tgz", + "integrity": "sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==", + "engines": { + "node": "6.* || 8.* || >= 10.*" + } }, "node_modules/jsonwebtoken/node_modules/ms": { "version": "2.1.3", @@ -463,23 +731,10 @@ "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz", "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==" }, - "node_modules/xml-encryption": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/xml-encryption/-/xml-encryption-2.0.0.tgz", - "integrity": "sha512-4Av83DdvAgUQQMfi/w8G01aJshbEZP9ewjmZMpS9t3H+OCZBDvyK4GJPnHGfWiXlArnPbYvR58JB9qF2x9Ds+Q==", - "dependencies": { - "@xmldom/xmldom": "^0.7.0", - "escape-html": "^1.0.3", - "xpath": "0.0.32" - }, - "engines": { - "node": ">=12" - } - }, "node_modules/passport": { - "version": "0.6.0", - "resolved": "https://registry.npmjs.org/passport/-/passport-0.6.0.tgz", - "integrity": "sha512-0fe+p3ZnrWRW74fe8+SvCyf4a3Pb2/h7gFkQ8yTJpAO50gDzlfjZUZTO1k5Eg9kUct22OxHLqDZoKUWRHOh9ug==", + "version": "0.7.0", + "resolved": "https://registry.npmjs.org/passport/-/passport-0.7.0.tgz", + "integrity": "sha512-cPLl+qZpSc+ireUvt+IzqbED1cHHkDoVYMo30jbJIdOOjQ1MQYZBPiNvmi8UM6lJuOpTPXJGZQk0DtC4y61MYQ==", "dependencies": { "passport-strategy": "1.x.x", "pause": "0.0.1", @@ -502,11 +757,25 @@ "node": ">=0.6.0" } }, + "node_modules/@types/range-parser": { + "version": "1.2.7", + "resolved": "https://registry.npmjs.org/@types/range-parser/-/range-parser-1.2.7.tgz", + "integrity": "sha512-hKormJbkJqzQGhziax5PItDUTMAM9uE2XXQmM37dyd4hVM+5aVl7oVxMVUiVQn2oCQFN/LKCZdvSM0pFRqbSmQ==" + }, "node_modules/escape-html": { "version": "1.0.3", "resolved": "https://registry.npmjs.org/escape-html/-/escape-html-1.0.3.tgz", "integrity": "sha512-NiSupZ4OeuGwr68lGIeym/ksIZMJodUGOSCZ/FSnTxcrekbvqrgdUxlJOMpijaKZVjAJrWrGs/6Jy8OMuyj9ow==" }, + "node_modules/@types/body-parser": { + "version": "1.19.5", + "resolved": "https://registry.npmjs.org/@types/body-parser/-/body-parser-1.19.5.tgz", + "integrity": "sha512-fB3Zu92ucau0iQ0JMCFQE7b/dv8Ot07NI3KaZIkIUNXq82k4eBAqUaneXfleGY9JWskeS9y+u0nXMyspcuQrCg==", + "dependencies": { + "@types/connect": "*", + "@types/node": "*" + } + }, "node_modules/lru-cache": { "version": "6.0.0", "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz", @@ -518,6 +787,22 @@ "node": ">=10" } }, + "node_modules/abort-controller": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/abort-controller/-/abort-controller-3.0.0.tgz", + "integrity": "sha512-h8lQ8tacZYnR3vNQTgibj+tODHI5/+l06Au2Pcriv/Gmet0eaj4TwWH41sO9wnHDiQsEj19q0drzdWdeAHtweg==", + "dependencies": { + "event-target-shim": "^5.0.0" + }, + "engines": { + "node": ">=6.5" + } + }, + "node_modules/@types/ms": { + "version": "0.7.34", + "resolved": "https://registry.npmjs.org/@types/ms/-/ms-0.7.34.tgz", + "integrity": "sha512-nG96G3Wp6acyAgJqGasjODb+acrI7KltPiRxzHPXnP3NgI28bpQDRv53olbqGXbfcgF5aiiHmO3xpwEpS5Ld9g==" + }, "node_modules/merge-options": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/merge-options/-/merge-options-2.0.0.tgz", @@ -539,6 +824,14 @@ "safe-buffer": "^5.0.1" } }, + "node_modules/thread-stream": { + "version": "2.4.1", + "resolved": "https://registry.npmjs.org/thread-stream/-/thread-stream-2.4.1.tgz", + "integrity": "sha512-d/Ex2iWd1whipbT681JmTINKw0ZwOUBZm7+Gjs64DHuX34mmw8vJL2bFAaNacaW72zYiTJxSHi5abUuOi5nsfg==", + "dependencies": { + "real-require": "^0.2.0" + } + }, "node_modules/is-plain-obj": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/is-plain-obj/-/is-plain-obj-2.1.0.tgz", @@ -586,6 +879,11 @@ "express-session": ">=1" } }, + "node_modules/pino-std-serializers": { + "version": "6.2.2", + "resolved": "https://registry.npmjs.org/pino-std-serializers/-/pino-std-serializers-6.2.2.tgz", + "integrity": "sha512-cHjPPsE+vhj/tnhCy/wiMh3M3z3h/j15zHQX+S9GkTBgqJuTuJzYJ4gUyACLhDaJ7kk9ba9iRDmbH2tJU03OiA==" + }, "node_modules/pg-cloudflare": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/pg-cloudflare/-/pg-cloudflare-1.1.1.tgz", @@ -593,41 +891,104 @@ "optional": true }, "node_modules/@redis/search": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/@redis/search/-/search-1.1.3.tgz", - "integrity": "sha512-4Dg1JjvCevdiCBTZqjhKkGoC5/BcB7k9j99kdMnaXFXg8x4eyOIVg9487CMv7/BUVkFLZCaIh8ead9mU15DNng==", + "version": "1.1.6", + "resolved": "https://registry.npmjs.org/@redis/search/-/search-1.1.6.tgz", + "integrity": "sha512-mZXCxbTYKBQ3M2lZnEddwEAks0Kc7nauire8q20oA0oA/LoA+E/b5Y5KZn232ztPb1FkIGqo12vh3Lf+Vw5iTw==", "peerDependencies": { "@redis/client": "^1.0.0" } }, "node_modules/redis": { - "version": "4.6.7", - "resolved": "https://registry.npmjs.org/redis/-/redis-4.6.7.tgz", - "integrity": "sha512-KrkuNJNpCwRm5vFJh0tteMxW8SaUzkm5fBH7eL5hd/D0fAkzvapxbfGPP/r+4JAXdQuX7nebsBkBqA2RHB7Usw==", + "version": "4.6.12", + "resolved": "https://registry.npmjs.org/redis/-/redis-4.6.12.tgz", + "integrity": "sha512-41Xuuko6P4uH4VPe5nE3BqXHB7a9lkFL0J29AlxKaIfD6eWO8VO/5PDF9ad2oS+mswMsfFxaM5DlE3tnXT+P8Q==", "dependencies": { "@redis/bloom": "1.2.0", - "@redis/client": "1.5.8", - "@redis/graph": "1.1.0", - "@redis/json": "1.0.4", - "@redis/search": "1.1.3", - "@redis/time-series": "1.0.4" + "@redis/client": "1.5.13", + "@redis/graph": "1.1.1", + "@redis/json": "1.0.6", + "@redis/search": "1.1.6", + "@redis/time-series": "1.0.5" + } + }, + "node_modules/@types/xml-crypto": { + "version": "1.4.6", + "resolved": "https://registry.npmjs.org/@types/xml-crypto/-/xml-crypto-1.4.6.tgz", + "integrity": "sha512-A6jEW2FxLZo1CXsRWnZHUX2wzR3uDju2Bozt6rDbSmU/W8gkilaVbwFEVN0/NhnUdMVzwYobWtM6bU1QJJFb7Q==", + "dependencies": { + "@types/node": "*", + "xpath": "0.0.27" + } + }, + "node_modules/lodash.isinteger": { + "version": "4.0.4", + "resolved": "https://registry.npmjs.org/lodash.isinteger/-/lodash.isinteger-4.0.4.tgz", + "integrity": "sha512-DBwtEWN2caHQ9/imiNeEA5ys1JoRtRfY3d7V9wkqtbycnAmTvRRmbHKDV4a0EYc678/dia0jrte4tjYwVBaZUA==" + }, + "node_modules/readable-stream": { + "version": "4.5.2", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-4.5.2.tgz", + "integrity": "sha512-yjavECdqeZ3GLXNgRXgeQEdz9fvDDkNKyHnbHRFtOr7/LcfgBcmct7t/ET+HaCTqfh06OzoAxrkN/IfjJBVe+g==", + "dependencies": { + "abort-controller": "^3.0.0", + "buffer": "^6.0.3", + "events": "^3.3.0", + "process": "^0.11.10", + "string_decoder": "^1.3.0" + }, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" } }, "node_modules/cookie-signature": { - "version": "1.0.6", - "resolved": "http://10.194.9.122/cookie-signature/-/cookie-signature-1.0.6.tgz", - "integrity": "sha1-4wOogrNCzD7oylE6eZmXNNqzriw=", - "license": "MIT" + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/cookie-signature/-/cookie-signature-1.0.7.tgz", + "integrity": "sha512-NXdYc3dLr47pBkpUCHtKSwIOQXLVn8dZEuywboCOJY/osA0wFSLlSawr3KN8qXJEyX66FcONTH8EIlVuK0yyFA==" + }, + "node_modules/pino": { + "version": "8.16.1", + "resolved": "https://registry.npmjs.org/pino/-/pino-8.16.1.tgz", + "integrity": "sha512-3bKsVhBmgPjGV9pyn4fO/8RtoVDR8ssW1ev819FsRXlRNgW8gR/9Kx+gCK4UPWd4JjrRDLWpzd/pb1AyWm3MGA==", + "dependencies": { + "atomic-sleep": "^1.0.0", + "fast-redact": "^3.1.1", + "on-exit-leak-free": "^2.1.0", + "pino-abstract-transport": "v1.1.0", + "pino-std-serializers": "^6.0.0", + "process-warning": "^2.0.0", + "quick-format-unescaped": "^4.0.3", + "real-require": "^0.2.0", + "safe-stable-stringify": "^2.3.1", + "sonic-boom": "^3.7.0", + "thread-stream": "^2.0.0" + }, + "bin": { + "pino": "bin.js" + } + }, + "node_modules/@types/xml-crypto/node_modules/xpath": { + "version": "0.0.27", + "resolved": "https://registry.npmjs.org/xpath/-/xpath-0.0.27.tgz", + "integrity": "sha512-fg03WRxtkCV6ohClePNAECYsmpKKTv5L8y/X3Dn1hQrec3POx2jHZ/0P2qQ6HvsrU1BmeqXcof3NGGueG6LxwQ==", + "engines": { + "node": ">=0.6.0" + } }, "node_modules/jsonwebtoken": { - "version": "9.0.0", - "resolved": "https://registry.npmjs.org/jsonwebtoken/-/jsonwebtoken-9.0.0.tgz", - "integrity": "sha512-tuGfYXxkQGDPnLJ7SibiQgVgeDgfbPq2k2ICcbgqW8WxWLBAxKQM/ZCu/IT8SOSwmaYl4dpTFCW5xZv7YbbWUw==", + "version": "9.0.2", + "resolved": "https://registry.npmjs.org/jsonwebtoken/-/jsonwebtoken-9.0.2.tgz", + "integrity": "sha512-PRp66vJ865SSqOlgqS8hujT5U4AOgMfhrwYIuIhfKaoSCZcirrmASQr8CX7cUg+RMih+hgznrjp99o+W4pJLHQ==", "dependencies": { "jws": "^3.2.2", - "lodash": "^4.17.21", + "lodash.includes": "^4.3.0", + "lodash.isboolean": "^3.0.3", + "lodash.isinteger": "^4.0.4", + "lodash.isnumber": "^3.0.3", + "lodash.isplainobject": "^4.0.6", + "lodash.isstring": "^4.0.1", + "lodash.once": "^4.0.0", "ms": "^2.1.1", - "semver": "^7.3.8" + "semver": "^7.5.4" }, "engines": { "node": ">=12", @@ -649,9 +1010,9 @@ "license": "MIT" }, "node_modules/@redis/client": { - "version": "1.5.8", - "resolved": "https://registry.npmjs.org/@redis/client/-/client-1.5.8.tgz", - "integrity": "sha512-xzElwHIO6rBAqzPeVnCzgvrnBEcFL1P0w8P65VNLRkdVW8rOE58f52hdj0BDgmsdOm4f1EoXPZtH4Fh7M/qUpw==", + "version": "1.5.13", + "resolved": "https://registry.npmjs.org/@redis/client/-/client-1.5.13.tgz", + "integrity": "sha512-epkUM9D0Sdmt93/8Ozk43PNjLi36RZzG+d/T1Gdu5AI8jvghonTeLYV69WVWdilvFo+PYxbP0TZ0saMvr6nscQ==", "dependencies": { "cluster-key-slot": "1.1.2", "generic-pool": "3.9.0", @@ -661,6 +1022,14 @@ "node": ">=14" } }, + "node_modules/events": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/events/-/events-3.3.0.tgz", + "integrity": "sha512-mQw+2fkQbALzQ7V0MY0IqdnXNOeTtP4r0lN9z7AAawCXgqea7bDii20AYrIBrFd/Hx0M2Ocz6S111CaFkUcb0Q==", + "engines": { + "node": ">=0.8.x" + } + }, "node_modules/vasync/node_modules/verror": { "version": "1.10.0", "resolved": "https://registry.npmjs.org/verror/-/verror-1.10.0.tgz", @@ -674,21 +1043,39 @@ "extsprintf": "^1.2.0" } }, - "node_modules/passport-saml/node_modules/debug": { - "version": "4.3.3", - "resolved": "http://10.194.9.122/debug/-/debug-4.3.3.tgz", - "integrity": "sha512-/zxw5+vh1Tfv+4Qn7a5nsbcJKPaSvCDhojn6FEl9vupwK2VCSDtEiEtqr8DFtzYFOdz63LBkxec7DYuc2jon6Q==", - "license": "MIT", + "node_modules/process": { + "version": "0.11.10", + "resolved": "https://registry.npmjs.org/process/-/process-0.11.10.tgz", + "integrity": "sha512-cdGef/drWFoydD1JsMzuFf8100nZl+GT+yacc2bEced5f9Rjk4z+WtFUTBu9PhOi9j/jfmBPu0mMEY4wIdAF8A==", + "engines": { + "node": ">= 0.6.0" + } + }, + "node_modules/@advana/redis-client": { + "version": "4.3.0", + "resolved": "http://10.194.9.122/@advana%2fredis-client/-/redis-client-4.3.0.tgz", + "integrity": "sha512-nXIgfTdgL6YhEBymcF/B90nhed3odq+ZE72ryn6auUdOZrf1h6MS0SbC/iCdwwSmv021CYQ/lSXROsw1zNfroQ==", "dependencies": { - "ms": "2.1.2" + "@advana/logger": "1.0.1", + "redis": "4.6.12" + }, + "bin": { + "redis-ready": "dist/cjs/bin/redisReady.js" }, "engines": { - "node": ">=6.0" + "node": ">=18" + } + }, + "node_modules/@node-saml/node-saml/node_modules/xml-crypto": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/xml-crypto/-/xml-crypto-3.2.0.tgz", + "integrity": "sha512-qVurBUOQrmvlgmZqIVBqmb06TD2a/PpEUfFPgD7BuBfjmoH4zgkqaWSIJrnymlCvM2GGt9x+XtJFA+ttoAufqg==", + "dependencies": { + "@xmldom/xmldom": "^0.8.8", + "xpath": "0.0.32" }, - "peerDependenciesMeta": { - "supports-color": { - "optional": true - } + "engines": { + "node": ">=4.0.0" } }, "node_modules/postgres-date": { @@ -700,6 +1087,41 @@ "node": ">=0.10.0" } }, + "node_modules/@types/connect": { + "version": "3.4.38", + "resolved": "https://registry.npmjs.org/@types/connect/-/connect-3.4.38.tgz", + "integrity": "sha512-K6uROf1LD88uDQqJCktA4yzL1YYAK6NgfsI0v/mTgyPKWsX1CnJ0XPSDhViejru1GcRkLWb8RlzFYJRqGUbaug==", + "dependencies": { + "@types/node": "*" + } + }, + "node_modules/@types/passport-strategy": { + "version": "0.2.38", + "resolved": "https://registry.npmjs.org/@types/passport-strategy/-/passport-strategy-0.2.38.tgz", + "integrity": "sha512-GC6eMqqojOooq993Tmnmp7AUTbbQSgilyvpCYQjT+H6JfG/g6RGc7nXEniZlp0zyKJ0WUdOiZWLBZft9Yug1uA==", + "dependencies": { + "@types/express": "*", + "@types/passport": "*" + } + }, + "node_modules/activedirectory2/node_modules/ldapjs": { + "version": "2.3.3", + "resolved": "https://registry.npmjs.org/ldapjs/-/ldapjs-2.3.3.tgz", + "integrity": "sha512-75QiiLJV/PQqtpH+HGls44dXweviFwQ6SiIK27EqzKQ5jU/7UFrl2E5nLdQ3IYRBzJ/AVFJI66u0MZ0uofKYwg==", + "dependencies": { + "abstract-logging": "^2.0.0", + "asn1": "^0.2.4", + "assert-plus": "^1.0.0", + "backoff": "^2.5.0", + "ldap-filter": "^0.3.3", + "once": "^1.4.0", + "vasync": "^2.2.0", + "verror": "^1.8.1" + }, + "engines": { + "node": ">=10.13.0" + } + }, "node_modules/on-headers": { "version": "1.0.2", "resolved": "http://10.194.9.122/on-headers/-/on-headers-1.0.2.tgz", @@ -717,13 +1139,21 @@ "node": ">= 4" } }, + "node_modules/event-target-shim": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/event-target-shim/-/event-target-shim-5.0.1.tgz", + "integrity": "sha512-i/2XbnSz/uxRCU6+NdVJgKWDTM427+MqYbkQzD321DuCQJUqOuJKIA0IM2+W2xtYHdKOmZ4dR6fExsd4SXL+WQ==", + "engines": { + "node": ">=6" + } + }, "node_modules/express-session": { - "version": "1.17.3", - "resolved": "https://registry.npmjs.org/express-session/-/express-session-1.17.3.tgz", - "integrity": "sha512-4+otWXlShYlG1Ma+2Jnn+xgKUZTMJ5QD3YvfilX3AcocOAbIkVylSWEklzALe/+Pu4qV6TYBj5GwOBFfdKqLBw==", + "version": "1.18.0", + "resolved": "https://registry.npmjs.org/express-session/-/express-session-1.18.0.tgz", + "integrity": "sha512-m93QLWr0ju+rOwApSsyso838LQwgfs44QtOP/WBiwtAgPIo/SAh1a5c6nn2BR6mFNZehTpqKDESzP+fRHVbxwQ==", "dependencies": { - "cookie": "0.4.2", - "cookie-signature": "1.0.6", + "cookie": "0.6.0", + "cookie-signature": "1.0.7", "debug": "2.6.9", "depd": "~2.0.0", "on-headers": "~1.0.2", @@ -735,6 +1165,27 @@ "node": ">= 0.8.0" } }, + "node_modules/process-warning": { + "version": "2.3.2", + "resolved": "https://registry.npmjs.org/process-warning/-/process-warning-2.3.2.tgz", + "integrity": "sha512-n9wh8tvBe5sFmsqlg+XQhaQLumwpqoAUruLwjCopgTmUBjJ/fjtBsJzKleCaIGBOMXYEhp1YfKl4d7rJ5ZKJGA==" + }, + "node_modules/@node-saml/passport-saml": { + "version": "4.0.4", + "resolved": "https://registry.npmjs.org/@node-saml/passport-saml/-/passport-saml-4.0.4.tgz", + "integrity": "sha512-xFw3gw0yo+K1mzlkW15NeBF7cVpRHN/4vpjmBKzov5YFImCWh/G0LcTZ8krH3yk2/eRPc3Or8LRPudVJBjmYaw==", + "dependencies": { + "@node-saml/node-saml": "^4.0.4", + "@types/express": "^4.17.14", + "@types/passport": "^1.0.11", + "@types/passport-strategy": "^0.2.35", + "passport": "^0.6.0", + "passport-strategy": "^1.0.0" + }, + "engines": { + "node": ">= 14" + } + }, "node_modules/yallist": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", @@ -764,6 +1215,31 @@ } ] }, + "node_modules/@node-saml/node-saml/node_modules/@xmldom/xmldom": { + "version": "0.8.10", + "resolved": "https://registry.npmjs.org/@xmldom/xmldom/-/xmldom-0.8.10.tgz", + "integrity": "sha512-2WALfTl4xo2SkGCYRt6rDTFfk9R1czmBvUQy12gK2KuRKIpWEhcbbzy8EZXtz/jkRqHX8bFEc6FC1HjX4TUWYw==", + "engines": { + "node": ">=10.0.0" + } + }, + "node_modules/@node-saml/passport-saml/node_modules/passport": { + "version": "0.6.0", + "resolved": "https://registry.npmjs.org/passport/-/passport-0.6.0.tgz", + "integrity": "sha512-0fe+p3ZnrWRW74fe8+SvCyf4a3Pb2/h7gFkQ8yTJpAO50gDzlfjZUZTO1k5Eg9kUct22OxHLqDZoKUWRHOh9ug==", + "dependencies": { + "passport-strategy": "1.x.x", + "pause": "0.0.1", + "utils-merge": "^1.0.1" + }, + "engines": { + "node": ">= 0.4.0" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/jaredhanson" + } + }, "node_modules/xml2js": { "version": "0.5.0", "resolved": "https://registry.npmjs.org/xml2js/-/xml2js-0.5.0.tgz", @@ -797,6 +1273,14 @@ "node": ">=0.8" } }, + "node_modules/@types/passport": { + "version": "1.0.16", + "resolved": "https://registry.npmjs.org/@types/passport/-/passport-1.0.16.tgz", + "integrity": "sha512-FD0qD5hbPWQzaM0wHUnJ/T0BBCJBxCeemtnCwc/ThhTg3x9jfrAcRUmj5Dopza+MfFS9acTe3wk7rcVnRIp/0A==", + "dependencies": { + "@types/express": "*" + } + }, "node_modules/buffer-writer": { "version": "2.0.0", "resolved": "http://10.194.9.122/buffer-writer/-/buffer-writer-2.0.0.tgz", @@ -806,13 +1290,10 @@ "node": ">=4" } }, - "node_modules/@xmldom/xmldom": { - "version": "0.7.13", - "resolved": "https://registry.npmjs.org/@xmldom/xmldom/-/xmldom-0.7.13.tgz", - "integrity": "sha512-lm2GW5PkosIzccsaZIz7tp8cPADSIlIHWDFTR1N0SzfinhhYgeIQjFMz4rYzanCScr3DqQLeomUDArp6MWKm+g==", - "engines": { - "node": ">=10.0.0" - } + "node_modules/undici-types": { + "version": "5.26.5", + "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-5.26.5.tgz", + "integrity": "sha512-JlCMO+ehdEIKqlFxk6IfVoAUVmgz7cU7zD/h9XZ0qzeosSHmUJVOzSQvvYSYWXkFXC+IfLKSIffhv0sVZup6pA==" }, "node_modules/pg-protocol": { "version": "1.6.0", @@ -832,22 +1313,159 @@ "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", "integrity": "sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==" }, + "node_modules/@types/xml-encryption": { + "version": "1.2.4", + "resolved": "https://registry.npmjs.org/@types/xml-encryption/-/xml-encryption-1.2.4.tgz", + "integrity": "sha512-I69K/WW1Dv7j6O3jh13z0X8sLWJRXbu5xnHDl9yHzUNDUBtUoBY058eb5s+x/WG6yZC1h8aKdI2EoyEPjyEh+Q==", + "dependencies": { + "@types/node": "*" + } + }, + "node_modules/@types/send": { + "version": "0.17.4", + "resolved": "https://registry.npmjs.org/@types/send/-/send-0.17.4.tgz", + "integrity": "sha512-x2EM6TJOybec7c52BX0ZspPodMsQUd5L6PRwOunVyVUhXiBSKf3AezDL8Dgvgt5o0UfKNfuA0eMLr2wLT4AiBA==", + "dependencies": { + "@types/mime": "^1", + "@types/node": "*" + } + }, + "node_modules/sonic-boom": { + "version": "3.8.0", + "resolved": "https://registry.npmjs.org/sonic-boom/-/sonic-boom-3.8.0.tgz", + "integrity": "sha512-ybz6OYOUjoQQCQ/i4LU8kaToD8ACtYP+Cj5qd2AO36bwbdewxWJ3ArmJ2cr6AvxlL2o0PqnCcPGUgkILbfkaCA==", + "dependencies": { + "atomic-sleep": "^1.0.0" + } + }, "node_modules/abstract-logging": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/abstract-logging/-/abstract-logging-2.0.1.tgz", "integrity": "sha512-2BjRTZxTPvheOvGbBslFSYOUkr+SjPtOnrLP33f+VIWLzezQpZcqVg7ja3L4dBXmzzgwT+a029jRx5PCi3JuiA==" + }, + "node_modules/pino-http": { + "version": "8.3.1", + "resolved": "https://registry.npmjs.org/pino-http/-/pino-http-8.3.1.tgz", + "integrity": "sha512-wqQMH2H+Di4ur5gaCYvWOMYhGmmmygHsgJduKr2HASSoegNsxfxiCDGxYYV8muOB8jKDHPoBXKGp03af+JESqg==", + "dependencies": { + "fast-url-parser": "^1.1.3", + "get-caller-file": "^2.0.5", + "pino": "^8.0.0", + "pino-std-serializers": "^6.0.0", + "process-warning": "^2.0.0" + } } }, "dependencies": { + "@advana/logger": { + "version": "1.0.1", + "resolved": "http://10.194.9.122/@advana%2flogger/-/logger-1.0.1.tgz", + "integrity": "sha512-ryl8NhAd86tzIz/DS2ubAZAQ++j1739nq8qd6N+uNYpAt8BftZ2lyVtf4mpDh2LrBc928g/cCTFbHZpAoiNAUw==", + "requires": { + "pino": "8.16.1", + "pino-http": "8.3.1" + } + }, + "@advana/redis-client": { + "version": "4.3.0", + "resolved": "http://10.194.9.122/@advana%2fredis-client/-/redis-client-4.3.0.tgz", + "integrity": "sha512-nXIgfTdgL6YhEBymcF/B90nhed3odq+ZE72ryn6auUdOZrf1h6MS0SbC/iCdwwSmv021CYQ/lSXROsw1zNfroQ==", + "requires": { + "@advana/logger": "1.0.1", + "redis": "4.6.12" + } + }, + "@node-saml/node-saml": { + "version": "4.0.5", + "resolved": "https://registry.npmjs.org/@node-saml/node-saml/-/node-saml-4.0.5.tgz", + "integrity": "sha512-J5DglElbY1tjOuaR1NPtjOXkXY5bpUhDoKVoeucYN98A3w4fwgjIOPqIGcb6cQsqFq2zZ6vTCeKn5C/hvefSaw==", + "requires": { + "@types/debug": "^4.1.7", + "@types/passport": "^1.0.11", + "@types/xml-crypto": "^1.4.2", + "@types/xml-encryption": "^1.2.1", + "@types/xml2js": "^0.4.11", + "@xmldom/xmldom": "^0.8.6", + "debug": "^4.3.4", + "xml-crypto": "^3.0.1", + "xml-encryption": "^3.0.2", + "xml2js": "0.5.0", + "xmlbuilder": "^15.1.1" + }, + "dependencies": { + "@xmldom/xmldom": { + "version": "0.8.10", + "resolved": "https://registry.npmjs.org/@xmldom/xmldom/-/xmldom-0.8.10.tgz", + "integrity": "sha512-2WALfTl4xo2SkGCYRt6rDTFfk9R1czmBvUQy12gK2KuRKIpWEhcbbzy8EZXtz/jkRqHX8bFEc6FC1HjX4TUWYw==" + }, + "debug": { + "version": "4.3.4", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz", + "integrity": "sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==", + "requires": { + "ms": "2.1.2" + } + }, + "ms": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", + "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==" + }, + "xml-crypto": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/xml-crypto/-/xml-crypto-3.2.0.tgz", + "integrity": "sha512-qVurBUOQrmvlgmZqIVBqmb06TD2a/PpEUfFPgD7BuBfjmoH4zgkqaWSIJrnymlCvM2GGt9x+XtJFA+ttoAufqg==", + "requires": { + "@xmldom/xmldom": "^0.8.8", + "xpath": "0.0.32" + } + }, + "xml-encryption": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/xml-encryption/-/xml-encryption-3.0.2.tgz", + "integrity": "sha512-VxYXPvsWB01/aqVLd6ZMPWZ+qaj0aIdF+cStrVJMcFj3iymwZeI0ABzB3VqMYv48DkSpRhnrXqTUkR34j+UDyg==", + "requires": { + "@xmldom/xmldom": "^0.8.5", + "escape-html": "^1.0.3", + "xpath": "0.0.32" + } + } + } + }, + "@node-saml/passport-saml": { + "version": "4.0.4", + "resolved": "https://registry.npmjs.org/@node-saml/passport-saml/-/passport-saml-4.0.4.tgz", + "integrity": "sha512-xFw3gw0yo+K1mzlkW15NeBF7cVpRHN/4vpjmBKzov5YFImCWh/G0LcTZ8krH3yk2/eRPc3Or8LRPudVJBjmYaw==", + "requires": { + "@node-saml/node-saml": "^4.0.4", + "@types/express": "^4.17.14", + "@types/passport": "^1.0.11", + "@types/passport-strategy": "^0.2.35", + "passport": "^0.6.0", + "passport-strategy": "^1.0.0" + }, + "dependencies": { + "passport": { + "version": "0.6.0", + "resolved": "https://registry.npmjs.org/passport/-/passport-0.6.0.tgz", + "integrity": "sha512-0fe+p3ZnrWRW74fe8+SvCyf4a3Pb2/h7gFkQ8yTJpAO50gDzlfjZUZTO1k5Eg9kUct22OxHLqDZoKUWRHOh9ug==", + "requires": { + "passport-strategy": "1.x.x", + "pause": "0.0.1", + "utils-merge": "^1.0.1" + } + } + } + }, "@redis/bloom": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/@redis/bloom/-/bloom-1.2.0.tgz", "integrity": "sha512-HG2DFjYKbpNmVXsa0keLHp/3leGJz1mjh09f2RLGGLQZzSHpkmZWuwJbAvo3QcRY8p80m5+ZdXZdYOSBLlp7Cg==" }, "@redis/client": { - "version": "1.5.8", - "resolved": "https://registry.npmjs.org/@redis/client/-/client-1.5.8.tgz", - "integrity": "sha512-xzElwHIO6rBAqzPeVnCzgvrnBEcFL1P0w8P65VNLRkdVW8rOE58f52hdj0BDgmsdOm4f1EoXPZtH4Fh7M/qUpw==", + "version": "1.5.13", + "resolved": "https://registry.npmjs.org/@redis/client/-/client-1.5.13.tgz", + "integrity": "sha512-epkUM9D0Sdmt93/8Ozk43PNjLi36RZzG+d/T1Gdu5AI8jvghonTeLYV69WVWdilvFo+PYxbP0TZ0saMvr6nscQ==", "requires": { "cluster-key-slot": "1.1.2", "generic-pool": "3.9.0", @@ -855,29 +1473,180 @@ } }, "@redis/graph": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/@redis/graph/-/graph-1.1.0.tgz", - "integrity": "sha512-16yZWngxyXPd+MJxeSr0dqh2AIOi8j9yXKcKCwVaKDbH3HTuETpDVPcLujhFYVPtYrngSco31BUcSa9TH31Gqg==" + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/@redis/graph/-/graph-1.1.1.tgz", + "integrity": "sha512-FEMTcTHZozZciLRl6GiiIB4zGm5z5F3F6a6FZCyrfxdKOhFlGkiAqlexWMBzCi4DcRoyiOsuLfW+cjlGWyExOw==" }, "@redis/json": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/@redis/json/-/json-1.0.4.tgz", - "integrity": "sha512-LUZE2Gdrhg0Rx7AN+cZkb1e6HjoSKaeeW8rYnt89Tly13GBI5eP4CwDVr+MY8BAYfCg4/N15OUrtLoona9uSgw==" + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/@redis/json/-/json-1.0.6.tgz", + "integrity": "sha512-rcZO3bfQbm2zPRpqo82XbW8zg4G/w4W3tI7X8Mqleq9goQjAGLL7q/1n1ZX4dXEAmORVZ4s1+uKLaUOg7LrUhw==" }, "@redis/search": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/@redis/search/-/search-1.1.3.tgz", - "integrity": "sha512-4Dg1JjvCevdiCBTZqjhKkGoC5/BcB7k9j99kdMnaXFXg8x4eyOIVg9487CMv7/BUVkFLZCaIh8ead9mU15DNng==" + "version": "1.1.6", + "resolved": "https://registry.npmjs.org/@redis/search/-/search-1.1.6.tgz", + "integrity": "sha512-mZXCxbTYKBQ3M2lZnEddwEAks0Kc7nauire8q20oA0oA/LoA+E/b5Y5KZn232ztPb1FkIGqo12vh3Lf+Vw5iTw==" }, "@redis/time-series": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/@redis/time-series/-/time-series-1.0.4.tgz", - "integrity": "sha512-ThUIgo2U/g7cCuZavucQTQzA9g9JbDDY2f64u3AbAoz/8vE2lt2U37LamDUVChhaDA3IRT9R6VvJwqnUfTJzng==" + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/@redis/time-series/-/time-series-1.0.5.tgz", + "integrity": "sha512-IFjIgTusQym2B5IZJG3XKr5llka7ey84fw/NOYqESP5WUfQs9zz1ww/9+qoz4ka/S6KcGBodzlCeZ5UImKbscg==" + }, + "@types/body-parser": { + "version": "1.19.5", + "resolved": "https://registry.npmjs.org/@types/body-parser/-/body-parser-1.19.5.tgz", + "integrity": "sha512-fB3Zu92ucau0iQ0JMCFQE7b/dv8Ot07NI3KaZIkIUNXq82k4eBAqUaneXfleGY9JWskeS9y+u0nXMyspcuQrCg==", + "requires": { + "@types/connect": "*", + "@types/node": "*" + } + }, + "@types/connect": { + "version": "3.4.38", + "resolved": "https://registry.npmjs.org/@types/connect/-/connect-3.4.38.tgz", + "integrity": "sha512-K6uROf1LD88uDQqJCktA4yzL1YYAK6NgfsI0v/mTgyPKWsX1CnJ0XPSDhViejru1GcRkLWb8RlzFYJRqGUbaug==", + "requires": { + "@types/node": "*" + } + }, + "@types/debug": { + "version": "4.1.12", + "resolved": "https://registry.npmjs.org/@types/debug/-/debug-4.1.12.tgz", + "integrity": "sha512-vIChWdVG3LG1SMxEvI/AK+FWJthlrqlTu7fbrlywTkkaONwk/UAGaULXRlf8vkzFBLVm0zkMdCquhL5aOjhXPQ==", + "requires": { + "@types/ms": "*" + } + }, + "@types/express": { + "version": "4.17.21", + "resolved": "https://registry.npmjs.org/@types/express/-/express-4.17.21.tgz", + "integrity": "sha512-ejlPM315qwLpaQlQDTjPdsUFSc6ZsP4AN6AlWnogPjQ7CVi7PYF3YVz+CY3jE2pwYf7E/7HlDAN0rV2GxTG0HQ==", + "requires": { + "@types/body-parser": "*", + "@types/express-serve-static-core": "^4.17.33", + "@types/qs": "*", + "@types/serve-static": "*" + } + }, + "@types/express-serve-static-core": { + "version": "4.17.43", + "resolved": "https://registry.npmjs.org/@types/express-serve-static-core/-/express-serve-static-core-4.17.43.tgz", + "integrity": "sha512-oaYtiBirUOPQGSWNGPWnzyAFJ0BP3cwvN4oWZQY+zUBwpVIGsKUkpBpSztp74drYcjavs7SKFZ4DX1V2QeN8rg==", + "requires": { + "@types/node": "*", + "@types/qs": "*", + "@types/range-parser": "*", + "@types/send": "*" + } + }, + "@types/http-errors": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/@types/http-errors/-/http-errors-2.0.4.tgz", + "integrity": "sha512-D0CFMMtydbJAegzOyHjtiKPLlvnm3iTZyZRSZoLq2mRhDdmLfIWOCYPfQJ4cu2erKghU++QvjcUjp/5h7hESpA==" + }, + "@types/mime": { + "version": "1.3.5", + "resolved": "https://registry.npmjs.org/@types/mime/-/mime-1.3.5.tgz", + "integrity": "sha512-/pyBZWSLD2n0dcHE3hq8s8ZvcETHtEuF+3E7XVt0Ig2nvsVQXdghHVcEkIWjy9A0wKfTn97a/PSDYohKIlnP/w==" + }, + "@types/ms": { + "version": "0.7.34", + "resolved": "https://registry.npmjs.org/@types/ms/-/ms-0.7.34.tgz", + "integrity": "sha512-nG96G3Wp6acyAgJqGasjODb+acrI7KltPiRxzHPXnP3NgI28bpQDRv53olbqGXbfcgF5aiiHmO3xpwEpS5Ld9g==" + }, + "@types/node": { + "version": "20.11.25", + "resolved": "https://registry.npmjs.org/@types/node/-/node-20.11.25.tgz", + "integrity": "sha512-TBHyJxk2b7HceLVGFcpAUjsa5zIdsPWlR6XHfyGzd0SFu+/NFgQgMAl96MSDZgQDvJAvV6BKsFOrt6zIL09JDw==", + "requires": { + "undici-types": "~5.26.4" + } + }, + "@types/passport": { + "version": "1.0.16", + "resolved": "https://registry.npmjs.org/@types/passport/-/passport-1.0.16.tgz", + "integrity": "sha512-FD0qD5hbPWQzaM0wHUnJ/T0BBCJBxCeemtnCwc/ThhTg3x9jfrAcRUmj5Dopza+MfFS9acTe3wk7rcVnRIp/0A==", + "requires": { + "@types/express": "*" + } + }, + "@types/passport-strategy": { + "version": "0.2.38", + "resolved": "https://registry.npmjs.org/@types/passport-strategy/-/passport-strategy-0.2.38.tgz", + "integrity": "sha512-GC6eMqqojOooq993Tmnmp7AUTbbQSgilyvpCYQjT+H6JfG/g6RGc7nXEniZlp0zyKJ0WUdOiZWLBZft9Yug1uA==", + "requires": { + "@types/express": "*", + "@types/passport": "*" + } + }, + "@types/qs": { + "version": "6.9.12", + "resolved": "https://registry.npmjs.org/@types/qs/-/qs-6.9.12.tgz", + "integrity": "sha512-bZcOkJ6uWrL0Qb2NAWKa7TBU+mJHPzhx9jjLL1KHF+XpzEcR7EXHvjbHlGtR/IsP1vyPrehuS6XqkmaePy//mg==" + }, + "@types/range-parser": { + "version": "1.2.7", + "resolved": "https://registry.npmjs.org/@types/range-parser/-/range-parser-1.2.7.tgz", + "integrity": "sha512-hKormJbkJqzQGhziax5PItDUTMAM9uE2XXQmM37dyd4hVM+5aVl7oVxMVUiVQn2oCQFN/LKCZdvSM0pFRqbSmQ==" + }, + "@types/send": { + "version": "0.17.4", + "resolved": "https://registry.npmjs.org/@types/send/-/send-0.17.4.tgz", + "integrity": "sha512-x2EM6TJOybec7c52BX0ZspPodMsQUd5L6PRwOunVyVUhXiBSKf3AezDL8Dgvgt5o0UfKNfuA0eMLr2wLT4AiBA==", + "requires": { + "@types/mime": "^1", + "@types/node": "*" + } + }, + "@types/serve-static": { + "version": "1.15.5", + "resolved": "https://registry.npmjs.org/@types/serve-static/-/serve-static-1.15.5.tgz", + "integrity": "sha512-PDRk21MnK70hja/YF8AHfC7yIsiQHn1rcXx7ijCFBX/k+XQJhQT/gw3xekXKJvx+5SXaMMS8oqQy09Mzvz2TuQ==", + "requires": { + "@types/http-errors": "*", + "@types/mime": "*", + "@types/node": "*" + } }, - "@xmldom/xmldom": { - "version": "0.7.13", - "resolved": "https://registry.npmjs.org/@xmldom/xmldom/-/xmldom-0.7.13.tgz", - "integrity": "sha512-lm2GW5PkosIzccsaZIz7tp8cPADSIlIHWDFTR1N0SzfinhhYgeIQjFMz4rYzanCScr3DqQLeomUDArp6MWKm+g==" + "@types/xml-crypto": { + "version": "1.4.6", + "resolved": "https://registry.npmjs.org/@types/xml-crypto/-/xml-crypto-1.4.6.tgz", + "integrity": "sha512-A6jEW2FxLZo1CXsRWnZHUX2wzR3uDju2Bozt6rDbSmU/W8gkilaVbwFEVN0/NhnUdMVzwYobWtM6bU1QJJFb7Q==", + "requires": { + "@types/node": "*", + "xpath": "0.0.27" + }, + "dependencies": { + "xpath": { + "version": "0.0.27", + "resolved": "https://registry.npmjs.org/xpath/-/xpath-0.0.27.tgz", + "integrity": "sha512-fg03WRxtkCV6ohClePNAECYsmpKKTv5L8y/X3Dn1hQrec3POx2jHZ/0P2qQ6HvsrU1BmeqXcof3NGGueG6LxwQ==" + } + } + }, + "@types/xml-encryption": { + "version": "1.2.4", + "resolved": "https://registry.npmjs.org/@types/xml-encryption/-/xml-encryption-1.2.4.tgz", + "integrity": "sha512-I69K/WW1Dv7j6O3jh13z0X8sLWJRXbu5xnHDl9yHzUNDUBtUoBY058eb5s+x/WG6yZC1h8aKdI2EoyEPjyEh+Q==", + "requires": { + "@types/node": "*" + } + }, + "@types/xml2js": { + "version": "0.4.14", + "resolved": "https://registry.npmjs.org/@types/xml2js/-/xml2js-0.4.14.tgz", + "integrity": "sha512-4YnrRemBShWRO2QjvUin8ESA41rH+9nQGLUGZV/1IDhi3SL9OhdpNC/MrulTWuptXKwhx/aDxE7toV0f/ypIXQ==", + "requires": { + "@types/node": "*" + } + }, + "abort-controller": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/abort-controller/-/abort-controller-3.0.0.tgz", + "integrity": "sha512-h8lQ8tacZYnR3vNQTgibj+tODHI5/+l06Au2Pcriv/Gmet0eaj4TwWH41sO9wnHDiQsEj19q0drzdWdeAHtweg==", + "requires": { + "event-target-shim": "^5.0.0" + } }, "abstract-logging": { "version": "2.0.1", @@ -885,14 +1654,31 @@ "integrity": "sha512-2BjRTZxTPvheOvGbBslFSYOUkr+SjPtOnrLP33f+VIWLzezQpZcqVg7ja3L4dBXmzzgwT+a029jRx5PCi3JuiA==" }, "activedirectory2": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/activedirectory2/-/activedirectory2-2.1.0.tgz", - "integrity": "sha512-HaccG+/mf5NpHL1mAcLzXed4+gGlO6l7mkBi8vNIo6sTJvLoJjHgvJg12F4cy5CNcRqvPS48++s5tfdSiafn4Q==", + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/activedirectory2/-/activedirectory2-2.2.0.tgz", + "integrity": "sha512-uGbw74xttFG6hgocU8T1a0oDofLsyTp44BPTn42JN5C2QlyO5kRl2E7ZoUdfpFzV+yxhaQTKI+8QqRB5HONYvA==", "requires": { "abstract-logging": "^2.0.0", "async": "^3.1.0", - "ldapjs": "^2.1.0", + "ldapjs": "^2.3.3", "merge-options": "^2.0.0" + }, + "dependencies": { + "ldapjs": { + "version": "2.3.3", + "resolved": "https://registry.npmjs.org/ldapjs/-/ldapjs-2.3.3.tgz", + "integrity": "sha512-75QiiLJV/PQqtpH+HGls44dXweviFwQ6SiIK27EqzKQ5jU/7UFrl2E5nLdQ3IYRBzJ/AVFJI66u0MZ0uofKYwg==", + "requires": { + "abstract-logging": "^2.0.0", + "asn1": "^0.2.4", + "assert-plus": "^1.0.0", + "backoff": "^2.5.0", + "ldap-filter": "^0.3.3", + "once": "^1.4.0", + "vasync": "^2.2.0", + "verror": "^1.8.1" + } + } } }, "asn1": { @@ -913,6 +1699,11 @@ "resolved": "https://registry.npmjs.org/async/-/async-3.2.4.tgz", "integrity": "sha512-iAB+JbDEGXhyIUavoDl9WP/Jj106Kz9DEn1DPgYw5ruDn0e3Wgi3sKFm55sASdGBNOQB8F59d9qQ7deqrHA8wQ==" }, + "atomic-sleep": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/atomic-sleep/-/atomic-sleep-1.0.0.tgz", + "integrity": "sha512-kNOjDqAh7px0XWNI+4QbzoiR/nTkHAWNud2uvnJquD1/x5a7EQZMJT0AczqK0Qn67oY/TTQ1LbUKajZpp3I9tQ==" + }, "backoff": { "version": "2.5.0", "resolved": "https://registry.npmjs.org/backoff/-/backoff-2.5.0.tgz", @@ -921,6 +1712,20 @@ "precond": "0.2" } }, + "base64-js": { + "version": "1.5.1", + "resolved": "https://registry.npmjs.org/base64-js/-/base64-js-1.5.1.tgz", + "integrity": "sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA==" + }, + "buffer": { + "version": "6.0.3", + "resolved": "https://registry.npmjs.org/buffer/-/buffer-6.0.3.tgz", + "integrity": "sha512-FTiCpNxtwiZZHEZbcbTIcZjERVICn9yq/pDFkTl95/AxzD1naBctN7YO68riM/gLSDY7sdrMby8hofADYuuqOA==", + "requires": { + "base64-js": "^1.3.1", + "ieee754": "^1.2.1" + } + }, "buffer-equal-constant-time": { "version": "1.0.1", "resolved": "http://10.194.9.122/buffer-equal-constant-time/-/buffer-equal-constant-time-1.0.1.tgz", @@ -942,14 +1747,14 @@ "integrity": "sha512-UaqO1EirWjON2ENsyau7N5lbkrdYBpS6mYlXSeff/OYXsd6EGZ+SXSmNPoljL2PSua8fgjAEaldSA73PMZQ9Eg==" }, "cookie": { - "version": "0.4.2", - "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.4.2.tgz", - "integrity": "sha512-aSWTXFzaKWkvHO1Ny/s+ePFpvKsPnjc551iI41v3ny/ow6tBG5Vd+FuqGNhh1LxOmVzOlGUriIlOaokOvhaStA==" + "version": "0.6.0", + "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.6.0.tgz", + "integrity": "sha512-U71cyTamuh1CRNCfpGY6to28lxvNwPG4Guz/EVjgf3Jmzv0vlDp1atT9eS5dDjMYHucpHbWns6Lwf3BKz6svdw==" }, "cookie-signature": { - "version": "1.0.6", - "resolved": "http://10.194.9.122/cookie-signature/-/cookie-signature-1.0.6.tgz", - "integrity": "sha1-4wOogrNCzD7oylE6eZmXNNqzriw=" + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/cookie-signature/-/cookie-signature-1.0.7.tgz", + "integrity": "sha512-NXdYc3dLr47pBkpUCHtKSwIOQXLVn8dZEuywboCOJY/osA0wFSLlSawr3KN8qXJEyX66FcONTH8EIlVuK0yyFA==" }, "core-util-is": { "version": "1.0.2", @@ -987,13 +1792,23 @@ "resolved": "https://registry.npmjs.org/escape-html/-/escape-html-1.0.3.tgz", "integrity": "sha512-NiSupZ4OeuGwr68lGIeym/ksIZMJodUGOSCZ/FSnTxcrekbvqrgdUxlJOMpijaKZVjAJrWrGs/6Jy8OMuyj9ow==" }, + "event-target-shim": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/event-target-shim/-/event-target-shim-5.0.1.tgz", + "integrity": "sha512-i/2XbnSz/uxRCU6+NdVJgKWDTM427+MqYbkQzD321DuCQJUqOuJKIA0IM2+W2xtYHdKOmZ4dR6fExsd4SXL+WQ==" + }, + "events": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/events/-/events-3.3.0.tgz", + "integrity": "sha512-mQw+2fkQbALzQ7V0MY0IqdnXNOeTtP4r0lN9z7AAawCXgqea7bDii20AYrIBrFd/Hx0M2Ocz6S111CaFkUcb0Q==" + }, "express-session": { - "version": "1.17.3", - "resolved": "https://registry.npmjs.org/express-session/-/express-session-1.17.3.tgz", - "integrity": "sha512-4+otWXlShYlG1Ma+2Jnn+xgKUZTMJ5QD3YvfilX3AcocOAbIkVylSWEklzALe/+Pu4qV6TYBj5GwOBFfdKqLBw==", + "version": "1.18.0", + "resolved": "https://registry.npmjs.org/express-session/-/express-session-1.18.0.tgz", + "integrity": "sha512-m93QLWr0ju+rOwApSsyso838LQwgfs44QtOP/WBiwtAgPIo/SAh1a5c6nn2BR6mFNZehTpqKDESzP+fRHVbxwQ==", "requires": { - "cookie": "0.4.2", - "cookie-signature": "1.0.6", + "cookie": "0.6.0", + "cookie-signature": "1.0.7", "debug": "2.6.9", "depd": "~2.0.0", "on-headers": "~1.0.2", @@ -1007,25 +1822,54 @@ "resolved": "https://registry.npmjs.org/extsprintf/-/extsprintf-1.4.1.tgz", "integrity": "sha512-Wrk35e8ydCKDj/ArClo1VrPVmN8zph5V4AtHwIuHhvMXsKf73UT3BOD+azBIW+3wOJ4FhEH7zyaJCFvChjYvMA==" }, + "fast-redact": { + "version": "3.4.0", + "resolved": "https://registry.npmjs.org/fast-redact/-/fast-redact-3.4.0.tgz", + "integrity": "sha512-2gwPvyna0zwBdxKnng1suu/dTL5s8XEy2ZqH8mwDUwJdDkV8w5kp+JV26mupdK68HmPMbm6yjW9m7/Ys/BHEHg==" + }, + "fast-url-parser": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/fast-url-parser/-/fast-url-parser-1.1.3.tgz", + "integrity": "sha512-5jOCVXADYNuRkKFzNJ0dCCewsZiYo0dz8QNYljkOpFC6r2U4OBmKtvm/Tsuh4w1YYdDqDb31a8TVhBJ2OJKdqQ==", + "requires": { + "punycode": "^1.3.2" + } + }, "generic-pool": { "version": "3.9.0", "resolved": "https://registry.npmjs.org/generic-pool/-/generic-pool-3.9.0.tgz", "integrity": "sha512-hymDOu5B53XvN4QT9dBmZxPX4CWhBPPLguTZ9MMFeFa/Kg0xWVfylOVNlJji/E7yTZWFd/q9GO5TxDLq156D7g==" }, + "get-caller-file": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-2.0.5.tgz", + "integrity": "sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==" + }, + "ieee754": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/ieee754/-/ieee754-1.2.1.tgz", + "integrity": "sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA==" + }, "is-plain-obj": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/is-plain-obj/-/is-plain-obj-2.1.0.tgz", "integrity": "sha512-YWnfyRwxL/+SsrWYfOpUtz5b3YD+nyfkHvjbcanzk8zgyO4ASD67uVMRt8k5bM4lLMDnXfriRhOpemw+NfT1eA==" }, "jsonwebtoken": { - "version": "9.0.0", - "resolved": "https://registry.npmjs.org/jsonwebtoken/-/jsonwebtoken-9.0.0.tgz", - "integrity": "sha512-tuGfYXxkQGDPnLJ7SibiQgVgeDgfbPq2k2ICcbgqW8WxWLBAxKQM/ZCu/IT8SOSwmaYl4dpTFCW5xZv7YbbWUw==", + "version": "9.0.2", + "resolved": "https://registry.npmjs.org/jsonwebtoken/-/jsonwebtoken-9.0.2.tgz", + "integrity": "sha512-PRp66vJ865SSqOlgqS8hujT5U4AOgMfhrwYIuIhfKaoSCZcirrmASQr8CX7cUg+RMih+hgznrjp99o+W4pJLHQ==", "requires": { "jws": "^3.2.2", - "lodash": "^4.17.21", + "lodash.includes": "^4.3.0", + "lodash.isboolean": "^3.0.3", + "lodash.isinteger": "^4.0.4", + "lodash.isnumber": "^3.0.3", + "lodash.isplainobject": "^4.0.6", + "lodash.isstring": "^4.0.1", + "lodash.once": "^4.0.0", "ms": "^2.1.1", - "semver": "^7.3.8" + "semver": "^7.5.4" }, "dependencies": { "ms": { @@ -1077,10 +1921,40 @@ "verror": "^1.8.1" } }, - "lodash": { - "version": "4.17.21", - "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz", - "integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==" + "lodash.includes": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/lodash.includes/-/lodash.includes-4.3.0.tgz", + "integrity": "sha512-W3Bx6mdkRTGtlJISOvVD/lbqjTlPPUDTMnlXZFnVwi9NKJ6tiAk6LVdlhZMm17VZisqhKcgzpO5Wz91PCt5b0w==" + }, + "lodash.isboolean": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/lodash.isboolean/-/lodash.isboolean-3.0.3.tgz", + "integrity": "sha512-Bz5mupy2SVbPHURB98VAcw+aHh4vRV5IPNhILUCsOzRmsTmSQ17jIuqopAentWoehktxGd9e/hbIXq980/1QJg==" + }, + "lodash.isinteger": { + "version": "4.0.4", + "resolved": "https://registry.npmjs.org/lodash.isinteger/-/lodash.isinteger-4.0.4.tgz", + "integrity": "sha512-DBwtEWN2caHQ9/imiNeEA5ys1JoRtRfY3d7V9wkqtbycnAmTvRRmbHKDV4a0EYc678/dia0jrte4tjYwVBaZUA==" + }, + "lodash.isnumber": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/lodash.isnumber/-/lodash.isnumber-3.0.3.tgz", + "integrity": "sha512-QYqzpfwO3/CWf3XP+Z+tkQsfaLL/EnUlXWVkIk5FUPc4sBdTehEqZONuyRt2P67PXAk+NXmTBcc97zw9t1FQrw==" + }, + "lodash.isplainobject": { + "version": "4.0.6", + "resolved": "https://registry.npmjs.org/lodash.isplainobject/-/lodash.isplainobject-4.0.6.tgz", + "integrity": "sha512-oSXzaWypCMHkPC3NvBEaPHf0KsA5mvPrOPgQWDsbg8n7orZ290M0BmC/jgRZ4vcJ6DTAhjrsSYgdsW/F+MFOBA==" + }, + "lodash.isstring": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/lodash.isstring/-/lodash.isstring-4.0.1.tgz", + "integrity": "sha512-0wJxfxH1wgO3GrbuP+dTTk7op+6L41QCXbGINEmD+ny/G/eCqGzxyCsh7159S+mgDDcoarnBw6PC1PS5+wUGgw==" + }, + "lodash.once": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/lodash.once/-/lodash.once-4.1.1.tgz", + "integrity": "sha512-Sb487aTOCr9drQVL8pIxOzVhafOjZN9UU54hiN8PU3uAiSV7lx1yYNpbNmex2PK6dSJoNTSJUUswT651yww3Mg==" }, "lru-cache": { "version": "6.0.0", @@ -1103,6 +1977,11 @@ "resolved": "http://10.194.9.122/ms/-/ms-2.0.0.tgz", "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=" }, + "on-exit-leak-free": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/on-exit-leak-free/-/on-exit-leak-free-2.1.2.tgz", + "integrity": "sha512-0eJJY6hXLGf1udHwfNftBqH+g73EU4B504nZeKpz1sYRKafAghwxEJunB2O7rDZkL4PGfsMVnTXZ2EjibbqcsA==" + }, "on-headers": { "version": "1.0.2", "resolved": "http://10.194.9.122/on-headers/-/on-headers-1.0.2.tgz", @@ -1127,44 +2006,15 @@ "integrity": "sha512-CiyeOxFT/JZyN5m0z9PfXw4SCBJ6Sygz1Dpl0wqjlhDEGGBP1GnsUVEL0p63hoG1fcj3fHynXi9NYO4nWOL+qQ==" }, "passport": { - "version": "0.6.0", - "resolved": "https://registry.npmjs.org/passport/-/passport-0.6.0.tgz", - "integrity": "sha512-0fe+p3ZnrWRW74fe8+SvCyf4a3Pb2/h7gFkQ8yTJpAO50gDzlfjZUZTO1k5Eg9kUct22OxHLqDZoKUWRHOh9ug==", + "version": "0.7.0", + "resolved": "https://registry.npmjs.org/passport/-/passport-0.7.0.tgz", + "integrity": "sha512-cPLl+qZpSc+ireUvt+IzqbED1cHHkDoVYMo30jbJIdOOjQ1MQYZBPiNvmi8UM6lJuOpTPXJGZQk0DtC4y61MYQ==", "requires": { "passport-strategy": "1.x.x", "pause": "0.0.1", "utils-merge": "^1.0.1" } }, - "passport-saml": { - "version": "3.2.4", - "resolved": "https://registry.npmjs.org/passport-saml/-/passport-saml-3.2.4.tgz", - "integrity": "sha512-JSgkFXeaexLNQh1RrOvJAgjLnZzH/S3HbX/mWAk+i7aulnjqUe7WKnPl1NPnJWqP7Dqsv0I2Xm6KIFHkftk0HA==", - "requires": { - "@xmldom/xmldom": "^0.7.6", - "debug": "^4.3.2", - "passport-strategy": "^1.0.0", - "xml-crypto": "^2.1.3", - "xml-encryption": "^2.0.0", - "xml2js": "0.5.0", - "xmlbuilder": "^15.1.1" - }, - "dependencies": { - "debug": { - "version": "4.3.3", - "resolved": "http://10.194.9.122/debug/-/debug-4.3.3.tgz", - "integrity": "sha512-/zxw5+vh1Tfv+4Qn7a5nsbcJKPaSvCDhojn6FEl9vupwK2VCSDtEiEtqr8DFtzYFOdz63LBkxec7DYuc2jon6Q==", - "requires": { - "ms": "2.1.2" - } - }, - "ms": { - "version": "2.1.2", - "resolved": "http://10.194.9.122/ms/-/ms-2.1.2.tgz", - "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==" - } - } - }, "passport-strategy": { "version": "1.0.0", "resolved": "http://10.194.9.122/passport-strategy/-/passport-strategy-1.0.0.tgz", @@ -1176,15 +2026,15 @@ "integrity": "sha1-HUCLP9t2kjuVQ9lvtMnf1TXZy10=" }, "pg": { - "version": "8.11.0", - "resolved": "https://registry.npmjs.org/pg/-/pg-8.11.0.tgz", - "integrity": "sha512-meLUVPn2TWgJyLmy7el3fQQVwft4gU5NGyvV0XbD41iU9Jbg8lCH4zexhIkihDzVHJStlt6r088G6/fWeNjhXA==", + "version": "8.11.3", + "resolved": "https://registry.npmjs.org/pg/-/pg-8.11.3.tgz", + "integrity": "sha512-+9iuvG8QfaaUrrph+kpF24cXkH1YOOUeArRNYIxq1viYHZagBxrTno7cecY1Fa44tJeZvaoG+Djpkc3JwehN5g==", "requires": { "buffer-writer": "2.0.0", "packet-reader": "1.0.0", - "pg-cloudflare": "^1.1.0", - "pg-connection-string": "^2.6.0", - "pg-pool": "^3.6.0", + "pg-cloudflare": "^1.1.1", + "pg-connection-string": "^2.6.2", + "pg-pool": "^3.6.1", "pg-protocol": "^1.6.0", "pg-types": "^2.1.0", "pgpass": "1.x" @@ -1236,6 +2086,50 @@ "split2": "^4.1.0" } }, + "pino": { + "version": "8.16.1", + "resolved": "https://registry.npmjs.org/pino/-/pino-8.16.1.tgz", + "integrity": "sha512-3bKsVhBmgPjGV9pyn4fO/8RtoVDR8ssW1ev819FsRXlRNgW8gR/9Kx+gCK4UPWd4JjrRDLWpzd/pb1AyWm3MGA==", + "requires": { + "atomic-sleep": "^1.0.0", + "fast-redact": "^3.1.1", + "on-exit-leak-free": "^2.1.0", + "pino-abstract-transport": "v1.1.0", + "pino-std-serializers": "^6.0.0", + "process-warning": "^2.0.0", + "quick-format-unescaped": "^4.0.3", + "real-require": "^0.2.0", + "safe-stable-stringify": "^2.3.1", + "sonic-boom": "^3.7.0", + "thread-stream": "^2.0.0" + } + }, + "pino-abstract-transport": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/pino-abstract-transport/-/pino-abstract-transport-1.1.0.tgz", + "integrity": "sha512-lsleG3/2a/JIWUtf9Q5gUNErBqwIu1tUKTT3dUzaf5DySw9ra1wcqKjJjLX1VTY64Wk1eEOYsVGSaGfCK85ekA==", + "requires": { + "readable-stream": "^4.0.0", + "split2": "^4.0.0" + } + }, + "pino-http": { + "version": "8.3.1", + "resolved": "https://registry.npmjs.org/pino-http/-/pino-http-8.3.1.tgz", + "integrity": "sha512-wqQMH2H+Di4ur5gaCYvWOMYhGmmmygHsgJduKr2HASSoegNsxfxiCDGxYYV8muOB8jKDHPoBXKGp03af+JESqg==", + "requires": { + "fast-url-parser": "^1.1.3", + "get-caller-file": "^2.0.5", + "pino": "^8.0.0", + "pino-std-serializers": "^6.0.0", + "process-warning": "^2.0.0" + } + }, + "pino-std-serializers": { + "version": "6.2.2", + "resolved": "https://registry.npmjs.org/pino-std-serializers/-/pino-std-serializers-6.2.2.tgz", + "integrity": "sha512-cHjPPsE+vhj/tnhCy/wiMh3M3z3h/j15zHQX+S9GkTBgqJuTuJzYJ4gUyACLhDaJ7kk9ba9iRDmbH2tJU03OiA==" + }, "postgres-array": { "version": "2.0.0", "resolved": "http://10.194.9.122/postgres-array/-/postgres-array-2.0.0.tgz", @@ -1264,22 +2158,59 @@ "resolved": "https://registry.npmjs.org/precond/-/precond-0.2.3.tgz", "integrity": "sha512-QCYG84SgGyGzqJ/vlMsxeXd/pgL/I94ixdNFyh1PusWmTCyVfPJjZ1K1jvHtsbfnXQs2TSkEP2fR7QiMZAnKFQ==" }, + "process": { + "version": "0.11.10", + "resolved": "https://registry.npmjs.org/process/-/process-0.11.10.tgz", + "integrity": "sha512-cdGef/drWFoydD1JsMzuFf8100nZl+GT+yacc2bEced5f9Rjk4z+WtFUTBu9PhOi9j/jfmBPu0mMEY4wIdAF8A==" + }, + "process-warning": { + "version": "2.3.2", + "resolved": "https://registry.npmjs.org/process-warning/-/process-warning-2.3.2.tgz", + "integrity": "sha512-n9wh8tvBe5sFmsqlg+XQhaQLumwpqoAUruLwjCopgTmUBjJ/fjtBsJzKleCaIGBOMXYEhp1YfKl4d7rJ5ZKJGA==" + }, + "punycode": { + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/punycode/-/punycode-1.4.1.tgz", + "integrity": "sha512-jmYNElW7yvO7TV33CjSmvSiE2yco3bV2czu/OzDKdMNVZQWfxCblURLhf+47syQRBntjfLdd/H0egrzIG+oaFQ==" + }, + "quick-format-unescaped": { + "version": "4.0.4", + "resolved": "https://registry.npmjs.org/quick-format-unescaped/-/quick-format-unescaped-4.0.4.tgz", + "integrity": "sha512-tYC1Q1hgyRuHgloV/YXs2w15unPVh8qfu/qCTfhTYamaw7fyhumKa2yGpdSo87vY32rIclj+4fWYQXUMs9EHvg==" + }, "random-bytes": { "version": "1.0.0", "resolved": "http://10.194.9.122/random-bytes/-/random-bytes-1.0.0.tgz", "integrity": "sha1-T2ih3Arli9P7lYSMMDJNt11kNgs=" }, + "readable-stream": { + "version": "4.5.2", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-4.5.2.tgz", + "integrity": "sha512-yjavECdqeZ3GLXNgRXgeQEdz9fvDDkNKyHnbHRFtOr7/LcfgBcmct7t/ET+HaCTqfh06OzoAxrkN/IfjJBVe+g==", + "requires": { + "abort-controller": "^3.0.0", + "buffer": "^6.0.3", + "events": "^3.3.0", + "process": "^0.11.10", + "string_decoder": "^1.3.0" + } + }, + "real-require": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/real-require/-/real-require-0.2.0.tgz", + "integrity": "sha512-57frrGM/OCTLqLOAh0mhVA9VBMHd+9U7Zb2THMGdBUoZVOtGbJzjxsYGDJ3A9AYYCP4hn6y1TVbaOfzWtm5GFg==" + }, "redis": { - "version": "4.6.7", - "resolved": "https://registry.npmjs.org/redis/-/redis-4.6.7.tgz", - "integrity": "sha512-KrkuNJNpCwRm5vFJh0tteMxW8SaUzkm5fBH7eL5hd/D0fAkzvapxbfGPP/r+4JAXdQuX7nebsBkBqA2RHB7Usw==", + "version": "4.6.12", + "resolved": "https://registry.npmjs.org/redis/-/redis-4.6.12.tgz", + "integrity": "sha512-41Xuuko6P4uH4VPe5nE3BqXHB7a9lkFL0J29AlxKaIfD6eWO8VO/5PDF9ad2oS+mswMsfFxaM5DlE3tnXT+P8Q==", "requires": { "@redis/bloom": "1.2.0", - "@redis/client": "1.5.8", - "@redis/graph": "1.1.0", - "@redis/json": "1.0.4", - "@redis/search": "1.1.3", - "@redis/time-series": "1.0.4" + "@redis/client": "1.5.13", + "@redis/graph": "1.1.1", + "@redis/json": "1.0.6", + "@redis/search": "1.1.6", + "@redis/time-series": "1.0.5" } }, "safe-buffer": { @@ -1287,6 +2218,11 @@ "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz", "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==" }, + "safe-stable-stringify": { + "version": "2.4.3", + "resolved": "https://registry.npmjs.org/safe-stable-stringify/-/safe-stable-stringify-2.4.3.tgz", + "integrity": "sha512-e2bDA2WJT0wxseVd4lsDP4+3ONX6HpMXQa1ZhFQ7SU+GjvORCmShbCMltrtIDfkYhVHrOcPtj+KhmDBdPdZD1g==" + }, "safer-buffer": { "version": "2.1.2", "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz", @@ -1310,6 +2246,14 @@ "lru-cache": "^6.0.0" } }, + "sonic-boom": { + "version": "3.8.0", + "resolved": "https://registry.npmjs.org/sonic-boom/-/sonic-boom-3.8.0.tgz", + "integrity": "sha512-ybz6OYOUjoQQCQ/i4LU8kaToD8ACtYP+Cj5qd2AO36bwbdewxWJ3ArmJ2cr6AvxlL2o0PqnCcPGUgkILbfkaCA==", + "requires": { + "atomic-sleep": "^1.0.0" + } + }, "split2": { "version": "4.1.0", "resolved": "http://10.194.9.122/split2/-/split2-4.1.0.tgz", @@ -1320,6 +2264,22 @@ "resolved": "http://10.194.9.122/ssh-key-decrypt/-/ssh-key-decrypt-0.1.2.tgz", "integrity": "sha1-8e3lsMezI7AA6TgF3+VPHwUBDtk=" }, + "string_decoder": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.3.0.tgz", + "integrity": "sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA==", + "requires": { + "safe-buffer": "~5.2.0" + } + }, + "thread-stream": { + "version": "2.4.1", + "resolved": "https://registry.npmjs.org/thread-stream/-/thread-stream-2.4.1.tgz", + "integrity": "sha512-d/Ex2iWd1whipbT681JmTINKw0ZwOUBZm7+Gjs64DHuX34mmw8vJL2bFAaNacaW72zYiTJxSHi5abUuOi5nsfg==", + "requires": { + "real-require": "^0.2.0" + } + }, "uid-safe": { "version": "2.1.5", "resolved": "http://10.194.9.122/uid-safe/-/uid-safe-2.1.5.tgz", @@ -1328,6 +2288,11 @@ "random-bytes": "~1.0.0" } }, + "undici-types": { + "version": "5.26.5", + "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-5.26.5.tgz", + "integrity": "sha512-JlCMO+ehdEIKqlFxk6IfVoAUVmgz7cU7zD/h9XZ0qzeosSHmUJVOzSQvvYSYWXkFXC+IfLKSIffhv0sVZup6pA==" + }, "utils-merge": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/utils-merge/-/utils-merge-1.0.1.tgz", @@ -1368,25 +2333,6 @@ "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", "integrity": "sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==" }, - "xml-crypto": { - "version": "2.1.3", - "resolved": "http://10.194.9.122/xml-crypto/-/xml-crypto-2.1.3.tgz", - "integrity": "sha512-MpXZwnn9JK0mNPZ5mnFIbNnQa+8lMGK4NtnX2FlJMfMWR60sJdFO9X72yO6ji068pxixzk53O7x0/iSKh6IhyQ==", - "requires": { - "@xmldom/xmldom": "^0.7.0", - "xpath": "0.0.32" - } - }, - "xml-encryption": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/xml-encryption/-/xml-encryption-2.0.0.tgz", - "integrity": "sha512-4Av83DdvAgUQQMfi/w8G01aJshbEZP9ewjmZMpS9t3H+OCZBDvyK4GJPnHGfWiXlArnPbYvR58JB9qF2x9Ds+Q==", - "requires": { - "@xmldom/xmldom": "^0.7.0", - "escape-html": "^1.0.3", - "xpath": "0.0.32" - } - }, "xml2js": { "version": "0.5.0", "resolved": "https://registry.npmjs.org/xml2js/-/xml2js-0.5.0.tgz", diff --git a/package.json b/package.json index c73c67c..b78e3ee 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "@dod-advana/advana-api-auth", - "version": "2.5.0-beta.8.1", + "version": "2.6.0", "description": "contains middleware shared authentication code", "main": "index.js", "scripts": { @@ -19,21 +19,21 @@ "author": "Advana", "license": "ISC", "dependencies": { - "activedirectory2": "2.1.0", - "connect-redis": "7.1.0", - "crypto-js": "4.1.1", - "express-session": "1.17.3", - "jsonwebtoken": "9.0.0", - "ldapjs": "2.3.1", - "passport": "0.6.0", - "passport-saml": "3.2.4", - "pg": "8.11.0", - "redis": "4.6.7", - "secure-random": "1.1.2", - "ssh-key-decrypt": "0.1.2" + "@advana/logger": "1.0.1", + "@advana/redis-client": "4.3.0", + "@node-saml/passport-saml": "4.0.4", + "activedirectory2": "2.2.0", + "connect-redis": "7.1.0", + "crypto-js": "4.1.1", + "express-session": "1.18.0", + "jsonwebtoken": "9.0.2", + "ldapjs": "2.3.1", + "passport": "0.7.0", + "pg": "8.11.3", + "secure-random": "1.1.2", + "ssh-key-decrypt": "0.1.2" }, "peerDependencies": { - "@dod-advana/advana-logger": "0.2.1" }, "overrides": { "xml2js": "0.5.0" diff --git a/samlConfigs.js b/samlConfigs.js index ca3d630..e5dca27 100644 --- a/samlConfigs.js +++ b/samlConfigs.js @@ -11,11 +11,13 @@ module.exports = { cert: process.env.SAML_CERT, skipRequestCompression: true, signatureAlgorithm: 'sha512', - identifierFormat: 'urn:oasis:names:tc:SAML:2.0:nameid-format:persistent' + identifierFormat: 'urn:oasis:names:tc:SAML:2.0:nameid-format:persistent', + wantAuthnResponseSigned: true, + wantAssertionsSigned: false, }, SAML_CLAIM_ID: 'urn:oid:1.2.840.113556.1.4.656', SAML_CLAIM_EMAIL: 'urn:oid:0.9.2342.19200300.100.1.3', SAML_CLAIM_DISPLAYNAME: 'urn:oid:2.16.840.1.113730.3.1.241', SAML_CLAIM_PERMS: 'urn:oid:2.5.6.8', SAML_CLAIM_CN: 'urn:oid:2.5.4.3', -} \ No newline at end of file +}; diff --git a/samlStrategy.js b/samlStrategy.js index e24a3b1..e393105 100644 --- a/samlStrategy.js +++ b/samlStrategy.js @@ -1,22 +1,27 @@ -const SamlStrategy = require('passport-saml').Strategy; +const SamlStrategy = require('@node-saml/passport-saml').Strategy; const SAML_CONFIGS = require('./samlConfigs'); -module.exports = new SamlStrategy(SAML_CONFIGS.SAML_OBJECT, function (profile, done) { - const perms = new Set(); - profile.getAssertion().Assertion.AttributeStatement.forEach((attributeStatement) => { - attributeStatement['Attribute'].forEach((attr) => { - if (attr['$']['Name'] === SAML_CONFIGS.SAML_CLAIM_PERMS) { - attr['AttributeValue'].forEach((attrValue) => { - perms.add(attrValue['_']); - }); - } - }); - }); - return done(null, { - id: profile[SAML_CONFIGS.SAML_CLAIM_ID], - email: profile[SAML_CONFIGS.SAML_CLAIM_EMAIL], - displayName: profile[SAML_CONFIGS.SAML_CLAIM_DISPLAYNAME], - perms: Array.from(perms), - cn: profile[SAML_CONFIGS.SAML_CLAIM_CN], - }); -}) \ No newline at end of file +module.exports = new SamlStrategy(SAML_CONFIGS.SAML_OBJECT, function ( + profile, + done +) { + const perms = new Set(); + profile + .getAssertion() + .Assertion.AttributeStatement.forEach((attributeStatement) => { + attributeStatement['Attribute'].forEach((attr) => { + if (attr['$']['Name'] === SAML_CONFIGS.SAML_CLAIM_PERMS) { + attr['AttributeValue'].forEach((attrValue) => { + perms.add(attrValue['_']); + }); + } + }); + }); + return done(null, { + id: profile[SAML_CONFIGS.SAML_CLAIM_ID], + email: profile[SAML_CONFIGS.SAML_CLAIM_EMAIL], + displayName: profile[SAML_CONFIGS.SAML_CLAIM_DISPLAYNAME], + perms: Array.from(perms), + cn: profile[SAML_CONFIGS.SAML_CLAIM_CN], + }); +}); From 54e4ed16733d10d6f12c175c9ff8d8be86d87b38 Mon Sep 17 00:00:00 2001 From: melodiebutz Date: Fri, 8 Mar 2024 13:59:18 -0800 Subject: [PATCH 2/3] if authenticated user doesnt have cn parse it from headers/display name --- index.js | 23 +++++++++++++++++++++++ 1 file changed, 23 insertions(+) diff --git a/index.js b/index.js index a47b7f2..976a14c 100644 --- a/index.js +++ b/index.js @@ -259,9 +259,32 @@ const ensureAuthenticated = async (req, res, next) => { requestLogger.warn(loggingContext, 'not authenticated: user disabled'); return res.status(403).send(); } + if (!req?.user?.cn || !req?.user?.perms) { + // User has been authenticated in another app that does not have the CN SAML values + if (req.get('x-env-ssl_client_certificate')) { + req.user.cn = req.get('x-env-ssl_client_certificate'); + } else { + if (req.user.displayName && req.user.id) { + const first = req.user.displayName.split(' ')[0]; + const last = req.user.displayName.split(' ')[1]; + req.user.cn = `${first}.${last}.MI.${req.user.id}`; + } else if (req.user.id) { + req.user.cn = `FIRST.LAST.MI.${req.user.id}`; + } else { + req.user.cn = 'FIRST.LAST.MI.1234567890@mil'; + } + req.user = await fetchUserInfo(req); + } + req.session.user = req.user; + req.session.user.session_id = req.sessionID; + } requestLogger.trace(loggingContext, 'authenticated'); return next(); } else if (env.SSO_DISABLED) { + // get user cn from headers + if (!req?.user?.cn && req.get('x-env-ssl_client_certificate')) { + req.user.cn = req.get('x-env-ssl_client_certificate'); + } req.session.user = await fetchUserInfo(req); requestLogger.trace(loggingContext, 'authenticated'); return next(); From f4cce02b8ca600203126395e64f1aeecd96fb139 Mon Sep 17 00:00:00 2001 From: melodiebutz Date: Fri, 8 Mar 2024 14:02:15 -0800 Subject: [PATCH 3/3] update readme --- README.md | 115 +----------------------------------------------------- 1 file changed, 1 insertion(+), 114 deletions(-) diff --git a/README.md b/README.md index c2760d3..c790486 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,6 @@ ## Configuration -**NOTE: For working with encrypted TLS/SSL connections to RDS (PostgreSQL) and ElastiCache (Redis) in the CSN AWS dev and test environments, you will need to include the Amazon Root CA and RDS us-east-1 certificates in your CA bundle (`TLS_CERT_CA` or `TLS_CERT_CA_FILEPATH`): [csn-aws.pem](./csn-aws.pem)** +**NOTE: For working with encrypted TLS/SSL connections to RDS (PostgreSQL) and ElastiCache (Redis) in the AWS dev and test environments, you will need to include the Amazon Root CA and RDS certificates in your CA bundle (`TLS_CERT_CA` or `TLS_CERT_CA_FILEPATH`)** | Environment Variable | Default Value | Description | | --- | --- | --- | @@ -36,116 +36,3 @@ | `TLS_KEY` | | The private certificate for signing JWT tokens for client-side session management. | | `TLS_KEY_FILEPATH` | | The file path of the private certificate for signing JWT tokens, if `TLS_KEY` is not defined. | | `TLS_KEY_PASSPHRASE` | | The passphrase for decrypting the private certificate for signing JWT tokens. | - -## Usage - -### `getAllowedOriginMiddleware` middleware - -The `getAllowedOriginMiddleware` middleware configures your Express.js application to send [CORS](https://developer.mozilla.org/en-US/docs/Web/HTTP/CORS) response headers. The middleware is configured using the `APPROVED_API_CALLERS` environment variable. - -```javascript -import Express from 'express'; -import AAA from '@advana/api-auth'; - -const app = Express(); -app.use(AAA.getAllowedOriginMiddleware); -``` - -### `redisSession` middleware - -The `redisSession` middleware configures your Express.js application to use the centralized Redis-backed storage for authenticated user sessions. The middleware is configured using the `REDIS_URL` (and `REDIS_USER`, `REDIS_PASSWORD`, and `TLS_CERT_CA` or `TLS_CERT_CA_FILEPATH`), `SECURE_SESSION`, `COOKIE_DOMAIN`, `EXPRESS_SESSION_SECRET`, and `EXPRESS_SESSION_MAX_AGE` environment variables. - -```javascript -import Express from 'express'; -import AAA from '@advana/api-auth'; - -const app = Express(); -app.use(AAA.redisSession()); -``` - -### `setupSaml` - -The `setupSaml` function configures your Express.js application to use the Advana single sign-on (SSO) provider using SAML-based authentication. This is configured using the `SSO_DISABLED`, `APPROVED_API_CALLERS`, `PG_HOST`, `PG_USER`, `PG_PASSWORD`, `PG_UM_DB`, `AD_ENABLED`, `LDAP_URL`, `LDAP_CERT`, `LDAP_USERNAME`, `LDAP_PASSWORD`, `LDAP_USER_FOLDER_CN`, `SAML_ISSUER`, `SAML_CALLBACK_URL`, `SAML_ENTRYPOINT`, `SAML_LOGOUT_URL`, `SAML_LOGOUT_CALLBACK_URL`, and `SAML_CERT` environment variables. - -This function also registers the following routes in your application: - -* GET /login -* POST /login/callback -* GET /login/fail -* GET /logout -* POST /logout/callback -* GET /setUserSession - -```javascript -import Express from 'express'; -import AAA from '@advana/api-auth'; - -const app = Express(); -AAA.setupSaml(app); -``` - -### `ensureAuthenticated` middleware - -The `ensureAuthenticated` middleware configures your Express.js application to ensure the current user is authenticated via the centralized Redis-backed storage for authenticated user sessions. The middleware is configured using the `SSO_DISABLED` environment variable, but also requires the `redisSession` middleware to be configured and in use. - -```javascript -import Express from 'express'; -import AAA from '@advana/api-auth'; - -const app = Express(); -app.use(AAA.redisSession()); -app.use(AAA.ensureAuthenticated); -``` - -### `getToken` POST request handler - -The `getToken` request handler responds to HTTP POST requests to the configured route (usually /api/auth/token) in your Express.js application with a JSON Web Token (JWT) to link the Redis-backed authenticated user session to your client application. The request handler is configured using the `TLS_KEY` or `TLS_KEY_FILEPATH`, and `TLS_PASSPHRASE` environment variables, but also requires the `redisSession` middleware to be configured and in use. - -```javascript -import Express from 'express'; -import AAA from '@advana/api-auth'; - -const app = Express(); -app.use(AAA.redisSession()); -app.post('/api/auth/token', AAA.getToken); -``` - -### `permCheck` middleware - -The `permCheck` middleware configures your Express.js application to authorize the current user session against an array of permissions. If the user has any of the specified permissions - or the WebApp Super Admin or Tier 3 Support permissions - the middleware returns `next()`. Otherwise, the middleware sends an HTTP 403 error and prevents access to any routes in the chain. This middleware requires the `redisSession` middleware to be configured and in use. - -```javascript -import Express from 'express'; -import AAA from '@advana/api-auth'; - -const app = Express(); -app.use(AAA.redisSession()); - -app.use((req, res, next) => - AAA.permCheck(req, res, next, [SPECIAL_PERMISSION]) -); - -// this route will not be served to the user unless he or she has -// the "SPECIAL_PERMISSION" permission. -app.get('/api/special/route', (req, res) => { - specialRouteHandler(req, res); -}); -``` - -### `fetchActiveDirectoryPermissions` - -The `fetchActiveDirectoryPermissions` function returns an array of permissions from Active Directory based on the specified user ID (typically found in `req.session.user.id`, but the value can come from elsewhere). The Active Directory connection must be configured using the `LDAP_URL`, `LDAP_CERT`, `LDAP_USERNAME`, `LDAP_PASSWORD`, and `LDAP_USER_FOLDER_CN` environment variables. - -```javascript -import Express from 'express'; -import AAA from '@advana/api-auth'; - -const app = Express(); -app.use(AAA.redisSession()); - -// please don't do this... -app.get('/example/route', (req, res, next) => { - const permissions = AAA.fetchActiveDirectoryPermissions(req.session.user.id); - return next(); -}); -``` \ No newline at end of file