passport-saml-metadata
Advanced tools
Comparing version 2.6.0 to 2.6.1
# Changelog | ||
All notable changes to this project will be documented in this file. See [standard-version](https://github.com/conventional-changelog/standard-version) for commit guidelines. | ||
### [2.6.1](https://github.com/compwright/passport-saml-metadata/compare/v2.6.0...v2.6.1) (2022-10-17) | ||
# Changelog | ||
## [Unreleased](https://github.com/compwright/passport-saml-metadata/tree/HEAD) | ||
@@ -4,0 +10,0 @@ |
{ | ||
"name": "passport-saml-metadata", | ||
"version": "2.6.0", | ||
"version": "2.6.1", | ||
"description": "SAML2 metadata loader", | ||
@@ -49,18 +49,7 @@ "author": { | ||
"main": "./src/", | ||
"semistandard": { | ||
"standard": { | ||
"env": [ | ||
"mocha" | ||
"jest" | ||
] | ||
}, | ||
"nyc": { | ||
"cache": true, | ||
"cacheDir": ".nyc_cache", | ||
"include": [ | ||
"src/**/*.js" | ||
], | ||
"reporter": [ | ||
"lcov", | ||
"text" | ||
] | ||
}, | ||
"engines": { | ||
@@ -70,16 +59,15 @@ "node": ">= 14" | ||
"dependencies": { | ||
"@xmldom/xmldom": "^0.8.2", | ||
"axios": "^0.27.2", | ||
"@xmldom/xmldom": "^0.8.3", | ||
"axios": "^1.1.3", | ||
"debug": "^4.3.2", | ||
"lodash": "^4.17.20", | ||
"passport-saml": "^3.1.0", | ||
"passport-saml": "^3.2.3", | ||
"xpath": "0.0.32" | ||
}, | ||
"devDependencies": { | ||
"axios-mock-adapter": "^1.19.0", | ||
"eslint": "*", | ||
"mocha": "*", | ||
"nyc": "*", | ||
"semistandard": "*" | ||
"axios-mock-adapter": "^1.21.2", | ||
"jest": "latest", | ||
"standard": "latest", | ||
"standard-version": "latest" | ||
} | ||
} |
@@ -1,4 +0,4 @@ | ||
const assert = require('assert'); | ||
const axios = require('axios'); | ||
const debug = require('debug')('passport-saml-metadata'); | ||
const assert = require('assert') | ||
const axios = require('axios') | ||
const debug = require('debug')('passport-saml-metadata') | ||
@@ -10,3 +10,3 @@ const defaults = { | ||
backupStore: new Map() | ||
}; | ||
} | ||
@@ -19,44 +19,44 @@ module.exports = async function (config = {}) { | ||
...params | ||
} = Object.assign({}, defaults, config); | ||
} = Object.assign({}, defaults, config) | ||
assert.ok(url, 'url is required'); | ||
assert.ok(backupStore, 'backupStore is required'); | ||
assert.equal(typeof backupStore.get, 'function', 'backupStore must have a get(key) function'); | ||
assert.equal(typeof backupStore.set, 'function', 'backupStore must have a set(key, value) function'); | ||
assert.ok(url, 'url is required') | ||
assert.ok(backupStore, 'backupStore is required') | ||
assert.equal(typeof backupStore.get, 'function', 'backupStore must have a get(key) function') | ||
assert.equal(typeof backupStore.set, 'function', 'backupStore must have a set(key, value) function') | ||
debug('Loading metadata', url, params.timeout, backupStore); | ||
debug('Loading metadata', url, params.timeout, backupStore) | ||
try { | ||
const res = await client.get(url, params); | ||
debug('Metadata loaded', res.headers['content-length']); | ||
backupStore.set(url, res.data); // Save in backup store | ||
return res.data; | ||
const res = await client.get(url, params) | ||
debug('Metadata loaded', res.headers['content-length']) | ||
backupStore.set(url, res.data) // Save in backup store | ||
return res.data | ||
} catch (err) { | ||
let error; | ||
let error | ||
if (err.response) { | ||
error = new Error(err.response.data); | ||
error.status = err.response.status; | ||
error = new Error(err.response.data) | ||
error.status = err.response.status | ||
} else if (err.request) { | ||
error = new Error('Error during request, no response'); | ||
error = new Error('Error during request, no response') | ||
} else { | ||
error = err; | ||
error = err | ||
} | ||
debug('Metadata request failed, attempting backup store', error); | ||
debug('Metadata request failed, attempting backup store', error) | ||
try { | ||
// Try from backup store | ||
const data = await Promise.resolve(backupStore.get(url)); | ||
const data = await Promise.resolve(backupStore.get(url)) | ||
if (data) { | ||
debug('Metadata loaded from backupStore', data.length); | ||
return data; | ||
debug('Metadata loaded from backupStore', data.length) | ||
return data | ||
} else { | ||
debug('Backup store was empty'); | ||
throw error; | ||
debug('Backup store was empty') | ||
throw error | ||
} | ||
} catch (err) { | ||
debug('Backup store request error', err); | ||
throw error; | ||
debug('Backup store request error', err) | ||
throw error | ||
} | ||
} | ||
}; | ||
} |
@@ -1,5 +0,5 @@ | ||
const fetch = require('./fetch'); | ||
const MetadataReader = require('./reader'); | ||
const { toPassportConfig, claimsToCamelCase } = require('./passport'); | ||
const metadata = require('./metadata'); | ||
const fetch = require('./fetch') | ||
const MetadataReader = require('./reader') | ||
const { toPassportConfig, claimsToCamelCase } = require('./passport') | ||
const metadata = require('./metadata') | ||
@@ -12,2 +12,2 @@ module.exports = { | ||
metadata | ||
}; | ||
} |
@@ -1,8 +0,8 @@ | ||
const assert = require('assert'); | ||
const SAML = require('passport-saml').SAML; | ||
const assert = require('assert') | ||
const SAML = require('passport-saml').SAML | ||
function configureMetadataRoute (app, config = {}) { | ||
assert.strictEqual(typeof config, 'object', 'config must be an object'); | ||
assert.ok(config.issuer, 'config.issuer is required'); | ||
assert.ok(config.callbackUrl, 'config.callbackUrl is required'); | ||
assert.strictEqual(typeof config, 'object', 'config must be an object') | ||
assert.ok(config.issuer, 'config.issuer is required') | ||
assert.ok(config.callbackUrl, 'config.callbackUrl is required') | ||
@@ -14,10 +14,10 @@ app.get('/FederationMetadata/2007-06/FederationMetadata.xml', function (req, res) { | ||
logoutCallbackUrl: config.logoutCallbackUrl | ||
}); | ||
const xml = saml.generateServiceProviderMetadata(); | ||
res.set('Content-Type', 'application/samlmetadata+xml').send(xml); | ||
}); | ||
}) | ||
const xml = saml.generateServiceProviderMetadata() | ||
res.set('Content-Type', 'application/samlmetadata+xml').send(xml) | ||
}) | ||
} | ||
module.exports = (config) => function () { | ||
configureMetadataRoute(this, config); | ||
}; | ||
configureMetadataRoute(this, config) | ||
} |
@@ -1,5 +0,5 @@ | ||
const debug = require('debug')('passport-saml-metadata'); | ||
const debug = require('debug')('passport-saml-metadata') | ||
function toPassportConfig (reader = {}, options = { multipleCerts: false }) { | ||
const { identifierFormat, identityProviderUrl, logoutUrl, signingCerts } = reader; | ||
const { identifierFormat, identityProviderUrl, logoutUrl, signingCerts } = reader | ||
@@ -12,21 +12,21 @@ const config = { | ||
identifierFormat | ||
}; | ||
} | ||
debug('Extracted configuration', config); | ||
debug('Extracted configuration', config) | ||
return config; | ||
return config | ||
} | ||
function claimsToCamelCase (claims, claimSchema) { | ||
const obj = {}; | ||
const obj = {} | ||
for (const [key, value] of Object.entries(claims)) { | ||
try { | ||
obj[claimSchema[key].camelCase] = value; | ||
obj[claimSchema[key].camelCase] = value | ||
} catch (e) { | ||
debug(`Error while translating claim ${key}`, e); | ||
debug(`Error while translating claim ${key}`, e) | ||
} | ||
} | ||
return obj; | ||
return obj | ||
} | ||
@@ -37,2 +37,2 @@ | ||
claimsToCamelCase | ||
}; | ||
} |
@@ -1,9 +0,9 @@ | ||
const assert = require('assert'); | ||
const debug = require('debug')('passport-saml-metadata'); | ||
const camelCase = require('lodash/camelCase'); | ||
const merge = require('lodash/merge'); | ||
const find = require('lodash/find'); | ||
const sortBy = require('lodash/sortBy'); | ||
const { DOMParser } = require('@xmldom/xmldom'); | ||
const xpath = require('xpath'); | ||
const assert = require('assert') | ||
const debug = require('debug')('passport-saml-metadata') | ||
const camelCase = require('lodash/camelCase') | ||
const merge = require('lodash/merge') | ||
const find = require('lodash/find') | ||
const sortBy = require('lodash/sortBy') | ||
const { DOMParser } = require('@xmldom/xmldom') | ||
const xpath = require('xpath') | ||
@@ -13,10 +13,10 @@ const defaultOptions = { | ||
throwExceptions: false | ||
}; | ||
} | ||
class MetadataReader { | ||
constructor (metadata, options = defaultOptions) { | ||
assert.equal(typeof metadata, 'string', 'metadata must be an XML string'); | ||
const doc = new DOMParser().parseFromString(metadata); | ||
assert.equal(typeof metadata, 'string', 'metadata must be an XML string') | ||
const doc = new DOMParser().parseFromString(metadata) | ||
this.options = merge({}, defaultOptions, options); | ||
this.options = merge({}, defaultOptions, options) | ||
@@ -27,12 +27,12 @@ const select = xpath.useNamespaces({ | ||
sig: 'http://www.w3.org/2000/09/xmldsig#' | ||
}); | ||
}) | ||
this.query = (query) => { | ||
try { | ||
return select(query, doc); | ||
return select(query, doc) | ||
} catch (e) { | ||
debug(`Could not read xpath query "${query}"`, e); | ||
throw e; | ||
debug(`Could not read xpath query "${query}"`, e) | ||
throw e | ||
} | ||
}; | ||
} | ||
} | ||
@@ -42,8 +42,8 @@ | ||
try { | ||
return this.query('//md:IDPSSODescriptor/md:NameIDFormat/text()')[0].nodeValue; | ||
return this.query('//md:IDPSSODescriptor/md:NameIDFormat/text()')[0].nodeValue | ||
} catch (e) { | ||
if (this.options.throwExceptions) { | ||
throw e; | ||
throw e | ||
} else { | ||
return undefined; | ||
return undefined | ||
} | ||
@@ -57,10 +57,10 @@ } | ||
const singleSignOnServiceElements = sortBy(this.query('//md:IDPSSODescriptor/md:SingleSignOnService'), (singleSignOnServiceElement) => { | ||
const indexAttribute = find(singleSignOnServiceElement.attributes, { name: 'index' }); | ||
const indexAttribute = find(singleSignOnServiceElement.attributes, { name: 'index' }) | ||
if (indexAttribute) { | ||
return indexAttribute.value; | ||
return indexAttribute.value | ||
} | ||
return 0; | ||
}); | ||
return 0 | ||
}) | ||
@@ -71,12 +71,12 @@ // Find the specified authentication binding, if not available default to the first binding in the list | ||
value: `urn:oasis:names:tc:SAML:2.0:bindings:${this.options.authnRequestBinding}` | ||
}); | ||
}) || singleSignOnServiceElements[0]; | ||
}) | ||
}) || singleSignOnServiceElements[0] | ||
// Return the location | ||
return find(singleSignOnServiceElement.attributes, { name: 'Location' }).value; | ||
return find(singleSignOnServiceElement.attributes, { name: 'Location' }).value | ||
} catch (e) { | ||
if (this.options.throwExceptions) { | ||
throw e; | ||
throw e | ||
} else { | ||
return undefined; | ||
return undefined | ||
} | ||
@@ -90,10 +90,10 @@ } | ||
const singleLogoutServiceElements = sortBy(this.query('//md:IDPSSODescriptor/md:SingleLogoutService'), (singleLogoutServiceElement) => { | ||
const indexAttribute = find(singleLogoutServiceElement.attributes, { name: 'index' }); | ||
const indexAttribute = find(singleLogoutServiceElement.attributes, { name: 'index' }) | ||
if (indexAttribute) { | ||
return indexAttribute.value; | ||
return indexAttribute.value | ||
} | ||
return 0; | ||
}); | ||
return 0 | ||
}) | ||
@@ -104,12 +104,12 @@ // Find the specified authentication binding, if not available default to the first binding in the list | ||
value: `urn:oasis:names:tc:SAML:2.0:bindings:${this.options.authnRequestBinding}` | ||
}); | ||
}) || singleLogoutServiceElements[0]; | ||
}) | ||
}) || singleLogoutServiceElements[0] | ||
// Return the location | ||
return find(singleLogoutServiceElement.attributes, { name: 'Location' }).value; | ||
return find(singleLogoutServiceElement.attributes, { name: 'Location' }).value | ||
} catch (e) { | ||
if (this.options.throwExceptions) { | ||
throw e; | ||
throw e | ||
} else { | ||
return undefined; | ||
return undefined | ||
} | ||
@@ -122,8 +122,8 @@ } | ||
return this.query('//md:IDPSSODescriptor/md:KeyDescriptor[@use="encryption" or not(@use)]/sig:KeyInfo/sig:X509Data/sig:X509Certificate') | ||
.map((node) => node.firstChild.data.replace(/[\r\n\t\s]/gm, '')); | ||
.map((node) => node.firstChild.data.replace(/[\r\n\t\s]/gm, '')) | ||
} catch (e) { | ||
if (this.options.throwExceptions) { | ||
throw e; | ||
throw e | ||
} else { | ||
return undefined; | ||
return undefined | ||
} | ||
@@ -135,8 +135,8 @@ } | ||
try { | ||
return this.encryptionCerts[0].replace(/[\r\n\t\s]/gm, ''); | ||
return this.encryptionCerts[0].replace(/[\r\n\t\s]/gm, '') | ||
} catch (e) { | ||
if (this.options.throwExceptions) { | ||
throw e; | ||
throw e | ||
} else { | ||
return undefined; | ||
return undefined | ||
} | ||
@@ -149,8 +149,8 @@ } | ||
return this.query('//md:IDPSSODescriptor/md:KeyDescriptor[@use="signing" or not(@use)]/sig:KeyInfo/sig:X509Data/sig:X509Certificate') | ||
.map((node) => node.firstChild.data.replace(/[\r\n\t\s]/gm, '')); | ||
.map((node) => node.firstChild.data.replace(/[\r\n\t\s]/gm, '')) | ||
} catch (e) { | ||
if (this.options.throwExceptions) { | ||
throw e; | ||
throw e | ||
} else { | ||
return undefined; | ||
return undefined | ||
} | ||
@@ -162,8 +162,8 @@ } | ||
try { | ||
return this.signingCerts[0].replace(/[\r\n\t\s]/gm, ''); | ||
return this.signingCerts[0].replace(/[\r\n\t\s]/gm, '') | ||
} catch (e) { | ||
if (this.options.throwExceptions) { | ||
throw e; | ||
throw e | ||
} else { | ||
return undefined; | ||
return undefined | ||
} | ||
@@ -178,18 +178,18 @@ } | ||
try { | ||
const name = node.value; | ||
const description = this.query(`//md:IDPSSODescriptor/claim:Attribute[@Name="${name}"]/@FriendlyName`)[0].value; | ||
const camelized = camelCase(description); | ||
claims[node.value] = { name, description, camelCase: camelized }; | ||
const name = node.value | ||
const description = this.query(`//md:IDPSSODescriptor/claim:Attribute[@Name="${name}"]/@FriendlyName`)[0].value | ||
const camelized = camelCase(description) | ||
claims[node.value] = { name, description, camelCase: camelized } | ||
} catch (e) { | ||
if (this.options.throwExceptions) { | ||
throw e; | ||
throw e | ||
} | ||
} | ||
return claims; | ||
}, {}); | ||
return claims | ||
}, {}) | ||
} catch (e) { | ||
if (this.options.throwExceptions) { | ||
throw e; | ||
throw e | ||
} | ||
return {}; | ||
return {} | ||
} | ||
@@ -199,2 +199,2 @@ } | ||
module.exports = MetadataReader; | ||
module.exports = MetadataReader |
Sorry, the diff of this file is not supported yet
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
4
25217
+ Addedaxios@1.7.9(transitive)
+ Addedproxy-from-env@1.1.0(transitive)
- Removedaxios@0.27.2(transitive)
Updated@xmldom/xmldom@^0.8.3
Updatedaxios@^1.1.3
Updatedpassport-saml@^3.2.3