New Case Study:See how Anthropic automated 95% of dependency reviews with Socket.Learn More
Socket
Sign inDemoInstall
Socket

@sap/approuter

Package Overview
Dependencies
Maintainers
3
Versions
195
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

@sap/approuter - npm Package Compare versions

Comparing version 6.0.2 to 6.5.0

lib/middleware/route-response-headers-handler.js

49

CHANGELOG.md

@@ -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 @@

7

lib/backend-request/headers.js

@@ -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

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc