Skip to content

Commit

Permalink
Merge pull request #53559 from callstack-internal/fix/mask-missing-fi…
Browse files Browse the repository at this point in the history
…elds

fix: mask fields with sensitive data for Export
  • Loading branch information
Gonals authored Dec 12, 2024
2 parents 629a083 + b24b57c commit 05b22e3
Show file tree
Hide file tree
Showing 2 changed files with 39 additions and 2 deletions.
27 changes: 25 additions & 2 deletions src/libs/ExportOnyxState/common.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,23 @@ import ONYXKEYS from '@src/ONYXKEYS';
import type {Session} from '@src/types/onyx';

const MASKING_PATTERN = '***';
const keysToMask = [
'plaidLinkToken',
'plaidAccessToken',
'plaidAccountID',
'addressName',
'addressCity',
'addressStreet',
'addressZipCode',
'street',
'city',
'state',
'zip',
'edits',
'lastMessageHtml',
'lastMessageText',
];

const emailRegex = /[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}/;

const emailMap = new Map<string, string>();
Expand Down Expand Up @@ -94,12 +111,18 @@ const maskFragileData = (data: Record<string, unknown> | unknown[] | null, paren

const value = data[propertyName];

if (typeof value === 'string' && Str.isValidEmail(value)) {
if (keysToMask.includes(key)) {
if (Array.isArray(value)) {
maskedData[key] = value.map(() => MASKING_PATTERN);
} else {
maskedData[key] = MASKING_PATTERN;
}
} else if (typeof value === 'string' && Str.isValidEmail(value)) {
maskedData[propertyName] = maskEmail(value);
} else if (typeof value === 'string' && stringContainsEmail(value)) {
maskedData[propertyName] = replaceEmailInString(value, maskEmail(extractEmail(value) ?? ''));
} else if (parentKey && parentKey.includes(ONYXKEYS.COLLECTION.REPORT_ACTIONS) && (propertyName === 'text' || propertyName === 'html')) {
maskedData[propertyName] = MASKING_PATTERN;
maskedData[key] = MASKING_PATTERN;
} else if (typeof value === 'object') {
maskedData[propertyName] = maskFragileData(value as Record<string, unknown>, propertyName.includes(ONYXKEYS.COLLECTION.REPORT_ACTIONS) ? propertyName : parentKey);
} else {
Expand Down
14 changes: 14 additions & 0 deletions tests/unit/ExportOnyxStateTest.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ import type * as OnyxTypes from '@src/types/onyx';

type ExampleOnyxState = {
session: OnyxTypes.Session;
[key: string]: unknown;
};

describe('maskOnyxState', () => {
Expand Down Expand Up @@ -85,4 +86,17 @@ describe('maskOnyxState', () => {
const result = ExportOnyxState.maskOnyxState(input, true) as Record<string, string>;
expect(result.emailString).not.toContain('[email protected]');
});

it('should mask keys that are in the fixed list', () => {
const input = {
session: mockSession,
edits: ['hey', 'hi'],
lastMessageHtml: 'hey',
};

const result = ExportOnyxState.maskOnyxState(input, true) as ExampleOnyxState;

expect(result.edits).toEqual(['***', '***']);
expect(result.lastMessageHtml).toEqual('***');
});
});

0 comments on commit 05b22e3

Please sign in to comment.