/**
* 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
debug: nop,
};
+/**
+ * Populates any absent logger levels.
+ * @param {Object} logger
+ */
const ensureLoggerLevels = (logger = {}) => {
for (const level in nullLogger) {
if (! (level in 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,
};