X-Git-Url: http://git.squeep.com/?a=blobdiff_plain;f=lib%2Fcommon.js;h=21070b8782918f267bf32e3adf96537df08e615a;hb=4778ea0b65e1f22f3d85cfa8bad0e1b29f87b7d3;hp=284427a7bd769742eafda2838b66275951a25de3;hpb=29837f0eeb9fcb4c53426e5bd89e9bdf7e9d961b;p=squeep-api-dingus diff --git a/lib/common.js b/lib/common.js index 284427a..21070b8 100644 --- a/lib/common.js +++ b/lib/common.js @@ -158,19 +158,51 @@ const pick = (obj, props) => { /** * Return a subset of a request object, suitable for logging. + * Obscures sensitive header values. * @param {http.ClientRequest} req */ const requestLogData = (req) => { - return pick(req, [ + const data = pick(req, [ 'method', 'url', 'httpVersion', 'headers', 'trailers', ]); + scrubHeaderObject(data); + return data; }; +/** + * Remove sensitive header data. + * @param {Object} data + * @param {Object} data.headers + */ +const scrubHeaderObject = (data) => { + if (data && data.headers && 'authorization' in data.headers) { + data.headers = Object.assign({}, data.headers, { + authorization: obscureAuthorizationHeader(data.headers['authorization']), + }); + } +} + + +/** + * Hide sensitive part of an Authorization header. + * @param {String} authHeader + * @returns {String} + */ +const obscureAuthorizationHeader = (authHeader) => { + if (!authHeader) { + return authHeader; + } + const space = authHeader.indexOf(' '); + // This blurs entire string if no space found, because -1. + return authHeader.slice(0, space + 1) + '*'.repeat(authHeader.length - (space + 1)); +} + + /** * Return a subset of a response object, suitable for logging. * @param {http.ServerResponse} res @@ -227,6 +259,10 @@ const nullLogger = { debug: nop, }; +/** + * Populates any absent logger levels. + * @param {Object} logger + */ const ensureLoggerLevels = (logger = {}) => { for (const level in nullLogger) { if (! (level in logger)) { @@ -236,22 +272,45 @@ const ensureLoggerLevels = (logger = {}) => { return logger; }; +/** + * Merges folded header lines + * @param {String[]} lines + */ +const unfoldHeaderLines = (lines) => { + const foldedLineRE = /^(\t| +)(.*)$/; + if (lines) { + lines.reduceRight((_, line, idx) => { + const result = foldedLineRE.exec(line); + if (result && idx) { + const prevIdx = idx - 1; + const mergedLine = `${lines[prevIdx]} ${result[2]}`; + lines.splice(prevIdx, 2, mergedLine); + return mergedLine; + } + }, null); + } + return lines; +}; + module.exports = { + ensureLoggerLevels, fileScope, generateETag, get, handlerLogData, - isClientCached, httpStatusCodeClass, + isClientCached, mergeDeep, mergeEnum, nop, nullLogger, - ensureLoggerLevels, + obscureAuthorizationHeader, pick, requestId, requestLogData, responseLogData, + scrubHeaderObject, setOptions, splitFirst, + unfoldHeaderLines, };