bridge-node-server/node_server/integration_api/int_security.js
Martin Donnelly 57bd6c8e6a init
2018-06-24 21:15:03 +01:00

95 lines
3.1 KiB
JavaScript

/**
* @fileOverview Security handler functions for the integrations API
*/
'use strict';
const debug = require('debug')('integration-api:security');
const config = require(global.configFile);
const utils = require(global.pathPrefix + 'utils.js');
const tokenUtils = require(global.pathPrefix + '../utils/tokens.js');
const hashingUtils = require(global.pathPrefix + '../utils/hashing.js');
module.exports = {
bearer: bearer
};
/**
* Handler for the `bearer` security type. It checks the bearer token is valid,
* and if so it fills in a `req.session` object with relevant session information.
*
*
* @param {Object} req - the express request
* @param {Object} def - the swagger security definition
* @param {string} scopes - the value of the Authorization header
* @param {function(error, v)} callback - Result callback
*/
function bearer(req, def, scopes, callback) {
debug('bridgeSession credentials verification');
//
// Check that there exists at least some value for X-XSRF-TOKEN
//
if (!scopes || scopes.indexOf('Bearer ') !== 0) {
debug('- no credentials supplied');
reportError(callback);
return;
}
//
// Validate the token
//
const token = scopes.substr(7); // Remove the `Bearer ` from the front
const tokenP = tokenUtils.validateToken(token).then(
function onSuccess(result) {
//
// Make a pseudo-session token out of our token. We do this
// by hashing the token, with the Client's _id as salt, then cropping
// the result to our token length. We crop from the end of the string
// to avoid the <version>:: at the start
//
let hashP = hashingUtils.regenerateHash(
+config.passwordCryptoVersion,
result.decoded.token,
result.client._id.toString()
).then((hash) => hash.slice(-1 * utils.tokenLength));
//
// Store the Merchant's client in the session for the controllers to
// access.
//
hashP.then((hash) => {
req.session = {
data: {
PseudoSession: hash,
Merchant: result.client
}
};
callback();
}).catch((err) => {
//
// Some error in generating the hash. Just use the default error
//
reportError(callback);
});
},
function onError(error) {
//
// Don't differentiate sources of error for security reasons
//
reportError(callback);
}
);
}
//
// Function to return a consistent error response for failures to authenticate.
// This function is deliberately light on details so as not to leak extra
// information.
//
// @param {securityCallback} callback - The callback to use for responses
//
function reportError(callback) {
var error = new Error('Not authorised');
error.statusCode = 401;
return callback(error);
}