UNPKG

@zakyyudha/habibi

Version:

A package to encrypt and decrypt PII fields with love and care

92 lines (91 loc) 3.73 kB
"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;