Commit a29f4fda authored by amrani's avatar amrani

major change to cryptostorage and all storages now support callbacks

parent b345214e
...@@ -209,64 +209,47 @@ ...@@ -209,64 +209,47 @@
} }
} }
function ensurePushableQueue(callback, argument_list, context) {
var result;
try {
result = callback.apply(context, argument_list);
} catch (e) {
return new RSVP.Queue()
.push(function returnPushableError() {
return RSVP.reject(e);
});
}
if (result instanceof RSVP.Queue) {
return result;
}
return new RSVP.Queue()
.push(function returnPushableResult() {
return result;
});
}
function declareMethod(klass, name, precondition_function, post_function) { function declareMethod(klass, name, precondition_function, post_function) {
klass.prototype[name] = function () { klass.prototype[name] = function () {
var argument_list = arguments, var argument_list = arguments,
context = this, context = this,
precondition_result, precondition_result;
storage_method,
queue;
// Precondition function are not asynchronous
if (precondition_function !== undefined) {
precondition_result = precondition_function.apply(
context.__storage,
[argument_list, context, name]
);
}
storage_method = context.__storage[name]; return new RSVP.Queue()
if (storage_method === undefined) { .push(function () {
throw new jIO.util.jIOError( if (precondition_function !== undefined) {
"Capacity '" + name + "' is not implemented on '" + return precondition_function.apply(
context.__type + "'", context.__storage,
501 [argument_list, context, name]
); );
} }
queue = ensurePushableQueue(storage_method, argument_list, })
context.__storage); .push(function (result) {
var storage_method = context.__storage[name];
if (post_function !== undefined) { precondition_result = result;
queue if (storage_method === undefined) {
.push(function (result) { throw new jIO.util.jIOError(
"Capacity '" + name + "' is not implemented on '" +
context.__type + "'",
501
);
}
return storage_method.apply(
context.__storage,
argument_list
);
})
.push(function (result) {
if (post_function !== undefined) {
return post_function.call( return post_function.call(
context, context,
argument_list, argument_list,
result, result,
precondition_result precondition_result
); );
}); }
} return result;
return queue; });
}; };
// Allow chain // Allow chain
return this; return this;
...@@ -298,16 +281,17 @@ ...@@ -298,16 +281,17 @@
JioProxyStorage.prototype.post = function () { JioProxyStorage.prototype.post = function () {
var context = this, var context = this,
argument_list = arguments; argument_list = arguments;
return ensurePushableQueue(function () { return new RSVP.Queue()
var storage_method = context.__storage.post; .push(function () {
if (storage_method === undefined) { var storage_method = context.__storage.post;
throw new jIO.util.jIOError( if (storage_method === undefined) {
"Capacity 'post' is not implemented on '" + context.__type + "'", throw new jIO.util.jIOError(
501 "Capacity 'post' is not implemented on '" + context.__type + "'",
); 501
} );
return context.__storage.post.apply(context.__storage, argument_list); }
}); return context.__storage.post.apply(context.__storage, argument_list);
});
}; };
declareMethod(JioProxyStorage, 'putAttachment', function (argument_list, declareMethod(JioProxyStorage, 'putAttachment', function (argument_list,
...@@ -425,8 +409,13 @@ ...@@ -425,8 +409,13 @@
501 501
); );
} }
return ensurePushableQueue(storage_method, argument_list, return new RSVP.Queue()
context.__storage); .push(function () {
return storage_method.apply(
context.__storage,
argument_list
);
});
}; };
JioProxyStorage.prototype.hasCapacity = function (name) { JioProxyStorage.prototype.hasCapacity = function (name) {
...@@ -450,26 +439,27 @@ ...@@ -450,26 +439,27 @@
if (options === undefined) { if (options === undefined) {
options = {}; options = {};
} }
return ensurePushableQueue(function () { return new RSVP.Queue()
if (context.hasCapacity("list") && .push(function () {
((options.query === undefined) || context.hasCapacity("query")) && if (context.hasCapacity("list") &&
((options.sort_on === undefined) || context.hasCapacity("sort")) && ((options.query === undefined) || context.hasCapacity("query")) &&
((options.select_list === undefined) || ((options.sort_on === undefined) || context.hasCapacity("sort")) &&
context.hasCapacity("select")) && ((options.select_list === undefined) ||
((options.include_docs === undefined) || context.hasCapacity("select")) &&
context.hasCapacity("include")) && ((options.include_docs === undefined) ||
((options.limit === undefined) || context.hasCapacity("limit"))) { context.hasCapacity("include")) &&
return context.buildQuery(options) ((options.limit === undefined) || context.hasCapacity("limit"))) {
.push(function (result) { return context.buildQuery(options);
return { }
data: { })
rows: result, .push(function (result) {
total_rows: result.length return {
} data: {
}; rows: result,
}); total_rows: result.length
} }
}); };
});
}; };
declareMethod(JioProxyStorage, "allAttachments", checkId); declareMethod(JioProxyStorage, "allAttachments", checkId);
...@@ -478,13 +468,14 @@ ...@@ -478,13 +468,14 @@
JioProxyStorage.prototype.repair = function () { JioProxyStorage.prototype.repair = function () {
var context = this, var context = this,
argument_list = arguments; argument_list = arguments;
return ensurePushableQueue(function () { return new RSVP.Queue()
var storage_method = context.__storage.repair; .push(function () {
if (storage_method !== undefined) { var storage_method = context.__storage.repair;
return context.__storage.repair.apply(context.__storage, if (storage_method !== undefined) {
argument_list); return context.__storage.repair.apply(context.__storage,
} argument_list);
}); }
});
}; };
///////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////
......
/* /*
* Copyright 2015, Nexedi SA * Copyright 2015, Nexedi SA
* Released under the LGPL license. * Released under the LGPL license.
* http://www.gnu.org/licenses/lgpl.html * hcrypto, Uint8Array, ArrayBuffer*/
*/
/*jslint nomen: true*/ /*jslint nomen: true*/
/*global jIO, RSVP, DOMException, Blob, crypto, Uint8Array, ArrayBuffer*/ /*global jIO, RSVP, DOMParser, Blob, DOMException, crypto, Uint8Array,
ArrayBuffer, CryptoKey*/
(function (jIO, RSVP, DOMException, Blob, crypto, Uint8Array, ArrayBuffer) { /*jslint maxlen: 160 */
(function (jIO, RSVP, DOMException, Blob, crypto, Uint8Array, ArrayBuffer, CryptoKey) {
"use strict"; "use strict";
/* /*
The cryptography system used by this storage is AES-GCM. 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
return new RSVP.Queue() return new RSVP.Queue()
.push(function () { .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({ var jio = jIO.createJIO({
type: "crypt", type: "crypt"
key: json_key,
sub_storage: {storage_definition} sub_storage: {storage_definition}
}); });
}); });
...@@ -41,26 +35,14 @@ ...@@ -41,26 +35,14 @@
* @constructor * @constructor
*/ */
var MIME_TYPE = "application/x-jio-aes-gcm-encryption";
function CryptStorage(spec) { var MIME_TYPE = "application/x-jio-aes-gcm-encryption";
this._key = spec.key;
this._jsonKey = true;
this._sub_storage = jIO.createJIO(spec.sub_storage);
}
function convertKey(that) { function CryptStorage(spec, utils) {
return new RSVP.Queue() this._utils = utils;
.push(function () { this._keyid = spec.keyid;
return crypto.subtle.importKey("jwk", that._key, this._key = "";
"AES-GCM", false, this._sub_storage = jIO.createJIO(spec.sub_storage, utils);
["encrypt", "decrypt"]);
})
.push(function (res) {
that._key = res;
that._jsonKey = false;
return;
});
} }
CryptStorage.prototype.get = function () { CryptStorage.prototype.get = function () {
...@@ -93,18 +75,10 @@ ...@@ -93,18 +75,10 @@
arguments); arguments);
}; };
CryptStorage.prototype.putAttachment = function (id, name, blob) { CryptStorage.prototype.putAttachment = function (id, name, blob) {
var initializaton_vector = crypto.getRandomValues(new Uint8Array(12)), var initializaton_vector = crypto.getRandomValues(new Uint8Array(12)),
that = this; that = this;
return new RSVP.Queue() return new RSVP.Queue()
.push(function () {
if (that._jsonKey === true) {
return convertKey(that);
}
return;
})
.push(function () { .push(function () {
return jIO.util.readBlobAsDataURL(blob); return jIO.util.readBlobAsDataURL(blob);
}) })
...@@ -114,64 +88,116 @@ ...@@ -114,64 +88,116 @@
buf = new ArrayBuffer(strLen), buf = new ArrayBuffer(strLen),
bufView = new Uint8Array(buf), bufView = new Uint8Array(buf),
i; i;
dataURL = dataURL.target.result; dataURL = dataURL.target.result;
for (i = 0; i < strLen; i += 1) { for (i = 0; i < strLen; i += 1) {
bufView[i] = dataURL.charCodeAt(i); bufView[i] = dataURL.charCodeAt(i);
} }
return crypto.subtle.encrypt({ return crypto.subtle.encrypt({
name : "AES-GCM", name: "AES-GCM",
iv : initializaton_vector iv: initializaton_vector
}, },
that._key, buf); that._key, buf);
}) })
.push(function (coded) { .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); 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) { CryptStorage.prototype.getAttachment = function (id, name) {
var that = this; var that = this;
return that._sub_storage.getAttachment(id, name) return that._sub_storage.getAttachment(id, name)
.push(function (blob) { .push(function (blob) {
if (blob.type !== MIME_TYPE) {
return blob;
}
return new RSVP.Queue() return new RSVP.Queue()
.push(function () { .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() return new RSVP.Queue()
.push(function () { .push(function () {
return crypto.subtle.decrypt({ return jIO.util.readBlobAsArrayBuffer(blob);
name : "AES-GCM",
iv : initializaton_vector
},
that._key, coded.slice(12));
})
.push(function (arr) {
//arraybuffer->string
arr = String.fromCharCode.apply(null, new Uint8Array(arr));
return jIO.util.dataURItoBlob(arr);
}) })
.push(undefined, function (error) { .push(function (coded) {
if (error instanceof DOMException) { var initializaton_vector;
return blob; coded = coded.target.result;
} initializaton_vector = new Uint8Array(coded.slice(0, 12));
throw error; 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 +213,32 @@ ...@@ -187,6 +213,32 @@
arguments); 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.addStorage('crypt', CryptStorage);
}(jIO, RSVP, DOMException, Blob, crypto, Uint8Array, ArrayBuffer)); }(jIO, RSVP, DOMException, Blob, crypto, Uint8Array, ArrayBuffer, CryptoKey));
...@@ -76,11 +76,12 @@ ...@@ -76,11 +76,12 @@
* @class DavStorage * @class DavStorage
* @constructor * @constructor
*/ */
function DavStorage(spec) { function DavStorage(spec, utils) {
if (typeof spec.url !== 'string') { if (typeof spec.url !== 'string') {
throw new TypeError("DavStorage 'url' is not of type string"); throw new TypeError("DavStorage 'url' is not of type string");
} }
this._url = spec.url; this._url = spec.url;
this._utils = utils;
// XXX digest login // XXX digest login
if (typeof spec.basic_login === 'string') { if (typeof spec.basic_login === 'string') {
this._authorization = "Basic " + spec.basic_login; this._authorization = "Basic " + spec.basic_login;
......
...@@ -8,8 +8,9 @@ ...@@ -8,8 +8,9 @@
* @class DocumentStorage * @class DocumentStorage
* @constructor * @constructor
*/ */
function DocumentStorage(spec) { function DocumentStorage(spec, utils) {
this._sub_storage = jIO.createJIO(spec.sub_storage); this._utils = utils;
this._sub_storage = jIO.createJIO(spec.sub_storage, utils);
this._document_id = spec.document_id; this._document_id = spec.document_id;
this._repair_attachment = spec.repair_attachment || false; this._repair_attachment = spec.repair_attachment || false;
} }
......
...@@ -9,8 +9,9 @@ ...@@ -9,8 +9,9 @@
* @class FileSystemBridgeStorage * @class FileSystemBridgeStorage
* @constructor * @constructor
*/ */
function FileSystemBridgeStorage(spec) { function FileSystemBridgeStorage(spec, utils) {
this._sub_storage = jIO.createJIO(spec.sub_storage); this._utils = utils;
this._sub_storage = jIO.createJIO(spec.sub_storage, utils);
} }
var DOCUMENT_EXTENSION = ".json", var DOCUMENT_EXTENSION = ".json",
DOCUMENT_KEY = "/.jio_documents/", DOCUMENT_KEY = "/.jio_documents/",
......
...@@ -105,11 +105,12 @@ ...@@ -105,11 +105,12 @@
* @class DropboxStorage * @class DropboxStorage
* @constructor * @constructor
*/ */
function DropboxStorage(spec) { function DropboxStorage(spec, utils) {
if (typeof spec.access_token !== 'string' || !spec.access_token) { if (typeof spec.access_token !== 'string' || !spec.access_token) {
throw new TypeError("Access Token' must be a string " + throw new TypeError("Access Token' must be a string " +
"which contains more than one character."); "which contains more than one character.");
} }
this._utils = utils;
this._access_token = spec.access_token; this._access_token = spec.access_token;
} }
...@@ -325,4 +326,4 @@ ...@@ -325,4 +326,4 @@
jIO.addStorage('dropbox', DropboxStorage); jIO.addStorage('dropbox', DropboxStorage);
}(jIO, RSVP, Blob, JSON)); }(jIO, RSVP, Blob, JSON));
\ No newline at end of file
...@@ -73,56 +73,59 @@ ...@@ -73,56 +73,59 @@
}; };
function extractPropertyFromFormJSON(json) { function extractPropertyFromFormJSON(json) {
var form = json._embedded._view, return new RSVP.Queue()
converted_json = { .push(function () {
portal_type: json._links.type.name var form = json._embedded._view,
}, converted_json = {
form_data_json = {}, portal_type: json._links.type.name
field, },
key, form_data_json = {},
prefix_length, field,
result; key,
prefix_length,
if (json._links.hasOwnProperty('parent')) { result;
converted_json.parent_relative_url =
new URI(json._links.parent.href).segment(2);
}
form_data_json.form_id = { if (json._links.hasOwnProperty('parent')) {
"key": [form.form_id.key], converted_json.parent_relative_url =
"default": form.form_id["default"] new URI(json._links.parent.href).segment(2);
};
// XXX How to store datetime
for (key in form) {
if (form.hasOwnProperty(key)) {
field = form[key];
prefix_length = 0;
if (key.indexOf('my_') === 0 && field.editable) {
prefix_length = 3;
}
if (key.indexOf('your_') === 0) {
prefix_length = 5;
} }
if ((prefix_length !== 0) &&
(allowed_field_dict.hasOwnProperty(field.type))) { form_data_json.form_id = {
form_data_json[key.substring(prefix_length)] = { "key": [form.form_id.key],
"default": field["default"], "default": form.form_id["default"]
"key": field.key };
}; // XXX How to store datetime
converted_json[key.substring(prefix_length)] = field["default"]; for (key in form) {
if (form.hasOwnProperty(key)) {
field = form[key];
prefix_length = 0;
if (key.indexOf('my_') === 0 && field.editable) {
prefix_length = 3;
}
if (key.indexOf('your_') === 0) {
prefix_length = 5;
}
if ((prefix_length !== 0) &&
(allowed_field_dict.hasOwnProperty(field.type))) {
form_data_json[key.substring(prefix_length)] = {
"default": field["default"],
"key": field.key
};
converted_json[key.substring(prefix_length)] = field["default"];
}
}
} }
}
}
result = { result = {
data: converted_json, data: converted_json,
form_data: form_data_json form_data: form_data_json
}; };
if (form.hasOwnProperty('_actions') && if (form.hasOwnProperty('_actions') &&
form._actions.hasOwnProperty('put')) { form._actions.hasOwnProperty('put')) {
result.action_href = form._actions.put.href; result.action_href = form._actions.put.href;
} }
return result; return result;
});
} }
function extractPropertyFromForm(context, id) { function extractPropertyFromForm(context, id) {
...@@ -139,12 +142,13 @@ ...@@ -139,12 +142,13 @@
} }
// XXX docstring // XXX docstring
function ERP5Storage(spec) { function ERP5Storage(spec, utils) {
if (typeof spec.url !== "string" || !spec.url) { if (typeof spec.url !== "string" || !spec.url) {
throw new TypeError("ERP5 'url' must be a string " + throw new TypeError("ERP5 'url' must be a string " +
"which contains more than one character."); "which contains more than one character.");
} }
this._url = spec.url; this._url = spec.url;
this._utils = utils;
this._default_view_reference = spec.default_view_reference; this._default_view_reference = spec.default_view_reference;
} }
......
...@@ -11,7 +11,7 @@ ...@@ -11,7 +11,7 @@
"{+access_token}", "{+access_token}",
get_feed_template = UriTemplate.parse(GET_FEED_URL); get_feed_template = UriTemplate.parse(GET_FEED_URL);
function FBStorage(spec) { function FBStorage(spec, utils) {
if (typeof spec.access_token !== 'string' || !spec.access_token) { if (typeof spec.access_token !== 'string' || !spec.access_token) {
throw new TypeError("Access Token must be a string " + throw new TypeError("Access Token must be a string " +
"which contains more than one character."); "which contains more than one character.");
...@@ -20,6 +20,7 @@ ...@@ -20,6 +20,7 @@
throw new TypeError("User ID must be a string " + throw new TypeError("User ID must be a string " +
"which contains more than one character."); "which contains more than one character.");
} }
this._utils = utils;
this._access_token = spec.access_token; this._access_token = spec.access_token;
this._user_id = spec.user_id; this._user_id = spec.user_id;
this._default_field_list = spec.default_field_list || []; this._default_field_list = spec.default_field_list || [];
......
...@@ -72,7 +72,7 @@ ...@@ -72,7 +72,7 @@
* @class GdriveStorage * @class GdriveStorage
* @constructor * @constructor
*/ */
function GdriveStorage(spec) { function GdriveStorage(spec, utils) {
if (spec === undefined || spec.access_token === undefined || if (spec === undefined || spec.access_token === undefined ||
typeof spec.access_token !== 'string') { typeof spec.access_token !== 'string') {
throw new TypeError("Access Token must be a string " + throw new TypeError("Access Token must be a string " +
...@@ -83,6 +83,7 @@ ...@@ -83,6 +83,7 @@
throw new TypeError("trashing parameter" + throw new TypeError("trashing parameter" +
" must be a boolean (true or false)"); " must be a boolean (true or false)");
} }
this._utils = utils;
this._trashing = spec.trashing || true; this._trashing = spec.trashing || true;
this._access_token = spec.access_token; this._access_token = spec.access_token;
return; return;
......
...@@ -283,8 +283,9 @@ ...@@ -283,8 +283,9 @@
* *
* @class GidStorage * @class GidStorage
*/ */
function GidStorage(spec) { function GidStorage(spec, utils) {
var that = this, priv = {}; var that = this, priv = {};
this._utils = utils;
priv.sub_storage = spec.sub_storage; priv.sub_storage = spec.sub_storage;
priv.constraints = spec.constraints || { priv.constraints = spec.constraints || {
......
...@@ -3,13 +3,14 @@ ...@@ -3,13 +3,14 @@
(function (jIO, RSVP, Blob) { (function (jIO, RSVP, Blob) {
"use strict"; "use strict";
function HttpStorage(spec) { function HttpStorage(spec, utils) {
if (spec.hasOwnProperty('catch_error')) { if (spec.hasOwnProperty('catch_error')) {
this._catch_error = spec.catch_error; this._catch_error = spec.catch_error;
} else { } else {
this._catch_error = false; this._catch_error = false;
} }
// If timeout not set, use 0 for no timeout value // If timeout not set, use 0 for no timeout value
this._utils = utils;
this._timeout = spec.timeout || 0; this._timeout = spec.timeout || 0;
} }
......
...@@ -38,12 +38,13 @@ ...@@ -38,12 +38,13 @@
// Read only as changing it can lead to data corruption // Read only as changing it can lead to data corruption
var UNITE = 2000000; var UNITE = 2000000;
function IndexedDBStorage(description) { function IndexedDBStorage(description, utils) {
if (typeof description.database !== "string" || if (typeof description.database !== "string" ||
description.database === "") { description.database === "") {
throw new TypeError("IndexedDBStorage 'database' description property " + throw new TypeError("IndexedDBStorage 'database' description property " +
"must be a non-empty string"); "must be a non-empty string");
} }
this._utils = utils;
this._database_name = "jio:" + description.database; this._database_name = "jio:" + description.database;
} }
......
...@@ -427,7 +427,7 @@ ...@@ -427,7 +427,7 @@
* @class IndexStorage * @class IndexStorage
* @constructor * @constructor
*/ */
function IndexStorage(spec) { function IndexStorage(spec, utils) {
var i; var i;
if (!Array.isArray(spec.indices)) { if (!Array.isArray(spec.indices)) {
throw new TypeError("IndexStorage 'indices' must be an array of " + throw new TypeError("IndexStorage 'indices' must be an array of " +
...@@ -451,6 +451,7 @@ ...@@ -451,6 +451,7 @@
"'indices[x].index' must be a string array"); "'indices[x].index' must be a string array");
} }
} }
this._utils = utils;
this._sub_storage = spec.sub_storage; this._sub_storage = spec.sub_storage;
} }
......
...@@ -24,7 +24,8 @@ ...@@ -24,7 +24,8 @@
(function (jIO, sessionStorage, localStorage, RSVP) { (function (jIO, sessionStorage, localStorage, RSVP) {
"use strict"; "use strict";
function LocalStorage(spec) { function LocalStorage(spec, utils) {
this._utils = utils;
if (spec.sessiononly === true) { if (spec.sessiononly === true) {
this._storage = sessionStorage; this._storage = sessionStorage;
} else { } else {
......
...@@ -29,8 +29,10 @@ ...@@ -29,8 +29,10 @@
* @class MemoryStorage * @class MemoryStorage
* @constructor * @constructor
*/ */
function MemoryStorage() { function MemoryStorage(spec, utils) {
this._spec = spec; //not used just for compatibility issue
this._database = {}; this._database = {};
this._utils = utils;
} }
MemoryStorage.prototype.put = function (id, metadata) { MemoryStorage.prototype.put = function (id, metadata) {
......
...@@ -205,8 +205,9 @@ ...@@ -205,8 +205,9 @@
* *
* @class MultiSplitStorage * @class MultiSplitStorage
*/ */
function MultiSplitStorage(spec) { function MultiSplitStorage(spec, utils) {
var that = this, priv = {}; var that = this, priv = {};
this._utils = utils;
/** /**
* The list of sub storages we want to use to store part of documents. * The list of sub storages we want to use to store part of documents.
......
...@@ -238,11 +238,12 @@ ...@@ -238,11 +238,12 @@
///////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////
// Storage // Storage
///////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////
function ParserStorage(spec) { function ParserStorage(spec, utils) {
this._utils = utils;
this._attachment_id = spec.attachment_id; this._attachment_id = spec.attachment_id;
this._document_id = spec.document_id; this._document_id = spec.document_id;
this._parser_name = spec.parser; 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) { ParserStorage.prototype.hasCapacity = function (capacity) {
......
...@@ -71,7 +71,8 @@ ...@@ -71,7 +71,8 @@
* @class QiniuStorage * @class QiniuStorage
* @constructor * @constructor
*/ */
function QiniuStorage(spec) { function QiniuStorage(spec, utils) {
this._utils = utils;
if (typeof spec.bucket !== 'string' && !spec.bucket) { if (typeof spec.bucket !== 'string' && !spec.bucket) {
throw new TypeError("Qiniu 'bucket' must be a string " + throw new TypeError("Qiniu 'bucket' must be a string " +
"which contains more than one character."); "which contains more than one character.");
......
...@@ -36,8 +36,9 @@ ...@@ -36,8 +36,9 @@
* @class QueryStorage * @class QueryStorage
* @constructor * @constructor
*/ */
function QueryStorage(spec) { function QueryStorage(spec, utils) {
this._sub_storage = jIO.createJIO(spec.sub_storage); this._utils = utils;
this._sub_storage = jIO.createJIO(spec.sub_storage, utils);
this._key_schema = {key_set: {}, cast_lookup: {}}; this._key_schema = {key_set: {}, cast_lookup: {}};
initKeySchema(this, spec); initKeySchema(this, spec);
} }
......
...@@ -53,18 +53,20 @@ ...@@ -53,18 +53,20 @@
return rusha.digestFromArrayBuffer(content); return rusha.digestFromArrayBuffer(content);
} }
function ReplicateStorage(spec) { function ReplicateStorage(spec, utils) {
this._utils = utils;
this._query_options = spec.query || {}; this._query_options = spec.query || {};
if (spec.signature_hash_key !== undefined) { if (spec.signature_hash_key !== undefined) {
this._query_options.select_list = [spec.signature_hash_key]; this._query_options.select_list = [spec.signature_hash_key];
} }
this._signature_hash_key = spec.signature_hash_key; this._signature_hash_key = spec.signature_hash_key;
this._local_sub_storage = jIO.createJIO(spec.local_sub_storage); this._local_sub_storage = jIO.createJIO(spec.local_sub_storage, utils);
this._remote_sub_storage = jIO.createJIO(spec.remote_sub_storage); this._remote_sub_storage = jIO.createJIO(spec.remote_sub_storage, utils);
if (spec.hasOwnProperty('signature_sub_storage')) { 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; this._custom_signature_sub_storage = true;
} else { } else {
this._signature_hash = "_replicate_" + generateHash( this._signature_hash = "_replicate_" + generateHash(
......
...@@ -16,8 +16,9 @@ ...@@ -16,8 +16,9 @@
var rusha = new Rusha(); var rusha = new Rusha();
function ShaStorage(spec) { function ShaStorage(spec, utils) {
this._sub_storage = jIO.createJIO(spec.sub_storage); this._utils = utils;
this._sub_storage = jIO.createJIO(spec.sub_storage, utils);
} }
ShaStorage.prototype.post = function (param) { ShaStorage.prototype.post = function (param) {
......
...@@ -32,14 +32,15 @@ ...@@ -32,14 +32,15 @@
* @class UnionStorage * @class UnionStorage
* @constructor * @constructor
*/ */
function UnionStorage(spec) { function UnionStorage(spec, utils) {
this._utils = utils;
if (!Array.isArray(spec.storage_list)) { if (!Array.isArray(spec.storage_list)) {
throw new jIO.util.jIOError("storage_list is not an Array", 400); throw new jIO.util.jIOError("storage_list is not an Array", 400);
} }
var i; var i;
this._storage_list = []; this._storage_list = [];
for (i = 0; i < spec.storage_list.length; i += 1) { 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));
} }
} }
......
...@@ -8,8 +8,9 @@ ...@@ -8,8 +8,9 @@
* @class UUIDStorage * @class UUIDStorage
* @constructor * @constructor
*/ */
function UUIDStorage(spec) { function UUIDStorage(spec, utils) {
this._sub_storage = jIO.createJIO(spec.sub_storage); this._utils = utils;
this._sub_storage = jIO.createJIO(spec.sub_storage, utils);
} }
UUIDStorage.prototype.get = function () { UUIDStorage.prototype.get = function () {
......
...@@ -69,7 +69,8 @@ ...@@ -69,7 +69,8 @@
}); });
} }
function WebSQLStorage(spec) { function WebSQLStorage(spec, utils) {
this._utils = utils;
if (typeof spec.database !== 'string' || !spec.database) { if (typeof spec.database !== 'string' || !spec.database) {
throw new TypeError("database must be a string " + throw new TypeError("database must be a string " +
"which contains more than one character."); "which contains more than one character.");
......
...@@ -12,8 +12,9 @@ ...@@ -12,8 +12,9 @@
var MIME_TYPE = "application/x-jio-utf16_lz_string"; var MIME_TYPE = "application/x-jio-utf16_lz_string";
function ZipStorage(spec) { function ZipStorage(spec, utils) {
this._sub_storage = jIO.createJIO(spec.sub_storage); this._utils = utils;
this._sub_storage = jIO.createJIO(spec.sub_storage, utils);
} }
ZipStorage.prototype.get = function () { ZipStorage.prototype.get = function () {
......
...@@ -90,13 +90,13 @@ case 5: case 8: case 11: case 14: case 16: ...@@ -90,13 +90,13 @@ case 5: case 8: case 11: case 14: case 16:
this.$ = $$[$0]; this.$ = $$[$0];
break; break;
case 6: case 6:
this.$ = mkComplexQuery('', 'AND', [$$[$0-1], $$[$0]]); this.$ = mkComplexQuery('AND', [$$[$0-1], $$[$0]]);
break; break;
case 7: case 7:
this.$ = mkComplexQuery('', 'OR', [$$[$0-2], $$[$0]]); this.$ = mkComplexQuery('OR', [$$[$0-2], $$[$0]]);
break; break;
case 9: case 9:
this.$ = mkComplexQuery('', 'AND', [$$[$0-2], $$[$0]]); this.$ = mkComplexQuery('AND', [$$[$0-2], $$[$0]]);
break; break;
case 10: case 10:
this.$ = mkNotQuery($$[$0]); this.$ = mkNotQuery($$[$0]);
...@@ -105,7 +105,7 @@ case 12: ...@@ -105,7 +105,7 @@ case 12:
this.$ = $$[$0-1]; this.$ = $$[$0-1];
break; break;
case 13: case 13:
querySetKey($$[$0], $$[$0-2]); this.$ = $$[$0]; simpleQuerySetKey($$[$0], $$[$0-2]); this.$ = $$[$0];
break; break;
case 15: case 15:
$$[$0].operator = $$[$0-1] ; this.$ = $$[$0]; $$[$0].operator = $$[$0-1] ; this.$ = $$[$0];
......
...@@ -45,13 +45,13 @@ end ...@@ -45,13 +45,13 @@ end
search_text search_text
: and_expression { $$ = $1; } : and_expression { $$ = $1; }
| and_expression search_text { $$ = mkComplexQuery('', 'AND', [$1, $2]); } | and_expression search_text { $$ = mkComplexQuery('AND', [$1, $2]); }
| and_expression OR search_text { $$ = mkComplexQuery('', 'OR', [$1, $3]); } | and_expression OR search_text { $$ = mkComplexQuery('OR', [$1, $3]); }
; ;
and_expression and_expression
: boolean_expression { $$ = $1; } : boolean_expression { $$ = $1; }
| boolean_expression AND and_expression { $$ = mkComplexQuery('', 'AND', [$1, $3]); } | boolean_expression AND and_expression { $$ = mkComplexQuery('AND', [$1, $3]); }
; ;
boolean_expression boolean_expression
...@@ -61,7 +61,7 @@ boolean_expression ...@@ -61,7 +61,7 @@ boolean_expression
expression expression
: LEFT_PARENTHESE search_text RIGHT_PARENTHESE { $$ = $2; } : LEFT_PARENTHESE search_text RIGHT_PARENTHESE { $$ = $2; }
| WORD DEFINITION expression { querySetKey($3, $1); $$ = $3; } | WORD DEFINITION expression { simpleQuerySetKey($3, $1); $$ = $3; }
| value { $$ = $1; } | value { $$ = $1; }
; ;
......
...@@ -26,9 +26,9 @@ var arrayExtend = function () { ...@@ -26,9 +26,9 @@ var arrayExtend = function () {
if (query.operator === "NOT") { if (query.operator === "NOT") {
return query.query_list[0]; return query.query_list[0];
} }
return {"type": "complex", "key": "", "operator": "NOT", "query_list": [query]}; return {"type": "complex", "operator": "NOT", "query_list": [query]};
}, mkComplexQuery = function (key, operator, query_list) { }, mkComplexQuery = function (operator, query_list) {
var i, query_list2 = []; var i, query_list2 = [];
for (i = 0; i < query_list.length; i += 1) { for (i = 0; i < query_list.length; i += 1) {
if (query_list[i].operator === operator) { if (query_list[i].operator === operator) {
...@@ -37,10 +37,17 @@ var arrayExtend = function () { ...@@ -37,10 +37,17 @@ var arrayExtend = function () {
query_list2.push(query_list[i]); query_list2.push(query_list[i]);
} }
} }
return {type:"complex",key:key,operator:operator,query_list:query_list2}; return {type:"complex",operator:operator,query_list:query_list2};
}, querySetKey = function (query, key) { }, simpleQuerySetKey = function (query, key) {
if (({simple: 1, complex: 1})[query.type] && !query.key) { var i;
if (query.type === "complex") {
for (i = 0; i < query.query_list.length; ++i) {
simpleQuerySetKey (query.query_list[i],key);
}
return true;
}
if (query.type === "simple" && !query.key) {
query.key = key; query.key = key;
return true; return true;
} }
......
...@@ -519,8 +519,6 @@ ...@@ -519,8 +519,6 @@
*/ */
this.operator = spec.operator; this.operator = spec.operator;
this.key = spec.key || this.key;
/** /**
* The sub Query list which are used to query an item. * The sub Query list which are used to query an item.
* *
...@@ -540,7 +538,6 @@ ...@@ -540,7 +538,6 @@
ComplexQuery.prototype.operator = "AND"; ComplexQuery.prototype.operator = "AND";
ComplexQuery.prototype.type = "complex"; ComplexQuery.prototype.type = "complex";
ComplexQuery.prototype.key = "";
/** /**
* #crossLink "Query/match:method" * #crossLink "Query/match:method"
...@@ -557,8 +554,21 @@ ...@@ -557,8 +554,21 @@
* #crossLink "Query/toString:method" * #crossLink "Query/toString:method"
*/ */
ComplexQuery.prototype.toString = function () { ComplexQuery.prototype.toString = function () {
/*global objectToSearchText */ var str_list = [], this_operator = this.operator;
return objectToSearchText(this.toJSON()); if (this.operator === "NOT") {
str_list.push("NOT (");
str_list.push(this.query_list[0].toString());
str_list.push(")");
return str_list.join(" ");
}
this.query_list.forEach(function (query) {
str_list.push("(");
str_list.push(query.toString());
str_list.push(")");
str_list.push(this_operator);
});
str_list.length -= 1;
return str_list.join(" ");
}; };
/** /**
...@@ -568,7 +578,6 @@ ...@@ -568,7 +578,6 @@
var s = { var s = {
"type": "complex", "type": "complex",
"operator": this.operator, "operator": this.operator,
"key": this.key,
"query_list": [] "query_list": []
}; };
this.query_list.forEach(function (query) { this.query_list.forEach(function (query) {
...@@ -658,26 +667,12 @@ ...@@ -658,26 +667,12 @@
}; };
function objectToSearchText(query) { function objectToSearchText(query) {
var str_list = [], operator = "", query_list = null; var str_list = [];
if (query.type === "complex") { if (query.type === "complex") {
query_list = query.query_list || [];
if (query_list.length === 0) {
return "";
}
operator = query.operator;
if (operator === "NOT") {
str_list.push("NOT");
// fallback to AND operator if several queries are given
// i.e. `NOT ( a AND b )`
operator = "AND";
}
if (query.key) {
str_list.push(query.key + ":");
}
str_list.push("("); str_list.push("(");
query_list.forEach(function (sub_query) { (query.query_list || []).forEach(function (sub_query) {
str_list.push(objectToSearchText(sub_query)); str_list.push(objectToSearchText(sub_query));
str_list.push(operator); str_list.push(query.operator);
}); });
str_list.length -= 1; str_list.length -= 1;
str_list.push(")"); str_list.push(")");
...@@ -854,7 +849,8 @@ ...@@ -854,7 +849,8 @@
* #crossLink "Query/toString:method" * #crossLink "Query/toString:method"
*/ */
SimpleQuery.prototype.toString = function () { SimpleQuery.prototype.toString = function () {
return objectToSearchText(this.toJSON()); return (this.key ? this.key + ":" : "") +
(this.operator ? " " + this.operator : "") + ' "' + this.value + '"';
}; };
/** /**
......
/*jslint nomen: true*/ /*jslint nomen: true*/
/*global Blob, crypto, Uint8Array, ArrayBuffer*/ /*global Blob, crypto, Uint8Array, ArrayBuffer, TextEncoder, window*/
/*jslint maxlen: 130 */
(function (jIO, QUnit, Blob) { (function (jIO, QUnit, Blob) {
"use strict"; "use strict";
var test = QUnit.test, var test = QUnit.test,
...@@ -11,9 +12,47 @@ ...@@ -11,9 +12,47 @@
equal = QUnit.equal, equal = QUnit.equal,
throws = QUnit.throws, throws = QUnit.throws,
module = QUnit.module, module = QUnit.module,
key = {"alg": "A256GCM", "ext": true, callback = {callback: function () {return true; }},
"k": "seeaLzpu8dHG07bO2ANH2GywbTqs_zrs4Vq8zmtYeE4", convertKey = function (str) {
"key_ops": ["encrypt", "decrypt"], "kty": "oct"}; 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 // Custom test substorage definition
...@@ -23,6 +62,14 @@ ...@@ -23,6 +62,14 @@
} }
jIO.addStorage('cryptstorage200', Storage200); jIO.addStorage('cryptstorage200', Storage200);
function Storagecallback(spec, utils) {
this._spec = spec;
this._utils = utils;
return this;
}
jIO.addStorage('Cryptstoragecallback', Storagecallback);
///////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////
// CryptStorage.constructor // CryptStorage.constructor
///////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////
...@@ -31,14 +78,29 @@ ...@@ -31,14 +78,29 @@
test("create substorage", function () { test("create substorage", function () {
var jio = jIO.createJIO({ var jio = jIO.createJIO({
type: "crypt", type: "crypt",
key: key, keyid: "key200",
sub_storage: {type : "cryptstorage200"} sub_storage: {type : "cryptstorage200"}
}); });
equal(jio.__type, "crypt"); equal(jio.__type, "crypt");
equal(jio.__storage._keyid, "key200");
equal(jio.__storage._sub_storage.__type, "cryptstorage200"); 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 // CryptStorage.get
///////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////
...@@ -49,7 +111,6 @@ ...@@ -49,7 +111,6 @@
var jio = jIO.createJIO({ var jio = jIO.createJIO({
type: "crypt", type: "crypt",
key: key,
sub_storage: {type : "cryptstorage200"} sub_storage: {type : "cryptstorage200"}
}); });
...@@ -82,7 +143,6 @@ ...@@ -82,7 +143,6 @@
var jio = jIO.createJIO({ var jio = jIO.createJIO({
type: "crypt", type: "crypt",
key: key,
sub_storage: {type : "cryptstorage200"} sub_storage: {type : "cryptstorage200"}
}); });
...@@ -115,7 +175,6 @@ ...@@ -115,7 +175,6 @@
var jio = jIO.createJIO({ var jio = jIO.createJIO({
type: "crypt", type: "crypt",
key: key,
sub_storage: {type : "cryptstorage200"} sub_storage: {type : "cryptstorage200"}
}); });
...@@ -146,7 +205,6 @@ ...@@ -146,7 +205,6 @@
var jio = jIO.createJIO({ var jio = jIO.createJIO({
type: "crypt", type: "crypt",
key: key,
sub_storage: {type : "cryptstorage200"} sub_storage: {type : "cryptstorage200"}
}); });
...@@ -174,7 +232,6 @@ ...@@ -174,7 +232,6 @@
test("hasCapacity return substorage value", function () { test("hasCapacity return substorage value", function () {
var jio = jIO.createJIO({ var jio = jIO.createJIO({
type: "crypt", type: "crypt",
key: key,
sub_storage: {type : "cryptstorage200"} sub_storage: {type : "cryptstorage200"}
}); });
...@@ -204,7 +261,6 @@ ...@@ -204,7 +261,6 @@
var jio = jIO.createJIO({ var jio = jIO.createJIO({
type: "crypt", type: "crypt",
key: key,
sub_storage: {type : "cryptstorage200"} sub_storage: {type : "cryptstorage200"}
}); });
...@@ -237,7 +293,6 @@ ...@@ -237,7 +293,6 @@
var jio = jIO.createJIO({ var jio = jIO.createJIO({
type: "crypt", type: "crypt",
key: key,
sub_storage: {type : "cryptstorage200"} sub_storage: {type : "cryptstorage200"}
}); });
...@@ -271,7 +326,6 @@ ...@@ -271,7 +326,6 @@
var jio = jIO.createJIO({ var jio = jIO.createJIO({
type: "crypt", type: "crypt",
key: key,
sub_storage: {type : "cryptstorage200"} sub_storage: {type : "cryptstorage200"}
}); });
...@@ -301,13 +355,13 @@ ...@@ -301,13 +355,13 @@
setup: function () { setup: function () {
this.jio = jIO.createJIO({ this.jio = jIO.createJIO({
type: "crypt", type: "crypt",
key: key, keyid: "key200",
sub_storage: {type : "cryptstorage200"} sub_storage: {type : "cryptstorage200"}
}); }, utils);
} }
}); });
test("return substorage getattachment", function () { test("return error if key is not type Cryptokey", function () {
var id = "/", var id = "/",
attachment = "stringattachment", attachment = "stringattachment",
blob = new Blob(['foo']); blob = new Blob(['foo']);
...@@ -322,64 +376,34 @@ ...@@ -322,64 +376,34 @@
expect(3); expect(3);
this.jio.getAttachment(id, attachment) 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) { .fail(function (error) {
ok(false, error); equal(error.message, "key200 : TypeError : password is not type CRYPTOKEY", "get attachement error shown");
}) })
.always(function () { .always(function () {
start(); start();
}); });
}); });
test("return substorage getattachment if not data url", function () { test("return error if decrypt fails", function () {
var id = "/", var id = "/",
attachment = "stringattachment", attachment = "stringattachment",
blob = new Blob(['foo'], that,
{type: 'application/x-jio-aes-gcm-encryption'}); blob = new Blob(['foo']); //non crypted file
Storage200.prototype.getAttachment = function (arg1, arg2) { Storage200.prototype.getAttachment = function () {
equal(arg1, id, "getAttachment 200 called");
equal(arg2, attachment, "getAttachment 200 called");
return blob; return blob;
}; };
stop(); stop();
expect(3); expect(1);
that = this;
this.jio.getAttachment(id, attachment) that.jio.getAttachment(id, attachment)
.then(function (result) { .fail(function () {
equal(result, blob, "Return substorage result"); return that.jio.getAttachment(id, attachment)
}) .push(undefined, function (error) {
.fail(function (error) { equal(error.message, "key200 : OperationError : Failed to decrypt due to incorrect password or data",
ok(false, error); "returned error : incorrect password or incrypted data");
});
}) })
.always(function () { .always(function () {
start(); start();
...@@ -389,11 +413,14 @@ ...@@ -389,11 +413,14 @@
test("decrypt blob from aes-gcm", function () { test("decrypt blob from aes-gcm", function () {
var id = "/", var id = "/",
attachment = "stringattachment", attachment = "stringattachment",
that,
value = "azertyuio\npàç_è-('é&", value = "azertyuio\npàç_è-('é&",
tocheck = "data:application/x-jio-aes-gcm-encryption;base64" + tocheck = "data:application/x-jio-aes-gcm-encryption" +
",+p/Ho+KgGHZC2zDLMbQQS2tXcsy0g+Ho41VZnlPEkXdmG9zm36c8iLCkv" + ";base64,6RxBftHGvMYG+ymk2e2viIhtdIcbui7+4UH57S0bl" +
"lanyWCN510NK4hj1EgWQ6WrLS5pCmA/yeAWh+HyfPkYKDRHVBl6+Hxd53I" + "D6fqrrWTcgzx/SZjXdzYQyK7a1pe2tM9msrPDyZrreN+b+rU9S" +
"TmiWQ6Vix2jaIQg==", "YodEKW/XgSkcQj9n+V77KT/qsQymLb1K3widtxA==",
blob = jIO.util.dataURItoBlob(tocheck); blob = jIO.util.dataURItoBlob(tocheck);
...@@ -401,32 +428,36 @@ ...@@ -401,32 +428,36 @@
Storage200.prototype.getAttachment = function (arg1, arg2) { Storage200.prototype.getAttachment = function (arg1, arg2) {
equal(arg1, id, "getAttachment 200 called"); equal(arg1, id, "getAttachment 200 called");
equal(arg2, attachment, "getAttachment 200 called"); equal(arg2, attachment, "getAttachment 200 called");
window.m = new Date().getTime();
return blob; return blob;
}; };
stop(); stop();
expect(6); expect(9);
this.jio.getAttachment(id, attachment) that = this;
.then(function (result) { that.jio.getAttachment(id, attachment)
ok(result !== blob, "Does not return substorage result"); .fail(function () {
ok(result instanceof Blob, "Data is Blob"); return that.jio.getAttachment(id, attachment)
deepEqual(result.type, "text/plain;charset=utf-8", .push(function (result) {
"Check mimetype"); ok(true, "Decryption time = " + (new Date().getTime() - window.m) + " milliseconde");
ok(result !== blob, "Does not return substorage result");
return jIO.util.readBlobAsText(result); ok(result instanceof Blob, "Data is Blob");
}) deepEqual(result.type, "text/plain;charset=utf-8",
.then(function (result) { "Check mimetype");
equal(result.target.result, value, "Attachment correctly fetched"); return jIO.util.readBlobAsText(result);
}) })
.fail(function (error) { .push(function (result) {
ok(false, error); equal(result.target.result, value, "Attachment correctly fetched");
return result;
});
}) })
.always(function () { .always(function () {
start(); start();
}); });
}); });
///////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////
// CryptStorage.putAttachment // CryptStorage.putAttachment
///////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////
...@@ -434,9 +465,9 @@ ...@@ -434,9 +465,9 @@
setup: function () { setup: function () {
this.jio = jIO.createJIO({ this.jio = jIO.createJIO({
type: "crypt", type: "crypt",
key: key, keyid: "key200",
sub_storage: {type : "cryptstorage200"} sub_storage: {type : "cryptstorage200"}
}); }, utils);
} }
}); });
...@@ -445,8 +476,19 @@ ...@@ -445,8 +476,19 @@
return new RSVP.Queue() return new RSVP.Queue()
.push(function () { .push(function () {
return crypto.subtle.importKey("jwk", key, return convertKey(userkey);
"AES-GCM", false, ["decrypt"]); })
.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) { .push(function (res) {
decryptKey = res; decryptKey = res;
...@@ -460,11 +502,10 @@ ...@@ -460,11 +502,10 @@
coded = coded.target.result; coded = coded.target.result;
iv = new Uint8Array(coded.slice(0, 12)); 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)); decryptKey, coded.slice(12));
}) })
.push(function (arr) { .push(function (arr) {
arr = String.fromCharCode.apply(null, new Uint8Array(arr)); arr = String.fromCharCode.apply(null, new Uint8Array(arr));
equal( equal(
arr, arr,
...@@ -477,6 +518,7 @@ ...@@ -477,6 +518,7 @@
test("crypt blob to aes-gcm", function () { test("crypt blob to aes-gcm", function () {
var id = "/", var id = "/",
that,
attachment = "stringattachment", attachment = "stringattachment",
value = "azertyuio\npàç_è-('é&", value = "azertyuio\npàç_è-('é&",
blob = new Blob([value], blob = new Blob([value],
...@@ -492,15 +534,16 @@ ...@@ -492,15 +534,16 @@
return decodeAES(arg3); return decodeAES(arg3);
}; };
stop(); stop();
expect(7); expect(7);
that = this;
this.jio.putAttachment(id, attachment, blob) this.jio.putAttachment(id, attachment, blob)
.then(function (result) { .fail(function () {
equal(result, "ok", "Return substorage result"); return that.jio.putAttachment(id, attachment, blob)
}) .push(function (result) {
.fail(function (error) { equal(result, "ok", "Return substorage result");
ok(false, error); });
}) })
.always(function () { .always(function () {
start(); start();
......
...@@ -11,7 +11,8 @@ ...@@ -11,7 +11,8 @@
equal = QUnit.equal, equal = QUnit.equal,
module = QUnit.module, module = QUnit.module,
domain = "https://example.org", domain = "https://example.org",
basic_login = "login:passwd"; basic_login = "login:passwd",
utils = {callback: function () {return true; }};
///////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////
// davStorage constructor // davStorage constructor
...@@ -30,6 +31,15 @@ ...@@ -30,6 +31,15 @@
deepEqual(jio.__storage._with_credentials, undefined); 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 () { test("Storage store basic login", function () {
var jio = jIO.createJIO({ var jio = jIO.createJIO({
type: "dav", type: "dav",
......
...@@ -9,7 +9,8 @@ ...@@ -9,7 +9,8 @@
expect = QUnit.expect, expect = QUnit.expect,
deepEqual = QUnit.deepEqual, deepEqual = QUnit.deepEqual,
equal = QUnit.equal, equal = QUnit.equal,
module = QUnit.module; module = QUnit.module,
utils = {callback: function () {return true; }};
///////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////
// Custom test substorage definition // Custom test substorage definition
...@@ -19,6 +20,13 @@ ...@@ -19,6 +20,13 @@
} }
jIO.addStorage('documentstorage200', Storage200); jIO.addStorage('documentstorage200', Storage200);
function Storagecallback(spec, utils) {
this._spec = spec;
this._utils = utils;
return this;
}
jIO.addStorage('documentstoragecallback', Storagecallback);
///////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////
// documentStorage.constructor // documentStorage.constructor
///////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////
...@@ -38,6 +46,19 @@ ...@@ -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 () { test("accept parameters", function () {
var jio = jIO.createJIO({ var jio = jIO.createJIO({
type: "document", type: "document",
......
...@@ -9,7 +9,8 @@ ...@@ -9,7 +9,8 @@
expect = QUnit.expect, expect = QUnit.expect,
deepEqual = QUnit.deepEqual, deepEqual = QUnit.deepEqual,
equal = QUnit.equal, equal = QUnit.equal,
module = QUnit.module; module = QUnit.module,
utils = {callback: function () {return true; }};
///////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////
// Custom test substorage definition // Custom test substorage definition
...@@ -19,6 +20,13 @@ ...@@ -19,6 +20,13 @@
} }
jIO.addStorage('drivetojiomapping200', Storage200); jIO.addStorage('drivetojiomapping200', Storage200);
function Storagecallback(spec, utils) {
this._spec = spec;
this._utils = utils;
return this;
}
jIO.addStorage('drivetojiomappingcallback', Storagecallback);
///////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////
// driveToJioMapping.constructor // driveToJioMapping.constructor
///////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////
...@@ -36,6 +44,19 @@ ...@@ -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 // driveToJioMapping.get
///////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////
......
...@@ -10,7 +10,8 @@ ...@@ -10,7 +10,8 @@
deepEqual = QUnit.deepEqual, deepEqual = QUnit.deepEqual,
equal = QUnit.equal, equal = QUnit.equal,
module = QUnit.module, module = QUnit.module,
token = "sample_token"; token = "sample_token",
utils = {callback: function () {return true; }};
///////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////
// DropboxStorage constructor // DropboxStorage constructor
...@@ -26,6 +27,15 @@ ...@@ -26,6 +27,15 @@
deepEqual(jio.__storage._access_token, token); 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 // DropboxStorage.put
///////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////
......
...@@ -11,6 +11,7 @@ ...@@ -11,6 +11,7 @@
equal = QUnit.equal, equal = QUnit.equal,
module = QUnit.module, module = QUnit.module,
domain = "https://example.org", domain = "https://example.org",
utils = {callback: function () {return true; }},
traverse_template = domain + "?mode=traverse{&relative_url,view}", traverse_template = domain + "?mode=traverse{&relative_url,view}",
search_template = domain + "?mode=search{&query,select_list*,limit*," + search_template = domain + "?mode=search{&query,select_list*,limit*," +
"sort_on*,local_roles*,selection_domain*}", "sort_on*,local_roles*,selection_domain*}",
...@@ -50,6 +51,15 @@ ...@@ -50,6 +51,15 @@
deepEqual(jio.__storage._default_view_reference, "bar_view"); 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 // erp5Storage.get
///////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////
......
...@@ -12,7 +12,8 @@ ...@@ -12,7 +12,8 @@
module = QUnit.module, module = QUnit.module,
throws = QUnit.throws, throws = QUnit.throws,
token = "sample_token", token = "sample_token",
user_id = "sample_user_id"; user_id = "sample_user_id",
utils = {callback: function () {return true; }};
///////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////
// Facebook Storage constructor // Facebook Storage constructor
...@@ -31,6 +32,16 @@ ...@@ -31,6 +32,16 @@
deepEqual(jio.__storage._user_id, user_id); 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 () { test("reject non string token", function () {
throws( throws(
......
...@@ -12,6 +12,7 @@ ...@@ -12,6 +12,7 @@
module = QUnit.module, module = QUnit.module,
throws = QUnit.throws, throws = QUnit.throws,
token = "sample_token", token = "sample_token",
utils = {callback: function () {return true; }},
domain = "https://www.googleapis.com", domain = "https://www.googleapis.com",
boundary = "---------314159265358979323846", boundary = "---------314159265358979323846",
list_url = domain + "/drive/v2/files" + list_url = domain + "/drive/v2/files" +
...@@ -58,6 +59,15 @@ ...@@ -58,6 +59,15 @@
deepEqual(jio.__storage._access_token, token); 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 () { test("reject invalid trashing parameter", function () {
throws( throws(
......
...@@ -10,7 +10,8 @@ ...@@ -10,7 +10,8 @@
deepEqual = QUnit.deepEqual, deepEqual = QUnit.deepEqual,
equal = QUnit.equal, equal = QUnit.equal,
module = QUnit.module, module = QUnit.module,
domain = "https://example.org"; domain = "https://example.org",
utils = {callback: function () {return true; }};
///////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////
// davStorage constructor // davStorage constructor
...@@ -27,6 +28,14 @@ ...@@ -27,6 +28,14 @@
deepEqual(jio.__storage._timeout, 0); 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 () { test("Storage store catch_error", function () {
var jio = jIO.createJIO({ var jio = jIO.createJIO({
type: "http", type: "http",
......
...@@ -13,6 +13,7 @@ ...@@ -13,6 +13,7 @@
equal = QUnit.equal, equal = QUnit.equal,
module = QUnit.module, module = QUnit.module,
big_string = "", big_string = "",
utils = {callback: function () {return true; }},
j; j;
for (j = 0; j < 3000000; j += 1) { for (j = 0; j < 3000000; j += 1) {
...@@ -48,6 +49,15 @@ ...@@ -48,6 +49,15 @@
deepEqual(jio.__storage._database_name, "jio:qunit"); 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 // documentStorage.hasCapacity
///////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////
......
...@@ -11,7 +11,8 @@ ...@@ -11,7 +11,8 @@
expect = QUnit.expect, expect = QUnit.expect,
deepEqual = QUnit.deepEqual, deepEqual = QUnit.deepEqual,
equal = QUnit.equal, equal = QUnit.equal,
module = QUnit.module; module = QUnit.module,
utils = {callback: function () {return true; }};
///////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////
// localStorage.constructor // localStorage.constructor
...@@ -26,6 +27,14 @@ ...@@ -26,6 +27,14 @@
equal(jio.__storage._storage, localStorage); 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 () { test("sessiononly", function () {
var jio = jIO.createJIO({ var jio = jIO.createJIO({
type: "local", type: "local",
......
...@@ -9,7 +9,8 @@ ...@@ -9,7 +9,8 @@
expect = QUnit.expect, expect = QUnit.expect,
deepEqual = QUnit.deepEqual, deepEqual = QUnit.deepEqual,
equal = QUnit.equal, equal = QUnit.equal,
module = QUnit.module; module = QUnit.module,
utils = {callback: function () {return true; }};
///////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////
// memoryStorage constructor // memoryStorage constructor
...@@ -25,6 +26,14 @@ ...@@ -25,6 +26,14 @@
deepEqual(jio.__storage._database, {}); 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 () { test("Storage's memory database is not shared", function () {
var jio = jIO.createJIO({ var jio = jIO.createJIO({
"type": "memory" "type": "memory"
......
...@@ -9,7 +9,8 @@ ...@@ -9,7 +9,8 @@
expect = QUnit.expect, expect = QUnit.expect,
deepEqual = QUnit.deepEqual, deepEqual = QUnit.deepEqual,
equal = QUnit.equal, equal = QUnit.equal,
module = QUnit.module; module = QUnit.module,
utils = {callback: function () {return true; }};
///////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////
// Custom RSS test substorage definition // Custom RSS test substorage definition
...@@ -51,6 +52,18 @@ ...@@ -51,6 +52,18 @@
}; };
jIO.addStorage('rssstorage200', RSSStorage200); 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 // Custom atom test substorage definition
///////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////
...@@ -174,6 +187,19 @@ ...@@ -174,6 +187,19 @@
equal(jio.__storage._parser, undefined); 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 // ParserStorage.allDocs
///////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////
......
...@@ -18,7 +18,8 @@ ...@@ -18,7 +18,8 @@
bucket: bucket, bucket: bucket,
access_key: access_key, access_key: access_key,
secret_key: secret_key secret_key: secret_key
}; },
utils = {callback: function () {return true; }};
///////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////
// qiniuStorage constructor // qiniuStorage constructor
...@@ -34,6 +35,14 @@ ...@@ -34,6 +35,14 @@
deepEqual(jio.__storage._secret_key, qiniu_spec.secret_key); 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 // qiniuStorage.get
///////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////
......
...@@ -10,7 +10,8 @@ ...@@ -10,7 +10,8 @@
deepEqual = QUnit.deepEqual, deepEqual = QUnit.deepEqual,
equal = QUnit.equal, equal = QUnit.equal,
module = QUnit.module, module = QUnit.module,
throws = QUnit.throws; throws = QUnit.throws,
utils = {callback: function () {return true; }};
///////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////
// Custom test substorage definition // Custom test substorage definition
...@@ -20,6 +21,13 @@ ...@@ -20,6 +21,13 @@
} }
jIO.addStorage('querystorage200', Storage200); jIO.addStorage('querystorage200', Storage200);
function Storagecallback(spec, utils) {
this._spec = spec;
this._utils = utils;
return this;
}
jIO.addStorage('querystoragecallback', Storagecallback);
///////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////
// queryStorage.constructor // queryStorage.constructor
///////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////
...@@ -45,6 +53,19 @@ ...@@ -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 () { test("failed on wrond schema", function () {
throws( throws(
function () { function () {
......
...@@ -12,6 +12,7 @@ ...@@ -12,6 +12,7 @@
module = QUnit.module, module = QUnit.module,
throws = QUnit.throws, throws = QUnit.throws,
big_string = "", big_string = "",
utils = {callback: function () {return true; }},
j; j;
for (j = 0; j < 30; j += 1) { for (j = 0; j < 30; j += 1) {
...@@ -36,6 +37,27 @@ ...@@ -36,6 +37,27 @@
} }
jIO.addStorage('signaturestorage2713', Storage2713); 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 // replicateStorage.constructor
///////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////
...@@ -103,6 +125,30 @@ ...@@ -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 () { test("accept parameters", function () {
var jio = jIO.createJIO({ var jio = jIO.createJIO({
type: "replicate", type: "replicate",
......
...@@ -10,7 +10,8 @@ ...@@ -10,7 +10,8 @@
deepEqual = QUnit.deepEqual, deepEqual = QUnit.deepEqual,
equal = QUnit.equal, equal = QUnit.equal,
module = QUnit.module, module = QUnit.module,
throws = QUnit.throws; throws = QUnit.throws,
utils = {callback: function () {return true; }};
///////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////
// Custom test substorage definition // Custom test substorage definition
...@@ -20,6 +21,13 @@ ...@@ -20,6 +21,13 @@
} }
jIO.addStorage('shastorage200', Storage200); jIO.addStorage('shastorage200', Storage200);
function Storagecallback(spec, utils) {
this._spec = spec;
this._utils = utils;
return this;
}
jIO.addStorage('shastoragecallback', Storagecallback);
///////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////
// shaStorage.constructor // shaStorage.constructor
///////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////
...@@ -37,6 +45,19 @@ ...@@ -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 // shaStorage.get
///////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////
......
...@@ -11,7 +11,8 @@ ...@@ -11,7 +11,8 @@
equal = QUnit.equal, equal = QUnit.equal,
module = QUnit.module, module = QUnit.module,
throws = QUnit.throws, throws = QUnit.throws,
frozen_blob = new Blob(["foobar"]); frozen_blob = new Blob(["foobar"]),
utils = {callback: function () {return true; }};
///////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////
// Custom test substorage definition // Custom test substorage definition
...@@ -115,6 +116,13 @@ ...@@ -115,6 +116,13 @@
Storage500.prototype.repair = generateError; Storage500.prototype.repair = generateError;
jIO.addStorage('unionstorage500', Storage500); jIO.addStorage('unionstorage500', Storage500);
function Storagecallback(spec, utils) {
this._spec = spec;
this._utils = utils;
return this;
}
jIO.addStorage('unioncallback', Storagecallback);
///////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////
// unionStorage.constructor // unionStorage.constructor
///////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////
...@@ -145,6 +153,20 @@ ...@@ -145,6 +153,20 @@
equal(jio.__storage._storage_list[1].__type, "unionstorage200"); 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 // unionStorage.get
///////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////
......
...@@ -10,7 +10,8 @@ ...@@ -10,7 +10,8 @@
deepEqual = QUnit.deepEqual, deepEqual = QUnit.deepEqual,
equal = QUnit.equal, equal = QUnit.equal,
module = QUnit.module, module = QUnit.module,
throws = QUnit.throws; throws = QUnit.throws,
utils = {callback: function () {return true; }};
///////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////
// Custom test substorage definition // Custom test substorage definition
...@@ -20,6 +21,13 @@ ...@@ -20,6 +21,13 @@
} }
jIO.addStorage('uuidstorage200', Storage200); jIO.addStorage('uuidstorage200', Storage200);
function Storagecallback(spec, utils) {
this._spec = spec;
this._utils = utils;
return this;
}
jIO.addStorage('uuidcallback', Storagecallback);
///////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////
// uuidStorage.constructor // uuidStorage.constructor
///////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////
...@@ -37,6 +45,19 @@ ...@@ -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 // uuidStorage.get
///////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////
......
...@@ -10,7 +10,8 @@ ...@@ -10,7 +10,8 @@
deepEqual = QUnit.deepEqual, deepEqual = QUnit.deepEqual,
equal = QUnit.equal, equal = QUnit.equal,
throws = QUnit.throws, throws = QUnit.throws,
module = QUnit.module; module = QUnit.module,
utils = {callback: function () {return true; }};
///////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////
// Custom test substorage definition // Custom test substorage definition
...@@ -20,6 +21,13 @@ ...@@ -20,6 +21,13 @@
} }
jIO.addStorage('zipstorage200', Storage200); jIO.addStorage('zipstorage200', Storage200);
function Storagecallback(spec, utils) {
this._spec = spec;
this._utils = utils;
return this;
}
jIO.addStorage('zipstoragecallback', Storagecallback);
///////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////
// ZipStorage.constructor // ZipStorage.constructor
///////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////
...@@ -33,6 +41,19 @@ ...@@ -33,6 +41,19 @@
equal(jio.__storage._sub_storage.__type, "zipstorage200"); 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 // ZipStorage.get
///////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////
......
...@@ -258,11 +258,9 @@ ...@@ -258,11 +258,9 @@
{ {
"type": "complex", "type": "complex",
"operator": "NOT", "operator": "NOT",
"key": "",
"query_list": [{ "query_list": [{
"type": "complex", "type": "complex",
"operator": "OR", "operator": "OR",
"key": "",
"query_list": [{ "query_list": [{
"key": "a", "key": "a",
"operator": "=", "operator": "=",
...@@ -271,7 +269,6 @@ ...@@ -271,7 +269,6 @@
}, { }, {
"type": "complex", "type": "complex",
"operator": "AND", "operator": "AND",
"key": "",
"query_list": [{ "query_list": [{
"key": "c", "key": "c",
"type": "simple", "type": "simple",
...@@ -311,23 +308,10 @@ ...@@ -311,23 +308,10 @@
"NOT(a:=b OR c:% AND d:<2)" "NOT(a:=b OR c:% AND d:<2)"
) )
).toString(), ).toString(),
"NOT ( ( a: = \"b\" OR ( c: \"%\" AND d: < \"2\" ) ) )", "NOT ( ( a: = \"b\" ) OR ( ( c: \"%\" ) AND ( d: < \"2\" ) ) )",
"create(create(\"NOT(a:=b OR c:% AND d:<2)\")).toString();" "create(create(\"NOT(a:=b OR c:% AND d:<2)\")).toString();"
); );
deepEqual(
jIO.QueryFactory.create(jIO.Query.objectToSearchText(jsoned)).toJSON(),
jsoned,
"create( objectToSearchText(create(\"NOT(a:=b OR c:% AND d:<2)\")" +
".toJSON()) ).toJSON()"
);
deepEqual(
jIO.QueryFactory.create("a:(b OR c)").toString(),
"a: ( \"b\" OR \"c\" )",
"create( \"a:(b OR c)\" ).toString()"
);
}); });
test('Docs with space, tab, and newline', function () { test('Docs with space, tab, and newline', function () {
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment