File: crypt.io.js

Recommend this page to a friend!
  Classes of Jason Gerfen   secStore.js   crypt.io.js   Download  
File: crypt.io.js
Role: Class source
Content type: text/plain
Description: Class source
Class: secStore.js
Store data securely using AES encryption
Author: By
Last change: Update of crypt.io.js
Date: 2 years ago
Size: 12,558 bytes
 

Contents

Class file image Download
/** * crypt.io - Encryption enabled browser storage * * https://www.github.com/jas-/crypt.io * * Author: Jason Gerfen <jason.gerfen@gmail.com> * License: MIT (see LICENSE) */ (function(window, undefined) { 'use strict'; /** * @function cryptio * @abstract Namespace for saving/retrieving encrypted HTML5 storage engine * data */ var cryptio = cryptio || function() { /** * @var {Object} defaults * @abstract Default set of options for plug-in * * @param {Boolean} encrypt Optionally encrypt stored data * @param {String} passphrase Passphrase to use (optional) * @param {String} storage Storage mechanism (local, session or cookies) */ var defaults = { passphrase: '', storage: 'local' }; /** * @method setup * @abstract Initial setup routines */ var setup = setup || { /** * @function set * @abstract Initialization * * @param {Object} opts Plug-in option object */ init: function(opts) { opts.passphrase = opts.passphrase || (crypto.key(opts.passphrase) || crypto.key()); } }; /** * @method storage * @abstract Interface to handle storage options */ var storage = storage || { /** * @function quota * @abstract Tests specified storage option for current amount of space available. * - Cookies: 4K * - localStorage: 5MB * - sessionStorage: 5MB * - default: 5MB * * @param {String} t Type of storage specified * * @returns {Boolean} */ quota: function(storage) { var max = /local|session/.test(storage) ? 1024 * 1025 * 5 : 1024 * 4, cur = libs.total(storage), total = max - cur; return total > 0; }, /** * @function set * @abstract Interface for saving to available storage mechanisms * * @param {Object} opts Default options * @param {String} key Index of storage object * @param {Object} data Data to be stored * @param {Function} cb Callback function * * @returns {Boolean} */ set: function(opts, key, data, cb) { var ret = false; if (!storage.quota(opts.storage)) cb('Browser storage quota has been exceeded.'); if (opts.passphrase) { try { data = sjcl.encrypt(opts.passphrase, storage.fromJSON(data)); } catch(err) { return cb(err); } } ret = this[opts.storage] ? this[opts.storage].set(key, data) : this.local.set(key, data); if (!ret) { cb('Error occured saving data'); } else { cb(null, 'Successfully set data'); } }, /** * @function get * @abstract Interface for retrieving from available storage mechanisms * * @param {Object} opts Default options * @param {String} key Index of storage object * @param {Function} cb Callback function * * @returns {Object} */ get: function(opts, key, cb) { var ret = false; ret = this[opts.storage] ? this[opts.storage].get(key) : this.local.get(key); try { ret = sjcl.decrypt(opts.passphrase, ret); } catch(err) { cb(err); } ret = storage.toJSON(ret); if (ret) { cb(null, ret); } else { cb('Error occured retrieving storage data'); } }, /** * @function fromJSON * @abstract Convert to JSON object to string * * @param {Object|Array|String} obj Object, Array or String to convert to JSON object * * @returns {String} */ fromJSON: function(obj) { var ret; try { ret = JSON.stringify(obj); } catch (e) { ret = obj; } return ret; }, /** * @function toJSON * @abstract Creates JSON object from formatted string * * @param {String} obj Object to convert to JSON object * * @returns {Object} */ toJSON: function(obj) { var ret; try { ret = JSON.parse(obj); } catch (e) { ret = obj; } return ret; }, /** * @method cookie * @abstract Method for handling setting & retrieving of cookie objects */ cookie: { /** * @function set * @abstract Handle setting of cookie objects * * @param {String} key Key to use for cookies * @param {String|Object} value String or object to place in cookie * * @returns {Boolean} */ set: function(key, value) { var date = new Date(); date.setTime(date.getTime() + (30 * 24 * 60 * 60 * 1000)); document.cookie = key + '=' + value + ';expires=' + date.toGMTString() + ';path=/;domain=' + this.domain(); return true; }, /** * @function get * @abstract Handle retrieval of cookie objects * * @param {String} key cookie key * * @returns {String|False} */ get: function(key) { var i, index, value, content = document.cookie.split(";"); for (i = 0; i < content.length; i++) { index = content[i].substr(0, content[i].indexOf('=')); value = content[i].substr(content[i].indexOf('=') + 1); index = index.replace(/^\s+|\s+$/g, ''); if (index == key) { return unescape(value); } } return false; }, /** * @function domain * @abstract Provides current domain of client for cookie realm * * @returns {String} */ domain: function() { return location.hostname; } }, /** * @method local * @abstract Method for handling setting & retrieving of localStorage objects */ local: { /** * @function set * @abstract Handle setting & retrieving of localStorage objects * * @param {String} key Index of storage object * @param {Object} data Data to be stored * * @returns {Boolean} */ set: function(key, data) { try { window.localStorage.setItem(key, data); return true; } catch (e) { return false; } }, /** * @function get * @abstract Handle retrieval of localStorage objects * * @param {String} key Index of storage object * * @returns {Object|String|Boolean} */ get: function(key) { return window.localStorage.getItem(key); } }, /** * @method session * @abstract Method for handling setting & retrieving of sessionStorage objects */ session: { /** * @function set * @abstract Set session storage objects * * @param {String} key Index of storage object * @param {Object} data Data to be stoed * * @returns {Boolean} */ set: function(key, data) { try { window.sessionStorage.setItem(key, data); return true; } catch (e) { return false; } }, /** * @function get * @abstract Retrieves sessionStorage objects * * @param {String} key Index of storage object * * @returns {Object|String|Boolean} */ get: function(key) { return window.sessionStorage.getItem(key); } } }; /** * @method crypto * @abstract Interface to handle encryption option */ var crypto = crypto || { /** * @function key * @abstract Prepares key for encryption/decryption routines * * @param {String} pass Optional passphrase * * @returns {String} */ key: function(pass) { pass = pass || this.muid(); var salt = crypto.salt(pass); return sjcl.codec.hex.fromBits(sjcl.misc.pbkdf2(pass, salt)); }, /** * @function muid * @abstract Generates a machine identifier * * @returns {String} */ muid: function() { var ret = window.navigator.appName + window.navigator.language + window.navigator.platform; return ret; }, /** * @function salt * @abstract Creates salt from string & iv * * @param {String} str Machine identification used as salt * * @returns {String} */ salt: function(str) { return sjcl.codec.base64.fromBits( sjcl.hash.sha256.hash(window.navigator.appName)); } }; /** * @method libs * @abstract Miscellaneous helper libraries */ var libs = libs || { /** * @function total * @abstract Returns size of specified storage * * @param {String} engine Storage mechanism * * @returns {Insteger} */ total: function(storage) { var current = '', engine = window.storage + 'Storage'; for (var key in engine) { if (engine.hasOwnProperty(key)) { current += engine[key]; } } return current ? 3 + ((current.length * 16) / (8 * 1024)) : 0; }, /** * @function size * @abstract Perform calculation on objects * * @param {Object|Array} obj The object/array to calculate * * @returns {Integer} */ size: function(obj) { var n = 0; if (/object/.test(typeof(obj))) { for (var i in obj) { if (obj.hasOwnProperty(obj[i])) n++; } } else if (/array/.test(typeof(obj))) { n = obj.length; } return n; }, /** * @function merge * @abstract Perform preliminary option/default object merge * * @param {Object} defaults Application defaults * @param {Object} obj User supplied object * * @returns {Object} */ merge: function(defaults, obj) { defaults = defaults || {}; for (var item in defaults) { if (defaults.hasOwnProperty(item)) { obj[item] = (/object/.test(typeof(defaults[item]))) ? this.merge(obj[item], defaults[item]) : defaults[item]; } obj[item] = defaults[item]; } return obj; } }; /** * @function get * @abstract Retrieves storage engine data * * @param {Object} obj User supplied options * @param {String} key Key of storage object to retrieve * @param {Function} cb User supplied callback function */ cryptio.prototype.get = function(obj, key, cb) { if (cb == undefined) cb = key, key = obj, obj = {}; var opts = libs.merge(obj, defaults); setup.init(opts); storage.get(opts, key, cb); }; /** * @function set * @abstract Saves data to specified storage engine * * @param {Object} obj User supplied options * @param {String} key Key of storage object to retrieve * @param {Object} data User provided data to store * @param {Function} cb User supplied callback function */ cryptio.prototype.set = function(obj, key, data, cb) { if (cb == undefined) cb = data,data = key, key = obj, obj = {}; var opts = libs.merge(obj, defaults); setup.init(opts); storage.set(opts, key, data, cb); }; }; /* crypt.io, do work */ window.cryptio = new cryptio; })(window);