@sap/xssec
Advanced tools
Comparing version
# Change Log | ||
All notable changes to this project will be documented in this file. | ||
## 3.5.0 - 2023-11-14 | ||
- update dependencies (e.g. axios 0 -> 1) | ||
## 3.4.0 - 2023-10-23 | ||
@@ -5,0 +8,0 @@ - add optional x5t validation (RFC 8705) for IAS tokens |
@@ -40,5 +40,5 @@ 'use strict'; | ||
getXsuaaJwks(jku, zid, attributes = {}) { | ||
if (!jku) { | ||
throw new Error("Cannot get JWKS from empty JKU."); | ||
getXsuaaJwks(uaaDomain, zid, attributes = {}) { | ||
if (!uaaDomain) { | ||
throw new Error("Cannot get JWKS from empty uaaDomain."); | ||
} | ||
@@ -50,3 +50,3 @@ | ||
if (!attributes.disableCache) { | ||
const keyParts = {jku, ...jwksParams}; | ||
const keyParts = {domain: uaaDomain, ...jwksParams}; | ||
replicaKey = this.createCacheKey(keyParts); | ||
@@ -58,3 +58,3 @@ | ||
if (!jwksReplica) { | ||
const xsuaaService = new XsuaaService(jku, zid); | ||
const xsuaaService = new XsuaaService(uaaDomain, zid); | ||
jwksReplica = new JwksReplica(xsuaaService, this.expirationTime, this.refreshPeriod).withParams(jwksParams); | ||
@@ -61,0 +61,0 @@ |
@@ -81,7 +81,5 @@ 'use strict'; | ||
try { | ||
this.updateJwks(); | ||
} catch(e) { | ||
debugError("Asynchronous JWKS refresh failed.", e); | ||
} | ||
this.updateJwks().catch((e) => { | ||
debugError("Asynchronous JWKS refresh failed.", e) | ||
}); | ||
} | ||
@@ -121,2 +119,2 @@ | ||
module.exports = JwksReplica; | ||
module.exports = JwksReplica; |
@@ -8,4 +8,2 @@ 'use strict'; | ||
const errors = require('./errors'); | ||
// use environment variable DEBUG with value 'xssec:*' for trace/error messages | ||
@@ -81,2 +79,6 @@ const debug = require('debug'); | ||
if(options.params) { | ||
axios_options.params = options.params; | ||
} | ||
if (options.form) { | ||
@@ -428,2 +430,6 @@ const formData = options.configType?.toLowerCase() === IAS ? toFormArray(options.form) : options.form; | ||
if (zid) { | ||
options.params = { zid }; | ||
} | ||
if (attributes) { | ||
@@ -430,0 +436,0 @@ if (attributes.correlationId) { |
@@ -54,5 +54,5 @@ 'use strict'; | ||
async fetchJwks(params = {}) { | ||
if(params.client_id !== this.serviceCredentials.clientid) { | ||
if(params.client_id && params.client_id !== this.serviceCredentials.clientid) { | ||
return Promise.reject("Invalid state: IdentityService#fetchJwks called with client_id value that is different from the client_id of the IdentityService object."); | ||
} | ||
} | ||
@@ -62,3 +62,3 @@ await this.fetchOidcInfo(); | ||
return new Promise(async (res, rej) => { | ||
return new Promise((res, rej) => { | ||
try { | ||
@@ -65,0 +65,0 @@ requests.fetchOIDCKey(jwksEndpoint, params, (err, json) => { |
@@ -5,18 +5,24 @@ 'use strict'; | ||
const PROTOCOL = "https://"; | ||
class XsuaaService { | ||
#jku; | ||
#url; | ||
#jku // JWKS URL | ||
#zid; // optional zone id | ||
// immutable public fields | ||
get url() { return this.#url; } | ||
get jku() { return this.#jku; } | ||
get zid() { return this.#zid; } | ||
constructor(jku, zid) { | ||
if(jku === undefined) { | ||
throw new Error("XsuaaService requires a jku to fetch JWKS from."); | ||
constructor(uaaDomain, zid) { | ||
if (uaaDomain === undefined) { | ||
throw new Error("XsuaaService requires a uaaDomain to fetch JWKS from."); | ||
} | ||
this.#jku = jku; | ||
this.#url = uaaDomain.startsWith(PROTOCOL) ? uaaDomain : `${PROTOCOL}${uaaDomain}`; | ||
this.#zid = zid; | ||
this.#jku = `${this.url}/token_keys`; | ||
} | ||
async fetchJwks() { | ||
@@ -41,3 +47,3 @@ return new Promise((res, rej) => { | ||
...this, | ||
jku: this.jku, | ||
url: this.url, | ||
zid: this.zid | ||
@@ -44,0 +50,0 @@ } |
@@ -266,13 +266,2 @@ 'use strict'; | ||
function validateJku(jkuUrl, uaaDomain) { | ||
if (!uaaDomain) { | ||
throw new Error("JKU could not be validated because attribute 'uaadomain' is missing from service credentials."); | ||
} | ||
var tokenKeyUrl = url.parse(jkuUrl); | ||
if (tokenKeyUrl.hostname.substring(tokenKeyUrl.hostname.indexOf(uaaDomain), tokenKeyUrl.hostname.length) !== uaaDomain) { | ||
throw new Error(`JKU of JWT token (${jkuUrl}) does not match UAA domain (${uaaDomain}).`); | ||
} | ||
} | ||
/* Adds missing line breaks to malformed PEM keys. | ||
@@ -338,12 +327,5 @@ * For backward-compatibility, a specific kind of malformed PEM needs to be supported that is lacking line breaks around the header and footer. | ||
try { | ||
validateJku(header.jku, serviceCredentials.uaadomain); | ||
} catch(e) { | ||
debugTrace("Using verification key from service configuration because JKU validation failed.", e.toString()); | ||
return callback(null, keyFromConfig); | ||
} | ||
let jwk; | ||
try { | ||
const jwks = jwksManager.getXsuaaJwks(header.jku, token.getZoneId(), attributes); | ||
const jwks = jwksManager.getXsuaaJwks(serviceCredentials.uaadomain || serviceCredentials.url, token.getZoneId(), attributes); | ||
jwk = await jwks.get(header.kid); | ||
@@ -458,12 +440,5 @@ } catch(e) { | ||
try { | ||
validateJku(header.jku, serviceCredentials.uaadomain); | ||
} catch(e) { | ||
debugTrace("Using verification key from service configuration because JKU validation failed.", e.toString()); | ||
return callback(null, keyFromConfig); | ||
} | ||
let jwk; | ||
try { | ||
const jwks = jwksManager.getXsuaaJwks(header.jku, token.getZoneId(), attributes); | ||
const jwks = jwksManager.getXsuaaJwks(serviceCredentials.uaadomain || serviceCredentials.url, token.getZoneId(), attributes); | ||
jwk = await jwks.get(header.kid); | ||
@@ -470,0 +445,0 @@ } catch(e) { |
{ | ||
"name": "@sap/xssec", | ||
"version": "3.4.0", | ||
"version": "3.5.0", | ||
"description": "XS Advanced Container Security API for node.js", | ||
@@ -24,24 +24,22 @@ "main": "./lib", | ||
"engines": { | ||
"node": ">=16.1.0" | ||
"node": ">=18" | ||
}, | ||
"devDependencies": { | ||
"@sap/xsenv": "^3.1.1", | ||
"convert": "^4.12.0", | ||
"eslint": "^8.50.0", | ||
"@sap/xsenv": "^4", | ||
"convert": "^4.13.2", | ||
"eslint": "^8.53.0", | ||
"istanbul": "^0.4.5", | ||
"jwt-decode": "^3.1.2", | ||
"mocha": "^8.0.0", | ||
"node-forge": "^1.3.0", | ||
"should": "^13.2.1", | ||
"sinon": "^14.0.0" | ||
"jwt-decode": "^4", | ||
"mocha": "^10.2.0", | ||
"node-forge": "^1.3.1", | ||
"rewire": "^7.0.0", | ||
"should": "^13.2.3", | ||
"sinon": "^17.0.1" | ||
}, | ||
"dependencies": { | ||
"axios": "^0.26.0", | ||
"debug": "^4.3.2", | ||
"axios": "^1.6", | ||
"debug": "^4.3.4", | ||
"jsonwebtoken": "^9.0.2", | ||
"lru-cache": "^6.0.0", | ||
"node-rsa": "^1.1.1", | ||
"rewire": "^7.0.0", | ||
"valid-url": "1.0.9" | ||
"node-rsa": "^1.1.1" | ||
} | ||
} |
@@ -210,3 +210,5 @@ @sap/xssec: XS Advanced Container Security API for node.js | ||
// when creating securityContext manually | ||
xssec.createSecurityContext(access_token, { x5tValidation: true }, function(error, securityContext, tokenInfo) { ... }); | ||
xssec.createSecurityContext(access_token, | ||
{ x5tValidation: true, x509Certificate: ... // PEM or DER encoded certificate as string | ||
}, function(error, securityContext, tokenInfo) { ... }); | ||
@@ -213,0 +215,0 @@ // when using passport |
4
-42.86%477
0.42%157759
-0.39%10
11.11%2455
-0.49%1
-50%+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
Updated
Updated