Some times we have a requirement to mask properties in a json string, these fields could be personal information that need to be hidden from prying eyes under the GDPR regulations. while json parse allows you to pass a function and selectively mask properties as they are being parsed, this becomes harder if you are already dealing with a JSON string and do not want to parse it to an object, mask it and parse it back to a string representation.
the following method uses two regex scripts to parse a normal json string and a json string that has had its quotes escaped.
export function maskProperty(jsonString, propId, mask) {
const maskedEscapedJson = applyMask(jsonString,`\\\\"${propId}\\\\":\\\\"[^,]*`, `\\"${propId}\\":\\"${mask}\\"`);
const maskedNormalJson = applyMask(jsonString, `"${propId}":[ \\t]*"[^,]*`, `"${propId}": "${mask}"`);
return maskedEscapedJson.applied ? maskedEscapedJson.maskedJson : maskedNormalJson.maskedJson;
}
function applyMask(jsonString, regexString, replacement){
const regex = new RegExp(regexString);
return {
maskedJson: jsonString.replace(regex, replacement),
applied: regex.test(jsonString)
}
}
module.exports = {
maskProperty,
};
Tests:
import {maskProperty} from '../json';
describe('masks property value in json', () => {
it('masks a property value in a quote escaped json string', () => {
const json = '{\\"context\\":\\"some\\",\\"transactionId\\":\\"93236388\\", \\"sector\\":\\"asia\\"}';
const maskedJson = maskProperty(json, "context", "X");
const unescapedJson = maskedJson.replace(/\\"/g, '"');
const result = JSON.parse(unescapedJson);
expect(result.context).toBe("X");
})
it('masks a property value in a normal json string', () => {
const json = '{"context":"some","transactionId":"93236388","sector":"asia"}';
const result = JSON.parse(maskProperty(json, "context", "X"));
expect(result.context).toBe("X");
})
})