@zakyyudha/habibi
Version:
A package to encrypt and decrypt PII fields with love and care
92 lines (91 loc) • 3.73 kB
JavaScript
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.Habibi = void 0;
class Habibi {
constructor(config = {}) {
this.piiFields = config.piiFields || ['nik', 'phoneNumber', 'email'];
this.encryptFn = config.encryptFn || ((str) => 'ENCRYPTED_' + str);
this.decryptFn = config.decryptFn || ((str) => str.replace('ENCRYPTED_', ''));
this.hashFn = config.hashFn || ((str) => 'HASHED_' + str);
this.logger = config.logger || ((err, key) => {
console.log(err, 'Error while processing fields ' + key);
});
this.stopOnError = config.stopOnError || false;
}
processField(value, key, fn, processHash) {
if (value === '')
return { value };
try {
const processedValue = fn(value);
if (processHash) {
return { value: processedValue, hash: this.hashFn(value) };
}
return { value: processedValue };
}
catch (err) {
this.logger(err, key);
if (this.stopOnError) {
throw err;
}
return { value };
}
}
processFields(obj, fn, processHash) {
if (Array.isArray(obj)) {
return obj.map(item => this.processFields(item, fn, processHash));
}
if (typeof obj !== 'object' || obj === null) {
return obj;
}
const result = {};
for (const key in obj) {
if (Object.prototype.hasOwnProperty.call(obj, key)) {
const value = obj[key];
if (key === '_id') {
result[key] = value;
}
else if (Array.isArray(value)) {
result[key] = value.map(item => {
if (typeof item === 'string' && this.piiFields.includes(key) && item !== '') {
const { value: processedValue, hash } = this.processField(item, key, fn, processHash);
if (hash) {
result[key + 'ByHmac'] = (result[key + 'ByHmac'] || []).concat(hash);
}
return processedValue;
}
return this.processFields(item, fn, processHash);
});
if (processHash && this.piiFields.includes(key)) {
result[key + 'ByHmac'] = result[key + 'ByHmac'] || value.map(item => {
if (typeof item === 'string' && item !== '') {
return this.hashFn(item);
}
return this.processFields(item, fn, processHash);
});
}
}
else if (typeof value === 'object') {
result[key] = this.processFields(value, fn, processHash);
}
else if (typeof value === 'string' && this.piiFields.includes(key) && value !== '') {
const { value: processedValue, hash } = this.processField(value, key, fn, processHash);
result[key] = processedValue;
if (hash) {
result[key + 'ByHmac'] = hash;
}
}
else {
result[key] = value;
}
}
}
return result;
}
decryptPIIFields(obj) {
return this.processFields(obj, this.decryptFn, false);
}
encryptPIIFields(obj) {
return this.processFields(obj, this.encryptFn, true);
}
}
exports.Habibi = Habibi;