UNPKG

openhim-core

Version:

The OpenHIM core application that provides logging and routing of http requests

211 lines (161 loc) 6.02 kB
"use strict"; 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