@sap/xssec
Advanced tools
Comparing version 3.0.6 to 3.0.7
'use strict'; | ||
var constants = require('./constants'); | ||
var request = require('requestretry'); | ||
var LRU = require('lru-cache'); | ||
var validUrl = require('valid-url'); | ||
const constants = require('./constants'); | ||
const LRU = require('lru-cache'); | ||
const validUrl = require('valid-url'); | ||
@@ -13,2 +12,4 @@ // use environment variable DEBUG with value 'xssec:*' for trace/error messages | ||
const requests = require('./requests'); | ||
debugError.log = console.error.bind(console); | ||
@@ -68,13 +69,10 @@ debugTrace.log = console.log.bind(console); | ||
if ((keyId === null) || (keyId === undefined)) { | ||
var error = new Error( | ||
'Parameter keyId null or undefined. To add a key to the KeyCache with function KeyCache.addKey, you need to specify parameter keyId.'); | ||
var error = new Error('Parameter keyId null or undefined. To add a key to the KeyCache with function KeyCache.addKey, you need to specify parameter keyId.'); | ||
throw error; | ||
} | ||
if ((key === null) || (key === undefined)) { | ||
var error = new Error( | ||
'Parameter key null or undefined. To add a key to the KeyCache with function KeyCache.addKey, you need to specify parameter key.'); | ||
var error = new Error('Parameter key null or undefined. To add a key to the KeyCache with function KeyCache.addKey, you need to specify parameter key.'); | ||
throw error; | ||
} | ||
debugTrace('Adding key to cache. keyID: "' + keyId + '", key: "' + key | ||
+ '".'); | ||
debugTrace('Adding key to cache. keyID: "' + keyId + '", key: "' + key + '".'); | ||
this.lruCache.set(keyId, key); | ||
@@ -87,21 +85,12 @@ }; | ||
if ((tokenKeyUrl === null) || (tokenKeyUrl === undefined)) { | ||
var error = new Error( | ||
'Parameter tokenKeyUrl null or undefined. To enable the KeyCache reading keys from the UAA which are yet unavailable in the cache, you need to specify parameter tokenKeyUrl as a valid https URL.'); | ||
return process.nextTick(function() { | ||
cb(error, null); | ||
}); | ||
var error = new Error('Parameter tokenKeyUrl null or undefined. To enable the KeyCache reading keys from the UAA which are yet unavailable in the cache, you need to specify parameter tokenKeyUrl as a valid https URL.'); | ||
return cb(error); | ||
} | ||
if (validUrl.isHttpsUri(tokenKeyUrl) === undefined) { | ||
var error = new Error( | ||
'Parameter tokenKeyUrl is not a valid https URL. To enable the KeyCache reading keys from the UAA which are yet unavailable in the cache, you need to specify parameter tokenKeyUrl as a valid https URL.'); | ||
return process.nextTick(function() { | ||
cb(error, null); | ||
}); | ||
var error = new Error('Parameter tokenKeyUrl is not a valid https URL. To enable the KeyCache reading keys from the UAA which are yet unavailable in the cache, you need to specify parameter tokenKeyUrl as a valid https URL.'); | ||
return cb(error); | ||
} | ||
if ((keyId === null) || (keyId === undefined)) { | ||
var error = new Error( | ||
'Parameter keyId null or undefined. To read a key from the KeyCache with function KeyCache.getKey, you need to specify parameter keyId.'); | ||
return process.nextTick(function() { | ||
cb(error, null); | ||
}); | ||
var error = new Error('Parameter keyId null or undefined. To read a key from the KeyCache with function KeyCache.getKey, you need to specify parameter keyId.'); | ||
return cb(error); | ||
} | ||
@@ -115,27 +104,37 @@ | ||
debugTrace('Key with keyID: "' + keyId + '" found in cache. Returning key "' + tmpResult + '".'); | ||
return process.nextTick(function() { | ||
cb(null, tmpResult); | ||
}); | ||
return cb(null, tmpResult); | ||
} else if (this.callUaaToReadTokenKeys === false) { | ||
// no cache hit, but configuration says not to try to obtain key from | ||
// UAA | ||
// no cache hit, but configuration says not to try to obtain key from UAA | ||
var error = new Error('Key "' + cacheKey + '" not found in cache. Configuration says not to query UAA.'); | ||
return process.nextTick(function() { | ||
cb(error, null); | ||
}); | ||
return cb(error); | ||
} else { | ||
// try to obtain key from UAA | ||
var options = { | ||
url : tokenKeyUrl, | ||
timeout: 2000, | ||
headers: { | ||
"User-Agent": constants.USER_AGENT, | ||
}, | ||
maxAttempts: 3, | ||
retryDelay: 500, | ||
followRedirect: false, | ||
retryStrategy: request.RetryStrategies.HTTPOrNetworkError | ||
}; | ||
debugTrace('Key "' + cacheKey + '" not found in cache. Querying keys from UAA via URL "' + tokenKeyUrl + '" and zid: "' + zid + '".'); | ||
debugTrace('Key "' + cacheKey + '" not found in cache. Querying keys from UAA via URL "' + options.url + '" and zid: "' + zid + '".'); | ||
return requests.fetchKeyFromXSUAA(tokenKeyUrl, zid, function(err, json) { | ||
if(err) { | ||
if (err.code === 'ETIMEDOUT' && err.connect === true) { | ||
debugError('getKey: HTTP connection timeout.'); | ||
} | ||
debugError('An error occurred when reading the token keys from ' + tokenKeyUrl + ': ' + err.message + err.stack); | ||
return cb(err); | ||
} | ||
for (var i = 0; i < json.keys.length; i++) { | ||
// Note: The following code removes line | ||
// breaks before adding the key to the cache | ||
self.addKey(tokenKeyUrl + json.keys[i].kid, json.keys[i].value.replace(/(\r\n|\n|\r)/gm, '')); | ||
} | ||
var tmpResult = self.lruCache.get(cacheKey); | ||
if (tmpResult !== undefined) { | ||
debugTrace('Key "' + cacheKey + '" found in cache. Returning key "' + tmpResult + '".'); | ||
return cb(null, tmpResult); | ||
} else { | ||
var error = new Error( | ||
'Obtained token keys from UAA, but key with requested keyID "' + | ||
cacheKey + '" still not found in cache.'); | ||
return cb(error); | ||
} | ||
}); | ||
request | ||
@@ -142,0 +141,0 @@ .get( |
'use strict'; | ||
var constants = require('./constants'); | ||
var request = require('request'); | ||
var url = require('url'); | ||
const constants = require('./constants'); | ||
const request = require('request'); | ||
const requestRetry = require('requestretry'); | ||
const url = require('url'); | ||
// use environment variable DEBUG with value 'xssec:*' for trace/error messages | ||
var debug = require('debug'); | ||
var debugTrace = debug('xssec:requests'); | ||
var debugError = debug('xssec:requests'); | ||
const debug = require('debug'); | ||
const debugTrace = debug('xssec:requests'); | ||
const debugError = debug('xssec:requests'); | ||
@@ -15,3 +16,3 @@ debugError.log = console.error.bind(console); | ||
module.exports.requestUserToken = function(securityContext, serviceCredentials, additionalAttributes, scopes, adaptSubdomain, cb) { | ||
module.exports.requestUserToken = function (securityContext, serviceCredentials, additionalAttributes, scopes, adaptSubdomain, cb) { | ||
// input validation | ||
@@ -47,8 +48,14 @@ if (!serviceCredentials) { | ||
var options = { | ||
url : urlWithCorrectSubdomain + '/oauth/token?grant_type=' + encodeURIComponent('urn:ietf:params:oauth:grant-type:jwt-bearer') + | ||
'&response_type=token&client_id=' + serviceCredentials.clientid + '&assertion=' + securityContext.getAppToken(), | ||
url: urlWithCorrectSubdomain + '/oauth/token', | ||
headers: { | ||
'Accept': 'application/json', | ||
'Content-Type': 'application/x-www-form-urlencoded', | ||
'User-Agent': constants.USER_AGENT | ||
}, | ||
form: { | ||
grant_type: 'urn:ietf:params:oauth:grant-type:jwt-bearer', | ||
response_type: 'token', | ||
client_id: serviceCredentials.clientid, | ||
assertion: securityContext.getAppToken() | ||
}, | ||
auth: { | ||
@@ -65,3 +72,3 @@ user: serviceCredentials.clientid, | ||
if (additionalAttributes !== null) { | ||
var authorities = { "az_attr" : additionalAttributes }; | ||
var authorities = { "az_attr": additionalAttributes }; | ||
options.url = options.url + "&authorities=" + encodeURIComponent(JSON.stringify(authorities)); | ||
@@ -73,3 +80,3 @@ } | ||
options, | ||
function(error, response, body) { | ||
function (error, response, body) { | ||
if (error) { | ||
@@ -83,11 +90,4 @@ if (error.code === 'ETIMEDOUT' && error.connect === true) { | ||
} | ||
if (response.statusCode === 401) { | ||
debugTrace('requestToken: Call to /oauth/token was not successful (grant_type: urn:ietf:params:oauth:grant-type:jwt-bearer). Bearer token invalid, requesting client does not have the grant_type or no scopes were granted.'); | ||
debugTrace(body); | ||
return cb(new Error('Call to /oauth/token was not successful (grant_type: urn:ietf:params:oauth:grant-type:jwt-bearer). Bearer token invalid, requesting client does not have the grant_type or no scopes were granted.'), null); | ||
} | ||
if (response.statusCode !== 200) { | ||
debugTrace('requestToken: Call to /oauth/token was not successful (grant_type: urn:ietf:params:oauth:grant-type:jwt-bearer). HTTP status code: ' + response.statusCode); | ||
debugTrace(body); | ||
return cb(new Error('Call to /oauth/token was not successful (grant_type: urn:ietf:params:oauth:grant-type:jwt-bearer). HTTP status code: ' + response.statusCode), null); | ||
return cb(new Error(response.statusCode + " - " + body)); | ||
} | ||
@@ -101,3 +101,2 @@ var json = null; | ||
return cb(null, json.access_token) | ||
// refresh token flow | ||
} | ||
@@ -107,3 +106,3 @@ ); | ||
module.exports.requestClientCredentialsToken = function(securityContext, serviceCredentials, additionalAttributes, cb) { | ||
module.exports.requestClientCredentialsToken = function (securityContext, serviceCredentials, additionalAttributes, cb) { | ||
// input validation | ||
@@ -137,6 +136,6 @@ if (!serviceCredentials) { | ||
var options = { | ||
url : urlWithCorrectSubdomain + '/oauth/token?grant_type=client_credentials&response_type=token', | ||
headers: { | ||
'Accept' : 'application/json', | ||
'Content-Type' : 'application/x-www-form-urlencoded', | ||
url: urlWithCorrectSubdomain + '/oauth/token?grant_type=client_credentials&response_type=token', | ||
headers: { | ||
'Accept': 'application/json', | ||
'Content-Type': 'application/x-www-form-urlencoded', | ||
'User-Agent': constants.USER_AGENT | ||
@@ -151,9 +150,9 @@ }, | ||
if (additionalAttributes !== null) { | ||
var authorities = { "az_attr" : additionalAttributes }; | ||
var authorities = { "az_attr": additionalAttributes }; | ||
options.url = options.url + "&authorities=" + encodeURIComponent(JSON.stringify(authorities)); | ||
} | ||
debugTrace('requestClientCredentialsToken::HTTP Call with %O', options); | ||
request.post( | ||
requestRetry.post( | ||
options, | ||
function(error, response, body) { | ||
function (error, response, body) { | ||
if (error) { | ||
@@ -165,12 +164,6 @@ if (error.code === 'ETIMEDOUT' && error.connect === true) { | ||
debugError(error.stack); | ||
return cb(error, null); | ||
return cb(error); | ||
} | ||
if (response.statusCode === 401) { | ||
debugTrace(body); | ||
debugTrace('requestToken: Call to /oauth/token was not successful (grant_type: client_credentials). Client credentials invalid.'); | ||
return cb(new Error('Call to /oauth/token was not successful (grant_type: client_credentials). Client credentials invalid.'), null); | ||
} | ||
if (response.statusCode !== 200) { | ||
debugTrace('requestToken: Call to /oauth/token was not successful (grant_type: client_credentials). HTTP status code: ' + response.statusCode); | ||
return cb(new Error('Call to /oauth/token was not successful (grant_type: client_credentials). HTTP status code ' + response.statusCode), null); | ||
return cb(new Error(response.statusCode + " - " + body)); | ||
} | ||
@@ -181,3 +174,3 @@ var json = null; | ||
} catch (e) { | ||
return cb(e, null); | ||
return cb(e); | ||
} | ||
@@ -188,1 +181,38 @@ return cb(null, json.access_token); | ||
}; | ||
module.exports.fetchKeyFromXSUAA = function (tokenKeyUrl, zid, cb) { | ||
// try to obtain key from UAA | ||
var options = { | ||
url: tokenKeyUrl, | ||
timeout: 2000, | ||
headers: { | ||
"User-Agent": constants.USER_AGENT, | ||
}, | ||
followRedirect: false, | ||
maxAttempts: 3, | ||
retryDelay: 500, | ||
retryStrategy: requestRetry.RetryStrategies.HTTPOrNetworkError | ||
}; | ||
requestRetry.get(options, function (err, response, body) { | ||
if (err) { | ||
return cb(err); | ||
} | ||
if (response.statusCode !== 200) { | ||
var error = new Error('Call was not successful. Error Code: ' + response.statusCode + " " + body); | ||
error.statuscode = response.statusCode; | ||
error.body = body; | ||
return cb(error); | ||
} | ||
try { | ||
var json = JSON.parse(body); | ||
return cb(null, json); | ||
} catch (e) { | ||
var error = new Error('Error parsing response from UAA: ' + e) | ||
return cb(error); | ||
} | ||
}); | ||
} |
@@ -5,3 +5,2 @@ 'use strict'; | ||
const constants = require('./constants'); | ||
const request = require('request'); | ||
const url = require('url'); | ||
@@ -23,2 +22,5 @@ | ||
function cleanUp(pem) { | ||
if(!pem) { | ||
return null; | ||
} | ||
//the old ccl based jwt verification library was able to read malformed PEM formatted input. | ||
@@ -25,0 +27,0 @@ //but with the jsonwebtoken module we need to clean up some PEM errors before using it... |
'use strict'; | ||
const constants = require('./constants'); | ||
const request = require('request'); | ||
const url = require('url'); | ||
@@ -5,0 +4,0 @@ |
{ | ||
"name": "@sap/xssec", | ||
"version": "3.0.6", | ||
"version": "3.0.7", | ||
"description": "XS Advanced Container Security API for node.js", | ||
@@ -10,5 +10,6 @@ "main": "./lib", | ||
}, | ||
"license": "SAP DEVELOPER LICENSE AGREEMENT", | ||
"repository": { | ||
"type": "git", | ||
"url": "ssh://git@github.wdf.sap.corp/xs2/node-xs2sec.git" | ||
"url": "git://github.wdf.sap.corp/CPSecurity/node-xs2sec.git" | ||
}, | ||
@@ -15,0 +16,0 @@ "files": [ |
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
Misc. License Issues
License(Experimental) A package's licensing information has fine-grained problems.
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
89455
1236
1