Skip to content

Commit

Permalink
Merge pull request #16 from veseo/master
Browse files Browse the repository at this point in the history
Implemented & exposed obfuscateSecret and obfuscatePii methods
  • Loading branch information
zupper committed Mar 8, 2021
2 parents f36c34a + 4056950 commit c1f9828
Show file tree
Hide file tree
Showing 5 changed files with 109 additions and 6 deletions.
8 changes: 4 additions & 4 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

4 changes: 2 additions & 2 deletions package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@luckbox/logger-factory",
"version": "3.0.1",
"version": "3.1.0",
"description": "Easy to use logger with several levels of logging as well as different adapters that can be used separately or in combinations",
"author": "Luckbox",
"license": "ISC",
Expand Down Expand Up @@ -36,7 +36,7 @@
},
"dependencies": {
"@sentry/node": "^6.0.4",
"lodash": "^4.17.20"
"lodash": "^4.17.21"
},
"devDependencies": {
"@luckbox/eslint-rules": "^4.0.5",
Expand Down
70 changes: 70 additions & 0 deletions src/Obfuscator.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,70 @@
import lodash from 'lodash';

enum Tag {
PII = 'PII',
SECRET = 'SECRET'
}

class Obfuscator {
public obfuscateObject(object: Record<string, unknown>, obfuscateSettings: Array<[string, Tag]>): Record<string, unknown> {
const clonedObj = lodash.cloneDeep(object);
const allPaths: Array<string> = this.collectPaths(object);

const pathToTagMap = new Map();
const allPathsToObfuscate = [];

for (const anObfuscateSetting of obfuscateSettings) {
pathToTagMap.set(anObfuscateSetting[0], anObfuscateSetting[1]);
allPathsToObfuscate.push(anObfuscateSetting[0]);
}

for (const path of allPaths) {
const actualPath = path[0];
if (allPathsToObfuscate.some((propPath) => new RegExp(propPath[0]).test(actualPath))) {
const rawValue = lodash.get(clonedObj, path);

const tag = this.determineTag(pathToTagMap, path);
if (!tag) {
continue;
}
lodash.set(clonedObj, path, this.obfuscateString(rawValue, tag));
}
}

return clonedObj;
}

public obfuscateString(value: string, tag: Tag): string {
const upperCasedTag = tag.toUpperCase();
return `[${upperCasedTag}]${value}[/${upperCasedTag}]`;
}

private collectPaths(input: any, currentPath?: string) {
const paths = [];

if (lodash.isPlainObject(input)) {
for (const key in input) {
const fullPath: string = this.buildPath(key, currentPath);
const value = input[key];

paths.push(fullPath, ...this.collectPaths(value).map((nestedPath) => this.buildPath(nestedPath, fullPath)));
}
}

return paths;
}

private buildPath(propPath: string, basePath?: string) {
return basePath === undefined ? String(propPath) : `${basePath}.${propPath}`;
}

private determineTag(pathToTagMap: any, path: string) {
const tag = pathToTagMap.get(path);
return tag;
}
}

export {
Obfuscator,
Tag,
};
3 changes: 3 additions & 0 deletions src/index.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import { LoggerFactory, Adapters, LogLevels, ConsoleAdapterSettings, SentryAdapterSettings } from './LoggerFactory';
import { Logger } from './Logger';
import { Obfuscator, Tag } from './Obfuscator';

export {
LoggerFactory,
Expand All @@ -8,4 +9,6 @@ export {
Logger,
ConsoleAdapterSettings,
SentryAdapterSettings,
Obfuscator,
Tag as ObfuscatorTag,
};
30 changes: 30 additions & 0 deletions src/tests/unit-tests/Obfuscator.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
import { Obfuscator, Tag } from '../../Obfuscator';

describe('Obfuscator', () => {
const obfuscator = new Obfuscator();

describe('obfuscateString', () => {
it('should wrap the provided tag around the string that needs to be obfuscated', () => {
expect(obfuscator.obfuscateString('string', Tag.PII)).toEqual('[PII]string[/PII]');
});
});

describe('obfuscateObject', () => {
it('should wrap the provided tag around root-level elements in object', () => {
const originalObject = { name: 'Pencho' };
const obfuscatedObject = { name: '[PII]Pencho[/PII]' };
expect(obfuscator.obfuscateObject(originalObject, [['name', Tag.PII]])).toEqual(obfuscatedObject);
});

it('should wrap the provided tag around nested elements in object', () => {
const originalObject = { id: 1, data: { name: 'Gosho', email: 'email@example.com' } };
const obfuscatedObject = { id: 1, data: { name: '[PII]Gosho[/PII]', email: '[PII]email@example.com[/PII]' } };
expect(obfuscator.obfuscateObject(originalObject, [['data.name', Tag.PII], ['data.email', Tag.PII]])).toEqual(obfuscatedObject);
});

it('should NOT wrap the provided tag around elements that are not specified for obfuscating in object', () => {
const originalObject = { favouriteColor: 'red', nested: { field: 'value' } };
expect(obfuscator.obfuscateObject(originalObject, [['name', Tag.PII]])).toEqual(originalObject);
});
});
});

0 comments on commit c1f9828

Please sign in to comment.