diff --git a/package.json b/package.json index 1c06b247..21f06fcf 100644 --- a/package.json +++ b/package.json @@ -50,7 +50,6 @@ "commander": "^12.0.0", "env-paths": "^3.0.0", "inquirer": "8.0.0", - "lodash.clonedeep": "^4.5.0", "mkdirp": "^3.0.1", "winston": "^3.13.0", "x25519": "^0.1.0" diff --git a/src/common/masking.ts b/src/common/masking.ts index ae9aa07f..3ee66295 100644 --- a/src/common/masking.ts +++ b/src/common/masking.ts @@ -1,37 +1,38 @@ -import cloneDeep from 'lodash.clonedeep' - -const DEFAULT_MASKED_FIELDS = [ +const PREFIX = 'data:application/UI8A;base64,' +const DEFAULT_MASKED_FIELDS = new Set([ 'seed', 'secretKey', 'addressRaw', -]; +]); export function maskPayload (payload: any): any { - if (typeof payload === 'string') return payload - - const clonedPayload = cloneDeep(payload); - const maskedPayload = {} + if ( + typeof payload === 'string' || + typeof payload === 'boolean' || + payload === null + ) return payload - if (!clonedPayload) { - return clonedPayload; - } + const maskedPayload = Array.isArray(payload) + ? [] + : {} // maskJSONFields doesn't handle nested objects very well so we'll // need to recursively walk to object and mask them one by one - for (const [property, value] of Object.entries(clonedPayload)) { - if (value && typeof value === 'object') { - if (Object.keys(clonedPayload[property]).filter(key => isNaN(parseInt(key))).length === 0) { - const reconstructedUintArr: number[] = Object.values(clonedPayload[property]) - maskedPayload[property] = "base64:" + Buffer.from(reconstructedUintArr).toString("base64"); - } else { - maskedPayload[property] = maskPayload(value); - } - } else if (value && typeof value === 'string' && DEFAULT_MASKED_FIELDS.includes(property)) { - maskedPayload[property] = "*".repeat(clonedPayload[property].length) - } else { - maskedPayload[property] = value + return Object.entries(payload).reduce((acc, [property, value]) => { + if (DEFAULT_MASKED_FIELDS.has(property)) { + // @ts-expect-error .length does not exist on type "unknown" + acc[property] = "*".repeat(value?.length || 32) + } + else if (value instanceof Uint8Array) { + acc[property] = PREFIX + Buffer.from(value).toString('base64') + } + else if (typeof value === 'object') { + acc[property] = maskPayload(value); + } + else { + acc[property] = value } - } - return maskedPayload; + return acc + }, maskedPayload) } diff --git a/tests/common.test.ts b/tests/common.test.ts new file mode 100644 index 00000000..8ec05314 --- /dev/null +++ b/tests/common.test.ts @@ -0,0 +1,53 @@ +import test from 'tape' + +import { maskPayload } from '../src/common/masking' + +test('common/masking', async (t) => { + + t.deepEqual( + maskPayload('dog'), + 'dog', + 'handles string' + ) + + t.deepEqual( + maskPayload(null), + null, + 'handles null' + ) + + t.deepEqual( + maskPayload(true), + true, + 'handles bool' + ) + + const buildPayload = () => { + return { + nested: { + seed: 'secrets', + secretKey: new Uint8Array([1,2,3]), + publicKey: new Uint8Array([4,5,6]), + arr: ['a', 'b', 'c'], + obj: { "0": 17, "1": 23 } + } + } + } + const payload = buildPayload() + const expected = { + nested: { + seed: '*'.repeat('secrets'.length), + secretKey: '***', + publicKey: 'data:application/UI8A;base64,BAUG', + arr: ['a', 'b', 'c'], + obj: { "0": 17, "1": 23 } + } + } + t.deepEqual(maskPayload(payload), expected, 'nested mess') + t.deepEqual(payload, buildPayload(), 'maskPayload does not mutate') + + + t.deepEqual(maskPayload([payload, payload]), [expected, expected], 'arrays') + + t.end() +}) diff --git a/yarn.lock b/yarn.lock index 53eef8ff..96dd29ae 100644 --- a/yarn.lock +++ b/yarn.lock @@ -2658,11 +2658,6 @@ locate-path@^6.0.0: dependencies: p-locate "^5.0.0" -lodash.clonedeep@^4.5.0: - version "4.5.0" - resolved "https://registry.yarnpkg.com/lodash.clonedeep/-/lodash.clonedeep-4.5.0.tgz#e23f3f9c4f8fbdde872529c1071857a086e5ccef" - integrity sha512-H5ZhCF25riFd9uB5UCkVKo61m3S/xZk1x4wA6yp/L3RFP6Z/eHH1ymQcGLo7J3GMPfm0V/7m1tryHuGVxpqEBQ== - lodash.merge@^4.6.2: version "4.6.2" resolved "https://registry.yarnpkg.com/lodash.merge/-/lodash.merge-4.6.2.tgz#558aa53b43b661e1925a0afdfa36a9a1085fe57a"