@sap/approuter
Advanced tools
Comparing version 6.0.2 to 6.5.0
@@ -8,2 +8,51 @@ # Change Log | ||
## 6.5.0 - 2019-10-03 | ||
### Added | ||
- Timeout for Business Service | ||
### Fixed | ||
- Adding destination token middleware for websockets | ||
## 6.4.1 - 2019-09-23 | ||
### Fixed | ||
- CSP header fix return frame-ancestors in login | ||
## 6.4.0 - 2019-09-16 | ||
### Added | ||
- Allowed dynamic destinations | ||
- Return CSP header with no cache | ||
- Added setXForwardedHeaders option | ||
## 6.3.0 - 2019-09-10 | ||
### Added | ||
- Support Cache-Control for static content from html5-repo | ||
## 6.2.0 - 2019-09-03 | ||
### Added | ||
- Support Subscription url from vcap. | ||
- Adding validation - Session created for one tenant must not be used by other tenants | ||
### Updated dependencies | ||
- deps: @sap/xssec@2.2.2 | ||
## 6.1.2 - 2019-08-28 | ||
- Support Xsuaa credentials in request body | ||
## 6.1.1 - 2019-08-27 | ||
- Fix in destination middleware - session.update | ||
## 6.1.0 - 2019-07-31 | ||
### Added | ||
- Support for redirection to logout page with query parameters after central logout | ||
- Connectivity is now returned in subscription getDependencies callback | ||
### Fixed | ||
- Error when processing unknown authentication types | ||
## 6.0.2 - 2019-07-14 | ||
@@ -10,0 +59,0 @@ |
@@ -49,3 +49,3 @@ 'use strict'; | ||
addCorrelationIdHeader(headers, req); | ||
addXForwardingHeaders(headers, req); | ||
addXForwardingHeaders(headers, req, destination); | ||
removeSecurityHeaders(headers, req); | ||
@@ -130,3 +130,6 @@ headerUtil.updateSapPassport(headers); | ||
function addXForwardingHeaders(headers, req) { | ||
function addXForwardingHeaders(headers, req, destination) { | ||
if (destination && destination.setXForwardedHeaders === false){ | ||
return; | ||
} | ||
if (req.headers.host) { | ||
@@ -133,0 +136,0 @@ headers['x-forwarded-host'] = req.headers['x-forwarded-host'] || req.headers.host; |
@@ -36,2 +36,3 @@ 'use strict'; | ||
var staticResourceHandler = require('./middleware/static-resource-handler'); | ||
var routeResponseHeadersHandler = require('./middleware/route-response-headers-handler'); | ||
var traceRequestMiddleware = require('./middleware/trace-request-middleware'); | ||
@@ -48,2 +49,3 @@ var welcomePageMiddleware = require('./middleware/welcome-page-middleware'); | ||
var service2ApprouterMiddleware = require('./middleware/service-to-approuter-middleware'); | ||
var subscriptionUtils = require('./utils/subscription-utils'); | ||
@@ -65,3 +67,3 @@ module.exports = function bootstrap(options) { | ||
app.use(traceRequestMiddleware); | ||
app.use('/callback/v1.0/tenants', bodyParser.json()); | ||
app.use(subscriptionUtils.getCallbackPath().onSubscriptionPrefix, bodyParser.json()); | ||
@@ -130,2 +132,3 @@ ext.insertMiddleware('first', app); | ||
app.use(httpMethodMatchingMiddleware); | ||
app.use(routeResponseHeadersHandler); | ||
app.use(staticResourceHandler); | ||
@@ -132,0 +135,0 @@ app.use(sessionCookieMiddleware(cookieName)); |
@@ -133,3 +133,2 @@ 'use strict'; | ||
externalReverseProxy: loadJsonVar('EXTERNAL_REVERSE_PROXY') | ||
}; | ||
@@ -136,0 +135,0 @@ |
@@ -12,3 +12,4 @@ { | ||
"timeout": { "type": "integer", "minimum": 1 }, | ||
"proxyType": { "type": "string", "enum": ["OnPremise"] } | ||
"proxyType": { "type": "string", "enum": ["OnPremise"] }, | ||
"setXForwardedHeaders": {"type": "boolean"} | ||
}, | ||
@@ -15,0 +16,0 @@ "required": ["name", "url"], |
@@ -29,12 +29,2 @@ { | ||
}, | ||
"authentication": { | ||
"type": "string", | ||
"minLength": 1, | ||
"enum": [ | ||
"BasicAuthentication", | ||
"NoAuthentication", | ||
"PrincipalPropagation", | ||
"OAuth2SAMLBearerAssertion" | ||
] | ||
}, | ||
"cloudConnectorLocationId": { | ||
@@ -50,2 +40,8 @@ "type": "string", | ||
}, | ||
"dynamicDestination": { | ||
"type": "boolean" | ||
}, | ||
"setXForwardedHeaders": { | ||
"type": "boolean" | ||
}, | ||
"sap-client": { | ||
@@ -52,0 +48,0 @@ "type": "string", |
@@ -113,3 +113,3 @@ 'use strict'; | ||
} else { | ||
var forbiddenProperties = ['replace', 'cacheControl']; | ||
var forbiddenProperties = ['replace']; | ||
for (var i = 0; i < forbiddenProperties.length; i++) { | ||
@@ -163,12 +163,6 @@ if (route[forbiddenProperties[i]]) { | ||
} | ||
if (destination.authentication && destination.authentication === 'PrincipalPropagation' && destination.proxyType === 'Internet') { | ||
throw 'the destination \"' + destination.name + | ||
'\" with \"PrincipalPropagation\" authentication type and \"Internet\" proxy type is not supported, ' + | ||
'please check the destination definition in the destinations service.'; | ||
if (destination.forwardAuthToken === true && destination.authentication && destination.authentication !== 'NoAuthentication') { | ||
throw 'Destination \"' + destination.name + | ||
' - ForwardAuthToken parameter cannot be used in destinations with authentication type not equal NoAuthentication'; | ||
} | ||
if (destination.authentication && destination.authentication === 'BasicAuthentication' && !destination.user) { | ||
throw 'the destination \"' + destination.name + | ||
'\" with \"BasicAuthentication\" authentication missing user and/or password property, ' + | ||
'please check the destination definition in the destinations service.'; | ||
} | ||
if (destination.proxyType === 'OnPremise') { | ||
@@ -175,0 +169,0 @@ if (destination.forwardAuthToken) { |
'use strict'; | ||
var xsenv = require('@sap/xsenv'); | ||
var urlUtils = require('../utils/url-utils'); | ||
var uaaUtils = require('../utils/uaa-utils'); | ||
module.exports = function isAuthorized(req) { | ||
module.exports = function checkAuthorization(req) { | ||
if (!req.internalUrl || req.internalUrl.route.authenticationType === 'none') { | ||
return true; | ||
return {isAuthorized: true}; | ||
} | ||
var scopesMessage = 'You do not have the required scopes to access this resource.'; | ||
var tenantMessage = 'You cannot use session from another tenant.'; | ||
var loggingData = getAuditLogAdditionalData (req); | ||
var auditLogMessage; | ||
var uaaConfig = req.routerConfig && req.routerConfig.uaaConfig; | ||
var tenantMode = uaaConfig && uaaConfig.options && uaaConfig.options.tenantmode; | ||
if (tenantMode === 'shared') { | ||
var tenantHostPattern = uaaConfig && uaaConfig.tenantHostPattern; | ||
var urlTenant = uaaUtils.retrieveTenantFromURL (urlUtils.getAppRouterHost(req), tenantHostPattern); | ||
if (urlTenant && req.session && req.session.user && req.session.user.tenant && | ||
urlTenant !== req.session.user.tenant) { | ||
auditLogMessage = 'User not authorized, IP: ' + | ||
loggingData.IP + ', JWT token tenant: ' + req.session.user.tenant + ', URL tenant: ' + urlTenant; | ||
writeToAuditLog (req, loggingData.user, auditLogMessage); | ||
return {isAuthorized: false, message: tenantMessage}; | ||
} | ||
} | ||
var routeScopes = req.internalUrl.route.scope; | ||
if (!routeScopes) { | ||
return true; | ||
return {isAuthorized: true}; | ||
} | ||
@@ -19,3 +41,3 @@ if (!Array.isArray(routeScopes)) { | ||
if (!oauthScopes) { | ||
return false; | ||
return {isAuthorized: false, message: scopesMessage}; | ||
} | ||
@@ -26,28 +48,41 @@ | ||
}); | ||
var result = {isAuthorized: isAuthorized}; | ||
if (!isAuthorized) { | ||
var userToLog = req.session.user.name; | ||
var auditlogCredentials; | ||
auditLogMessage = 'User not authorized, source of route: ' + req.internalUrl.route.source + ', IP: ' + | ||
loggingData.IP + ', required scopes: ' + routeScopes + ', user scopes: ' + oauthScopes; | ||
writeToAuditLog (req, loggingData.user, auditLogMessage); | ||
result.message = scopesMessage; | ||
} | ||
try { | ||
auditlogCredentials = xsenv.cfServiceCredentials({tag: 'auditlog'}); | ||
} catch (error){ | ||
auditlogCredentials = null; | ||
} | ||
return result; | ||
}; | ||
var IP = req.headers['x-forwarded-for'] || req.connection.remoteAddress; | ||
if (!auditlogCredentials) { | ||
userToLog = '******'; | ||
IP = '******'; | ||
} | ||
var message = 'User not authorized, source of route: ' + req.internalUrl.route.source + ', IP: ' + IP + ', required scopes: ' + routeScopes + ', user scopes: ' + oauthScopes; | ||
req.app.auditLogger.securityMessage(message) | ||
.by(userToLog) | ||
.log(function (err) { | ||
if (err) { | ||
throw err; | ||
} | ||
}); | ||
function writeToAuditLog (req, userToLog, message) { | ||
req.app.auditLogger.securityMessage(message) | ||
.by(userToLog) | ||
.log(function (err) { | ||
if (err) { | ||
throw err; | ||
} | ||
}); | ||
} | ||
function getAuditLogAdditionalData (req) { | ||
var userToLog = req.session.user && req.session.user.name; | ||
var auditlogCredentials; | ||
try { | ||
auditlogCredentials = xsenv.cfServiceCredentials({tag: 'auditlog'}); | ||
} catch (error){ | ||
auditlogCredentials = null; | ||
} | ||
return isAuthorized; | ||
}; | ||
var IP = req.headers['x-forwarded-for'] || req.connection.remoteAddress; | ||
if (!auditlogCredentials) { | ||
userToLog = '******'; | ||
IP = '******'; | ||
} | ||
return {user: userToLog, IP: IP}; | ||
} |
'use strict'; | ||
var isAuthorised = require('./authorization-handler'); | ||
var checkAuthorization = require('./authorization-handler'); | ||
module.exports = function authorizationCheck(req, res, next) { | ||
if (isAuthorised(req)) { | ||
var authorizationResult = checkAuthorization (req); | ||
if (authorizationResult.isAuthorized) { | ||
next(); | ||
} else { | ||
var error = new Error('You do not have the required scopes to access this resource.'); | ||
var error = new Error(authorizationResult.message); | ||
error.status = 403; | ||
@@ -12,0 +13,0 @@ next(error); |
@@ -30,7 +30,2 @@ 'use strict'; | ||
} | ||
// if forwardToken is true and the authentication type is not NoAuthentication | ||
// (it means that we got authToken from destination service) ==> throw error | ||
if (destinationLookUpResult.destinationConfiguration.forwardAuthToken === 'true' && destinationLookUpResult.destinationConfiguration.Authentication !== 'NoAuthentication') { | ||
return cb('Wrong configuration of destination ' + destinationName + ': forwardToken cannot be set to true for destination with authentication'); | ||
} | ||
if (destinationLookUpResult.authTokens) { | ||
@@ -51,2 +46,5 @@ var authTokenExpiresIn = destinationLookUpResult.authTokens[0].expires_in; | ||
result.destination = destinations[0]; | ||
if (options.dynamicDestination && !result.destination.dynamicDestination){ | ||
return cb('Destination ' + destinationName + ' is not defined as a dynamic destination in destination service, configure additional property HTML5.DynamicDestination true'); | ||
} | ||
result.authToken = destinationLookUpResult.authTokens ? destinationLookUpResult.authTokens[0] : null; | ||
@@ -53,0 +51,0 @@ return cb(null, result); |
@@ -12,3 +12,7 @@ 'use strict'; | ||
} | ||
var options = {destinationName: req.internalUrl.route.destination, session: req.session, app: req.app}; | ||
var options = { | ||
destinationName: req.internalUrl.route.destination, | ||
session: req.session, app: req.app, | ||
dynamicDestination:req.internalUrl.destination.dynamicDestination | ||
}; | ||
if (req.routerConfig && req.routerConfig.getToken) { | ||
@@ -40,3 +44,3 @@ req.routerConfig.getToken(req, function (err, jwt) { | ||
if (!req.session.user.destinations){ | ||
req.session.user.destinations = []; | ||
req.session.user.destinations = {}; | ||
} | ||
@@ -56,4 +60,4 @@ if (!req.session.user.destinationUserExchangeToken){ | ||
} | ||
return next(); | ||
}); | ||
return next(); | ||
}); | ||
@@ -60,0 +64,0 @@ } |
@@ -5,6 +5,9 @@ 'use strict'; | ||
var dynamicRoutingUtils = require('../utils/dynamic-routing-utils'); | ||
var urijs = require('urijs'); | ||
module.exports = function(req, res, next) { | ||
var coreUrl = dynamicRoutingUtils.getCoreUrl(req); | ||
var parsedUrl = urijs.parse(coreUrl); | ||
if (req.method === 'GET' && req.routerConfig.appConfig.logout && req.routerConfig.appConfig.logout.logoutEndpoint && | ||
dynamicRoutingUtils.getCoreUrl(req) === req.routerConfig.appConfig.logout.logoutEndpoint) { | ||
parsedUrl.path === req.routerConfig.appConfig.logout.logoutEndpoint) { | ||
return logoutProvider.centralLogout(req, res); | ||
@@ -11,0 +14,0 @@ } |
@@ -182,2 +182,10 @@ 'use strict'; | ||
} | ||
// concat query parameters for logout page, if exists | ||
var queryParams = URI.parse(req.url).query; | ||
if (queryParams) { | ||
logoutPage = logoutPage + '?' + queryParams; | ||
} | ||
var uri = URI.parse(logoutPage); | ||
@@ -184,0 +192,0 @@ if (uri.protocol && uri.hostname) { |
@@ -70,2 +70,3 @@ 'use strict'; | ||
if (destination) { | ||
var dynamicDestination = false; | ||
if (route.destination === '*'){ | ||
@@ -76,7 +77,9 @@ var hostname = urlUtils.getAppRouterHost(req); | ||
destination = destinationHostPatternMatches && destinationHostPatternMatches[1]; | ||
} else { | ||
destination = !destination.startsWith('$') ? destination : url.replace(route.source, route.destination); | ||
dynamicDestination = true; | ||
} else if (destination.startsWith('$')){ | ||
destination = url.replace(route.source, route.destination); | ||
dynamicDestination = true; | ||
} | ||
var oDestination = routerConfig.destinations[destination] ? | ||
routerConfig.destinations[destination] : {url: 'DESTINATION_URL_PLACEHOLDER', name: destination}; | ||
routerConfig.destinations[destination] : {url: 'DESTINATION_URL_PLACEHOLDER', name: destination, dynamicDestination: dynamicDestination}; | ||
@@ -83,0 +86,0 @@ rewrittenUrl = urlUtils.parse(_.trimEnd(oDestination.url, '/') + '/' + _.trimStart(path, '/')); |
@@ -149,3 +149,4 @@ 'use strict'; | ||
function attachCacheBusterHeaders(req,res){ | ||
if (dynamicRoutingUtils.isDynamicRouting() && req.internalUrl && | ||
var cacheControlHeader = res.getHeaders() && res.getHeaders()['cache-control']; | ||
if (!cacheControlHeader && dynamicRoutingUtils.isDynamicRouting() && req.internalUrl && | ||
req.internalUrl.route && | ||
@@ -152,0 +153,0 @@ dynamicRoutingUtils.isHtml5RepoService(req.internalUrl.route.service) && |
@@ -19,4 +19,2 @@ 'use strict'; | ||
var fullDirName = path.resolve(routerConfig.workingDir, url.route.localDir); | ||
var cacheControl = url.route.cacheControl; | ||
cacheControl && res.setHeader('Cache-Control', cacheControl); | ||
tracer.info('[STATIC] Serving static path:', fullDirName); | ||
@@ -23,0 +21,0 @@ |
@@ -10,3 +10,3 @@ 'use strict'; | ||
var parsedUrl = urijs.parse(req.url); | ||
if (parsedUrl.path === '/callback/v1.0/dependencies'){ | ||
if (parsedUrl.path === subscriptionUtils.getCallbackPath().getDependenciesPath){ | ||
missingBindingErr = isSaaSRegistryBound(); | ||
@@ -28,3 +28,3 @@ if (missingBindingErr){ | ||
}); | ||
} else if (req.url.startsWith('/callback/v1.0/tenants')){ | ||
} else if (req.url.startsWith(subscriptionUtils.getCallbackPath().onSubscriptionPrefix)){ | ||
missingBindingErr = isSaaSRegistryBound(); | ||
@@ -31,0 +31,0 @@ if (missingBindingErr){ |
@@ -10,2 +10,3 @@ 'use strict'; | ||
var cookieUtils = require('../utils/cookie-utils'); | ||
var headerUtil = require('../utils/header-util'); | ||
@@ -63,3 +64,4 @@ module.exports = OAuth2Strategy; | ||
req.res.setHeader('Content-Type', 'text/html'); | ||
req.res.setHeader('Content-Security-Policy', "script-src 'self' 'unsafe-inline'"); | ||
req.res.setHeader('Content-Security-Policy', "script-src 'self' 'unsafe-inline'; frame-ancestors *"); | ||
req.res.setHeader('Cache-Control', headerUtil.NOCACHE_HEADER_VALUE); | ||
req.res.end( | ||
@@ -66,0 +68,0 @@ '<html>' + |
@@ -0,1 +1,2 @@ | ||
'use strict'; | ||
@@ -42,11 +43,13 @@ | ||
var requestStart = Date.now(); | ||
/* eslint-disable camelcase */ | ||
params.client_id = this._options.clientid; | ||
/* eslint-disable camelcase */ | ||
params.client_secret = this._options.clientsecret; | ||
var requestOptions = { | ||
headers: this._options.customHeaders, | ||
url: this._options.tokenURL, | ||
auth: { | ||
user: this._options.clientid, | ||
pass: this._options.clientsecret | ||
}, | ||
form: params | ||
}; | ||
passportUtils.callUaa(requestOptions, null, function (err, uaaResponse) { | ||
@@ -53,0 +56,0 @@ if (err) { |
@@ -28,3 +28,4 @@ 'use strict'; | ||
getUserProperties: function (options) { | ||
var userName = jwtDecode(options.accessToken).user_name; | ||
var token = jwtDecode(options.accessToken); | ||
var userName = token.user_name; | ||
var scopes = []; | ||
@@ -44,3 +45,4 @@ if (options.scope) | ||
}, | ||
scopes: scopes | ||
scopes: scopes, | ||
tenant: token.ext_attr && token.ext_attr.zdn | ||
}; | ||
@@ -47,0 +49,0 @@ }, |
@@ -40,13 +40,26 @@ 'use strict'; | ||
getEndPoint: function (serviceCredentials, endPoint) { | ||
if (endPoint) { | ||
getEndPoint: function (serviceCredentials, endPointName) { | ||
var endPoint = {}; | ||
if (endPointName) { | ||
if (serviceCredentials.endpoints) { | ||
return {'url': serviceCredentials.endpoints[endPoint] + '/'}; | ||
if (typeof(serviceCredentials.endpoints[endPointName]) === 'string') { | ||
endPoint.url = serviceCredentials.endpoints[endPointName] + '/'; | ||
} else if (typeof(serviceCredentials.endpoints[endPointName]) === 'object') { | ||
endPoint.url = serviceCredentials.endpoints[endPointName].url; | ||
endPoint.timeout = serviceCredentials.endpoints[endPointName].timeout; | ||
} | ||
} | ||
if (serviceCredentials[endPoint]) { | ||
return {'url': serviceCredentials[endPoint] + '/'}; | ||
if (serviceCredentials[endPointName]) { | ||
if (typeof(serviceCredentials[endPointName]) === 'string') { | ||
endPoint.url = serviceCredentials[endPointName] + '/'; | ||
} else if (typeof(serviceCredentials[endPointName]) === 'object'){ | ||
endPoint.url = serviceCredentials[endPointName].url; | ||
endPoint.timeout = serviceCredentials[endPointName].timeout; | ||
} | ||
} | ||
} else { | ||
return serviceCredentials.url ? {'url': serviceCredentials.url + '/'} : {'url': serviceCredentials.uri + '/'}; | ||
endPoint.url = serviceCredentials.url ? serviceCredentials.url + '/' : serviceCredentials.uri + '/'; | ||
} | ||
endPoint.timeout = endPoint.timeout ? endPoint.timeout : 30000; | ||
return endPoint; | ||
}, | ||
@@ -53,0 +66,0 @@ |
@@ -46,2 +46,6 @@ 'use strict'; | ||
destinations[i].preserveHostHeader = destinations[i].preserveHostHeader === 'true' || destinations[i].preserveHostHeader === true; | ||
destinations[i].dynamicDestination = destinations[i].dynamicDestination === 'true' || destinations[i].dynamicDestination === true; | ||
if (destinations[i].hasOwnProperty('setXForwardedHeaders')) { | ||
destinations[i].setXForwardedHeaders = destinations[i].setXForwardedHeaders === 'true' || destinations[i].setXForwardedHeaders === true; | ||
} | ||
if (destinations[i].timeout && !isNaN(destinations[i].timeout)) { | ||
@@ -90,4 +94,6 @@ destinations[i].timeout = _.toSafeInteger(destinations[i].timeout); | ||
{ | ||
var value = destination[key]; | ||
key = key.replace('HTML5.', ''); | ||
var newKey = key.substr(0, 1).toLowerCase() + key.substr(1); | ||
newobj[newKey] = destination[key]; | ||
newobj[newKey] = value; | ||
} | ||
@@ -134,2 +140,5 @@ } | ||
if (err || !res || !res.statusCode) { | ||
if (err){ | ||
logger.error('Destination error: ' + err); | ||
} | ||
return cb('Error while retrieving destination ' + destinationName + ' from destination service'); | ||
@@ -150,2 +159,2 @@ } | ||
}); | ||
} | ||
} |
@@ -9,2 +9,3 @@ 'use strict'; | ||
var uaaUtils = require('./uaa-utils'); | ||
var urijs = require('urijs'); | ||
@@ -15,2 +16,3 @@ exports.getDependencies = getDependencies; | ||
exports.getError = getError; | ||
exports.getCallbackPath = getCallbackPath; | ||
@@ -109,3 +111,3 @@ function checkScopes(req, cb){ | ||
var cred = env[svcName][0].credentials; | ||
if (svcName === 'destination'){ | ||
if (svcName === 'destination' || svcName === 'connectivity'){ | ||
appId = cred.xsappname; | ||
@@ -133,3 +135,29 @@ appName = svcName; | ||
function getCallbackPath(){ | ||
var callBackPath = { | ||
getDependenciesPath: '/callback/v1.0/dependencies', | ||
onSubscriptionPrefix: '/callback/v1.0/tenants' | ||
}; | ||
if (process.env.VCAP_SERVICES) | ||
{ | ||
var env = JSON.parse(process.env.VCAP_SERVICES); | ||
if (env['saas-registry']) { | ||
var appUrls = env['saas-registry'][0].credentials.appUrls; | ||
if (appUrls) { | ||
var appUrlsJson = JSON.parse(appUrls); | ||
var parsedUrl = urijs.parse(appUrlsJson.getDependencies); | ||
callBackPath.getDependenciesPath = parsedUrl.path; | ||
parsedUrl = urijs.parse(appUrlsJson.onSubscription); | ||
let index = parsedUrl.path.indexOf('/{tenantId}'); | ||
if (index > 0){ | ||
parsedUrl.path = parsedUrl.path.substring(0,index); | ||
} | ||
callBackPath.onSubscriptionPrefix = parsedUrl.path; | ||
} | ||
} | ||
} | ||
return callBackPath; | ||
} | ||
@@ -11,2 +11,3 @@ 'use strict'; | ||
exports.resolveUaaConfig = resolveUaaConfig; | ||
exports.retrieveTenantFromURL = retrieveTenantFromURL; | ||
@@ -34,5 +35,3 @@ exports.getUaaConfig = function(req, cb) { | ||
function tenantUaaConfigResolver(uaaOptions, requestHost, tenantHostPattern) { | ||
requestHost = requestHost.split(':')[0]; // remove port | ||
var tenantHostPatternMatches = tenantHostPattern.exec(requestHost); | ||
var tenant = tenantHostPatternMatches && tenantHostPatternMatches[1]; | ||
var tenant = retrieveTenantFromURL (requestHost, tenantHostPattern); | ||
uaaOptions.tenant = tenant; | ||
@@ -59,1 +58,8 @@ var tenantUaaHost = (tenant ? tenant + '.' : '') + uaaOptions.uaadomain; | ||
} | ||
function retrieveTenantFromURL (approuterHost, tenantHostPattern) { | ||
approuterHost = approuterHost.split(':')[0]; // remove port | ||
var tenantHostPatternMatches = tenantHostPattern.exec(approuterHost); | ||
var tenant = tenantHostPatternMatches && tenantHostPatternMatches[1]; | ||
return tenant; | ||
} |
@@ -24,2 +24,3 @@ 'use strict'; | ||
var dynamicRoutingUtils = require('../utils/dynamic-routing-utils'); | ||
var destinationTokenMiddleware = require('../middleware/destination-token-middleware'); | ||
@@ -125,26 +126,31 @@ module.exports = WsProxy; | ||
function createBackendConnection(req, cb) { | ||
var targetUrl = req.internalUrl; | ||
var url = targetUrl.href; | ||
var tracer = getTracer(req); | ||
tracer.debug('[websockets] connecting to backend server: %s', url); | ||
var outgoing; | ||
destinationTokenMiddleware(req,{},function (err) { | ||
if (err) { | ||
return reportError(err, tracer, cb); | ||
} | ||
var targetUrl = req.internalUrl; | ||
var url = targetUrl.href; | ||
tracer.debug('[websockets] connecting to backend server: %s', url); | ||
var outgoing; | ||
try { | ||
outgoing = new WebSocket(url, { | ||
agent: agents.get(targetUrl.protocol, buildProxyUri(targetUrl.destination)), | ||
headers: getHeaders(req), | ||
rejectUnauthorized: !(targetUrl.destination.strictSSL === false) | ||
try { | ||
outgoing = new WebSocket(url, { | ||
agent: agents.get(targetUrl.protocol, buildProxyUri(targetUrl.destination)), | ||
headers: getHeaders(req), | ||
rejectUnauthorized: !(targetUrl.destination.strictSSL === false) | ||
}); | ||
} catch (err) { | ||
return reportError(new VError(err, 'Could not connect to backend server'), tracer, cb); | ||
} | ||
var errorHandler = function (err) { | ||
reportError(new VError(err, 'Outgoing connection error occurred'), tracer, cb); | ||
}; | ||
outgoing.on('error', errorHandler); | ||
outgoing.on('open', function () { | ||
tracer.debug('[websockets] outgoing connection opened'); | ||
req.backendSocket = outgoing; | ||
outgoing.removeListener('error', errorHandler); | ||
cb(true); | ||
}); | ||
} catch (err) { | ||
return reportError(new VError(err, 'Could not connect to backend server'), tracer, cb); | ||
} | ||
var errorHandler = function (err) { | ||
reportError(new VError(err, 'Outgoing connection error occurred'), tracer, cb); | ||
}; | ||
outgoing.on('error', errorHandler); | ||
outgoing.on('open', function () { | ||
tracer.debug('[websockets] outgoing connection opened'); | ||
req.backendSocket = outgoing; | ||
outgoing.removeListener('error', errorHandler); | ||
cb(true); | ||
}); | ||
@@ -151,0 +157,0 @@ } |
@@ -1,1 +0,1 @@ | ||
{"bundleDependencies":false,"dependencies":{"@sap/audit-logging":"2.3.0","@sap/e2e-trace":"1.4.1","@sap/logging":"5.0.2","@sap/xsenv":"1.3.0","@sap/xssec":"2.1.16","agentkeepalive":"2.0.5","async":"2.0.1","base64-url":"2.0.0","basic-auth":"1.0.3","body-parser":"1.18.3","commander":"2.9.0","compression":"1.7.3","connect":"3.6.5","cookie":"0.2.2","cookie-parser":"1.3.5","cookie-signature":"1.1.0","debug":"3.1.0","deepmerge":"2.1.1","encodeurl":"1.0.2","express-session":"1.15.6","http-proxy-agent":"2.1.0","https-proxy-agent":"2.2.0","jwt-decode":"2.0.1","lodash":"4.17.13","lru-cache":"4.0.0","mime":"1.4.1","moment":"2.19.3","ms":"2.1.1","mustache":"2.2.1","node-cache":"4.1.1","passport":"0.3.2","request":"2.87.0","request-stats":"2.0.1","safe-regex":"1.1.0","scmp":"1.0.0","send":"0.16.2","serve-static":"1.13.2","tough-cookie":"2.3.3","tv4":"1.2.7","uid-safe":"2.1.5","urijs":"1.16.1","uuid":"3.2.1","verror":"1.10.0","ws":"1.1.5"},"deprecated":false,"description":"Node.js based application router","devDependencies":{"chai":"3.5.0","diveSync":"0.3.0","eslint":"3.2.2","express":"4.16.2","filter-node-package":"2.0.0","gulp":"^3.9.1","gulp-eslint":"^4.0.0","gulp-mocha":"^4.3.1","istanbul":"0.4.4","markdown-toc":"1.1.0","mocha":"3.0.2","mock-require":"3.0.2","node-build":"1.0.0","node-mocks-http":"1.5.2","node-style":"^2.0.0","proxyquire":"1.7.10","rewire":"2.5.2","rimraf":"2.5.4","sinon":"1.17.5","sonarqube-scanner":"^2.1.2","supertest":"3.3.0"},"engines":{"node":"^8.0.0 || ^10.0.0"},"main":"approuter.js","name":"@sap/approuter","repository":{},"scripts":{"lint":"eslint -c node_modules/node-style/.eslintrc -f stylish lib/ approuter.js","prepareRelease":"node build/delete-extra-packages.js && clean-packages && npm prune --production","sonar":"gulp sonarqube","start":"node approuter.js","test":"node build/test","toc":"markdown-toc -i README.md && markdown-toc -i doc/extending.md && markdown-toc -i doc/sizingGuide.md"},"version":"6.0.2","license":"SEE LICENSE IN developer-license-3.1.txt"} | ||
{"bundleDependencies":false,"dependencies":{"@sap/audit-logging":"2.3.0","@sap/e2e-trace":"1.4.1","@sap/logging":"5.0.2","@sap/xsenv":"1.3.0","@sap/xssec":"2.2.2","agentkeepalive":"2.0.5","async":"2.0.1","base64-url":"2.0.0","basic-auth":"1.0.3","body-parser":"1.18.3","commander":"2.9.0","compression":"1.7.3","connect":"3.6.5","cookie":"0.2.2","cookie-parser":"1.3.5","cookie-signature":"1.1.0","debug":"3.1.0","deepmerge":"2.1.1","encodeurl":"1.0.2","express-session":"1.15.6","http-proxy-agent":"2.1.0","https-proxy-agent":"2.2.0","jwt-decode":"2.0.1","lodash":"4.17.13","lru-cache":"4.0.0","mime":"1.4.1","moment":"2.19.3","ms":"2.1.1","mustache":"2.2.1","node-cache":"4.1.1","passport":"0.3.2","request":"2.87.0","request-stats":"2.0.1","safe-regex":"1.1.0","scmp":"1.0.0","send":"0.16.2","serve-static":"1.13.2","tough-cookie":"2.3.3","tv4":"1.2.7","uid-safe":"2.1.5","urijs":"1.16.1","uuid":"3.2.1","verror":"1.10.0","ws":"1.1.5"},"deprecated":false,"description":"Node.js based application router","devDependencies":{"chai":"3.5.0","diveSync":"0.3.0","eslint":"3.2.2","express":"4.16.2","filter-node-package":"2.0.0","gulp":"^3.9.1","gulp-eslint":"^4.0.0","gulp-mocha":"^4.3.1","istanbul":"0.4.4","markdown-toc":"1.1.0","mocha":"3.0.2","mock-require":"3.0.2","node-build":"1.0.0","node-mocks-http":"1.5.2","node-style":"^2.0.0","proxyquire":"1.7.10","rewire":"2.5.2","rimraf":"2.5.4","sinon":"1.17.5","sonarqube-scanner":"^2.1.2","supertest":"3.3.0"},"engines":{"node":"^8.0.0 || ^10.0.0"},"main":"approuter.js","name":"@sap/approuter","repository":{},"scripts":{"lint":"eslint -c node_modules/node-style/.eslintrc -f stylish lib/ approuter.js","prepareRelease":"node build/delete-extra-packages.js && clean-packages && npm prune --production","sonar":"gulp sonarqube","start":"node approuter.js","test":"node build/test","toc":"markdown-toc -i README.md && markdown-toc -i doc/extending.md && markdown-toc -i doc/sizingGuide.md"},"version":"6.5.0","license":"SEE LICENSE IN developer-license-3.1.txt"} |
Sorry, the diff of this file is too big to display
Sorry, the diff of this file is not supported yet
1072600
115
6263
1949
31
1
+ Added@sap/xsenv@2.2.0(transitive)
+ Added@sap/xssec@2.2.2(transitive)
+ Addeddebug@4.1.1(transitive)
+ Addedlru-cache@5.1.1(transitive)
+ Addedms@2.1.3(transitive)
+ Addedyallist@3.1.1(transitive)
- Removed@sap/xssec@2.1.16(transitive)
- Removedlru-cache@4.1.1(transitive)
Updated@sap/xssec@2.2.2