-
Notifications
You must be signed in to change notification settings - Fork 3
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #16 from veseo/master
Implemented & exposed obfuscateSecret and obfuscatePii methods
- Loading branch information
Showing
5 changed files
with
109 additions
and
6 deletions.
There are no files selected for viewing
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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, | ||
}; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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); | ||
}); | ||
}); | ||
}); |