2018-03-06 16:20:04 -05:00
|
|
|
/* eslint-env node */
|
|
|
|
|
2018-04-06 12:43:34 -04:00
|
|
|
const is = require('@sindresorhus/is');
|
2018-04-06 12:40:26 -04:00
|
|
|
const path = require('path');
|
2018-03-06 16:20:04 -05:00
|
|
|
|
2018-04-02 15:08:53 -04:00
|
|
|
const { compose } = require('lodash/fp');
|
2018-04-06 12:43:34 -04:00
|
|
|
const { escapeRegExp } = require('lodash');
|
2018-03-06 16:20:04 -05:00
|
|
|
|
2018-04-06 12:54:29 -04:00
|
|
|
const APP_ROOT_PATH = path.join(__dirname, '..', '..', '..');
|
2018-03-06 16:20:04 -05:00
|
|
|
const PHONE_NUMBER_PATTERN = /\+\d{7,12}(\d{3})/g;
|
|
|
|
const GROUP_ID_PATTERN = /(group\()([^)]+)(\))/g;
|
2018-04-06 12:54:29 -04:00
|
|
|
const REDACTION_PLACEHOLDER = '[REDACTED]';
|
2018-03-06 16:20:04 -05:00
|
|
|
|
2018-04-06 12:54:29 -04:00
|
|
|
// _redactPath :: Path -> String -> String
|
2018-04-27 17:25:04 -04:00
|
|
|
exports._redactPath = filePath => {
|
2018-04-06 12:54:29 -04:00
|
|
|
if (!is.string(filePath)) {
|
2018-04-11 15:44:52 -04:00
|
|
|
throw new TypeError("'filePath' must be a string");
|
2018-04-06 12:54:29 -04:00
|
|
|
}
|
|
|
|
|
|
|
|
const filePathPattern = exports._pathToRegExp(filePath);
|
|
|
|
|
2018-04-27 17:25:04 -04:00
|
|
|
return text => {
|
2018-04-06 12:54:29 -04:00
|
|
|
if (!is.string(text)) {
|
2018-04-11 15:44:52 -04:00
|
|
|
throw new TypeError("'text' must be a string");
|
2018-04-06 12:54:29 -04:00
|
|
|
}
|
|
|
|
|
|
|
|
if (!is.regExp(filePathPattern)) {
|
|
|
|
return text;
|
|
|
|
}
|
|
|
|
|
|
|
|
return text.replace(filePathPattern, REDACTION_PLACEHOLDER);
|
|
|
|
};
|
|
|
|
};
|
|
|
|
|
|
|
|
// _pathToRegExp :: Path -> Maybe RegExp
|
2018-04-27 17:25:04 -04:00
|
|
|
exports._pathToRegExp = filePath => {
|
2018-03-07 10:57:39 -05:00
|
|
|
try {
|
2018-04-06 13:19:41 -04:00
|
|
|
const pathWithNormalizedSlashes = filePath.replace(/\//g, '\\');
|
2018-04-06 14:25:55 -04:00
|
|
|
const pathWithEscapedSlashes = filePath.replace(/\\/g, '\\\\');
|
2018-04-06 13:19:41 -04:00
|
|
|
const urlEncodedPath = encodeURI(filePath);
|
2018-03-07 10:57:39 -05:00
|
|
|
// Safe `String::replaceAll`:
|
|
|
|
// https://github.com/lodash/lodash/issues/1084#issuecomment-86698786
|
2018-04-06 13:19:41 -04:00
|
|
|
const patternString = [
|
|
|
|
filePath,
|
|
|
|
pathWithNormalizedSlashes,
|
2018-04-06 14:25:55 -04:00
|
|
|
pathWithEscapedSlashes,
|
2018-04-06 13:19:41 -04:00
|
|
|
urlEncodedPath,
|
2018-04-27 17:25:04 -04:00
|
|
|
]
|
|
|
|
.map(escapeRegExp)
|
|
|
|
.join('|');
|
2018-04-06 13:19:41 -04:00
|
|
|
return new RegExp(patternString, 'g');
|
2018-03-07 10:57:39 -05:00
|
|
|
} catch (error) {
|
|
|
|
return null;
|
|
|
|
}
|
2018-04-06 12:54:29 -04:00
|
|
|
};
|
2018-03-06 16:20:04 -05:00
|
|
|
|
2018-04-06 12:54:29 -04:00
|
|
|
// Public API
|
2018-03-06 16:20:04 -05:00
|
|
|
// redactPhoneNumbers :: String -> String
|
2018-04-27 17:25:04 -04:00
|
|
|
exports.redactPhoneNumbers = text => {
|
2018-04-06 12:43:34 -04:00
|
|
|
if (!is.string(text)) {
|
2018-04-11 15:44:52 -04:00
|
|
|
throw new TypeError("'text' must be a string");
|
2018-03-06 16:20:04 -05:00
|
|
|
}
|
|
|
|
|
|
|
|
return text.replace(PHONE_NUMBER_PATTERN, `+${REDACTION_PLACEHOLDER}$1`);
|
|
|
|
};
|
|
|
|
|
|
|
|
// redactGroupIds :: String -> String
|
2018-04-27 17:25:04 -04:00
|
|
|
exports.redactGroupIds = text => {
|
2018-04-06 12:43:34 -04:00
|
|
|
if (!is.string(text)) {
|
2018-04-11 15:44:52 -04:00
|
|
|
throw new TypeError("'text' must be a string");
|
2018-03-06 16:20:04 -05:00
|
|
|
}
|
|
|
|
|
|
|
|
return text.replace(
|
|
|
|
GROUP_ID_PATTERN,
|
|
|
|
(match, before, id, after) =>
|
2018-05-03 11:46:21 -04:00
|
|
|
`${before}${REDACTION_PLACEHOLDER}${removeNewlines(id).slice(-3)}${after}`
|
2018-03-06 16:20:04 -05:00
|
|
|
);
|
|
|
|
};
|
|
|
|
|
|
|
|
// redactSensitivePaths :: String -> String
|
2018-04-06 12:54:29 -04:00
|
|
|
exports.redactSensitivePaths = exports._redactPath(APP_ROOT_PATH);
|
2018-03-06 16:20:04 -05:00
|
|
|
|
|
|
|
// redactAll :: String -> String
|
|
|
|
exports.redactAll = compose(
|
|
|
|
exports.redactSensitivePaths,
|
|
|
|
exports.redactGroupIds,
|
|
|
|
exports.redactPhoneNumbers
|
|
|
|
);
|
2018-05-03 11:46:21 -04:00
|
|
|
|
|
|
|
const removeNewlines = text => text.replace(/\r?\n|\r/g, '');
|