diff --git a/src/jio.storage/cryptstorage.js b/src/jio.storage/cryptstorage.js index d9a021b5d6a1ae51d95914bed564d327169ca0ea..d174cd1cc385e91a14f9d9efed861b5a3a790fb9 100644 --- a/src/jio.storage/cryptstorage.js +++ b/src/jio.storage/cryptstorage.js @@ -1,37 +1,75 @@ /* - * Copyright 2015, Nexedi SA + * Copyright 2018, Nexedi SA * Released under the LGPL license. * http://www.gnu.org/licenses/lgpl.html */ - /*jslint nomen: true*/ -/*global jIO, RSVP, DOMException, Blob, crypto, Uint8Array, ArrayBuffer*/ - -(function (jIO, RSVP, DOMException, Blob, crypto, Uint8Array, ArrayBuffer) { +/*global jIO, RSVP, DOMParser, Blob, DOMException, crypto, Uint8Array, + ArrayBuffer, CryptoKey*/ +/*jslint maxlen: 160 */ +(function (jIO, RSVP, DOMException, Blob, crypto, Uint8Array, ArrayBuffer, CryptoKey) { "use strict"; /* The cryptography system used by this storage is AES-GCM. - Here is an example of how to generate a key to the json format: + + Here is an example of how to generate a strong user key : + + -go to the website : https://randomkeygen.com/ pike a key and memorize it + after that you can Import your key like in exemple above . + + -exemple of key generation : + + var your_key = mySuperHardKey2018, + buffer = new TextEncoder("utf-8").encode(your_key); + + return new RSVP.Queue() + .push(function () { + return RSVP.all([window.crypto.subtle.digest("SHA-256", buffer), + window.crypto.subtle.importKey( + "raw", + buffer, + {name: "PBKDF2" + }, + false, + ["deriveKey"] + ) + ]); + }) + .push(function (my_array) { + return { + CryptoKey: my_array[1], + Salt: my_array[0] + }; + }) + .push(undefined, function (error) { + throw error; + }); + + -once storage created you use the callback to call addkey function and add + the required CryptoKey you generated earlier . + + utils = {"crypto_getCryptoKey": function (callback) { + return new RSVP.Queue() + .push(function () { + addkey = callback.addkey_crypto; + error = callback.error_crypto; + }) + .push(undefined, function (error) { + throw error; + }); return new RSVP.Queue() .push(function () { - return crypto.subtle.generateKey({name: "AES-GCM", length: 256}, - true, ["encrypt", "decrypt"]); - }) - .push(function (key) { - return crypto.subtle.exportKey("jwk", key); - }) - .push(function (json_key) { var jio = jIO.createJIO({ - type: "crypt", - key: json_key, + type: "crypt" sub_storage: {storage_definition} - }); + }, utils); }); - + Find more informations about this cryptography system on https://github.com/diafygi/webcrypto-examples#aes-gcm + https://developer.mozilla.org/en-US/docs/Web/API/SubtleCrypto/deriveKey */ /** @@ -41,26 +79,14 @@ * @constructor */ - var MIME_TYPE = "application/x-jio-aes-gcm-encryption"; - function CryptStorage(spec) { - this._key = spec.key; - this._jsonKey = true; - this._sub_storage = jIO.createJIO(spec.sub_storage); - } + var MIME_TYPE = "application/x-jio-aes-gcm-encryption"; - function convertKey(that) { - return new RSVP.Queue() - .push(function () { - return crypto.subtle.importKey("jwk", that._key, - "AES-GCM", false, - ["encrypt", "decrypt"]); - }) - .push(function (res) { - that._key = res; - that._jsonKey = false; - return; - }); + function CryptStorage(spec, utils) { + this._utils = utils; + this._keyid = spec.keyid; + this._key = ""; + this._sub_storage = jIO.createJIO(spec.sub_storage, utils); } CryptStorage.prototype.get = function () { @@ -93,18 +119,10 @@ arguments); }; - CryptStorage.prototype.putAttachment = function (id, name, blob) { var initializaton_vector = crypto.getRandomValues(new Uint8Array(12)), that = this; - return new RSVP.Queue() - .push(function () { - if (that._jsonKey === true) { - return convertKey(that); - } - return; - }) .push(function () { return jIO.util.readBlobAsDataURL(blob); }) @@ -114,64 +132,116 @@ buf = new ArrayBuffer(strLen), bufView = new Uint8Array(buf), i; - dataURL = dataURL.target.result; for (i = 0; i < strLen; i += 1) { bufView[i] = dataURL.charCodeAt(i); } return crypto.subtle.encrypt({ - name : "AES-GCM", - iv : initializaton_vector + name: "AES-GCM", + iv: initializaton_vector }, - that._key, buf); + that._key, buf); }) .push(function (coded) { - var blob = new Blob([initializaton_vector, coded], {type: MIME_TYPE}); + var blob = new Blob([initializaton_vector, coded], { + type: MIME_TYPE + }); return that._sub_storage.putAttachment(id, name, blob); + }) + .push(undefined, function (error) { + var cryptoerror = {keyid: that._keyid}, + callback_crypto = { + addkey_crypto: that.addkey.bind(that), + error_crypto: cryptoerror + }; + if (that._utils === undefined) { + throw new jIO.util.jIOError(that._keyid + ": no callback function declared"); + } + if (!that._utils.hasOwnProperty("crypto_getCryptoKey")) { + throw new jIO.util.jIOError(that._keyid + ":crypto_getCryptoKey function not declared in callback"); + } + if (error instanceof DOMException) { + if (error.name === "OperationError") { + cryptoerror.error_type = error.name; + cryptoerror.error_message = "Failed to decrypt due to incorrect password or data"; + } else if (error.name === "InvalidAccessError") { + cryptoerror.error_type = error.name; + cryptoerror.error_message = "invalid encryption algorithm, or invalid key for specified encryption algorithm"; + } + } else if (error instanceof TypeError) { + cryptoerror.error_type = error.name; + cryptoerror.error_message = "password is not type CRYPTOKEY"; + } + return new RSVP.Queue() + .push(function () { + return that._utils.crypto_getCryptoKey(callback_crypto); + }) + .push(function () { + throw new jIO.util.jIOError(that._keyid + " : " + cryptoerror.error_type + + " : " + cryptoerror.error_message, 801); + }); }); }; CryptStorage.prototype.getAttachment = function (id, name) { var that = this; - return that._sub_storage.getAttachment(id, name) .push(function (blob) { - if (blob.type !== MIME_TYPE) { - return blob; - } return new RSVP.Queue() .push(function () { - if (that._jsonKey === true) { - return convertKey(that); - } - return; - }) - .push(function () { - return jIO.util.readBlobAsArrayBuffer(blob); - }) - .push(function (coded) { - var initializaton_vector; - - coded = coded.target.result; - initializaton_vector = new Uint8Array(coded.slice(0, 12)); return new RSVP.Queue() .push(function () { - return crypto.subtle.decrypt({ - name : "AES-GCM", - iv : initializaton_vector - }, - that._key, coded.slice(12)); + return jIO.util.readBlobAsArrayBuffer(blob); }) - .push(function (arr) { - //arraybuffer->string - arr = String.fromCharCode.apply(null, new Uint8Array(arr)); - return jIO.util.dataURItoBlob(arr); - }) - .push(undefined, function (error) { - if (error instanceof DOMException) { - return blob; - } - throw error; + .push(function (coded) { + var initializaton_vector; + coded = coded.target.result; + initializaton_vector = new Uint8Array(coded.slice(0, 12)); + return new RSVP.Queue() + .push(function () { + return crypto.subtle.decrypt({ + name: "AES-GCM", + iv: initializaton_vector + }, + that._key, coded.slice(12)); + }) + .push(function (arr) { + arr = String.fromCharCode.apply(null, new Uint8Array(arr)); + return jIO.util.dataURItoBlob(arr); + }) + .push(undefined, function (error) { + var cryptoerror = {keyid: that._keyid}, + callback_crypto = { + addkey_crypto: that.addkey.bind(that), + error_crypto: cryptoerror + }; + if (that._utils === undefined) { + throw new jIO.util.jIOError(that._keyid + ": no callback function declared"); + } + if (!that._utils.hasOwnProperty("crypto_getCryptoKey")) { + throw new jIO.util.jIOError(that._keyid + ":crypto_getCryptoKey function not declared in callback"); + } + if (error instanceof DOMException) { + if (error.name === "OperationError") { + cryptoerror.error_type = error.name; + cryptoerror.error_message = "Failed to decrypt due to incorrect password or data"; + } else if (error.name === "InvalidAccessError") { + cryptoerror.error_type = error.name; + cryptoerror.error_message = "invalid encryption algorithm, or invalid key for specified encryption algorithm"; + } + } else if (error instanceof TypeError) { + cryptoerror.error_type = error.name; + cryptoerror.error_message = "password is not type CRYPTOKEY"; + } + return new RSVP.Queue() + .push(function () { + return that._utils.crypto_getCryptoKey(callback_crypto); + }) + .push(function () { + throw new jIO.util.jIOError(that._keyid + " : " + cryptoerror.error_type + + " : " + cryptoerror.error_message, 801); + }); + }); }); }); }); @@ -187,6 +257,32 @@ arguments); }; + CryptStorage.prototype.addkey = function (key) { + var that = this; + if (key === undefined || key === null) {return; } + if (!(key.hasOwnProperty("CryptoKey") && key.hasOwnProperty("Salt"))) {return; } + if (!(key.CryptoKey instanceof CryptoKey && key.Salt instanceof ArrayBuffer)) {return; } + if (key.CryptoKey.algorithm.name !== "PBKDF2" + && key.CryptoKey.usages[0] !== "deriveKey") {return; } + return new RSVP.Queue() + .push(function () { + return window.crypto.subtle.deriveKey({ + "name": "PBKDF2", + "salt": key.Salt, + "iterations": 1000, + //we can add iteration number but slow CPU will freez + "hash": "SHA-256" + }, key.CryptoKey, { + "name": "AES-GCM", + "length": 256 + }, false, ["encrypt", "decrypt"]); + }) + .push(function (res) { + that._key = res; + }); + }; + + jIO.addStorage('crypt', CryptStorage); -}(jIO, RSVP, DOMException, Blob, crypto, Uint8Array, ArrayBuffer)); +}(jIO, RSVP, DOMException, Blob, crypto, Uint8Array, ArrayBuffer, CryptoKey)); diff --git a/src/jio.storage/davstorage.js b/src/jio.storage/davstorage.js index 7203ce05364ce5763ed7c81b51bf3da8d19adc03..d219f711982f61d671e81198270c017aed822216 100644 --- a/src/jio.storage/davstorage.js +++ b/src/jio.storage/davstorage.js @@ -76,11 +76,12 @@ * @class DavStorage * @constructor */ - function DavStorage(spec) { + function DavStorage(spec, utils) { if (typeof spec.url !== 'string') { throw new TypeError("DavStorage 'url' is not of type string"); } this._url = spec.url; + this._utils = utils; // XXX digest login if (typeof spec.basic_login === 'string') { this._authorization = "Basic " + spec.basic_login; diff --git a/src/jio.storage/documentstorage.js b/src/jio.storage/documentstorage.js index 1be4e0ace89d5eae4f4969acd54b520f73d16159..26c018994d21e6bd8e9a080abd765539a30984cc 100644 --- a/src/jio.storage/documentstorage.js +++ b/src/jio.storage/documentstorage.js @@ -8,8 +8,9 @@ * @class DocumentStorage * @constructor */ - function DocumentStorage(spec) { - this._sub_storage = jIO.createJIO(spec.sub_storage); + function DocumentStorage(spec, utils) { + this._utils = utils; + this._sub_storage = jIO.createJIO(spec.sub_storage, utils); this._document_id = spec.document_id; this._repair_attachment = spec.repair_attachment || false; } diff --git a/src/jio.storage/drivetojiomapping.js b/src/jio.storage/drivetojiomapping.js index 6dda555e97d1269fc9fccd7c6aef0582b842f2d4..c13dee63039c240653fd59aaee3b852aa5390b4f 100644 --- a/src/jio.storage/drivetojiomapping.js +++ b/src/jio.storage/drivetojiomapping.js @@ -9,8 +9,9 @@ * @class FileSystemBridgeStorage * @constructor */ - function FileSystemBridgeStorage(spec) { - this._sub_storage = jIO.createJIO(spec.sub_storage); + function FileSystemBridgeStorage(spec, utils) { + this._utils = utils; + this._sub_storage = jIO.createJIO(spec.sub_storage, utils); } var DOCUMENT_EXTENSION = ".json", DOCUMENT_KEY = "/.jio_documents/", diff --git a/src/jio.storage/dropboxstorage.js b/src/jio.storage/dropboxstorage.js index 4c5127088c3d7c29899035b7719f130aecf46b15..51d8f0aec766275f6dbb86b353c1ba9e7267424a 100644 --- a/src/jio.storage/dropboxstorage.js +++ b/src/jio.storage/dropboxstorage.js @@ -105,11 +105,12 @@ * @class DropboxStorage * @constructor */ - function DropboxStorage(spec) { + function DropboxStorage(spec, utils) { if (typeof spec.access_token !== 'string' || !spec.access_token) { throw new TypeError("Access Token' must be a string " + "which contains more than one character."); } + this._utils = utils; this._access_token = spec.access_token; } @@ -325,4 +326,4 @@ jIO.addStorage('dropbox', DropboxStorage); -}(jIO, RSVP, Blob, JSON)); +}(jIO, RSVP, Blob, JSON)); \ No newline at end of file diff --git a/src/jio.storage/erp5storage.js b/src/jio.storage/erp5storage.js index b18431229065a025af51492c37b20c4f6cae68a7..785cdf801e8735d7a241a960381c615ccca6d9e2 100644 --- a/src/jio.storage/erp5storage.js +++ b/src/jio.storage/erp5storage.js @@ -139,12 +139,13 @@ } // XXX docstring - function ERP5Storage(spec) { + function ERP5Storage(spec, utils) { if (typeof spec.url !== "string" || !spec.url) { throw new TypeError("ERP5 'url' must be a string " + "which contains more than one character."); } this._url = spec.url; + this._utils = utils; this._default_view_reference = spec.default_view_reference; } diff --git a/src/jio.storage/fbstorage.js b/src/jio.storage/fbstorage.js index bca93e0379cfca020cfb682fed2c25eaa304a293..fe7966990410cb1a97f558a92191854d6c6405c2 100644 --- a/src/jio.storage/fbstorage.js +++ b/src/jio.storage/fbstorage.js @@ -11,7 +11,7 @@ "{+access_token}", get_feed_template = UriTemplate.parse(GET_FEED_URL); - function FBStorage(spec) { + function FBStorage(spec, utils) { if (typeof spec.access_token !== 'string' || !spec.access_token) { throw new TypeError("Access Token must be a string " + "which contains more than one character."); @@ -20,6 +20,7 @@ throw new TypeError("User ID must be a string " + "which contains more than one character."); } + this._utils = utils; this._access_token = spec.access_token; this._user_id = spec.user_id; this._default_field_list = spec.default_field_list || []; diff --git a/src/jio.storage/gdrivestorage.js b/src/jio.storage/gdrivestorage.js index 2bb4807de5a5806ece987e8630cd9e131c0f6553..25a6ee6501ed3b8c33ed145bedccd349378ebb3b 100644 --- a/src/jio.storage/gdrivestorage.js +++ b/src/jio.storage/gdrivestorage.js @@ -72,7 +72,7 @@ * @class GdriveStorage * @constructor */ - function GdriveStorage(spec) { + function GdriveStorage(spec, utils) { if (spec === undefined || spec.access_token === undefined || typeof spec.access_token !== 'string') { throw new TypeError("Access Token must be a string " + @@ -83,6 +83,7 @@ throw new TypeError("trashing parameter" + " must be a boolean (true or false)"); } + this._utils = utils; this._trashing = spec.trashing || true; this._access_token = spec.access_token; return; diff --git a/src/jio.storage/gidstorage.js b/src/jio.storage/gidstorage.js index a19eadb79c233ae975ffefe864f3e4269d2eef94..b485b3d904600fbd448a507a2f66b3ead4b3eb7b 100644 --- a/src/jio.storage/gidstorage.js +++ b/src/jio.storage/gidstorage.js @@ -283,8 +283,9 @@ * * @class GidStorage */ - function GidStorage(spec) { + function GidStorage(spec, utils) { var that = this, priv = {}; + this._utils = utils; priv.sub_storage = spec.sub_storage; priv.constraints = spec.constraints || { diff --git a/src/jio.storage/httpstorage.js b/src/jio.storage/httpstorage.js index 46faf1c29d07dd078cdec31eee021b54b20369ea..68133f2142a062b70bd3d3df9125477da131e4fe 100644 --- a/src/jio.storage/httpstorage.js +++ b/src/jio.storage/httpstorage.js @@ -3,13 +3,14 @@ (function (jIO, RSVP, Blob) { "use strict"; - function HttpStorage(spec) { + function HttpStorage(spec, utils) { if (spec.hasOwnProperty('catch_error')) { this._catch_error = spec.catch_error; } else { this._catch_error = false; } // If timeout not set, use 0 for no timeout value + this._utils = utils; this._timeout = spec.timeout || 0; } diff --git a/src/jio.storage/indexeddbstorage.js b/src/jio.storage/indexeddbstorage.js index 3860f0ed9f39e038f9f00c54b7dfcdff9371c0cb..e1f7e415b7f2a423b63fff74d0c253e10edcd344 100644 --- a/src/jio.storage/indexeddbstorage.js +++ b/src/jio.storage/indexeddbstorage.js @@ -38,12 +38,13 @@ // Read only as changing it can lead to data corruption var UNITE = 2000000; - function IndexedDBStorage(description) { + function IndexedDBStorage(description, utils) { if (typeof description.database !== "string" || description.database === "") { throw new TypeError("IndexedDBStorage 'database' description property " + "must be a non-empty string"); } + this._utils = utils; this._database_name = "jio:" + description.database; } diff --git a/src/jio.storage/indexstorage.js b/src/jio.storage/indexstorage.js index 8b22903f30b1a4f18944de03dc6fb8ce55eb4ab5..11a8b0189b63045d1834b23469f54c3bfd600c22 100644 --- a/src/jio.storage/indexstorage.js +++ b/src/jio.storage/indexstorage.js @@ -427,7 +427,7 @@ * @class IndexStorage * @constructor */ - function IndexStorage(spec) { + function IndexStorage(spec, utils) { var i; if (!Array.isArray(spec.indices)) { throw new TypeError("IndexStorage 'indices' must be an array of " + @@ -451,6 +451,7 @@ "'indices[x].index' must be a string array"); } } + this._utils = utils; this._sub_storage = spec.sub_storage; } diff --git a/src/jio.storage/localstorage.js b/src/jio.storage/localstorage.js index cade8daa96f51b50cd878fd786f92bc4be92d5a6..a807f96a042e9c6f4129450525727b98b7ec7d25 100644 --- a/src/jio.storage/localstorage.js +++ b/src/jio.storage/localstorage.js @@ -24,7 +24,8 @@ (function (jIO, sessionStorage, localStorage, RSVP) { "use strict"; - function LocalStorage(spec) { + function LocalStorage(spec, utils) { + this._utils = utils; if (spec.sessiononly === true) { this._storage = sessionStorage; } else { diff --git a/src/jio.storage/memorystorage.js b/src/jio.storage/memorystorage.js index e07a8acf3ca5997a6f3f31ef2ab924bc67259e84..1c5addd77b05bec1e1b622d731fd2a1e7f7b4374 100644 --- a/src/jio.storage/memorystorage.js +++ b/src/jio.storage/memorystorage.js @@ -29,8 +29,10 @@ * @class MemoryStorage * @constructor */ - function MemoryStorage() { + function MemoryStorage(spec, utils) { + this._spec = spec; //not used just for compatibility issue this._database = {}; + this._utils = utils; } MemoryStorage.prototype.put = function (id, metadata) { diff --git a/src/jio.storage/multisplitstorage.js b/src/jio.storage/multisplitstorage.js index 886f959c653647370fbafe8a0cb771973875335c..d2574121976e13852c12c08159278950d96b01c0 100644 --- a/src/jio.storage/multisplitstorage.js +++ b/src/jio.storage/multisplitstorage.js @@ -205,8 +205,9 @@ * * @class MultiSplitStorage */ - function MultiSplitStorage(spec) { + function MultiSplitStorage(spec, utils) { var that = this, priv = {}; + this._utils = utils; /** * The list of sub storages we want to use to store part of documents. diff --git a/src/jio.storage/parserstorage.js b/src/jio.storage/parserstorage.js index 74065e2eb47bf52050edacde47a856fadabd3db2..d92a655155195dc7e759b03c71660b22fc8c7fa8 100644 --- a/src/jio.storage/parserstorage.js +++ b/src/jio.storage/parserstorage.js @@ -238,11 +238,12 @@ ///////////////////////////////////////////////////////////// // Storage ///////////////////////////////////////////////////////////// - function ParserStorage(spec) { + function ParserStorage(spec, utils) { + this._utils = utils; this._attachment_id = spec.attachment_id; this._document_id = spec.document_id; this._parser_name = spec.parser; - this._sub_storage = jIO.createJIO(spec.sub_storage); + this._sub_storage = jIO.createJIO(spec.sub_storage, utils); } ParserStorage.prototype.hasCapacity = function (capacity) { diff --git a/src/jio.storage/qiniustorage.js b/src/jio.storage/qiniustorage.js index bde60a55f46534ec96940e5e88957de112d0c99f..9c926b1a86f723da1d65842843d82a97207725bf 100644 --- a/src/jio.storage/qiniustorage.js +++ b/src/jio.storage/qiniustorage.js @@ -71,7 +71,8 @@ * @class QiniuStorage * @constructor */ - function QiniuStorage(spec) { + function QiniuStorage(spec, utils) { + this._utils = utils; if (typeof spec.bucket !== 'string' && !spec.bucket) { throw new TypeError("Qiniu 'bucket' must be a string " + "which contains more than one character."); diff --git a/src/jio.storage/querystorage.js b/src/jio.storage/querystorage.js index 02302f3b40f66bff3b726d1f4a4a830e3cbb4a90..4a78166bace2ca6732c15cdab7520dd3d0a5d4fc 100644 --- a/src/jio.storage/querystorage.js +++ b/src/jio.storage/querystorage.js @@ -36,8 +36,9 @@ * @class QueryStorage * @constructor */ - function QueryStorage(spec) { - this._sub_storage = jIO.createJIO(spec.sub_storage); + function QueryStorage(spec, utils) { + this._utils = utils; + this._sub_storage = jIO.createJIO(spec.sub_storage, utils); this._key_schema = {key_set: {}, cast_lookup: {}}; initKeySchema(this, spec); } diff --git a/src/jio.storage/replicatestorage.js b/src/jio.storage/replicatestorage.js index 7d4e3db7bbac7a04b8b41d27867738555e067e4a..b4aa16d282cd2717980eb69f2d2fe6b8a796506a 100644 --- a/src/jio.storage/replicatestorage.js +++ b/src/jio.storage/replicatestorage.js @@ -53,18 +53,20 @@ return rusha.digestFromArrayBuffer(content); } - function ReplicateStorage(spec) { + function ReplicateStorage(spec, utils) { + this._utils = utils; this._query_options = spec.query || {}; if (spec.signature_hash_key !== undefined) { this._query_options.select_list = [spec.signature_hash_key]; } this._signature_hash_key = spec.signature_hash_key; - this._local_sub_storage = jIO.createJIO(spec.local_sub_storage); - this._remote_sub_storage = jIO.createJIO(spec.remote_sub_storage); + this._local_sub_storage = jIO.createJIO(spec.local_sub_storage, utils); + this._remote_sub_storage = jIO.createJIO(spec.remote_sub_storage, utils); if (spec.hasOwnProperty('signature_sub_storage')) { - this._signature_sub_storage = jIO.createJIO(spec.signature_sub_storage); + this._signature_sub_storage = jIO.createJIO(spec.signature_sub_storage, + utils); this._custom_signature_sub_storage = true; } else { this._signature_hash = "_replicate_" + generateHash( diff --git a/src/jio.storage/shastorage.js b/src/jio.storage/shastorage.js index d479fcbfbd19166bdbfffaa7310f8d183b5ac886..6d2fe5955fb71b3c5efe424c89e45bcc64d1165e 100644 --- a/src/jio.storage/shastorage.js +++ b/src/jio.storage/shastorage.js @@ -16,8 +16,9 @@ var rusha = new Rusha(); - function ShaStorage(spec) { - this._sub_storage = jIO.createJIO(spec.sub_storage); + function ShaStorage(spec, utils) { + this._utils = utils; + this._sub_storage = jIO.createJIO(spec.sub_storage, utils); } ShaStorage.prototype.post = function (param) { diff --git a/src/jio.storage/unionstorage.js b/src/jio.storage/unionstorage.js index eb5b0c641810fe877bce2f08250ab2c6141e5960..23b3c6e388444855544f8e48ecb715dd2a4b7cfc 100644 --- a/src/jio.storage/unionstorage.js +++ b/src/jio.storage/unionstorage.js @@ -32,14 +32,15 @@ * @class UnionStorage * @constructor */ - function UnionStorage(spec) { + function UnionStorage(spec, utils) { + this._utils = utils; if (!Array.isArray(spec.storage_list)) { throw new jIO.util.jIOError("storage_list is not an Array", 400); } var i; this._storage_list = []; for (i = 0; i < spec.storage_list.length; i += 1) { - this._storage_list.push(jIO.createJIO(spec.storage_list[i])); + this._storage_list.push(jIO.createJIO(spec.storage_list[i], utils)); } } diff --git a/src/jio.storage/uuidstorage.js b/src/jio.storage/uuidstorage.js index 85a655616a18bed46730f068b06053c3e0d40a79..9250c2e1cd847420e1a08592df3ac28be2d7f823 100644 --- a/src/jio.storage/uuidstorage.js +++ b/src/jio.storage/uuidstorage.js @@ -8,8 +8,9 @@ * @class UUIDStorage * @constructor */ - function UUIDStorage(spec) { - this._sub_storage = jIO.createJIO(spec.sub_storage); + function UUIDStorage(spec, utils) { + this._utils = utils; + this._sub_storage = jIO.createJIO(spec.sub_storage, utils); } UUIDStorage.prototype.get = function () { diff --git a/src/jio.storage/websqlstorage.js b/src/jio.storage/websqlstorage.js index 3addae99ba081303d00fbc72507a7d549ba2cc02..4b4ce34e5bbf6cc7e14c61d3e379ef3cac184737 100644 --- a/src/jio.storage/websqlstorage.js +++ b/src/jio.storage/websqlstorage.js @@ -69,7 +69,8 @@ }); } - function WebSQLStorage(spec) { + function WebSQLStorage(spec, utils) { + this._utils = utils; if (typeof spec.database !== 'string' || !spec.database) { throw new TypeError("database must be a string " + "which contains more than one character."); diff --git a/src/jio.storage/zipstorage.js b/src/jio.storage/zipstorage.js index 6d3236a2022f646db8caad9a399cdeaf966daf99..456d5e23a239e1111fac12d103f39c919cf4b93e 100644 --- a/src/jio.storage/zipstorage.js +++ b/src/jio.storage/zipstorage.js @@ -12,8 +12,9 @@ var MIME_TYPE = "application/x-jio-utf16_lz_string"; - function ZipStorage(spec) { - this._sub_storage = jIO.createJIO(spec.sub_storage); + function ZipStorage(spec, utils) { + this._utils = utils; + this._sub_storage = jIO.createJIO(spec.sub_storage, utils); } ZipStorage.prototype.get = function () { diff --git a/test/jio.storage/cryptstorage.tests.js b/test/jio.storage/cryptstorage.tests.js index 1c6cca47501e90677a1f5de60e0965ee8ea666df..29f323e4b5f4be48ca86c4c4e7faab28d0906504 100644 --- a/test/jio.storage/cryptstorage.tests.js +++ b/test/jio.storage/cryptstorage.tests.js @@ -1,5 +1,6 @@ /*jslint nomen: true*/ -/*global Blob, crypto, Uint8Array, ArrayBuffer*/ +/*global Blob, crypto, Uint8Array, ArrayBuffer, TextEncoder, window*/ +/*jslint maxlen: 130 */ (function (jIO, QUnit, Blob) { "use strict"; var test = QUnit.test, @@ -11,9 +12,47 @@ equal = QUnit.equal, throws = QUnit.throws, module = QUnit.module, - key = {"alg": "A256GCM", "ext": true, - "k": "seeaLzpu8dHG07bO2ANH2GywbTqs_zrs4Vq8zmtYeE4", - "key_ops": ["encrypt", "decrypt"], "kty": "oct"}; + callback = {callback: function () {return true; }}, + convertKey = function (str) { + var buffer = new TextEncoder("utf-8").encode(str); + // We transform the string into an arraybuffer. + return new RSVP.Queue() + .push(function () { + return RSVP.all([crypto.subtle.digest("SHA-256", buffer), + crypto.subtle.importKey( + "raw", + buffer, + {name: "PBKDF2" + }, + false, + ["deriveKey"] + ) + ]); + }) + .push(function (my_array) { + return { + CryptoKey: my_array[1], + Salt: my_array[0] + }; + }) + .push(undefined, function (error) { + throw error; + }); + }, + userkey = "passwordHADR0909", + utils = {"crypto_getCryptoKey": function (callback) { + return new RSVP.Queue() + .push(function () { + return convertKey(userkey); + }) + .push(function (crypto_key) { + return callback.addkey_crypto(crypto_key); + }) + .push(undefined, function (error) { + throw error; + }); + }}; + ///////////////////////////////////////////////////////////////// // Custom test substorage definition @@ -23,6 +62,14 @@ } jIO.addStorage('cryptstorage200', Storage200); + function Storagecallback(spec, utils) { + this._spec = spec; + this._utils = utils; + return this; + } + jIO.addStorage('Cryptstoragecallback', Storagecallback); + + ///////////////////////////////////////////////////////////////// // CryptStorage.constructor ///////////////////////////////////////////////////////////////// @@ -31,14 +78,29 @@ test("create substorage", function () { var jio = jIO.createJIO({ type: "crypt", - key: key, + keyid: "key200", sub_storage: {type : "cryptstorage200"} }); equal(jio.__type, "crypt"); + equal(jio.__storage._keyid, "key200"); equal(jio.__storage._sub_storage.__type, "cryptstorage200"); }); + test("Test callback", function () { + var jio = jIO.createJIO({ + type: "crypt", + keyid: "key200", + sub_storage: { + type: "Cryptstoragecallback" + } + }, callback); + + deepEqual(jio.__storage._utils.callback(), true); + deepEqual(jio.__storage._sub_storage.__storage._utils.callback(), true); + + }); + ///////////////////////////////////////////////////////////////// // CryptStorage.get ///////////////////////////////////////////////////////////////// @@ -49,7 +111,6 @@ var jio = jIO.createJIO({ type: "crypt", - key: key, sub_storage: {type : "cryptstorage200"} }); @@ -82,7 +143,6 @@ var jio = jIO.createJIO({ type: "crypt", - key: key, sub_storage: {type : "cryptstorage200"} }); @@ -115,7 +175,6 @@ var jio = jIO.createJIO({ type: "crypt", - key: key, sub_storage: {type : "cryptstorage200"} }); @@ -146,7 +205,6 @@ var jio = jIO.createJIO({ type: "crypt", - key: key, sub_storage: {type : "cryptstorage200"} }); @@ -174,7 +232,6 @@ test("hasCapacity return substorage value", function () { var jio = jIO.createJIO({ type: "crypt", - key: key, sub_storage: {type : "cryptstorage200"} }); @@ -204,7 +261,6 @@ var jio = jIO.createJIO({ type: "crypt", - key: key, sub_storage: {type : "cryptstorage200"} }); @@ -237,7 +293,6 @@ var jio = jIO.createJIO({ type: "crypt", - key: key, sub_storage: {type : "cryptstorage200"} }); @@ -271,7 +326,6 @@ var jio = jIO.createJIO({ type: "crypt", - key: key, sub_storage: {type : "cryptstorage200"} }); @@ -301,13 +355,13 @@ setup: function () { this.jio = jIO.createJIO({ type: "crypt", - key: key, + keyid: "key200", sub_storage: {type : "cryptstorage200"} - }); + }, utils); } }); - test("return substorage getattachment", function () { + test("return error if key is not type Cryptokey", function () { var id = "/", attachment = "stringattachment", blob = new Blob(['foo']); @@ -322,64 +376,34 @@ expect(3); this.jio.getAttachment(id, attachment) - .then(function (result) { - equal(result, blob, "Return substorage result"); - }) - .fail(function (error) { - ok(false, error); - }) - .always(function () { - start(); - }); - }); - - test("return substorage getattachment if decrypt fails", function () { - var id = "/", - attachment = "stringattachment", - blob = new Blob(['foo'], {type: 'application/x-jio-aes-gcm-encryption'}); - - Storage200.prototype.getAttachment = function (arg1, arg2) { - equal(arg1, id, "getAttachment 200 called"); - equal(arg2, attachment, "getAttachment 200 called"); - return blob; - }; - - stop(); - expect(3); - - this.jio.getAttachment(id, attachment) - .then(function (result) { - equal(result, blob, "Return substorage result"); - }) .fail(function (error) { - ok(false, error); + equal(error.message, "key200 : TypeError : password is not type CRYPTOKEY", "get attachement error shown"); }) .always(function () { start(); }); }); - test("return substorage getattachment if not data url", function () { + test("return error if decrypt fails", function () { var id = "/", attachment = "stringattachment", - blob = new Blob(['foo'], - {type: 'application/x-jio-aes-gcm-encryption'}); + that, + blob = new Blob(['foo']); //non crypted file - Storage200.prototype.getAttachment = function (arg1, arg2) { - equal(arg1, id, "getAttachment 200 called"); - equal(arg2, attachment, "getAttachment 200 called"); + Storage200.prototype.getAttachment = function () { return blob; }; stop(); - expect(3); - - this.jio.getAttachment(id, attachment) - .then(function (result) { - equal(result, blob, "Return substorage result"); - }) - .fail(function (error) { - ok(false, error); + expect(1); + that = this; + that.jio.getAttachment(id, attachment) + .fail(function () { + return that.jio.getAttachment(id, attachment) + .push(undefined, function (error) { + equal(error.message, "key200 : OperationError : Failed to decrypt due to incorrect password or data", + "returned error : incorrect password or incrypted data"); + }); }) .always(function () { start(); @@ -389,11 +413,14 @@ test("decrypt blob from aes-gcm", function () { var id = "/", attachment = "stringattachment", + that, value = "azertyuio\npàç_è-('é&", - tocheck = "data:application/x-jio-aes-gcm-encryption;base64" + - ",+p/Ho+KgGHZC2zDLMbQQS2tXcsy0g+Ho41VZnlPEkXdmG9zm36c8iLCkv" + - "lanyWCN510NK4hj1EgWQ6WrLS5pCmA/yeAWh+HyfPkYKDRHVBl6+Hxd53I" + - "TmiWQ6Vix2jaIQg==", + tocheck = "data:application/x-jio-aes-gcm-encryption" + + ";base64,6RxBftHGvMYG+ymk2e2viIhtdIcbui7+4UH57S0bl" + + "D6fqrrWTcgzx/SZjXdzYQyK7a1pe2tM9msrPDyZrreN+b+rU9S" + + "YodEKW/XgSkcQj9n+V77KT/qsQymLb1K3widtxA==", + + blob = jIO.util.dataURItoBlob(tocheck); @@ -401,32 +428,36 @@ Storage200.prototype.getAttachment = function (arg1, arg2) { equal(arg1, id, "getAttachment 200 called"); equal(arg2, attachment, "getAttachment 200 called"); + window.m = new Date().getTime(); return blob; }; stop(); - expect(6); - - this.jio.getAttachment(id, attachment) - .then(function (result) { - ok(result !== blob, "Does not return substorage result"); - ok(result instanceof Blob, "Data is Blob"); - deepEqual(result.type, "text/plain;charset=utf-8", - "Check mimetype"); - - return jIO.util.readBlobAsText(result); - }) - .then(function (result) { - equal(result.target.result, value, "Attachment correctly fetched"); - }) - .fail(function (error) { - ok(false, error); + expect(9); + + that = this; + that.jio.getAttachment(id, attachment) + .fail(function () { + return that.jio.getAttachment(id, attachment) + .push(function (result) { + ok(true, "Decryption time = " + (new Date().getTime() - window.m) + " milliseconde"); + ok(result !== blob, "Does not return substorage result"); + ok(result instanceof Blob, "Data is Blob"); + deepEqual(result.type, "text/plain;charset=utf-8", + "Check mimetype"); + return jIO.util.readBlobAsText(result); + }) + .push(function (result) { + equal(result.target.result, value, "Attachment correctly fetched"); + return result; + }); }) .always(function () { start(); }); }); + ///////////////////////////////////////////////////////////////// // CryptStorage.putAttachment ///////////////////////////////////////////////////////////////// @@ -434,9 +465,9 @@ setup: function () { this.jio = jIO.createJIO({ type: "crypt", - key: key, + keyid: "key200", sub_storage: {type : "cryptstorage200"} - }); + }, utils); } }); @@ -445,8 +476,19 @@ return new RSVP.Queue() .push(function () { - return crypto.subtle.importKey("jwk", key, - "AES-GCM", false, ["decrypt"]); + return convertKey(userkey); + }) + .push(function (key) { + return window.crypto.subtle.deriveKey({ + "name": "PBKDF2", + "salt": key.Salt, + "iterations": 1000, + //we can add iteration number but slow CPU will freez + "hash": "SHA-256" + }, key.CryptoKey, { + "name": "AES-GCM", + "length": 256 + }, false, ["encrypt", "decrypt"]); }) .push(function (res) { decryptKey = res; @@ -460,11 +502,10 @@ coded = coded.target.result; iv = new Uint8Array(coded.slice(0, 12)); - return crypto.subtle.decrypt({name : "AES-GCM", iv : iv}, + return crypto.subtle.decrypt({name: "AES-GCM", iv: iv}, decryptKey, coded.slice(12)); }) .push(function (arr) { - arr = String.fromCharCode.apply(null, new Uint8Array(arr)); equal( arr, @@ -477,6 +518,7 @@ test("crypt blob to aes-gcm", function () { var id = "/", + that, attachment = "stringattachment", value = "azertyuio\npàç_è-('é&", blob = new Blob([value], @@ -492,15 +534,16 @@ return decodeAES(arg3); }; + stop(); expect(7); - + that = this; this.jio.putAttachment(id, attachment, blob) - .then(function (result) { - equal(result, "ok", "Return substorage result"); - }) - .fail(function (error) { - ok(false, error); + .fail(function () { + return that.jio.putAttachment(id, attachment, blob) + .push(function (result) { + equal(result, "ok", "Return substorage result"); + }); }) .always(function () { start(); diff --git a/test/jio.storage/davstorage.tests.js b/test/jio.storage/davstorage.tests.js index 9fe37b77975863c741806030ea377bed075b67ab..5fd72724f789cc7d1f191c3be8bf39d3b8d2f2b1 100644 --- a/test/jio.storage/davstorage.tests.js +++ b/test/jio.storage/davstorage.tests.js @@ -11,7 +11,8 @@ equal = QUnit.equal, module = QUnit.module, domain = "https://example.org", - basic_login = "login:passwd"; + basic_login = "login:passwd", + utils = {callback: function () {return true; }}; ///////////////////////////////////////////////////////////////// // davStorage constructor @@ -30,6 +31,15 @@ deepEqual(jio.__storage._with_credentials, undefined); }); + test("Test callback", function () { + var jio = jIO.createJIO({ + type: "dav", + url: domain + }, utils); + + deepEqual(jio.__storage._utils.callback(), true); + }); + test("Storage store basic login", function () { var jio = jIO.createJIO({ type: "dav", diff --git a/test/jio.storage/documentstorage.tests.js b/test/jio.storage/documentstorage.tests.js index e188f4edfa871688136980bcc83cb6bc61a6fa3d..4123c6c34378cac2e32e36d0261c8639bfa85b19 100644 --- a/test/jio.storage/documentstorage.tests.js +++ b/test/jio.storage/documentstorage.tests.js @@ -9,7 +9,8 @@ expect = QUnit.expect, deepEqual = QUnit.deepEqual, equal = QUnit.equal, - module = QUnit.module; + module = QUnit.module, + utils = {callback: function () {return true; }}; ///////////////////////////////////////////////////////////////// // Custom test substorage definition @@ -19,6 +20,13 @@ } jIO.addStorage('documentstorage200', Storage200); + function Storagecallback(spec, utils) { + this._spec = spec; + this._utils = utils; + return this; + } + jIO.addStorage('documentstoragecallback', Storagecallback); + ///////////////////////////////////////////////////////////////// // documentStorage.constructor ///////////////////////////////////////////////////////////////// @@ -38,6 +46,19 @@ }); + test("Test callback", function () { + var jio = jIO.createJIO({ + type: "document", + sub_storage: { + type: "documentstoragecallback" + } + }, utils); + + deepEqual(jio.__storage._utils.callback(), true); + deepEqual(jio.__storage._sub_storage.__storage._utils.callback(), true); + + }); + test("accept parameters", function () { var jio = jIO.createJIO({ type: "document", diff --git a/test/jio.storage/drivetojiomapping.tests.js b/test/jio.storage/drivetojiomapping.tests.js index d8d82501cfdb3467aba91c8b1bab8e579c4dd2a0..654da2f55c937f925566abb81f7a1d81e53ce7f1 100644 --- a/test/jio.storage/drivetojiomapping.tests.js +++ b/test/jio.storage/drivetojiomapping.tests.js @@ -9,7 +9,8 @@ expect = QUnit.expect, deepEqual = QUnit.deepEqual, equal = QUnit.equal, - module = QUnit.module; + module = QUnit.module, + utils = {callback: function () {return true; }}; ///////////////////////////////////////////////////////////////// // Custom test substorage definition @@ -19,6 +20,13 @@ } jIO.addStorage('drivetojiomapping200', Storage200); + function Storagecallback(spec, utils) { + this._spec = spec; + this._utils = utils; + return this; + } + jIO.addStorage('drivetojiomappingcallback', Storagecallback); + ///////////////////////////////////////////////////////////////// // driveToJioMapping.constructor ///////////////////////////////////////////////////////////////// @@ -36,6 +44,19 @@ }); + test("Test callback", function () { + var jio = jIO.createJIO({ + type: "drivetojiomapping", + sub_storage: { + type: "drivetojiomappingcallback" + } + }, utils); + + deepEqual(jio.__storage._utils.callback(), true); + deepEqual(jio.__storage._sub_storage.__storage._utils.callback(), true); + + }); + ///////////////////////////////////////////////////////////////// // driveToJioMapping.get ///////////////////////////////////////////////////////////////// diff --git a/test/jio.storage/dropboxstorage.tests.js b/test/jio.storage/dropboxstorage.tests.js index 683867aaf26d645d8a72e356279ff554a459e58e..a3b754ceab92f45aa7ea744d06d5a59d97825a30 100644 --- a/test/jio.storage/dropboxstorage.tests.js +++ b/test/jio.storage/dropboxstorage.tests.js @@ -10,7 +10,8 @@ deepEqual = QUnit.deepEqual, equal = QUnit.equal, module = QUnit.module, - token = "sample_token"; + token = "sample_token", + utils = {callback: function () {return true; }}; ///////////////////////////////////////////////////////////////// // DropboxStorage constructor @@ -26,6 +27,15 @@ deepEqual(jio.__storage._access_token, token); }); + test("Test callback", function () { + var jio = jIO.createJIO({ + type: "dropbox", + access_token: token + }, utils); + + deepEqual(jio.__storage._utils.callback(), true); + }); + ///////////////////////////////////////////////////////////////// // DropboxStorage.put ///////////////////////////////////////////////////////////////// diff --git a/test/jio.storage/erp5storage.tests.js b/test/jio.storage/erp5storage.tests.js index acafdb63a0617a769b52f8e2850d1b2eb535fb95..7d59d100f69047e61292fcf9d482787abeb305d2 100644 --- a/test/jio.storage/erp5storage.tests.js +++ b/test/jio.storage/erp5storage.tests.js @@ -11,6 +11,7 @@ equal = QUnit.equal, module = QUnit.module, domain = "https://example.org", + utils = {callback: function () {return true; }}, traverse_template = domain + "?mode=traverse{&relative_url,view}", search_template = domain + "?mode=search{&query,select_list*,limit*," + "sort_on*,local_roles*,selection_domain*}", @@ -50,6 +51,15 @@ deepEqual(jio.__storage._default_view_reference, "bar_view"); }); + test("Test callback", function () { + var jio = jIO.createJIO({ + type: "erp5", + url: domain + }, utils); + + deepEqual(jio.__storage._utils.callback(), true); + }); + ///////////////////////////////////////////////////////////////// // erp5Storage.get ///////////////////////////////////////////////////////////////// diff --git a/test/jio.storage/fbstorage.tests.js b/test/jio.storage/fbstorage.tests.js index 1a1ec493ff243623487d8b9f6f933c37f0779a80..7d37ef62b0aa48378f0220186520de91cdcc487c 100644 --- a/test/jio.storage/fbstorage.tests.js +++ b/test/jio.storage/fbstorage.tests.js @@ -12,7 +12,8 @@ module = QUnit.module, throws = QUnit.throws, token = "sample_token", - user_id = "sample_user_id"; + user_id = "sample_user_id", + utils = {callback: function () {return true; }}; ///////////////////////////////////////////////////////////////// // Facebook Storage constructor @@ -31,6 +32,16 @@ deepEqual(jio.__storage._user_id, user_id); }); + test("Test callback", function () { + var jio = jIO.createJIO({ + type: "facebook", + access_token: token, + user_id: user_id + }, utils); + + deepEqual(jio.__storage._utils.callback(), true); + }); + test("reject non string token", function () { throws( diff --git a/test/jio.storage/gdrivestorage.tests.js b/test/jio.storage/gdrivestorage.tests.js index 2e3516c96e4ce72c61233200ab6ec6d379f2c151..d382d2db1513999bde5d2500efb7152031828043 100644 --- a/test/jio.storage/gdrivestorage.tests.js +++ b/test/jio.storage/gdrivestorage.tests.js @@ -12,6 +12,7 @@ module = QUnit.module, throws = QUnit.throws, token = "sample_token", + utils = {callback: function () {return true; }}, domain = "https://www.googleapis.com", boundary = "---------314159265358979323846", list_url = domain + "/drive/v2/files" + @@ -58,6 +59,15 @@ deepEqual(jio.__storage._access_token, token); }); + test("Test callback", function () { + var jio = jIO.createJIO({ + type: "gdrive", + access_token: token + }, utils); + + deepEqual(jio.__storage._utils.callback(), true); + }); + test("reject invalid trashing parameter", function () { throws( diff --git a/test/jio.storage/httpstorage.tests.js b/test/jio.storage/httpstorage.tests.js index 89b66b3d96098100c969a20cb42351d5f715fded..b8f42303c8307e28952bd936d16eef8378516f61 100644 --- a/test/jio.storage/httpstorage.tests.js +++ b/test/jio.storage/httpstorage.tests.js @@ -10,7 +10,8 @@ deepEqual = QUnit.deepEqual, equal = QUnit.equal, module = QUnit.module, - domain = "https://example.org"; + domain = "https://example.org", + utils = {callback: function () {return true; }}; ///////////////////////////////////////////////////////////////// // davStorage constructor @@ -27,6 +28,14 @@ deepEqual(jio.__storage._timeout, 0); }); + test("Test callback", function () { + var jio = jIO.createJIO({ + type: "http" + }, utils); + + deepEqual(jio.__storage._utils.callback(), true); + }); + test("Storage store catch_error", function () { var jio = jIO.createJIO({ type: "http", diff --git a/test/jio.storage/indexeddbstorage.tests.js b/test/jio.storage/indexeddbstorage.tests.js index 9fe8c72db1d03a7c21a0d8ddb94f110c7e9b00cb..2652da5d7133bdb6e5fc8e7f45da5b0d8463ac52 100644 --- a/test/jio.storage/indexeddbstorage.tests.js +++ b/test/jio.storage/indexeddbstorage.tests.js @@ -13,6 +13,7 @@ equal = QUnit.equal, module = QUnit.module, big_string = "", + utils = {callback: function () {return true; }}, j; for (j = 0; j < 3000000; j += 1) { @@ -48,6 +49,15 @@ deepEqual(jio.__storage._database_name, "jio:qunit"); }); + test("Test callback", function () { + var jio = jIO.createJIO({ + type: "indexeddb", + database: "qunit" + }, utils); + + deepEqual(jio.__storage._utils.callback(), true); + }); + ///////////////////////////////////////////////////////////////// // documentStorage.hasCapacity ///////////////////////////////////////////////////////////////// diff --git a/test/jio.storage/localstorage.tests.js b/test/jio.storage/localstorage.tests.js index 15a97e48fc3c87b6413996f389c280ca0daf8a4c..03502274dfb582bc2d11e77e29177d36c5d2cfa2 100644 --- a/test/jio.storage/localstorage.tests.js +++ b/test/jio.storage/localstorage.tests.js @@ -11,7 +11,8 @@ expect = QUnit.expect, deepEqual = QUnit.deepEqual, equal = QUnit.equal, - module = QUnit.module; + module = QUnit.module, + utils = {callback: function () {return true; }}; ///////////////////////////////////////////////////////////////// // localStorage.constructor @@ -26,6 +27,14 @@ equal(jio.__storage._storage, localStorage); }); + test("Test callback", function () { + var jio = jIO.createJIO({ + type: "local" + }, utils); + + deepEqual(jio.__storage._utils.callback(), true); + }); + test("sessiononly", function () { var jio = jIO.createJIO({ type: "local", diff --git a/test/jio.storage/memorystorage.tests.js b/test/jio.storage/memorystorage.tests.js index a77c7cadd5551bee1a939da2325fcef9c5191102..43d5f97dd04da8690a33c5286c0bdb2ef550ee1e 100644 --- a/test/jio.storage/memorystorage.tests.js +++ b/test/jio.storage/memorystorage.tests.js @@ -9,7 +9,8 @@ expect = QUnit.expect, deepEqual = QUnit.deepEqual, equal = QUnit.equal, - module = QUnit.module; + module = QUnit.module, + utils = {callback: function () {return true; }}; ///////////////////////////////////////////////////////////////// // memoryStorage constructor @@ -25,6 +26,14 @@ deepEqual(jio.__storage._database, {}); }); + test("Test callback", function () { + var jio = jIO.createJIO({ + type: "memory" + }, utils); + + deepEqual(jio.__storage._utils.callback(), true); + }); + test("Storage's memory database is not shared", function () { var jio = jIO.createJIO({ "type": "memory" diff --git a/test/jio.storage/parserstorage.tests.js b/test/jio.storage/parserstorage.tests.js index cbfe7e15989a8041c0717115faed2362d67736f3..dff91d464f793005d75420d415d12ac742065bf3 100644 --- a/test/jio.storage/parserstorage.tests.js +++ b/test/jio.storage/parserstorage.tests.js @@ -9,7 +9,8 @@ expect = QUnit.expect, deepEqual = QUnit.deepEqual, equal = QUnit.equal, - module = QUnit.module; + module = QUnit.module, + utils = {callback: function () {return true; }}; ///////////////////////////////////////////////////////////////// // Custom RSS test substorage definition @@ -51,6 +52,18 @@ }; jIO.addStorage('rssstorage200', RSSStorage200); + + ///////////////////////////////////////////////////////////////// + // Custom callback test substorage definition + ///////////////////////////////////////////////////////////////// + + function Storagecallback(spec, utils) { + this._spec = spec; + this._utils = utils; + return this; + } + jIO.addStorage('parsestoragecallback', Storagecallback); + ///////////////////////////////////////////////////////////////// // Custom atom test substorage definition ///////////////////////////////////////////////////////////////// @@ -174,6 +187,19 @@ equal(jio.__storage._parser, undefined); }); + test("Test callback", function () { + var jio = jIO.createJIO({ + type: "parser", + sub_storage: { + type: "parsestoragecallback" + } + }, utils); + + deepEqual(jio.__storage._utils.callback(), true); + deepEqual(jio.__storage._sub_storage.__storage._utils.callback(), true); + + }); + ///////////////////////////////////////////////////////////////// // ParserStorage.allDocs ///////////////////////////////////////////////////////////////// @@ -908,4 +934,4 @@ }); }); -}(jIO, QUnit, Blob)); +}(jIO, QUnit, Blob)); \ No newline at end of file diff --git a/test/jio.storage/qiniustorage.tests.js b/test/jio.storage/qiniustorage.tests.js index 707209b664f957ee9082b1c290608ef35499f70e..9adfbe71cc2974aebb812376f3f5c85f027dcfc5 100644 --- a/test/jio.storage/qiniustorage.tests.js +++ b/test/jio.storage/qiniustorage.tests.js @@ -18,7 +18,8 @@ bucket: bucket, access_key: access_key, secret_key: secret_key - }; + }, + utils = {callback: function () {return true; }}; ///////////////////////////////////////////////////////////////// // qiniuStorage constructor @@ -34,6 +35,14 @@ deepEqual(jio.__storage._secret_key, qiniu_spec.secret_key); }); + test("Test callback", function () { + var jio = jIO.createJIO({ + type: "qiniu" + }, utils); + + deepEqual(jio.__storage._utils.callback(), true); + }); + ///////////////////////////////////////////////////////////////// // qiniuStorage.get ///////////////////////////////////////////////////////////////// diff --git a/test/jio.storage/querystorage.tests.js b/test/jio.storage/querystorage.tests.js index b420637c7a5bda1ff36cc37af2aa33995d148ea4..a5ca8b1f13347a8c8a8747d05065f6a5925b9075 100644 --- a/test/jio.storage/querystorage.tests.js +++ b/test/jio.storage/querystorage.tests.js @@ -10,7 +10,8 @@ deepEqual = QUnit.deepEqual, equal = QUnit.equal, module = QUnit.module, - throws = QUnit.throws; + throws = QUnit.throws, + utils = {callback: function () {return true; }}; ///////////////////////////////////////////////////////////////// // Custom test substorage definition @@ -20,6 +21,13 @@ } jIO.addStorage('querystorage200', Storage200); + function Storagecallback(spec, utils) { + this._spec = spec; + this._utils = utils; + return this; + } + jIO.addStorage('querystoragecallback', Storagecallback); + ///////////////////////////////////////////////////////////////// // queryStorage.constructor ///////////////////////////////////////////////////////////////// @@ -45,6 +53,19 @@ }); + test("Test callback", function () { + var jio = jIO.createJIO({ + type: "query", + sub_storage: { + type: "querystoragecallback" + } + }, utils); + + deepEqual(jio.__storage._utils.callback(), true); + deepEqual(jio.__storage._sub_storage.__storage._utils.callback(), true); + + }); + test("failed on wrond schema", function () { throws( function () { diff --git a/test/jio.storage/replicatestorage.tests.js b/test/jio.storage/replicatestorage.tests.js index a46a2aa5253b8416fd8331a0241bcb661528e7ca..08443e3328dff7a6990a8ddae81d674e21b46c99 100644 --- a/test/jio.storage/replicatestorage.tests.js +++ b/test/jio.storage/replicatestorage.tests.js @@ -12,6 +12,7 @@ module = QUnit.module, throws = QUnit.throws, big_string = "", + utils = {callback: function () {return true; }}, j; for (j = 0; j < 30; j += 1) { @@ -36,6 +37,27 @@ } jIO.addStorage('signaturestorage2713', Storage2713); + function Storagecallback(spec, utils) { + this._spec = spec; + this._utils = utils; + return this; + } + jIO.addStorage('localcallback', Storagecallback); + + function Storagecallback1(spec, utils) { + this._spec = spec; + this._utils = utils; + return this; + } + jIO.addStorage('replicatecallback', Storagecallback1); + + function Storagecallback2(spec, utils) { + this._spec = spec; + this._utils = utils; + return this; + } + jIO.addStorage('signaturecallback', Storagecallback2); + ///////////////////////////////////////////////////////////////// // replicateStorage.constructor ///////////////////////////////////////////////////////////////// @@ -103,6 +125,30 @@ }); + test("Test callback", function () { + var jio = jIO.createJIO({ + type: "replicate", + local_sub_storage: { + type: "localcallback" + }, + remote_sub_storage: { + type: "replicatecallback" + }, + signature_sub_storage: { + type: "signaturecallback" + } + }, utils); + + deepEqual(jio.__storage._utils.callback(), true); + deepEqual(jio.__storage._local_sub_storage.__storage. + _utils.callback(), true); + deepEqual(jio.__storage._remote_sub_storage.__storage. + _utils.callback(), true); + deepEqual(jio.__storage._signature_sub_storage.__storage. + _utils.callback(), true); + + }); + test("accept parameters", function () { var jio = jIO.createJIO({ type: "replicate", diff --git a/test/jio.storage/shastorage.tests.js b/test/jio.storage/shastorage.tests.js index e325e96300d4855d2644a7da9257fb435434bebf..186aed42a3862a03d740a2cc0f1d74e9de8eda42 100644 --- a/test/jio.storage/shastorage.tests.js +++ b/test/jio.storage/shastorage.tests.js @@ -10,7 +10,8 @@ deepEqual = QUnit.deepEqual, equal = QUnit.equal, module = QUnit.module, - throws = QUnit.throws; + throws = QUnit.throws, + utils = {callback: function () {return true; }}; ///////////////////////////////////////////////////////////////// // Custom test substorage definition @@ -20,6 +21,13 @@ } jIO.addStorage('shastorage200', Storage200); + function Storagecallback(spec, utils) { + this._spec = spec; + this._utils = utils; + return this; + } + jIO.addStorage('shastoragecallback', Storagecallback); + ///////////////////////////////////////////////////////////////// // shaStorage.constructor ///////////////////////////////////////////////////////////////// @@ -37,6 +45,19 @@ }); + test("Test callback", function () { + var jio = jIO.createJIO({ + type: "document", + sub_storage: { + type: "shastoragecallback" + } + }, utils); + + deepEqual(jio.__storage._utils.callback(), true); + deepEqual(jio.__storage._sub_storage.__storage._utils.callback(), true); + + }); + ///////////////////////////////////////////////////////////////// // shaStorage.get ///////////////////////////////////////////////////////////////// diff --git a/test/jio.storage/unionstorage.tests.js b/test/jio.storage/unionstorage.tests.js index 8c21af6d9fd126eb128533c847a6cae217068312..8582f17fd5b5eced7bb8e18ab9029f027bcd76e5 100644 --- a/test/jio.storage/unionstorage.tests.js +++ b/test/jio.storage/unionstorage.tests.js @@ -11,7 +11,8 @@ equal = QUnit.equal, module = QUnit.module, throws = QUnit.throws, - frozen_blob = new Blob(["foobar"]); + frozen_blob = new Blob(["foobar"]), + utils = {callback: function () {return true; }}; ///////////////////////////////////////////////////////////////// // Custom test substorage definition @@ -115,6 +116,13 @@ Storage500.prototype.repair = generateError; jIO.addStorage('unionstorage500', Storage500); + function Storagecallback(spec, utils) { + this._spec = spec; + this._utils = utils; + return this; + } + jIO.addStorage('unioncallback', Storagecallback); + ///////////////////////////////////////////////////////////////// // unionStorage.constructor ///////////////////////////////////////////////////////////////// @@ -145,6 +153,20 @@ equal(jio.__storage._storage_list[1].__type, "unionstorage200"); }); + test("Test callback", function () { + var jio = jIO.createJIO({ + type: "union", + storage_list: [{ + type: "unioncallback" + }] + }, utils); + + deepEqual(jio.__storage._utils.callback(), true); + deepEqual(jio.__storage._storage_list["0"]. + __storage._utils.callback(), true); + + }); + ///////////////////////////////////////////////////////////////// // unionStorage.get ///////////////////////////////////////////////////////////////// diff --git a/test/jio.storage/uuidstorage.tests.js b/test/jio.storage/uuidstorage.tests.js index 56e02eb3f8f5d0f720d5d524883114792f760bbe..80e5ce40d347c871db06e784e78eeb9f6a370140 100644 --- a/test/jio.storage/uuidstorage.tests.js +++ b/test/jio.storage/uuidstorage.tests.js @@ -10,7 +10,8 @@ deepEqual = QUnit.deepEqual, equal = QUnit.equal, module = QUnit.module, - throws = QUnit.throws; + throws = QUnit.throws, + utils = {callback: function () {return true; }}; ///////////////////////////////////////////////////////////////// // Custom test substorage definition @@ -20,6 +21,13 @@ } jIO.addStorage('uuidstorage200', Storage200); + function Storagecallback(spec, utils) { + this._spec = spec; + this._utils = utils; + return this; + } + jIO.addStorage('uuidcallback', Storagecallback); + ///////////////////////////////////////////////////////////////// // uuidStorage.constructor ///////////////////////////////////////////////////////////////// @@ -37,6 +45,19 @@ }); + test("Test callback", function () { + var jio = jIO.createJIO({ + type: "uuid", + sub_storage: { + type: "uuidcallback" + } + }, utils); + + deepEqual(jio.__storage._utils.callback(), true); + deepEqual(jio.__storage._sub_storage.__storage._utils.callback(), true); + + }); + ///////////////////////////////////////////////////////////////// // uuidStorage.get ///////////////////////////////////////////////////////////////// diff --git a/test/jio.storage/zipstorage.tests.js b/test/jio.storage/zipstorage.tests.js index 3c05d712ebc32a31ced2b18505b399ba6dd9dcea..10ce7eeca70f473233b0fd27ae2d75297da1e94b 100644 --- a/test/jio.storage/zipstorage.tests.js +++ b/test/jio.storage/zipstorage.tests.js @@ -10,7 +10,8 @@ deepEqual = QUnit.deepEqual, equal = QUnit.equal, throws = QUnit.throws, - module = QUnit.module; + module = QUnit.module, + utils = {callback: function () {return true; }}; ///////////////////////////////////////////////////////////////// // Custom test substorage definition @@ -20,6 +21,13 @@ } jIO.addStorage('zipstorage200', Storage200); + function Storagecallback(spec, utils) { + this._spec = spec; + this._utils = utils; + return this; + } + jIO.addStorage('zipstoragecallback', Storagecallback); + ///////////////////////////////////////////////////////////////// // ZipStorage.constructor ///////////////////////////////////////////////////////////////// @@ -33,6 +41,19 @@ equal(jio.__storage._sub_storage.__type, "zipstorage200"); }); + test("Test callback", function () { + var jio = jIO.createJIO({ + type: "document", + sub_storage: { + type: "zipstoragecallback" + } + }, utils); + + deepEqual(jio.__storage._utils.callback(), true); + deepEqual(jio.__storage._sub_storage.__storage._utils.callback(), true); + + }); + ///////////////////////////////////////////////////////////////// // ZipStorage.get /////////////////////////////////////////////////////////////////