diff --git a/src/libs/ExportOnyxState/common.ts b/src/libs/ExportOnyxState/common.ts index 53034cebb48be..40e7bddfaf6d0 100644 --- a/src/libs/ExportOnyxState/common.ts +++ b/src/libs/ExportOnyxState/common.ts @@ -6,6 +6,7 @@ import type OnyxState from '@src/types/onyx/OnyxState'; import type {MaskOnyxState} from './types'; const MASKING_PATTERN = '***'; + const keysToMask = [ 'plaidLinkToken', 'plaidAccessToken', @@ -21,8 +22,51 @@ const keysToMask = [ 'edits', 'lastMessageHtml', 'lastMessageText', + 'login', + 'avatar', + 'avatarURL', + 'email', + 'remainingWalletLimit', + 'walletLimit', + 'availableBalance', + 'currentBalance', + 'walletLinkedAccountType', + 'walletLimitEnforcementPeriod', + 'tier', + 'tierName', + 'primaryLogin', + 'validateCode', + 'displayName', + 'zipCode', + 'owner', + 'name', + 'oldPolicyName', + 'policyAvatar', + 'policyName', + 'receivableAccount', + 'payableAcct', + 'invoiceItem', + 'payableList', + 'merchant', + 'cardName', + 'cardNumber', + 'amount', + 'comment', + 'bank', + 'modifiedMerchant', + 'originalAmount', ]; +function getMaskingPattern(value: unknown) { + if (typeof value === 'string') { + return '*'.repeat(value.length); + } + if (Array.isArray(value)) { + return value.map((v) => (typeof v === 'string' ? '*'.repeat(v.length) : '')); + } + return MASKING_PATTERN; +} + const onyxKeysToRemove: Array> = [ONYXKEYS.NVP_PRIVATE_PUSH_NOTIFICATION_ID]; const emailRegex = /[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}/; @@ -64,7 +108,7 @@ const maskSessionDetails = (onyxState: OnyxState): OnyxState => { maskedData[key] = session[key as keyof Session]; return; } - maskedData[key] = MASKING_PATTERN; + maskedData[key] = getMaskingPattern(session[key as keyof Session]); }); return { @@ -118,20 +162,20 @@ const maskFragileData = (data: OnyxState | unknown[] | null, parentKey?: string) if (keysToMask.includes(key)) { if (Array.isArray(value)) { - maskedData[key] = value.map(() => MASKING_PATTERN); + maskedData[key] = value.map((v) => getMaskingPattern(v)); } else { - maskedData[key] = MASKING_PATTERN; + maskedData[key] = getMaskingPattern(value); } } 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[key] = MASKING_PATTERN; + maskedData[key] = getMaskingPattern(value); } else if (typeof value === 'object') { maskedData[propertyName] = maskFragileData(value as OnyxState, propertyName.includes(ONYXKEYS.COLLECTION.REPORT_ACTIONS) ? propertyName : parentKey); } else { - maskedData[propertyName] = value; + maskedData[propertyName] = getMaskingPattern(value); } }); diff --git a/tests/unit/ExportOnyxStateTest.ts b/tests/unit/ExportOnyxStateTest.ts index 61fdea1147347..89a9369a59f8f 100644 --- a/tests/unit/ExportOnyxStateTest.ts +++ b/tests/unit/ExportOnyxStateTest.ts @@ -18,8 +18,8 @@ describe('maskOnyxState', () => { const input = {session: mockSession}; const result = ExportOnyxState.maskOnyxState(input) as ExampleOnyxState; - expect(result.session.authToken).toBe('***'); - expect(result.session.encryptedAuthToken).toBe('***'); + expect(result.session.authToken).toBe('********************'); + expect(result.session.encryptedAuthToken).toBe('*************************'); }); it('should not mask fragile data when isMaskingFragileDataEnabled is false', () => { @@ -28,8 +28,8 @@ describe('maskOnyxState', () => { }; const result = ExportOnyxState.maskOnyxState(input) as ExampleOnyxState; - expect(result.session.authToken).toBe('***'); - expect(result.session.encryptedAuthToken).toBe('***'); + expect(result.session.authToken).toBe('********************'); + expect(result.session.encryptedAuthToken).toBe('*************************'); expect(result.session.email).toBe('user@example.com'); }); @@ -39,8 +39,8 @@ describe('maskOnyxState', () => { }; const result = ExportOnyxState.maskOnyxState(input, true) as ExampleOnyxState; - expect(result.session.authToken).toBe('***'); - expect(result.session.encryptedAuthToken).toBe('***'); + expect(result.session.authToken).toBe('********************'); + expect(result.session.encryptedAuthToken).toBe('*************************'); }); it('should mask emails as a string value in property with a random email', () => { @@ -96,7 +96,7 @@ describe('maskOnyxState', () => { const result = ExportOnyxState.maskOnyxState(input, true) as ExampleOnyxState; - expect(result.edits).toEqual(['***', '***']); + expect(result.edits).toEqual(['***', '**']); expect(result.lastMessageHtml).toEqual('***'); }); });