@sap/approuter
Advanced tools
Comparing version 14.1.2 to 14.2.0
@@ -9,2 +9,12 @@ # Change Log | ||
## 14.2.0 - 2023-07-11 | ||
### Added | ||
- Credentials caching support | ||
- No html5 app found (503 response) caching support | ||
### Fixed | ||
- support not case sensitive in dynamicDestination property | ||
- fix redis with Sentinel mode initialization: use 'sentinelPassword' instead of 'password'. | ||
## 14.1.2 - 2023-06-13 | ||
@@ -11,0 +21,0 @@ |
@@ -32,3 +32,2 @@ 'use strict'; | ||
const urlSchema = require('./schemas/url-schema.json'); | ||
const xsenv = require('@sap/xsenv'); | ||
let regexErr; | ||
@@ -200,10 +199,9 @@ | ||
if (!connectivityCreds) { | ||
try { | ||
connectivityCreds = xsenv.serviceCredentials({tag: 'connectivity'}); | ||
} catch (e) { | ||
connectivityCreds = vcapUtils.getServiceCredentials({tag: 'connectivity'}); | ||
if (!connectivityCreds) { | ||
throw 'Destination \"' + destination.name + | ||
'\" with ProxyType \"OnPremise\" but connectivity service is not bound.'; | ||
} | ||
validateConnectivityCredentials(connectivityCreds); | ||
} | ||
validateConnectivityCredentials(connectivityCreds); | ||
} | ||
@@ -210,0 +208,0 @@ }); |
'use strict'; | ||
const urlUtils = require('../utils/url-utils'); | ||
const uaaUtils = require('../utils/uaa-utils'); | ||
const logger = require('../utils/logger'); | ||
const urlUtils = require('../utils/url-utils'); | ||
const uaaUtils = require('../utils/uaa-utils'); | ||
const loggerUtil = require('../utils/logger'); | ||
const logger = loggerUtil.getLogger('/authorization-handler'); | ||
@@ -13,3 +14,3 @@ module.exports = function checkAuthorization(req) { | ||
const tenantMessage = 'You cannot use session from another tenant.'; | ||
const loggingData = logger.getAuditLogAdditionalData(req); | ||
const loggingData = loggerUtil.getAuditLogAdditionalData(req); | ||
let auditLogMessage; | ||
@@ -28,5 +29,5 @@ | ||
loggingData.IP + ', JWT token tenant: ' + req.session.user.tenant + ', URL tenant: ' + urlTenant; | ||
logger.writeToAuditLog(req, loggingData, auditLogMessage, function (err) { | ||
loggerUtil.writeToAuditLog(req, loggingData, auditLogMessage, function (err) { | ||
if (err) { | ||
throw err; | ||
logger.error(err,'Failed to write to audit log'); | ||
} | ||
@@ -62,5 +63,5 @@ }); | ||
loggingData.IP + ', required scopes: ' + routeScopes + ', user scopes: ' + oauthScopes; | ||
logger.writeToAuditLog(req, loggingData, auditLogMessage, function (err) { | ||
loggerUtil.writeToAuditLog(req, loggingData, auditLogMessage, function (err) { | ||
if (err) { | ||
throw err; | ||
logger.error(err,'Failed to write to audit log'); | ||
} | ||
@@ -67,0 +68,0 @@ }); |
/* eslint-disable camelcase,max-depth */ | ||
'use strict'; | ||
const xsenv = require('@sap/xsenv'); | ||
const NodeCache = require('node-cache'); | ||
@@ -15,2 +14,3 @@ const destinationUtils = require('./destination-utils'); | ||
const html5RepoUtils = require('../utils/html5-repo-utils'); | ||
const vcapUtils = require('./vcap-utils'); | ||
@@ -41,36 +41,11 @@ const expiredDataMapInstance = new Map(); | ||
} | ||
try { | ||
return xsenv.serviceCredentials(function (service) { | ||
let vcapSrvServiceName; | ||
if (service.credentials && service.credentials['sap.cloud.service.alias']) { | ||
vcapSrvServiceName = ignoreDots ? service.credentials['sap.cloud.service.alias'].replace(/\./g, '') : service.credentials['sap.cloud.service.alias']; | ||
if (vcapSrvServiceName === serviceName) { | ||
return true; | ||
} | ||
} | ||
if (service.credentials && service.credentials['sap.cloud.service']) { | ||
vcapSrvServiceName = ignoreDots ? service.credentials['sap.cloud.service'].replace(/\./g, '') : service.credentials['sap.cloud.service']; | ||
if (vcapSrvServiceName === serviceName) { | ||
return true; | ||
} | ||
} | ||
if (service.tags) { | ||
for (let i = 0; i < service.tags.length; i++) { | ||
vcapSrvServiceName = ignoreDots ? service.tags[i].replace(/\./g, '') : service.tags[i]; | ||
if (serviceName === vcapSrvServiceName) { | ||
return true; | ||
} | ||
} | ||
} | ||
return false; | ||
}); | ||
} catch (e) { | ||
let credentials = getBSDestination(serviceName, ignoreDots, req); | ||
if (!credentials) { | ||
credentials = html5RepoUtils.getCredentials(serviceName, req); | ||
} | ||
let credentials = vcapUtils.getCredentialsBySapCloudService(serviceName, ignoreDots); | ||
if (credentials) { | ||
return credentials; | ||
} | ||
credentials = getBSDestination(serviceName, ignoreDots, req); | ||
if (!credentials) { | ||
credentials = html5RepoUtils.getCredentials(serviceName, req); | ||
} | ||
return credentials; | ||
} | ||
@@ -224,3 +199,3 @@ | ||
} | ||
let html5Cred = xsenv.serviceCredentials({tag: 'html5-apps-repo-rt'}); | ||
let html5Cred = vcapUtils.getServiceCredentials({tag: 'html5-apps-repo-rt'}); | ||
let requestOptions = { | ||
@@ -360,3 +335,3 @@ url: html5Cred.uri + '/applications/content/' + appKey.appNameWithoutPrefix + '-' + appKey.appVersion, | ||
return new Promise((resolve) => { | ||
let html5Cred = xsenv.serviceCredentials({tag: 'html5-apps-repo-rt'}); | ||
let html5Cred = vcapUtils.getServiceCredentials({tag: 'html5-apps-repo-rt'}); | ||
let html5RepoToken = req.app.services && req.app.services['html5-apps-repo-rt'] && | ||
@@ -526,3 +501,3 @@ req.app.services['html5-apps-repo-rt'].token && req.app.services['html5-apps-repo-rt'].token.accessToken; | ||
function collectXsuaaOrXsuaaAppHostDestinations(destination, destinationBSCredentials, serviceName, destinationXsappname, sapCloudServiceKey, tracer) { | ||
let ownUAACredentials = xsenv.serviceCredentials({label: 'xsuaa'}); | ||
let ownUAACredentials = vcapUtils.getServiceCredentials({label: 'xsuaa'}); | ||
@@ -529,0 +504,0 @@ destinationBSCredentials[sapCloudServiceKey] = { |
@@ -6,3 +6,3 @@ 'use strict'; | ||
const logger = loggingUtils.getLogger('/Destination service'); | ||
const xsenv = require('@sap/xsenv'); | ||
const vcapUtils = require('./vcap-utils'); | ||
const request = require('./request-utils'); | ||
@@ -325,3 +325,3 @@ const tokenUtils = require('./token-utils'); | ||
try { | ||
let credentials = xsenv.serviceCredentials({tag: 'connectivity'}); | ||
let credentials = vcapUtils.getServiceCredentials({tag: 'connectivity'}); | ||
destination['proxyHost'] = credentials.onpremise_proxy_host; | ||
@@ -354,3 +354,3 @@ destination['proxyPort'] = credentials.onpremise_proxy_port; | ||
destinations[i].preserveHostHeader = destinations[i].preserveHostHeader === 'true' || destinations[i].preserveHostHeader === true; | ||
destinations[i].dynamicDestination = destinations[i].dynamicDestination === 'true' || destinations[i].dynamicDestination === true; | ||
destinations[i].dynamicDestination = (destinations[i].hasOwnProperty('dynamicDestination') && destinations[i].dynamicDestination ? destinations[i].dynamicDestination.toLowerCase() === 'true' : false) || destinations[i].dynamicDestination === true; | ||
destinations[i].trustAll = destinations[i].trustAll === 'true' || destinations[i].trustAll === true; | ||
@@ -452,14 +452,3 @@ if (destinations[i].hasOwnProperty('setXForwardedHeaders')) { | ||
function getDestinationServiceCredentials() { | ||
let errorOccurred; | ||
let credentials; | ||
try { | ||
credentials = xsenv.serviceCredentials({tag: DESTINATION}); | ||
credentials.label = DESTINATION; | ||
} catch (e) { | ||
errorOccurred = true; | ||
} | ||
if (errorOccurred || !credentials) { | ||
return null; | ||
} | ||
return credentials; | ||
return vcapUtils.getServiceCredentials({tag: DESTINATION}); | ||
} | ||
@@ -466,0 +455,0 @@ |
@@ -21,2 +21,3 @@ 'use strict'; | ||
const html5RepoUtils = require('../utils/html5-repo-utils'); | ||
const HTML5_APP_NOT_FOUND = 503; | ||
@@ -118,3 +119,3 @@ let ar; | ||
if (config && !skipXSAppJsonCache) { | ||
return callback(null, config); | ||
return callback(null, (config === HTML5_APP_NOT_FOUND ? null : config)); | ||
} | ||
@@ -137,4 +138,5 @@ | ||
return callback('Application does not have xs-app.json'); | ||
} else if (res.statusCode === 503) { | ||
} else if (res.statusCode === HTML5_APP_NOT_FOUND) { | ||
tracer.info('Application %s does not exist', appKey.entireKey); | ||
configCache.set(appKey.entireKey, HTML5_APP_NOT_FOUND); | ||
if (process.env.SAAS_APPROUTER) { | ||
@@ -141,0 +143,0 @@ applicationLogUtils.logRequestSetTenant(req, req.tenant); |
@@ -77,2 +77,3 @@ 'use strict'; | ||
redisOptions.password = this.credentials.password; | ||
redisOptions.sentinelPassword = this.credentials.password; | ||
} else { | ||
@@ -79,0 +80,0 @@ redisOptions.host = this.credentials.hostname; |
@@ -95,3 +95,3 @@ 'use strict'; | ||
} else { | ||
ownCredentials = xsenv.serviceCredentials({label: 'xsuaa'}); | ||
ownCredentials = vcapUtils.getServiceCredentials({label: 'xsuaa'}); | ||
doCheckToken(req, token, ownCredentials,cb); | ||
@@ -98,0 +98,0 @@ } |
@@ -6,2 +6,3 @@ 'use strict'; | ||
const xsenv = require('@sap/xsenv'); | ||
const serviceCredentialsCache = {}; | ||
@@ -24,4 +25,13 @@ module.exports = { | ||
getServiceCredentials : function (options) { | ||
const cacheKey = JSON.stringify(options); | ||
let errorOccurred; | ||
let credentials; | ||
let credentials = getCachedCredentials(cacheKey); | ||
if (credentials){ | ||
if (credentials.notFound) { | ||
return null; | ||
} else { | ||
return credentials; | ||
} | ||
} | ||
try { | ||
@@ -34,8 +44,66 @@ credentials = xsenv.serviceCredentials(options); | ||
tracer.debug('service credentials with options ' + JSON.stringify(options) + ' not found'); | ||
module.exports.setCachedCredentials(cacheKey, {notFound: true}); | ||
return null; | ||
} | ||
module.exports.setCachedCredentials(cacheKey, credentials); | ||
return credentials; | ||
}, | ||
getCredentialsBySapCloudService: function(serviceName, ignoreDots){ | ||
const cacheKey = ignoreDots ? serviceName + 'ignoreDots' : serviceName; | ||
let credentials = getCachedCredentials(cacheKey); | ||
if (credentials){ | ||
return credentials; | ||
} | ||
try { | ||
credentials = xsenv.serviceCredentials(function (service) { | ||
let vcapSrvServiceName; | ||
if (service.credentials && service.credentials['sap.cloud.service.alias']) { | ||
vcapSrvServiceName = ignoreDots ? service.credentials['sap.cloud.service.alias'].replace(/\./g, '') : service.credentials['sap.cloud.service.alias']; | ||
if (vcapSrvServiceName === serviceName) { | ||
return true; | ||
} | ||
} | ||
if (service.credentials && service.credentials['sap.cloud.service']) { | ||
vcapSrvServiceName = ignoreDots ? service.credentials['sap.cloud.service'].replace(/\./g, '') : service.credentials['sap.cloud.service']; | ||
if (vcapSrvServiceName === serviceName) { | ||
return true; | ||
} | ||
} | ||
if (service.tags) { | ||
for (let i = 0; i < service.tags.length; i++) { | ||
vcapSrvServiceName = ignoreDots ? service.tags[i].replace(/\./g, '') : service.tags[i]; | ||
if (serviceName === vcapSrvServiceName) { | ||
return true; | ||
} | ||
} | ||
} | ||
return false; | ||
}); | ||
} catch (e) { | ||
tracer.debug('service credentials for service ' + serviceName + ' not found'); | ||
} | ||
module.exports.setCachedCredentials(cacheKey, credentials); | ||
return credentials; | ||
}, | ||
setCachedCredentials: function(cacheKey, credentials) { | ||
const cacheServiceCredentials = loadJsonVar('CACHE_SERVICE_CREDENTIALS'); | ||
if (cacheServiceCredentials && credentials){ | ||
credentials.cached = true; | ||
serviceCredentialsCache[cacheKey] = credentials; | ||
} | ||
} | ||
}; | ||
function getCachedCredentials(cacheKey){ | ||
const cacheServiceCredentials = loadJsonVar('CACHE_SERVICE_CREDENTIALS'); | ||
if (cacheServiceCredentials){ | ||
return serviceCredentialsCache[cacheKey]; | ||
} | ||
} | ||
function setName(appEnv) { | ||
@@ -55,1 +123,11 @@ if (appEnv.name || appEnv.application_name) { | ||
} | ||
function loadJsonVar(envVar) { | ||
if (envVar in process.env) { | ||
try { | ||
return JSON.parse(process.env[envVar]); | ||
} catch (e) { | ||
throw new Error(`Invalid value for environment variable ${envVar}`); | ||
} | ||
} | ||
} |
{ | ||
"name": "@sap/approuter", | ||
"description": "Node.js based application router", | ||
"version": "14.1.2", | ||
"version": "14.2.0", | ||
"repository": {}, | ||
@@ -6,0 +6,0 @@ "main": "approuter.js", |
Sorry, the diff of this file is too big to display
687127
11299
2392
127