Browse Source

Feature/improve redactAttributes in object helper

pull/5151/head
Ananta Podder 2 weeks ago
parent
commit
92c836ea0b
  1. 90
      apps/api/src/helper/object.helper.ts
  2. 8
      apps/api/src/helper/redactyle.helper.ts
  3. 6
      package-lock.json
  4. 1
      package.json

90
apps/api/src/helper/object.helper.ts

@ -1,6 +1,8 @@
import { Big } from 'big.js'; import { Big } from 'big.js';
import { cloneDeep, isArray, isObject } from 'lodash'; import { cloneDeep, isArray, isObject } from 'lodash';
import { RedactylNullSupported } from './redactyle.helper';
export function hasNotDefinedValuesInObject(aObject: Object): boolean { export function hasNotDefinedValuesInObject(aObject: Object): boolean {
for (const key in aObject) { for (const key in aObject) {
if (aObject[key] === null || aObject[key] === undefined) { if (aObject[key] === null || aObject[key] === undefined) {
@ -44,47 +46,67 @@ export function redactAttributes({
return object; return object;
} }
// Create deep clone let redactedObject = isFirstRun ? cloneDeep(object) : object;
const redactedObject = isFirstRun
? JSON.parse(JSON.stringify(object))
: object;
for (const option of options) { for (const option of options) {
if (redactedObject.hasOwnProperty(option.attribute)) { const { attribute, valueMap } = option;
if (option.valueMap['*'] || option.valueMap['*'] === null) {
redactedObject[option.attribute] = option.valueMap['*']; const redactyl = new RedactylNullSupported({ properties: [] });
} else if (option.valueMap[redactedObject[option.attribute]]) { redactyl.addProperties([attribute]);
redactedObject[option.attribute] =
option.valueMap[redactedObject[option.attribute]]; // Handle different value mapping scenarios
} if ('*' in valueMap) {
// Wildcard replacement - replace all instances of this attribute
redactyl.setText(valueMap['*']);
redactedObject = redactyl.redact(redactedObject);
} else { } else {
// If the attribute is not present on the current object, // Specific value mapping - need to handle this differently
// check if it exists on any nested objects // We'll use a custom approach for specific value mappings
for (const property in redactedObject) { redactedObject = redactSpecificValues(
if (isArray(redactedObject[property])) { redactedObject,
redactedObject[property] = redactedObject[property].map( attribute,
(currentObject) => { valueMap
return redactAttributes({
options,
isFirstRun: false,
object: currentObject
});
}
); );
} else if (
isObject(redactedObject[property]) &&
!(redactedObject[property] instanceof Big)
) {
// Recursively call the function on the nested object
redactedObject[property] = redactAttributes({
options,
isFirstRun: false,
object: redactedObject[property]
});
} }
} }
return redactedObject;
} }
// Helper function to handle specific value mappings (non-wildcard)
function redactSpecificValues(
obj: any,
attribute: string,
valueMap: { [key: string]: any }
): any {
if (!obj || typeof obj !== 'object') {
return obj;
} }
return redactedObject; if (isArray(obj)) {
return obj.map((item) => redactSpecificValues(item, attribute, valueMap));
}
const result = { ...obj };
// Check if current level has the attribute and if its value should be replaced
if (attribute in result) {
const currentValue = result[attribute];
if (currentValue in valueMap) {
result[attribute] = valueMap[currentValue];
}
}
// Recursively process nested objects
for (const key in result) {
if (isObject(result[key]) && !(result[key] instanceof Big)) {
result[key] = redactSpecificValues(result[key], attribute, valueMap);
} else if (isArray(result[key])) {
result[key] = result[key].map((item: any) =>
isObject(item) ? redactSpecificValues(item, attribute, valueMap) : item
);
}
}
return result;
} }

8
apps/api/src/helper/redactyle.helper.ts

@ -0,0 +1,8 @@
import Redactyl = require('redactyl.js');
export class RedactylNullSupported extends Redactyl {
text: string | null = null;
setText(text) {
this.text = text;
return this;
}
}

6
package-lock.json

@ -87,6 +87,7 @@
"passport-google-oauth20": "2.0.0", "passport-google-oauth20": "2.0.0",
"passport-headerapikey": "1.2.2", "passport-headerapikey": "1.2.2",
"passport-jwt": "4.0.1", "passport-jwt": "4.0.1",
"redactyl.js": "^1.6.0",
"reflect-metadata": "0.2.2", "reflect-metadata": "0.2.2",
"rxjs": "7.8.1", "rxjs": "7.8.1",
"stripe": "18.2.1", "stripe": "18.2.1",
@ -30036,6 +30037,11 @@
"node": ">= 0.10" "node": ">= 0.10"
} }
}, },
"node_modules/redactyl.js": {
"version": "1.6.0",
"resolved": "https://registry.npmjs.org/redactyl.js/-/redactyl.js-1.6.0.tgz",
"integrity": "sha512-K5HZ+fVPfR7PWABroIUb+of2HVDM/VNcHYCTB1ZTqXVpCAwpj++c0eSHg0oJcDIBaNAe59DeKHzJ6rC7p91B5g=="
},
"node_modules/redent": { "node_modules/redent": {
"version": "3.0.0", "version": "3.0.0",
"resolved": "https://registry.npmjs.org/redent/-/redent-3.0.0.tgz", "resolved": "https://registry.npmjs.org/redent/-/redent-3.0.0.tgz",

1
package.json

@ -133,6 +133,7 @@
"passport-google-oauth20": "2.0.0", "passport-google-oauth20": "2.0.0",
"passport-headerapikey": "1.2.2", "passport-headerapikey": "1.2.2",
"passport-jwt": "4.0.1", "passport-jwt": "4.0.1",
"redactyl.js": "^1.6.0",
"reflect-metadata": "0.2.2", "reflect-metadata": "0.2.2",
"rxjs": "7.8.1", "rxjs": "7.8.1",
"stripe": "18.2.1", "stripe": "18.2.1",

Loading…
Cancel
Save