Add user path to logging exceptions
This commit is contained in:
parent
0e19c17160
commit
33595646c1
7 changed files with 60 additions and 41 deletions
126
ts/util/privacy.ts
Normal file
126
ts/util/privacy.ts
Normal file
|
@ -0,0 +1,126 @@
|
|||
// Copyright 2018-2021 Signal Messenger, LLC
|
||||
// SPDX-License-Identifier: AGPL-3.0-only
|
||||
|
||||
/* eslint-env node */
|
||||
|
||||
import is from '@sindresorhus/is';
|
||||
import { join as pathJoin } from 'path';
|
||||
|
||||
import { compose } from 'lodash/fp';
|
||||
import { escapeRegExp } from 'lodash';
|
||||
|
||||
export const APP_ROOT_PATH = pathJoin(__dirname, '..', '..');
|
||||
|
||||
const PHONE_NUMBER_PATTERN = /\+\d{7,12}(\d{3})/g;
|
||||
const UUID_PATTERN = /[0-9A-F]{8}-[0-9A-F]{4}-4[0-9A-F]{3}-[89AB][0-9A-F]{3}-[0-9A-F]{9}([0-9A-F]{3})/gi;
|
||||
const GROUP_ID_PATTERN = /(group\()([^)]+)(\))/g;
|
||||
const GROUP_V2_ID_PATTERN = /(groupv2\()([^=)]+)(=?=?\))/g;
|
||||
const REDACTION_PLACEHOLDER = '[REDACTED]';
|
||||
|
||||
export type RedactFunction = (value: string) => string;
|
||||
|
||||
export const _redactPath = (filePath: string): RedactFunction => {
|
||||
if (!is.string(filePath)) {
|
||||
throw new TypeError("'filePath' must be a string");
|
||||
}
|
||||
|
||||
const filePathPattern = exports._pathToRegExp(filePath);
|
||||
|
||||
return (text: string): string => {
|
||||
if (!is.string(text)) {
|
||||
throw new TypeError("'text' must be a string");
|
||||
}
|
||||
|
||||
if (!is.regExp(filePathPattern)) {
|
||||
return text;
|
||||
}
|
||||
|
||||
return text.replace(filePathPattern, REDACTION_PLACEHOLDER);
|
||||
};
|
||||
};
|
||||
|
||||
export const _pathToRegExp = (filePath: string): RegExp | undefined => {
|
||||
try {
|
||||
const pathWithNormalizedSlashes = filePath.replace(/\//g, '\\');
|
||||
const pathWithEscapedSlashes = filePath.replace(/\\/g, '\\\\');
|
||||
const urlEncodedPath = encodeURI(filePath);
|
||||
// Safe `String::replaceAll`:
|
||||
// https://github.com/lodash/lodash/issues/1084#issuecomment-86698786
|
||||
const patternString = [
|
||||
filePath,
|
||||
pathWithNormalizedSlashes,
|
||||
pathWithEscapedSlashes,
|
||||
urlEncodedPath,
|
||||
]
|
||||
.map(escapeRegExp)
|
||||
.join('|');
|
||||
return new RegExp(patternString, 'g');
|
||||
} catch (error) {
|
||||
return undefined;
|
||||
}
|
||||
};
|
||||
|
||||
// Public API
|
||||
export const redactPhoneNumbers = (text: string): string => {
|
||||
if (!is.string(text)) {
|
||||
throw new TypeError("'text' must be a string");
|
||||
}
|
||||
|
||||
return text.replace(PHONE_NUMBER_PATTERN, `+${REDACTION_PLACEHOLDER}$1`);
|
||||
};
|
||||
|
||||
export const redactUuids = (text: string): string => {
|
||||
if (!is.string(text)) {
|
||||
throw new TypeError("'text' must be a string");
|
||||
}
|
||||
|
||||
return text.replace(UUID_PATTERN, `${REDACTION_PLACEHOLDER}$1`);
|
||||
};
|
||||
|
||||
export const redactGroupIds = (text: string): string => {
|
||||
if (!is.string(text)) {
|
||||
throw new TypeError("'text' must be a string");
|
||||
}
|
||||
|
||||
return text
|
||||
.replace(
|
||||
GROUP_ID_PATTERN,
|
||||
(_, before, id, after) =>
|
||||
`${before}${REDACTION_PLACEHOLDER}${removeNewlines(id).slice(
|
||||
-3
|
||||
)}${after}`
|
||||
)
|
||||
.replace(
|
||||
GROUP_V2_ID_PATTERN,
|
||||
(_, before, id, after) =>
|
||||
`${before}${REDACTION_PLACEHOLDER}${removeNewlines(id).slice(
|
||||
-3
|
||||
)}${after}`
|
||||
);
|
||||
};
|
||||
|
||||
const createRedactSensitivePaths = (
|
||||
paths: ReadonlyArray<string>
|
||||
): RedactFunction => {
|
||||
return compose(paths.map(filePath => exports._redactPath(filePath)));
|
||||
};
|
||||
|
||||
const sensitivePaths: Array<string> = [];
|
||||
|
||||
let redactSensitivePaths: RedactFunction = (text: string) => text;
|
||||
|
||||
export const addSensitivePath = (filePath: string): void => {
|
||||
sensitivePaths.push(filePath);
|
||||
redactSensitivePaths = createRedactSensitivePaths(sensitivePaths);
|
||||
};
|
||||
|
||||
addSensitivePath(APP_ROOT_PATH);
|
||||
|
||||
export const redactAll: RedactFunction = compose(
|
||||
(text: string) => redactSensitivePaths(text),
|
||||
redactGroupIds,
|
||||
redactPhoneNumbers,
|
||||
redactUuids
|
||||
);
|
||||
|
||||
const removeNewlines: RedactFunction = text => text.replace(/\r?\n|\r/g, '');
|
Loading…
Add table
Add a link
Reference in a new issue