forerunnerdb
Version:
A NoSQL document store database for browsers and Node.js.
120 lines (96 loc) • 2.85 kB
JavaScript
var Shared = require('./Shared'),
CryptoJS = require('crypto-js');
var Plugin = function () {
this.init.apply(this, arguments);
};
Plugin.prototype.init = function (options) {
// Ensure at least a password is passed in options
if (!options || !options.pass) {
throw('Cannot initialise persistent storage encryption without a passphrase provided in the passed options object as the "pass" field.');
}
this._algo = options.algo || 'AES';
this._pass = options.pass;
};
Shared.mixin(Plugin.prototype, 'Mixin.Common');
/**
* Gets / sets the current pass-phrase being used to encrypt / decrypt
* data with the plugin.
*/
Shared.synthesize(Plugin.prototype, 'pass');
Plugin.prototype.stringify = function (cipherParams) {
// create json object with ciphertext
var jsonObj = {
ct: cipherParams.ciphertext.toString(CryptoJS.enc.Base64)
};
// optionally add iv and salt
if (cipherParams.iv) {
jsonObj.iv = cipherParams.iv.toString();
}
if (cipherParams.salt) {
jsonObj.s = cipherParams.salt.toString();
}
// stringify json object
return this.jStringify(jsonObj);
};
Plugin.prototype.parse = function (jsonStr) {
// parse json string
var jsonObj = this.jParse(jsonStr);
// extract ciphertext from json object, and create cipher params object
var cipherParams = CryptoJS.lib.CipherParams.create({
ciphertext: CryptoJS.enc.Base64.parse(jsonObj.ct)
});
// optionally extract iv and salt
if (jsonObj.iv) {
cipherParams.iv = CryptoJS.enc.Hex.parse(jsonObj.iv);
}
if (jsonObj.s) {
cipherParams.salt = CryptoJS.enc.Hex.parse(jsonObj.s);
}
return cipherParams;
};
Plugin.prototype.encode = function (val, meta, finished) {
var self = this,
wrapper = {
type: 'fdbCrypto'
},
encryptedVal;
// Encrypt the data
encryptedVal = CryptoJS[this._algo].encrypt(val, this._pass, {
format: {
stringify: function () { return self.stringify.apply(self, arguments); },
parse: function () { return self.parse.apply(self, arguments); }
}
});
wrapper.data = encryptedVal.toString();
wrapper.enabled = true;
meta.encryption = {
enabled: wrapper.enabled
};
if (finished) {
finished(false, this.jStringify(wrapper), meta);
}
};
Plugin.prototype.decode = function (wrapper, meta, finished) {
var self = this,
data;
if (wrapper) {
wrapper = this.jParse(wrapper);
data = CryptoJS[this._algo].decrypt(wrapper.data, this._pass, {
format: {
stringify: function () { return self.stringify.apply(self, arguments); },
parse: function () { return self.parse.apply(self, arguments); }
}
}).toString(CryptoJS.enc.Utf8);
if (finished) {
finished(false, data, meta);
}
} else {
if (finished) {
finished(false, wrapper, meta);
}
}
};
// Register this plugin with the persistent storage class
Shared.plugins.FdbCrypto = Plugin;
module.exports = Plugin;
;