openhim-core
Version:
The OpenHIM core application that provides logging and routing of http requests
211 lines (161 loc) • 6.02 kB
JavaScript
;
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.caseInsensitiveRegex = caseInsensitiveRegex;
exports.isNullOrEmpty = isNullOrEmpty;
exports.isNullOrWhitespace = isNullOrWhitespace;
exports.logAndSetResponse = logAndSetResponse;
exports.getAllChannelsInPriorityOrder = getAllChannelsInPriorityOrder;
exports.getKeystore = getKeystore;
exports.statusCodePatternMatch = statusCodePatternMatch;
exports.uniqArray = uniqArray;
exports.serverTimezone = serverTimezone;
exports.enforceMaxBodiesSize = enforceMaxBodiesSize;
exports.selectAuditFields = selectAuditFields;
exports.MAX_BODIES_SIZE = exports.typeIsArray = void 0;
var _momentTimezone = _interopRequireDefault(require("moment-timezone"));
var _winston = _interopRequireDefault(require("winston"));
var _lodash = _interopRequireDefault(require("lodash"));
var _channels = require("./model/channels");
var _keystore = require("./model/keystore");
var _config = require("./config");
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
_config.config.caching = _config.config.get('caching');
_config.config.api = _config.config.get('api');
/**
* Will take in a string and return a safe regex that will match case insensitive
*
* @export
* @param {string} value that needs to be matched
* @returns {RegExp} regex that will match case insensitive
*/
function caseInsensitiveRegex(value) {
return new RegExp(`^${_lodash.default.escapeRegExp(value)}$`, 'i');
}
function isNullOrEmpty(arr) {
if (arr == null) {
return true;
}
return arr.length === 0;
}
function isNullOrWhitespace(value) {
return /^\s*$/.test(value || '');
} // function to log errors and return response
function logAndSetResponse(ctx, status, msg, logLevel) {
_winston.default[logLevel](msg);
ctx.body = msg;
ctx.status = status;
return status;
}
const cacheValueStore = {};
const {
refreshMillis
} = _config.config.caching;
function getCachedValues(store, callback) {
const lastCheck = cacheValueStore[`${store}`] != null ? cacheValueStore[`${store}`].lastCheck : undefined;
if (!_config.config.caching.enabled || lastCheck == null || new Date() - lastCheck > refreshMillis) {
const handler = (err, results) => {
if (err) {
return callback(err);
}
if (_config.config.caching.enabled) {
if (!lastCheck) {
cacheValueStore[`${store}`] = {};
}
cacheValueStore[`${store}`].value = results;
cacheValueStore[`${store}`].lastCheck = new Date();
}
return callback(null, results);
}; // TODO make this more generic (had issues passing Channel.find as a param [higher order function])
if (store === 'channels') {
return _channels.ChannelModel.find({}).sort({
priority: 1
}).exec((err, channels) => {
if (err) {
return handler(err);
}
const noPriorityChannels = [];
const sortedChannels = [];
channels.forEach(channel => {
if (channel.priority == null) {
return noPriorityChannels.push(channel);
} else {
return sortedChannels.push(channel);
}
});
return handler(null, sortedChannels.concat(noPriorityChannels));
});
} else if (store === 'keystore') {
return _keystore.KeystoreModel.findOne({}, handler);
} else {
return callback(new Error(`Internal error: Invalid store ${store}`));
}
} else {
return callback(null, cacheValueStore[`${store}`].value);
}
}
function getAllChannelsInPriorityOrder(callback) {
return getCachedValues('channels', callback);
}
function getKeystore(callback) {
return getCachedValues('keystore', callback);
} // function to check if string match status code pattern
function statusCodePatternMatch(string, callback) {
return /\dxx/.test(string);
} // returns an array with no duplicates
function uniqArray(arr) {
const dict = arr.reduce((p, c) => {
p[c] = c;
return p;
}, {});
const result = [];
for (const k in dict) {
const v = dict[k];
result.push(v);
}
return result;
} // thanks to https://coffeescript-cookbook.github.io/chapters/arrays/check-type-is-array
const typeIsArray = Array.isArray || (value => ({}).toString.call(value) === '[object Array]'); // get the server timezone
exports.typeIsArray = typeIsArray;
function serverTimezone() {
return _momentTimezone.default.tz.guess();
} // Max size allowed for ALL bodies in the transaction together
// Use min 1 to allow space for all routes on a transation and max 15 MiB leaving 1 MiB available for the transaction metadata
const mbs = _config.config.api.maxBodiesSizeMB;
const MAX_BODIES_SIZE = mbs >= 1 && mbs <= 15 ? mbs * 1024 * 1024 : 15 * 1024 * 1024;
exports.MAX_BODIES_SIZE = MAX_BODIES_SIZE;
const appendText = _config.config.api.truncateAppend;
const appendTextLength = Buffer.byteLength(appendText);
function enforceMaxBodiesSize(ctx, tx) {
let enforced = false; // running total for all bodies
if (ctx.totalBodyLength == null) {
ctx.totalBodyLength = 0;
}
let len = Buffer.byteLength(tx.body);
if (ctx.totalBodyLength + len > MAX_BODIES_SIZE) {
len = Math.max(0, MAX_BODIES_SIZE - ctx.totalBodyLength);
if (len > appendTextLength) {
tx.body = tx.body.slice(0, len - appendTextLength) + appendText;
} else {
tx.body = appendText;
}
enforced = true;
_winston.default.warn('Truncated body for storage as it exceeds limits');
}
ctx.totalBodyLength += len;
return enforced;
}
/**
* Return an object containing the relevant fields for audit logging from the authenticated user.
*
* @param {Object} authenticated The authenticated user.
* @return {Object} The object containing selected audit fields.
*/
function selectAuditFields(authenticated) {
return {
id: authenticated._id,
name: `${authenticated.firstname} ${authenticated.surname}`
};
}
//# sourceMappingURL=utils.js.map