aws-kms-ee
Version:
AWS KMS Envelope Encryption
111 lines (96 loc) • 3.97 kB
JavaScript
;
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.getClientLogger = exports.logError = exports.decryptValue = exports.encryptValue = exports.debug = undefined;
var _util = require('util');
var _crypto = require('./crypto');
var crypto = _interopRequireWildcard(_crypto);
function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } else { var newObj = {}; if (obj != null) { for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) newObj[key] = obj[key]; } } newObj.default = obj; return newObj; } }
const debug = exports.debug = require('debug')('kms');
const parse = value => {
/* istanbul ignore else */
if (value) {
// DEPRECATED - will remove this natural feature flag in future version
// this is only intended to provide limited compatibility for services that are stuck on v.0.8.0 or older
if (!(value.startsWith('{') && value.endsWith('}')) && // ignore stringified object
!(value.startsWith('[') && value.endsWith(']')) && // ignore stringified array
!(value.startsWith('"') && value.endsWith('"')) && // ignore properly stringified string
value.split('E').length === 2 // without stringification it is impossible to tell a string that looks like an expo number from an actual number
) {
// forwards compatibility for previousy non-stringified strings that look exponential
return value;
} else {
try {
return JSON.parse(value);
} catch (e) /* istanbul ignore next */{
// this will handle when the encrypted value was not stringified
return value;
}
}
} else {
return value;
}
};
const encryptValue = exports.encryptValue = (key, value, dek, AES = true) => {
/* istanbul ignore if */
if (value === null) {
return value;
} else {
let encryptedValue;
try {
encryptedValue = crypto.encrypt(JSON.stringify(value), dek.Plaintext.toString(), AES);
return encryptedValue.toString();
} catch (err) /* istanbul ignore next */{
throw new Error(`${err.message}, Field: ${key}, Value: ${value}, Encrypted Value: ${encryptedValue}`);
}
}
};
const decryptValue = exports.decryptValue = (key, value, dek, AES = true) => {
/* istanbul ignore if */
if (value === null) {
return value;
} else {
let decryptedValue;
try {
decryptedValue = crypto.decrypt(value, dek.Plaintext.toString(), AES);
return parse(decryptedValue);
} catch (err) /* istanbul ignore next */{
throw new Error(`${err.message}, Field: ${key}, Value: ${value}, Decrypted Value: ${decryptedValue}`);
}
}
};
const logError = exports.logError = (err, forEncrypt, region) => {
console.error(JSON.stringify({
message: `could not ${forEncrypt ? 'encrypt' : 'decrypt'} data key for region: ${region}`,
errorMessage: err.message,
errorType: err.name,
stackTrace: err.stack
}));
const tags = {
account: process.env.ACCOUNT_NAME,
region: process.env.AWS_REGION,
functionname: process.env.AWS_LAMBDA_FUNCTION_NAME,
stage: process.env.SERVERLESS_STAGE,
service: process.env.SERVERLESS_PROJECT,
apiname: `${process.env.SERVERLESS_STAGE}-${process.env.SERVERLESS_PROJECT}`,
memorysize: process.env.AWS_LAMBDA_FUNCTION_MEMORY_SIZE,
type: err.name
};
const flattenedTags = Object.keys(tags).reduce((t, key) => {
if (tags[key]) t.push(`${key}:${tags[key]}`);
return t;
}, []).join(',');
const timestamp = Math.floor(Date.now() / 1000); // unix format
return `MONITORING|${timestamp}|1|count|kms.error.count|#${flattenedTags}`;
};
const getClientLogger = exports.getClientLogger = (dbg = debug) => {
const normalize = msg => (typeof msg === 'string' ? msg : (0, _util.inspect)(msg, { depth: 3 })).replace(/\n/g, '\r');
const log = (...content) => dbg(...content.map(normalize));
return {
debug: () => {},
info: log,
warn: log,
error: log
};
};