Skip to content

Commit

Permalink
Initial commit
Browse files Browse the repository at this point in the history
  • Loading branch information
fixe committed Aug 12, 2019
0 parents commit f5954d0
Show file tree
Hide file tree
Showing 8 changed files with 3,824 additions and 0 deletions.
3 changes: 3 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
.eslintcache
coverage/
node_modules/
4 changes: 4 additions & 0 deletions .travis.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
language: node_js

node_js:
- 10
1 change: 1 addition & 0 deletions LICENSE
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
(c) Copyright 2019 Uphold, Inc. All rights reserved.
16 changes: 16 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
# anonymizer
Object redaction with whitelist as main feature.

## Arguments
1. `whitelist` _(Object)_: The whitelist object.

### Example

```js
const anonymizer = require('@uphold/anonymizer');
const anonymize = anonymizer(['foo.key', 'bar.*']);

anonymize({ foo: { key: 'public', another: 'bar' }, bar: { foo: 1, bar: 2 } });

//=> { foo: { key: 'public', another: '--REDACTED--' }, bar: { foo: 1, bar: 2 } }
```
44 changes: 44 additions & 0 deletions package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
{
"name": "@uphold/anonymizer",
"version": "1.1.0",
"description": "Object redaction with whitelist as main feature.",
"homepage": "https://github.com/uphold/anonymizer#readme",
"bugs": {
"url": "https://github.com/uphold/anonymizer/issues"
},
"repository": {
"type": "git",
"url": "git+https://github.com/uphold/anonymizer.git"
},
"license": "SEE LICENSE IN LICENSE",
"main": "src",
"directories": {
"test": "test"
},
"scripts": {
"test": "jest"
},
"jest": {
"collectCoverage": true,
"coveragePathIgnorePatterns": [
"/node_modules/"
],
"modulePaths": [
"<rootDir>"
],
"restoreMocks": true,
"testEnvironment": "node",
"testRegex": "test/.*\\.test.js$"
},
"dependencies": {
"json-stringify-safe": "^5.0.1",
"traverse": "^0.6.6"
},
"devDependencies": {
"jest": "^24.8.0",
"pre-commit": "^1.2.2"
},
"publishConfig": {
"registry": "https://npm.pkg.github.com/"
}
}
39 changes: 39 additions & 0 deletions src/index.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
'use strict';

/**
* Module dependencies.
*/

const stringify = require('json-stringify-safe');
const traverse = require('traverse');

/**
* Constants.
*/

const replacement = '--REDACTED--';

/**
* Module exports.
*/

module.exports = (whitelist = []) => {
const terms = whitelist.join('|');
const paths = new RegExp(`^(${terms.replace('*', '.*')})$`, 'i');

return values => {
const clone = JSON.parse(stringify(values));

traverse(clone).forEach(function() {
if (!this.isLeaf) {
return;
}

if (!paths.test(this.path.join('.'))) {
this.update(replacement);
}
});

return clone;
};
};
83 changes: 83 additions & 0 deletions test/src/index.test.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,83 @@
'use strict';

/**
* Module dependencies.
*/

const anonymizer = require('src');

/**
* Test `Anonymizer`.
*/

describe('Anonymizer', () => {
describe('anonymize', () => {
const whitelist = ['key1', 'key2', 'key3'];

whitelist.forEach(key => {
it(`should not obfuscate \`${key}\``, () => {
const anonymize = anonymizer(whitelist);

expect(anonymize({ [key]: 'foo' })).toEqual({ [key]: 'foo' });
});

it(`should not obfuscate \`${key}\` with different casing`, () => {
const anonymize = anonymizer(whitelist);

expect(anonymize({ [key.toUpperCase()]: 'foo' })).toEqual({ [key.toUpperCase()]: 'foo' });
expect(anonymize({ [key.toLowerCase()]: 'foo' })).toEqual({ [key.toLowerCase()]: 'foo' });
});

it(`should obfuscate keys that contain \`${key}\``, () => {
const anonymize = anonymizer(whitelist);

expect(anonymize({ [`${key}foo`]: 'bar' })).toEqual({ [`${key}foo`]: '--REDACTED--' });
expect(anonymize({ [`foo${key}`]: 'bar' })).toEqual({ [`foo${key}`]: '--REDACTED--' });
expect(anonymize({ [`foo${key}foo`]: 'bar' })).toEqual({ [`foo${key}foo`]: '--REDACTED--' });
});
});

it('should not obfuscate recursively the keys of an object that are part of the whitelist', () => {
const anonymize = anonymizer(whitelist);

expect(anonymize({
foo: {
bar: {
baz: { bax: [2, 3, { bax: 4, [whitelist[1]]: '5' }] },
[whitelist[0]]: 'foobar',
[whitelist[2]]: 'foobiz'
}
}
})).toEqual({
foo: {
bar: {
baz: { bax: ['--REDACTED--', '--REDACTED--', { bax: '--REDACTED--', [whitelist[1]]: '--REDACTED--' }] },
[whitelist[0]]: '--REDACTED--',
[whitelist[2]]: '--REDACTED--'
}
}
});
});

it('should not obfuscate a key that is part of the whitelist', () => {
const anonymize = anonymizer(['foo']);

expect(anonymize({ foo: 'bar' })).toEqual({ foo: 'bar' });
});

it('should allow using `*` in the whitelist path', () => {
const anonymize = anonymizer(['*.foo']);

expect(anonymize({ parent: { foo: 'bar' } })).toEqual({ parent: { foo: 'bar' } });
});

it('should allow circular references', () => {
const object = {};
object.reference = object;

const anonymize = anonymizer(['*']);

expect(anonymize(object)).toEqual({ reference: '[Circular ~]' });
});
});
});
Loading

0 comments on commit f5954d0

Please sign in to comment.