diff --git a/apps/api/src/helper/object.helper.ts b/apps/api/src/helper/object.helper.ts index 2f0399fb8..1538228b8 100644 --- a/apps/api/src/helper/object.helper.ts +++ b/apps/api/src/helper/object.helper.ts @@ -32,9 +32,11 @@ export function nullifyValuesInObjects(aObjects: T[], keys: string[]): T[] { } export function redactAttributes({ + isFirstRun = true, object, options }: { + isFirstRun?: boolean; object: any; options: { attribute: string; valueMap: { [key: string]: any } }[]; }): any { @@ -42,7 +44,10 @@ export function redactAttributes({ return object; } - const redactedObject = cloneDeep(object); + // Create deep clone + const redactedObject = isFirstRun + ? JSON.parse(JSON.stringify(object)) + : object; for (const option of options) { if (redactedObject.hasOwnProperty(option.attribute)) { @@ -59,7 +64,11 @@ export function redactAttributes({ if (isArray(redactedObject[property])) { redactedObject[property] = redactedObject[property].map( (currentObject) => { - return redactAttributes({ options, object: currentObject }); + return redactAttributes({ + options, + isFirstRun: false, + object: currentObject + }); } ); } else if ( @@ -69,6 +78,7 @@ export function redactAttributes({ // Recursively call the function on the nested object redactedObject[property] = redactAttributes({ options, + isFirstRun: false, object: redactedObject[property] }); } diff --git a/apps/api/src/interceptors/redact-values-in-response.interceptor.ts b/apps/api/src/interceptors/redact-values-in-response.interceptor.ts index c380cefc8..6b10a4ebb 100644 --- a/apps/api/src/interceptors/redact-values-in-response.interceptor.ts +++ b/apps/api/src/interceptors/redact-values-in-response.interceptor.ts @@ -30,32 +30,28 @@ export class RedactValuesInResponseInterceptor hasImpersonationId || this.userService.isRestrictedView(request.user) ) { - const attributes = [ - 'balance', - 'balanceInBaseCurrency', - 'comment', - 'convertedBalance', - 'dividendInBaseCurrency', - 'fee', - 'feeInBaseCurrency', - 'filteredValueInBaseCurrency', - 'grossPerformance', - 'investment', - 'netPerformance', - 'quantity', - 'symbolMapping', - 'totalBalanceInBaseCurrency', - 'totalValueInBaseCurrency', - 'unitPrice', - 'value', - 'valueInBaseCurrency' - ]; - - console.time('oldExecutionTime'); - data = redactAttributes({ object: data, - options: attributes.map((attribute) => { + options: [ + 'balance', + 'balanceInBaseCurrency', + 'comment', + 'convertedBalance', + 'dividendInBaseCurrency', + 'fee', + 'feeInBaseCurrency', + 'filteredValueInBaseCurrency', + 'grossPerformance', + 'investment', + 'netPerformance', + 'quantity', + 'symbolMapping', + 'totalBalanceInBaseCurrency', + 'totalValueInBaseCurrency', + 'unitPrice', + 'value', + 'valueInBaseCurrency' + ].map((attribute) => { return { attribute, valueMap: { @@ -64,59 +60,10 @@ export class RedactValuesInResponseInterceptor }; }) }); - - console.timeLog('oldExecutionTime'); - - data = this.redactObject({ - attributes, - data, - valueMap: { - '*': null - } - }); } return data; }) ); } - - private redactObject({ - attributes, - data, - valueMap - }: { - attributes: string[]; - data: any; - valueMap: { [key: string]: any }; - }) { - console.time('newExecutionTime'); - - // Stringify the JSON object - let jsonString = JSON.stringify(data); - - // Nullify occurrences of attributes in the string - for (const attribute of attributes) { - const regex = new RegExp(`"${attribute}"\\s*:\\s*"[^"]*"`, 'g'); - - if (valueMap['*'] || valueMap['*'] === null) { - jsonString = jsonString.replace( - regex, - `"${attribute}":${valueMap['*']}` - ); - } else if (valueMap[attribute]) { - jsonString = jsonString.replace( - regex, - `"${attribute}":${valueMap[attribute]}` - ); - } - } - - // Transform the stringified JSON back to an object - const transformedObject = JSON.parse(jsonString); - - console.timeLog('newExecutionTime'); - - return transformedObject; - } }