Commit b45474eb authored by amrani's avatar amrani

added callback to all storage and major change to crypto stoarge

parent 549b3ed8
/*
* Copyright 2015, Nexedi SA
* Released under the LGPL license.
* Released under the LGPL license.
* hcrypto, Uint8Array, ArrayBuffer*/
/*jslint nomen: true*/
/*global jIO, RSVP, DOMParser, Blob, DOMException, crypto, Uint8Array,
ArrayBuffer, CryptoKey*/
/*jslint maxlen: 160 */
/*global jIO, RSVP, DOMException, Blob, crypto, Uint8Array, ArrayBuffer, CryptoKey*/
(function (jIO, RSVP, DOMException, Blob, crypto, Uint8Array, ArrayBuffer,
CryptoKey) {
(function (jIO, RSVP, DOMException, Blob, crypto, Uint8Array, ArrayBuffer, CryptoKey) {
"use strict";
/*
......@@ -35,69 +36,13 @@
*/
function hexToBuffer(hex) {
// Xxxx use Uint8Array or ArrayBuffer or DataView
var i,
byteLen = hex.length / 2,
arr,
j = 0;
if (byteLen !== parseInt(byteLen, 10)) {
throw new Error("Invalid hex length '" + hex.length + "'");
}
arr = new Uint8Array(byteLen);
for (i = 0; i < byteLen; i += 1) {
arr[i] = parseInt(hex[j] + hex[j + 1], 16);
j += 2;
}
return arr;
}
function convertKey(that) {
return new RSVP.Queue()
.push(function () {
return window.crypto.subtle.deriveKey({
"name": "PBKDF2",
"salt": hexToBuffer("6f0904840608c09ae18c131542fbd1bd"),
"iterations": 1000,
//we can add iteration number but slow CPU will freez
"hash": "SHA-256"
}, that.importedkey, {
"name": "AES-GCM",
"length": 256
}, false, ["encrypt", "decrypt"]);
})
.push(function (res) {
that.key = res;
return;
});
}
function addevent(that) {
try {
window.addEventListener('message', function (event) {
if (event.origin !== window.origin) {return; }
if (!(event.data instanceof CryptoKey)) {return; }
if (event.data.algorithm.name !== "PBKDF2" &&
event.data.usages[0] !== "deriveKey") {return; }
that.importedkey = event.data;
convertKey(that);
}, false);
} catch (error) {
throw new jIO.util.jIOError(error + "failed to build event lisener please reload the page", 803);
}
}
var MIME_TYPE = "application/x-jio-aes-gcm-encryption";
function CryptStorage(spec) {
addevent(this);
this.importedkey = "";
this.key = "";
this._sub_storage = jIO.createJIO(spec.sub_storage);
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 () {
......@@ -131,7 +76,6 @@
};
CryptStorage.prototype.putAttachment = function (id, name, blob) {
var initializaton_vector = crypto.getRandomValues(new Uint8Array(12)),
that = this;
return new RSVP.Queue()
......@@ -152,7 +96,7 @@
name: "AES-GCM",
iv: initializaton_vector
},
that.key, buf);
that._key, buf);
})
.push(function (coded) {
var blob = new Blob([initializaton_vector, coded], {
......@@ -161,16 +105,37 @@
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") {
throw new jIO.util.jIOError(error.name + " : failed to decrypt due to mismatching password", 801);
}
if (error.name === "InvalidAccessError") {
throw new jIO.util.jIOError(error.name + " : invalid encryption algorithm, or invalid key for specified encryption algorithm", 801);
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) {
throw new jIO.util.jIOError(error + " : password is not type CRYPTOKEY ", 801);
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);
});
});
};
......@@ -178,9 +143,6 @@
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 () {
return new RSVP.Queue()
......@@ -197,25 +159,44 @@
name: "AES-GCM",
iv: initializaton_vector
},
that.key, coded.slice(12));
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) {
if (error instanceof DOMException) {
if (error.name === "OperationError") {
throw new jIO.util.jIOError(error.name + " : failed to decrypt due to mismatching password", 801);
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 (error.name === "InvalidAccessError") {
throw new jIO.util.jIOError(error.name + " : invalid encryption algorithm, or invalid key for specified encryption algorithm", 801);
if (!that._utils.hasOwnProperty("crypto_getCryptoKey")) {
throw new jIO.util.jIOError(that._keyid + ":crypto_getCryptoKey function not declared in callback");
}
return blob;
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";
}
if (error instanceof TypeError) {
throw new jIO.util.jIOError(error + " : password is not type CRYPTOKEY ", 801);
} 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);
});
});
});
});
......@@ -232,6 +213,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, CryptoKey));
......@@ -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;
......
......@@ -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;
}
......
......@@ -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/",
......
......@@ -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;
}
......@@ -255,15 +256,12 @@
})
.push(function (evt) {
if (evt.target.response instanceof Blob) {
//create a new blob with type AES-GCM to decrypt back
var cryptblob = new Blob([evt.target.response],
{type: "application/x-jio-aes-gcm-encryption"});
return cryptblob;
return evt.target.response;
}
return new Blob(
[evt.target.responseText],
{"type": "application/x-jio-aes-gcm-encryption"}
// evt.target.getResponseHeader('Content-Type') ||
{"type": evt.target.getResponseHeader('Content-Type') ||
"application/octet-stream"}
);
}, function (error) {
if (error.target !== undefined && error.target.status === 409) {
......
......@@ -142,12 +142,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;
}
......
......@@ -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 || [];
......
......@@ -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;
......
......@@ -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 || {
......
......@@ -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;
}
......
......@@ -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;
}
......
......@@ -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;
}
......
......@@ -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 {
......
......@@ -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) {
......
......@@ -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.
......
......@@ -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) {
......
......@@ -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.");
......
......@@ -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);
}
......
......@@ -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(
......
......@@ -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) {
......
......@@ -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));
}
}
......
......@@ -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 () {
......
......@@ -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.");
......
......@@ -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 () {
......
/*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,14 +12,46 @@
equal = QUnit.equal,
throws = QUnit.throws,
module = QUnit.module,
key = "password",
key_generated_by_password = {
"alg": "A256GCM",
"ext": true,
"k": "wBHHU4Es8IqMCnH03Jxhc1ZTQN7hzo6GkCNnbA_0kjI",
"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;
});
}};
/////////////////////////////////////////////////////////////////
......@@ -29,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
/////////////////////////////////////////////////////////////////
......@@ -37,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
/////////////////////////////////////////////////////////////////
......@@ -55,7 +111,6 @@
var jio = jIO.createJIO({
type: "crypt",
key: key,
sub_storage: {type : "cryptstorage200"}
});
......@@ -88,7 +143,6 @@
var jio = jIO.createJIO({
type: "crypt",
key: key,
sub_storage: {type : "cryptstorage200"}
});
......@@ -121,7 +175,6 @@
var jio = jIO.createJIO({
type: "crypt",
key: key,
sub_storage: {type : "cryptstorage200"}
});
......@@ -152,7 +205,6 @@
var jio = jIO.createJIO({
type: "crypt",
key: key,
sub_storage: {type : "cryptstorage200"}
});
......@@ -180,7 +232,6 @@
test("hasCapacity return substorage value", function () {
var jio = jIO.createJIO({
type: "crypt",
key: key,
sub_storage: {type : "cryptstorage200"}
});
......@@ -210,7 +261,6 @@
var jio = jIO.createJIO({
type: "crypt",
key: key,
sub_storage: {type : "cryptstorage200"}
});
......@@ -243,7 +293,6 @@
var jio = jIO.createJIO({
type: "crypt",
key: key,
sub_storage: {type : "cryptstorage200"}
});
......@@ -277,7 +326,6 @@
var jio = jIO.createJIO({
type: "crypt",
key: key,
sub_storage: {type : "cryptstorage200"}
});
......@@ -307,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']);
......@@ -328,63 +376,34 @@
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 decrypt fails", 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);
})
.always(function () {
start();
});
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");
});
test("return substorage getattachment if not data url", 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);
})
.always(function () {
start();
......@@ -394,11 +413,12 @@
test("decrypt blob from aes-gcm", function () {
var id = "/",
attachment = "stringattachment",
that,
value = "azertyuio\npàç_è-('é&",
tocheck = "data:application/x-jio-aes-gcm-encryption" +
";base64,2lHQ9xpJJ9qd81DxZEyd1LICtaV3XD+I2d5cp137L4NQC" +
"vdkasBaFkPUE5XiY88g5z0oN9dcDASfChmvgqrkDExKS+zVglvVVs" +
"CyECYorZ5fwgMCWAL5vUNCCaqhFVFyng==",
";base64,6RxBftHGvMYG+ymk2e2viIhtdIcbui7+4UH57S0bl" +
"D6fqrrWTcgzx/SZjXdzYQyK7a1pe2tM9msrPDyZrreN+b+rU9S" +
"YodEKW/XgSkcQj9n+V77KT/qsQymLb1K3widtxA==",
......@@ -408,26 +428,29 @@
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) {
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);
})
.then(function (result) {
.push(function (result) {
equal(result.target.result, value, "Attachment correctly fetched");
})
.fail(function (error) {
ok(false, error);
return result;
});
})
.always(function () {
start();
......@@ -442,9 +465,9 @@
setup: function () {
this.jio = jIO.createJIO({
type: "crypt",
key: key,
keyid: "key200",
sub_storage: {type : "cryptstorage200"}
});
}, utils);
}
});
......@@ -453,8 +476,19 @@
return new RSVP.Queue()
.push(function () {
return crypto.subtle.importKey("jwk", key_generated_by_password,
"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;
......@@ -484,6 +518,7 @@
test("crypt blob to aes-gcm", function () {
var id = "/",
that,
attachment = "stringattachment",
value = "azertyuio\npàç_è-('é&",
blob = new Blob([value],
......@@ -502,13 +537,13 @@
stop();
expect(7);
that = this;
this.jio.putAttachment(id, attachment, blob)
.then(function (result) {
.fail(function () {
return that.jio.putAttachment(id, attachment, blob)
.push(function (result) {
equal(result, "ok", "Return substorage result");
})
.fail(function (error) {
ok(false, error);
});
})
.always(function () {
start();
......
......@@ -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",
......
......@@ -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",
......
......@@ -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
/////////////////////////////////////////////////////////////////
......
......@@ -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
/////////////////////////////////////////////////////////////////
......
......@@ -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
/////////////////////////////////////////////////////////////////
......
......@@ -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(
......
......@@ -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(
......
......@@ -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",
......
......@@ -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
/////////////////////////////////////////////////////////////////
......
......@@ -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",
......
......@@ -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"
......
......@@ -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
/////////////////////////////////////////////////////////////////
......
......@@ -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
/////////////////////////////////////////////////////////////////
......
......@@ -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 () {
......
......@@ -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",
......
......@@ -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
/////////////////////////////////////////////////////////////////
......
......@@ -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
/////////////////////////////////////////////////////////////////
......
......@@ -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
/////////////////////////////////////////////////////////////////
......
......@@ -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
/////////////////////////////////////////////////////////////////
......
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