mirror of
https://github.com/moparisthebest/mail
synced 2024-11-26 02:42:17 -05:00
refactored all files to use functional strict scope
This commit is contained in:
parent
5ee864fe01
commit
5c0e04cc31
@ -1,4 +1,4 @@
|
|||||||
var app;
|
var app; // container for the application namespace
|
||||||
|
|
||||||
(function() {
|
(function() {
|
||||||
'use strict';
|
'use strict';
|
||||||
|
@ -1,3 +1,4 @@
|
|||||||
|
(function() {
|
||||||
'use strict';
|
'use strict';
|
||||||
|
|
||||||
// import web worker dependencies
|
// import web worker dependencies
|
||||||
@ -11,8 +12,6 @@ importScripts('../app-config.js');
|
|||||||
importScripts('./aes-ccm.js');
|
importScripts('./aes-ccm.js');
|
||||||
importScripts('./util.js');
|
importScripts('./util.js');
|
||||||
|
|
||||||
var AESBATCHWORKER = (function () {
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* In the web worker thread context, 'this' and 'self' can be used as a global
|
* In the web worker thread context, 'this' and 'self' can be used as a global
|
||||||
* variable namespace similar to the 'window' object in the main thread
|
* variable namespace similar to the 'window' object in the main thread
|
||||||
|
@ -1,3 +1,4 @@
|
|||||||
|
(function() {
|
||||||
'use strict';
|
'use strict';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -21,7 +22,11 @@ app.crypto.AesCBC = function() {
|
|||||||
var ivWords = CryptoJS.enc.Base64.parse(iv);
|
var ivWords = CryptoJS.enc.Base64.parse(iv);
|
||||||
var plaintextWords = CryptoJS.enc.Utf8.parse(plaintext);
|
var plaintextWords = CryptoJS.enc.Utf8.parse(plaintext);
|
||||||
|
|
||||||
var encrypted = CryptoJS.AES.encrypt(plaintextWords, keyWords, { iv: ivWords, mode: mode, padding: padding });
|
var encrypted = CryptoJS.AES.encrypt(plaintextWords, keyWords, {
|
||||||
|
iv: ivWords,
|
||||||
|
mode: mode,
|
||||||
|
padding: padding
|
||||||
|
});
|
||||||
var ctBase64 = CryptoJS.enc.Base64.stringify(encrypted.ciphertext);
|
var ctBase64 = CryptoJS.enc.Base64.stringify(encrypted.ciphertext);
|
||||||
|
|
||||||
return ctBase64;
|
return ctBase64;
|
||||||
@ -39,10 +44,16 @@ app.crypto.AesCBC = function() {
|
|||||||
var keyWords = CryptoJS.enc.Base64.parse(key);
|
var keyWords = CryptoJS.enc.Base64.parse(key);
|
||||||
var ivWords = CryptoJS.enc.Base64.parse(iv);
|
var ivWords = CryptoJS.enc.Base64.parse(iv);
|
||||||
|
|
||||||
var decrypted = CryptoJS.AES.decrypt(ciphertext, keyWords, { iv: ivWords, mode: mode, padding: padding });
|
var decrypted = CryptoJS.AES.decrypt(ciphertext, keyWords, {
|
||||||
|
iv: ivWords,
|
||||||
|
mode: mode,
|
||||||
|
padding: padding
|
||||||
|
});
|
||||||
var pt = decrypted.toString(CryptoJS.enc.Utf8);
|
var pt = decrypted.toString(CryptoJS.enc.Utf8);
|
||||||
|
|
||||||
return pt;
|
return pt;
|
||||||
};
|
};
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
}());
|
@ -1,3 +1,4 @@
|
|||||||
|
(function() {
|
||||||
'use strict';
|
'use strict';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -49,3 +50,5 @@ app.crypto.AesCCM = function() {
|
|||||||
};
|
};
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
}());
|
@ -1,3 +1,4 @@
|
|||||||
|
(function() {
|
||||||
'use strict';
|
'use strict';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -49,3 +50,5 @@ app.crypto.AesGCM = function() {
|
|||||||
};
|
};
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
}());
|
@ -1,3 +1,4 @@
|
|||||||
|
(function() {
|
||||||
'use strict';
|
'use strict';
|
||||||
|
|
||||||
// import web worker dependencies
|
// import web worker dependencies
|
||||||
@ -10,8 +11,6 @@ importScripts('../../lib/sjcl/ccm.js');
|
|||||||
importScripts('../app-config.js');
|
importScripts('../app-config.js');
|
||||||
importScripts('./aes-ccm.js');
|
importScripts('./aes-ccm.js');
|
||||||
|
|
||||||
var AESWORKER = (function () {
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* In the web worker thread context, 'this' and 'self' can be used as a global
|
* In the web worker thread context, 'this' and 'self' can be used as a global
|
||||||
* variable namespace similar to the 'window' object in the main thread
|
* variable namespace similar to the 'window' object in the main thread
|
||||||
|
@ -1,3 +1,4 @@
|
|||||||
|
(function() {
|
||||||
'use strict';
|
'use strict';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -32,7 +33,10 @@ app.crypto.Crypto = function(window, util) {
|
|||||||
symmetricUserKey = util.random(keySize);
|
symmetricUserKey = util.random(keySize);
|
||||||
var iv = util.random(ivSize);
|
var iv = util.random(ivSize);
|
||||||
var key = aes.encrypt(symmetricUserKey, pbkdf2, iv);
|
var key = aes.encrypt(symmetricUserKey, pbkdf2, iv);
|
||||||
keyStore.persist(storageId, { key: key, iv: iv });
|
keyStore.persist(storageId, {
|
||||||
|
key: key,
|
||||||
|
iv: iv
|
||||||
|
});
|
||||||
} else {
|
} else {
|
||||||
// decrypt key
|
// decrypt key
|
||||||
symmetricUserKey = aes.decrypt(encryptedKey.key, pbkdf2, encryptedKey.iv);
|
symmetricUserKey = aes.decrypt(encryptedKey.key, pbkdf2, encryptedKey.iv);
|
||||||
@ -58,7 +62,10 @@ app.crypto.Crypto = function(window, util) {
|
|||||||
}, false);
|
}, false);
|
||||||
|
|
||||||
// send plaintext data to the worker
|
// send plaintext data to the worker
|
||||||
worker.postMessage({ password:password, keySize:keySize });
|
worker.postMessage({
|
||||||
|
password: password,
|
||||||
|
keySize: keySize
|
||||||
|
});
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
// no WebWorker support... do synchronous call
|
// no WebWorker support... do synchronous call
|
||||||
@ -79,7 +86,12 @@ app.crypto.Crypto = function(window, util) {
|
|||||||
worker.addEventListener('message', function(e) {
|
worker.addEventListener('message', function(e) {
|
||||||
callback(e.data);
|
callback(e.data);
|
||||||
}, false);
|
}, false);
|
||||||
worker.postMessage({ type:'encrypt', plaintext:plaintext, key:key, iv:iv });
|
worker.postMessage({
|
||||||
|
type: 'encrypt',
|
||||||
|
plaintext: plaintext,
|
||||||
|
key: key,
|
||||||
|
iv: iv
|
||||||
|
});
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
var ct = this.aesEncryptSync(plaintext, key, iv);
|
var ct = this.aesEncryptSync(plaintext, key, iv);
|
||||||
@ -94,7 +106,12 @@ app.crypto.Crypto = function(window, util) {
|
|||||||
worker.addEventListener('message', function(e) {
|
worker.addEventListener('message', function(e) {
|
||||||
callback(e.data);
|
callback(e.data);
|
||||||
}, false);
|
}, false);
|
||||||
worker.postMessage({ type:'decrypt', ciphertext:ciphertext, key:key, iv:iv });
|
worker.postMessage({
|
||||||
|
type: 'decrypt',
|
||||||
|
ciphertext: ciphertext,
|
||||||
|
key: key,
|
||||||
|
iv: iv
|
||||||
|
});
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
var pt = this.aesDecryptSync(ciphertext, key, iv);
|
var pt = this.aesDecryptSync(ciphertext, key, iv);
|
||||||
@ -121,7 +138,10 @@ app.crypto.Crypto = function(window, util) {
|
|||||||
worker.addEventListener('message', function(e) {
|
worker.addEventListener('message', function(e) {
|
||||||
callback(e.data);
|
callback(e.data);
|
||||||
}, false);
|
}, false);
|
||||||
worker.postMessage({ type:'encrypt', list:list });
|
worker.postMessage({
|
||||||
|
type: 'encrypt',
|
||||||
|
list: list
|
||||||
|
});
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
var encryptedList = util.encryptList(aes, list);
|
var encryptedList = util.encryptList(aes, list);
|
||||||
@ -136,7 +156,10 @@ app.crypto.Crypto = function(window, util) {
|
|||||||
worker.addEventListener('message', function(e) {
|
worker.addEventListener('message', function(e) {
|
||||||
callback(e.data);
|
callback(e.data);
|
||||||
}, false);
|
}, false);
|
||||||
worker.postMessage({ type:'decrypt', list:list });
|
worker.postMessage({
|
||||||
|
type: 'decrypt',
|
||||||
|
list: list
|
||||||
|
});
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
var decryptedList = util.decryptList(aes, list);
|
var decryptedList = util.decryptList(aes, list);
|
||||||
@ -164,7 +187,8 @@ app.crypto.Crypto = function(window, util) {
|
|||||||
};
|
};
|
||||||
|
|
||||||
this.aesEncryptListForUser = function(list, callback) {
|
this.aesEncryptListForUser = function(list, callback) {
|
||||||
var i, envelope, envelopes = [], self = this;
|
var i, envelope, envelopes = [],
|
||||||
|
self = this;
|
||||||
|
|
||||||
// package objects into batchable envelope format
|
// package objects into batchable envelope format
|
||||||
for (i = 0; i < list.length; i++) {
|
for (i = 0; i < list.length; i++) {
|
||||||
@ -221,3 +245,5 @@ app.crypto.Crypto = function(window, util) {
|
|||||||
};
|
};
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
}());
|
@ -1,3 +1,4 @@
|
|||||||
|
(function() {
|
||||||
'use strict';
|
'use strict';
|
||||||
|
|
||||||
// import web worker dependencies
|
// import web worker dependencies
|
||||||
@ -9,8 +10,6 @@ importScripts('../../lib/crypto-js/pbkdf2.js');
|
|||||||
importScripts('../app-config.js');
|
importScripts('../app-config.js');
|
||||||
importScripts('./pbkdf2.js');
|
importScripts('./pbkdf2.js');
|
||||||
|
|
||||||
var PBKDF2WORKER = (function () {
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* In the web worker thread context, 'this' and 'self' can be used as a global
|
* In the web worker thread context, 'this' and 'self' can be used as a global
|
||||||
* variable namespace similar to the 'window' object in the main thread
|
* variable namespace similar to the 'window' object in the main thread
|
||||||
|
@ -1,3 +1,4 @@
|
|||||||
|
(function() {
|
||||||
'use strict';
|
'use strict';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -13,10 +14,15 @@ app.crypto.PBKDF2 = function() {
|
|||||||
*/
|
*/
|
||||||
this.getKey = function(password, keySize) {
|
this.getKey = function(password, keySize) {
|
||||||
var salt = CryptoJS.enc.Base64.parse("vbhmLjC+Ub6MSbhS6/CkOwxB25wvwRkSLP2DzDtYb+4="); // from random 256 bit value
|
var salt = CryptoJS.enc.Base64.parse("vbhmLjC+Ub6MSbhS6/CkOwxB25wvwRkSLP2DzDtYb+4="); // from random 256 bit value
|
||||||
var key = CryptoJS.PBKDF2(password, salt, { keySize: keySize/32, iterations: 1000 });
|
var key = CryptoJS.PBKDF2(password, salt, {
|
||||||
|
keySize: keySize / 32,
|
||||||
|
iterations: 1000
|
||||||
|
});
|
||||||
var keyBase64 = CryptoJS.enc.Base64.stringify(key);
|
var keyBase64 = CryptoJS.enc.Base64.stringify(key);
|
||||||
|
|
||||||
return keyBase64;
|
return keyBase64;
|
||||||
};
|
};
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
}());
|
@ -1,3 +1,4 @@
|
|||||||
|
(function() {
|
||||||
'use strict';
|
'use strict';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -51,7 +52,9 @@ app.crypto.PGP = function(window, openpgp, util, server) {
|
|||||||
*/
|
*/
|
||||||
self.generateKeys = function(numBits) {
|
self.generateKeys = function(numBits) {
|
||||||
// check passphrase
|
// check passphrase
|
||||||
if (!passphrase && passphrase !== '') { throw 'No passphrase set!'; }
|
if (!passphrase && passphrase !== '') {
|
||||||
|
throw 'No passphrase set!';
|
||||||
|
}
|
||||||
|
|
||||||
var userId = 'SafeWith.me User <anonymous@dunno.com>';
|
var userId = 'SafeWith.me User <anonymous@dunno.com>';
|
||||||
var keys = openpgp.generate_key_pair(1, numBits, userId, passphrase); // keytype 1=RSA
|
var keys = openpgp.generate_key_pair(1, numBits, userId, passphrase); // keytype 1=RSA
|
||||||
@ -66,7 +69,9 @@ app.crypto.PGP = function(window, openpgp, util, server) {
|
|||||||
*/
|
*/
|
||||||
self.importKeys = function(publicKeyArmored, privateKeyArmored) {
|
self.importKeys = function(publicKeyArmored, privateKeyArmored) {
|
||||||
// check passphrase
|
// check passphrase
|
||||||
if (!passphrase && passphrase !== '') { throw 'No passphrase set!'; }
|
if (!passphrase && passphrase !== '') {
|
||||||
|
throw 'No passphrase set!';
|
||||||
|
}
|
||||||
|
|
||||||
// store keys in html5 local storage
|
// store keys in html5 local storage
|
||||||
openpgp.keyring.importPrivateKey(privateKeyArmored, passphrase);
|
openpgp.keyring.importPrivateKey(privateKeyArmored, passphrase);
|
||||||
@ -164,6 +169,7 @@ app.crypto.PGP = function(window, openpgp, util, server) {
|
|||||||
});
|
});
|
||||||
|
|
||||||
// then upload private key
|
// then upload private key
|
||||||
|
|
||||||
function uploadPrivateKeys() {
|
function uploadPrivateKeys() {
|
||||||
server.xhr({
|
server.xhr({
|
||||||
type: 'POST',
|
type: 'POST',
|
||||||
@ -202,6 +208,7 @@ app.crypto.PGP = function(window, openpgp, util, server) {
|
|||||||
});
|
});
|
||||||
|
|
||||||
// get private key
|
// get private key
|
||||||
|
|
||||||
function getPrivateKey(pubKey) {
|
function getPrivateKey(pubKey) {
|
||||||
server.xhr({
|
server.xhr({
|
||||||
type: 'GET',
|
type: 'GET',
|
||||||
@ -210,7 +217,10 @@ app.crypto.PGP = function(window, openpgp, util, server) {
|
|||||||
success: function(privKey) {
|
success: function(privKey) {
|
||||||
// import keys
|
// import keys
|
||||||
self.importKeys(pubKey.asciiArmored, privKey.asciiArmored, email);
|
self.importKeys(pubKey.asciiArmored, privKey.asciiArmored, email);
|
||||||
callback({ privateKey:privKey, publicKey:pubKey });
|
callback({
|
||||||
|
privateKey: privKey,
|
||||||
|
publicKey: pubKey
|
||||||
|
});
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
@ -220,7 +230,9 @@ app.crypto.PGP = function(window, openpgp, util, server) {
|
|||||||
* Get the current user's private key
|
* Get the current user's private key
|
||||||
*/
|
*/
|
||||||
self.getPrivateKey = function() {
|
self.getPrivateKey = function() {
|
||||||
if (!privateKey) { return undefined; }
|
if (!privateKey) {
|
||||||
|
return undefined;
|
||||||
|
}
|
||||||
return privateKey.armored;
|
return privateKey.armored;
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -228,7 +240,9 @@ app.crypto.PGP = function(window, openpgp, util, server) {
|
|||||||
* Get the current user's public key
|
* Get the current user's public key
|
||||||
*/
|
*/
|
||||||
self.getPublicKey = function() {
|
self.getPublicKey = function() {
|
||||||
if (!publicKey) { return undefined; }
|
if (!publicKey) {
|
||||||
|
return undefined;
|
||||||
|
}
|
||||||
return publicKey.armored;
|
return publicKey.armored;
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -289,19 +303,25 @@ app.crypto.PGP = function(window, openpgp, util, server) {
|
|||||||
// Find the private (sub)key for the session key of the message
|
// Find the private (sub)key for the session key of the message
|
||||||
for (var i = 0; i < msg[0].sessionKeys.length; i++) {
|
for (var i = 0; i < msg[0].sessionKeys.length; i++) {
|
||||||
if (priv_key[0].privateKeyPacket.publicKey.getKeyId() == msg[0].sessionKeys[i].keyId.bytes) {
|
if (priv_key[0].privateKeyPacket.publicKey.getKeyId() == msg[0].sessionKeys[i].keyId.bytes) {
|
||||||
keymat = { key: priv_key[0], keymaterial: priv_key[0].privateKeyPacket};
|
keymat = {
|
||||||
|
key: priv_key[0],
|
||||||
|
keymaterial: priv_key[0].privateKeyPacket
|
||||||
|
};
|
||||||
sesskey = msg[0].sessionKeys[i];
|
sesskey = msg[0].sessionKeys[i];
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
for (var j = 0; j < priv_key[0].subKeys.length; j++) {
|
for (var j = 0; j < priv_key[0].subKeys.length; j++) {
|
||||||
if (priv_key[0].subKeys[j].publicKey.getKeyId() == msg[0].sessionKeys[i].keyId.bytes) {
|
if (priv_key[0].subKeys[j].publicKey.getKeyId() == msg[0].sessionKeys[i].keyId.bytes) {
|
||||||
keymat = { key: priv_key[0], keymaterial: priv_key[0].subKeys[j]};
|
keymat = {
|
||||||
|
key: priv_key[0],
|
||||||
|
keymaterial: priv_key[0].subKeys[j]
|
||||||
|
};
|
||||||
sesskey = msg[0].sessionKeys[i];
|
sesskey = msg[0].sessionKeys[i];
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (keymat != null) {
|
if (keymat !== null) {
|
||||||
if (!keymat.keymaterial.decryptSecretMPIs(passphrase)) {
|
if (!keymat.keymaterial.decryptSecretMPIs(passphrase)) {
|
||||||
throw "Passphrase for secrect key was incorrect!";
|
throw "Passphrase for secrect key was incorrect!";
|
||||||
}
|
}
|
||||||
@ -316,7 +336,10 @@ app.crypto.PGP = function(window, openpgp, util, server) {
|
|||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
}());
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This function needs to be implemented, since it is used by the openpgp utils
|
* This function needs to be implemented, since it is used by the openpgp utils
|
||||||
*/
|
*/
|
||||||
|
|
||||||
function showMessages(str) {}
|
function showMessages(str) {}
|
@ -1,3 +1,4 @@
|
|||||||
|
(function() {
|
||||||
'use strict';
|
'use strict';
|
||||||
|
|
||||||
app.crypto.Util = function(window, uuid) {
|
app.crypto.Util = function(window, uuid) {
|
||||||
@ -42,7 +43,12 @@ app.crypto.Util = function(window, uuid) {
|
|||||||
// stringify to JSON before encryption
|
// stringify to JSON before encryption
|
||||||
json = JSON.stringify(list[i].plaintext);
|
json = JSON.stringify(list[i].plaintext);
|
||||||
ct = aes.encrypt(json, list[i].key, list[i].iv);
|
ct = aes.encrypt(json, list[i].key, list[i].iv);
|
||||||
outList.push({ id:list[i].id, ciphertext:ct, key:list[i].key, iv:list[i].iv });
|
outList.push({
|
||||||
|
id: list[i].id,
|
||||||
|
ciphertext: ct,
|
||||||
|
key: list[i].key,
|
||||||
|
iv: list[i].iv
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
return outList;
|
return outList;
|
||||||
@ -60,7 +66,12 @@ app.crypto.Util = function(window, uuid) {
|
|||||||
// decrypt JSON and parse to object literal
|
// decrypt JSON and parse to object literal
|
||||||
json = aes.decrypt(list[i].ciphertext, list[i].key, list[i].iv);
|
json = aes.decrypt(list[i].ciphertext, list[i].key, list[i].iv);
|
||||||
pt = JSON.parse(json);
|
pt = JSON.parse(json);
|
||||||
outList.push({ id:list[i].id, plaintext:pt, key:list[i].key, iv:list[i].iv });
|
outList.push({
|
||||||
|
id: list[i].id,
|
||||||
|
plaintext: pt,
|
||||||
|
key: list[i].key,
|
||||||
|
iv: list[i].iv
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
return outList;
|
return outList;
|
||||||
@ -97,7 +108,9 @@ app.crypto.Util = function(window, uuid) {
|
|||||||
*/
|
*/
|
||||||
this.arrBuf2Blob = function(buf, mimeType) {
|
this.arrBuf2Blob = function(buf, mimeType) {
|
||||||
var b = new Uint8Array(buf);
|
var b = new Uint8Array(buf);
|
||||||
var blob = new Blob([b], {type: mimeType});
|
var blob = new Blob([b], {
|
||||||
|
type: mimeType
|
||||||
|
});
|
||||||
|
|
||||||
return blob;
|
return blob;
|
||||||
};
|
};
|
||||||
@ -151,3 +164,5 @@ app.crypto.Util = function(window, uuid) {
|
|||||||
};
|
};
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
}());
|
@ -1,3 +1,4 @@
|
|||||||
|
(function() {
|
||||||
'use strict';
|
'use strict';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -25,7 +26,10 @@ app.dao.CloudStorage = function(window, $) {
|
|||||||
callback(list);
|
callback(list);
|
||||||
},
|
},
|
||||||
error: function(xhr, textStatus, err) {
|
error: function(xhr, textStatus, err) {
|
||||||
callback({error: err, status: textStatus});
|
callback({
|
||||||
|
error: err,
|
||||||
|
status: textStatus
|
||||||
|
});
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
@ -55,7 +59,10 @@ app.dao.CloudStorage = function(window, $) {
|
|||||||
callback();
|
callback();
|
||||||
},
|
},
|
||||||
error: function(xhr, textStatus, err) {
|
error: function(xhr, textStatus, err) {
|
||||||
callback({error: err, status: textStatus});
|
callback({
|
||||||
|
error: err,
|
||||||
|
status: textStatus
|
||||||
|
});
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
@ -78,21 +85,30 @@ app.dao.CloudStorage = function(window, $) {
|
|||||||
success: function(fetchedKey) {
|
success: function(fetchedKey) {
|
||||||
if ((!storedKey || !storedKey.key) && fetchedKey && fetchedKey.encryptedKey && fetchedKey.keyIV) {
|
if ((!storedKey || !storedKey.key) && fetchedKey && fetchedKey.encryptedKey && fetchedKey.keyIV) {
|
||||||
// no local key... persist fetched key
|
// no local key... persist fetched key
|
||||||
keyStore.persist(storageId, { key: fetchedKey.encryptedKey, iv: fetchedKey.keyIV });
|
keyStore.persist(storageId, {
|
||||||
|
key: fetchedKey.encryptedKey,
|
||||||
|
iv: fetchedKey.keyIV
|
||||||
|
});
|
||||||
replaceCallback();
|
replaceCallback();
|
||||||
|
|
||||||
} else if (storedKey && fetchedKey && (storedKey.key !== fetchedKey.encryptedKey || storedKey.iv !== fetchedKey.keyIV)) {
|
} else if (storedKey && fetchedKey && (storedKey.key !== fetchedKey.encryptedKey || storedKey.iv !== fetchedKey.keyIV)) {
|
||||||
// local and fetched keys are not equal
|
// local and fetched keys are not equal
|
||||||
if (confirm('Swap local key?')) {
|
if (confirm('Swap local key?')) {
|
||||||
// replace local key with fetched key
|
// replace local key with fetched key
|
||||||
keyStore.persist(storageId, { key: fetchedKey.encryptedKey, iv: fetchedKey.keyIV });
|
keyStore.persist(storageId, {
|
||||||
|
key: fetchedKey.encryptedKey,
|
||||||
|
iv: fetchedKey.keyIV
|
||||||
|
});
|
||||||
replaceCallback();
|
replaceCallback();
|
||||||
} else {
|
} else {
|
||||||
if (confirm('Swap cloud key?')) {
|
if (confirm('Swap cloud key?')) {
|
||||||
// upload local key to cloud
|
// upload local key to cloud
|
||||||
self.persistUserSecretKey(emailAddress, callback);
|
self.persistUserSecretKey(emailAddress, callback);
|
||||||
} else {
|
} else {
|
||||||
callback({error: 'err', status: 'Key not synced!'});
|
callback({
|
||||||
|
error: 'err',
|
||||||
|
status: 'Key not synced!'
|
||||||
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -102,9 +118,14 @@ app.dao.CloudStorage = function(window, $) {
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
error: function(xhr, textStatus, err) {
|
error: function(xhr, textStatus, err) {
|
||||||
callback({error: err, status: textStatus});
|
callback({
|
||||||
|
error: err,
|
||||||
|
status: textStatus
|
||||||
|
});
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
}());
|
@ -1,3 +1,4 @@
|
|||||||
|
(function() {
|
||||||
'use strict';
|
'use strict';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -27,7 +28,10 @@ app.dao.DeviceStorage = function(util, crypto, jsonDao, sqlcipherDao) {
|
|||||||
key = crypto.emailAddress + '_' + type + '_' + list[i].id;
|
key = crypto.emailAddress + '_' + type + '_' + list[i].id;
|
||||||
}
|
}
|
||||||
|
|
||||||
items.push({ key:key, object:list[i] });
|
items.push({
|
||||||
|
key: key,
|
||||||
|
object: list[i]
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
jsonDao.batch(items, function() {
|
jsonDao.batch(items, function() {
|
||||||
@ -61,3 +65,5 @@ app.dao.DeviceStorage = function(util, crypto, jsonDao, sqlcipherDao) {
|
|||||||
};
|
};
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
}());
|
@ -1,3 +1,4 @@
|
|||||||
|
(function() {
|
||||||
'use strict';
|
'use strict';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -38,7 +39,9 @@ app.dao.EmailDAO = function(_, crypto, devicestorage, cloudstorage) {
|
|||||||
* Fetch an email with the following id
|
* Fetch an email with the following id
|
||||||
*/
|
*/
|
||||||
this.getItem = function(folderName, itemId) {
|
this.getItem = function(folderName, itemId) {
|
||||||
var folder = this.account.get('folders').where({name: folderName})[0];
|
var folder = this.account.get('folders').where({
|
||||||
|
name: folderName
|
||||||
|
})[0];
|
||||||
var mail = _.find(folder.get('items').models, function(email) {
|
var mail = _.find(folder.get('items').models, function(email) {
|
||||||
return email.id + '' === itemId + '';
|
return email.id + '' === itemId + '';
|
||||||
});
|
});
|
||||||
@ -54,7 +57,9 @@ app.dao.EmailDAO = function(_, crypto, devicestorage, cloudstorage) {
|
|||||||
var collection, folder, self = this;
|
var collection, folder, self = this;
|
||||||
|
|
||||||
// check if items are in memory already (account.folders model)
|
// check if items are in memory already (account.folders model)
|
||||||
folder = this.account.get('folders').where({name: folderName})[0];
|
folder = this.account.get('folders').where({
|
||||||
|
name: folderName
|
||||||
|
})[0];
|
||||||
|
|
||||||
if (!folder) {
|
if (!folder) {
|
||||||
// get items from storage
|
// get items from storage
|
||||||
@ -64,7 +69,9 @@ app.dao.EmailDAO = function(_, crypto, devicestorage, cloudstorage) {
|
|||||||
|
|
||||||
// cache collection in folder memory
|
// cache collection in folder memory
|
||||||
if (decryptedList.length > 0) {
|
if (decryptedList.length > 0) {
|
||||||
folder = new app.model.Folder({name: folderName});
|
folder = new app.model.Folder({
|
||||||
|
name: folderName
|
||||||
|
});
|
||||||
folder.set('items', collection);
|
folder.set('items', collection);
|
||||||
self.account.get('folders').add(folder);
|
self.account.get('folders').add(folder);
|
||||||
}
|
}
|
||||||
@ -98,7 +105,9 @@ app.dao.EmailDAO = function(_, crypto, devicestorage, cloudstorage) {
|
|||||||
// persist encrypted list in device storage
|
// persist encrypted list in device storage
|
||||||
devicestorage.storeEcryptedList(res, 'email_' + folderName, function() {
|
devicestorage.storeEcryptedList(res, 'email_' + folderName, function() {
|
||||||
// remove cached folder in account model
|
// remove cached folder in account model
|
||||||
folder = self.account.get('folders').where({name: folderName})[0];
|
folder = self.account.get('folders').where({
|
||||||
|
name: folderName
|
||||||
|
})[0];
|
||||||
if (folder) {
|
if (folder) {
|
||||||
self.account.get('folders').remove(folder);
|
self.account.get('folders').remove(folder);
|
||||||
}
|
}
|
||||||
@ -108,3 +117,5 @@ app.dao.EmailDAO = function(_, crypto, devicestorage, cloudstorage) {
|
|||||||
};
|
};
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
}());
|
@ -1,3 +1,4 @@
|
|||||||
|
(function() {
|
||||||
'use strict';
|
'use strict';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -5,37 +6,38 @@
|
|||||||
*/
|
*/
|
||||||
app.dao.LawnchairDAO = function(window) {
|
app.dao.LawnchairDAO = function(window) {
|
||||||
|
|
||||||
|
var db = new Lawnchair({
|
||||||
|
name: 'data-store'
|
||||||
|
}, function() {});
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Create or update an object
|
* Create or update an object
|
||||||
*/
|
*/
|
||||||
this.persist = function(key, object, callback) {
|
this.persist = function(key, object, callback) {
|
||||||
Lawnchair(function() {
|
db.save({
|
||||||
this.save({ key:key, object:object }, callback);
|
key: key,
|
||||||
});
|
object: object
|
||||||
|
}, callback);
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Persist a bunch of items at once
|
* Persist a bunch of items at once
|
||||||
*/
|
*/
|
||||||
this.batch = function(list, callback) {
|
this.batch = function(list, callback) {
|
||||||
Lawnchair(function() {
|
db.batch(list, callback);
|
||||||
this.batch(list, callback);
|
|
||||||
});
|
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Read a single item by its key
|
* Read a single item by its key
|
||||||
*/
|
*/
|
||||||
this.read = function(key, callback) {
|
this.read = function(key, callback) {
|
||||||
Lawnchair(function() {
|
db.get(key, function(o) {
|
||||||
this.get(key, function(o) {
|
|
||||||
if (o) {
|
if (o) {
|
||||||
callback(o.object);
|
callback(o.object);
|
||||||
} else {
|
} else {
|
||||||
callback(null);
|
callback(null);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
});
|
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -45,13 +47,12 @@ app.dao.LawnchairDAO = function(window) {
|
|||||||
* @param num [Number] The number of items to fetch (null means fetch all)
|
* @param num [Number] The number of items to fetch (null means fetch all)
|
||||||
*/
|
*/
|
||||||
this.list = function(type, offset, num, callback) {
|
this.list = function(type, offset, num, callback) {
|
||||||
var i, list = [], matchingKeys = [], parts, timeStr, time;
|
var i, list = [],
|
||||||
|
matchingKeys = [],
|
||||||
Lawnchair(function() {
|
parts, timeStr, time;
|
||||||
var self = this;
|
|
||||||
|
|
||||||
// get all keys
|
// get all keys
|
||||||
this.keys(function(keys) {
|
db.keys(function(keys) {
|
||||||
|
|
||||||
// check if key begins with type
|
// check if key begins with type
|
||||||
for (i = 0; i < keys.length; i++) {
|
for (i = 0; i < keys.length; i++) {
|
||||||
@ -87,7 +88,7 @@ app.dao.LawnchairDAO = function(window) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// fetch all items from data-store with matching key
|
// fetch all items from data-store with matching key
|
||||||
self.get(matchingKeys, function(matchingList) {
|
db.get(matchingKeys, function(matchingList) {
|
||||||
for (i = 0; i < matchingList.length; i++) {
|
for (i = 0; i < matchingList.length; i++) {
|
||||||
list.push(matchingList[i].object);
|
list.push(matchingList[i].object);
|
||||||
}
|
}
|
||||||
@ -97,25 +98,22 @@ app.dao.LawnchairDAO = function(window) {
|
|||||||
});
|
});
|
||||||
|
|
||||||
});
|
});
|
||||||
});
|
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Removes an object liter from local storage by its key (delete)
|
* Removes an object liter from local storage by its key (delete)
|
||||||
*/
|
*/
|
||||||
this.remove = function(key, callback) {
|
this.remove = function(key, callback) {
|
||||||
Lawnchair(function() {
|
db.remove(key, callback);
|
||||||
this.remove(key, callback);
|
|
||||||
});
|
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Clears the whole local storage cache
|
* Clears the whole local storage cache
|
||||||
*/
|
*/
|
||||||
this.clear = function(callback) {
|
this.clear = function(callback) {
|
||||||
Lawnchair(function() {
|
db.nuke(callback);
|
||||||
this.nuke(callback);
|
|
||||||
});
|
|
||||||
};
|
};
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
}());
|
@ -1,3 +1,4 @@
|
|||||||
|
(function() {
|
||||||
'use strict';
|
'use strict';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -54,3 +55,5 @@ app.dao.LocalStorageDAO = function(window) {
|
|||||||
};
|
};
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
}());
|
@ -1,3 +1,4 @@
|
|||||||
|
(function() {
|
||||||
'use strict';
|
'use strict';
|
||||||
|
|
||||||
app.model.Account = Backbone.Model.extend({
|
app.model.Account = Backbone.Model.extend({
|
||||||
@ -19,7 +20,8 @@ app.model.AccountCollection = Backbone.Collection.extend({
|
|||||||
|
|
||||||
model: app.model.Account,
|
model: app.model.Account,
|
||||||
|
|
||||||
findByName: function (key) {
|
findByName: function(key) {}
|
||||||
}
|
|
||||||
|
|
||||||
});
|
});
|
||||||
|
|
||||||
|
}());
|
@ -1,3 +1,4 @@
|
|||||||
|
(function() {
|
||||||
'use strict';
|
'use strict';
|
||||||
|
|
||||||
app.model.Email = Backbone.Model.extend({
|
app.model.Email = Backbone.Model.extend({
|
||||||
@ -29,7 +30,8 @@ app.model.EmailCollection = Backbone.Collection.extend({
|
|||||||
|
|
||||||
model: app.model.Email,
|
model: app.model.Email,
|
||||||
|
|
||||||
findByName: function (key) {
|
findByName: function(key) {}
|
||||||
}
|
|
||||||
|
|
||||||
});
|
});
|
||||||
|
|
||||||
|
}());
|
@ -1,3 +1,4 @@
|
|||||||
|
(function() {
|
||||||
'use strict';
|
'use strict';
|
||||||
|
|
||||||
app.model.Folder = Backbone.Model.extend({
|
app.model.Folder = Backbone.Model.extend({
|
||||||
@ -7,8 +8,7 @@ app.model.Folder = Backbone.Model.extend({
|
|||||||
items: null
|
items: null
|
||||||
},
|
},
|
||||||
|
|
||||||
initialize: function () {
|
initialize: function() {}
|
||||||
}
|
|
||||||
|
|
||||||
});
|
});
|
||||||
|
|
||||||
@ -16,7 +16,8 @@ app.model.FolderCollection = Backbone.Collection.extend({
|
|||||||
|
|
||||||
model: app.model.Folder,
|
model: app.model.Folder,
|
||||||
|
|
||||||
findByName: function (key) {
|
findByName: function(key) {}
|
||||||
}
|
|
||||||
|
|
||||||
});
|
});
|
||||||
|
|
||||||
|
}());
|
@ -1,3 +1,4 @@
|
|||||||
|
(function() {
|
||||||
'use strict';
|
'use strict';
|
||||||
|
|
||||||
app.view.AccountsView = Backbone.View.extend({
|
app.view.AccountsView = Backbone.View.extend({
|
||||||
@ -11,3 +12,5 @@ app.view.AccountsView = Backbone.View.extend({
|
|||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
}());
|
@ -1,3 +1,4 @@
|
|||||||
|
(function() {
|
||||||
'use strict';
|
'use strict';
|
||||||
|
|
||||||
app.view.ComposeView = Backbone.View.extend({
|
app.view.ComposeView = Backbone.View.extend({
|
||||||
@ -11,3 +12,5 @@ app.view.ComposeView = Backbone.View.extend({
|
|||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
}());
|
@ -1,3 +1,4 @@
|
|||||||
|
(function() {
|
||||||
'use strict';
|
'use strict';
|
||||||
|
|
||||||
app.view.FolderListView = Backbone.View.extend({
|
app.view.FolderListView = Backbone.View.extend({
|
||||||
@ -21,3 +22,5 @@ app.view.FolderListView = Backbone.View.extend({
|
|||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
}());
|
@ -1,3 +1,4 @@
|
|||||||
|
(function() {
|
||||||
'use strict';
|
'use strict';
|
||||||
|
|
||||||
app.view.LoginView = Backbone.View.extend({
|
app.view.LoginView = Backbone.View.extend({
|
||||||
@ -8,7 +9,8 @@ app.view.LoginView = Backbone.View.extend({
|
|||||||
},
|
},
|
||||||
|
|
||||||
render: function(eventName) {
|
render: function(eventName) {
|
||||||
var self = this, page = $(this.el);
|
var self = this,
|
||||||
|
page = $(this.el);
|
||||||
|
|
||||||
page.html(this.template());
|
page.html(this.template());
|
||||||
page.attr('data-theme', 'a');
|
page.attr('data-theme', 'a');
|
||||||
@ -32,10 +34,16 @@ app.view.LoginView = Backbone.View.extend({
|
|||||||
});
|
});
|
||||||
|
|
||||||
// show loading msg during init
|
// show loading msg during init
|
||||||
$.mobile.loading('show', { text: 'Unlocking...', textVisible: true, theme: 'c' });
|
$.mobile.loading('show', {
|
||||||
|
text: 'Unlocking...',
|
||||||
|
textVisible: true,
|
||||||
|
theme: 'c'
|
||||||
|
});
|
||||||
this.dao.init(account, password, function() {
|
this.dao.init(account, password, function() {
|
||||||
$.mobile.loading('hide');
|
$.mobile.loading('hide');
|
||||||
window.location = '#accounts/' + account.get('emailAddress') + '/folders';
|
window.location = '#accounts/' + account.get('emailAddress') + '/folders';
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
}());
|
@ -1,3 +1,4 @@
|
|||||||
|
(function() {
|
||||||
'use strict';
|
'use strict';
|
||||||
|
|
||||||
app.view.MessageListView = Backbone.View.extend({
|
app.view.MessageListView = Backbone.View.extend({
|
||||||
@ -27,7 +28,10 @@ app.view.MessageListView = Backbone.View.extend({
|
|||||||
syncFolder: function() {
|
syncFolder: function() {
|
||||||
var self = this;
|
var self = this;
|
||||||
|
|
||||||
$.mobile.loading('show', { text: 'Syncing...', textVisible: true });
|
$.mobile.loading('show', {
|
||||||
|
text: 'Syncing...',
|
||||||
|
textVisible: true
|
||||||
|
});
|
||||||
// sync from cloud
|
// sync from cloud
|
||||||
this.dao.syncFromCloud(this.folder, function(res) {
|
this.dao.syncFromCloud(this.folder, function(res) {
|
||||||
$.mobile.loading('hide');
|
$.mobile.loading('hide');
|
||||||
@ -52,7 +56,10 @@ app.view.MessageListView = Backbone.View.extend({
|
|||||||
list = page.find('#message-list'),
|
list = page.find('#message-list'),
|
||||||
listItemArgs, i, email;
|
listItemArgs, i, email;
|
||||||
|
|
||||||
$.mobile.loading('show', { text: 'decrypting...', textVisible: true });
|
$.mobile.loading('show', {
|
||||||
|
text: 'decrypting...',
|
||||||
|
textVisible: true
|
||||||
|
});
|
||||||
this.dao.listItems(this.folder, 0, 10, function(collection) {
|
this.dao.listItems(this.folder, 0, 10, function(collection) {
|
||||||
// clear list
|
// clear list
|
||||||
list.html('');
|
list.html('');
|
||||||
@ -60,7 +67,11 @@ app.view.MessageListView = Backbone.View.extend({
|
|||||||
// append items to list in reverse order so mails with the most recent date will be displayed first
|
// append items to list in reverse order so mails with the most recent date will be displayed first
|
||||||
for (i = collection.models.length - 1; i >= 0; i--) {
|
for (i = collection.models.length - 1; i >= 0; i--) {
|
||||||
email = collection.at(i);
|
email = collection.at(i);
|
||||||
listItemArgs = {account: self.options.account, folder: self.folder, model: email};
|
listItemArgs = {
|
||||||
|
account: self.options.account,
|
||||||
|
folder: self.folder,
|
||||||
|
model: email
|
||||||
|
};
|
||||||
list.append(new app.view.MessageListItemView(listItemArgs).render().el);
|
list.append(new app.view.MessageListItemView(listItemArgs).render().el);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -71,3 +82,5 @@ app.view.MessageListView = Backbone.View.extend({
|
|||||||
}
|
}
|
||||||
|
|
||||||
});
|
});
|
||||||
|
|
||||||
|
}());
|
@ -1,3 +1,4 @@
|
|||||||
|
(function() {
|
||||||
'use strict';
|
'use strict';
|
||||||
|
|
||||||
app.view.MessageListItemView = Backbone.View.extend({
|
app.view.MessageListItemView = Backbone.View.extend({
|
||||||
@ -22,3 +23,5 @@ app.view.MessageListItemView = Backbone.View.extend({
|
|||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
}());
|
@ -1,3 +1,4 @@
|
|||||||
|
(function() {
|
||||||
'use strict';
|
'use strict';
|
||||||
|
|
||||||
app.view.ReadView = Backbone.View.extend({
|
app.view.ReadView = Backbone.View.extend({
|
||||||
@ -30,3 +31,5 @@ app.view.ReadView = Backbone.View.extend({
|
|||||||
}
|
}
|
||||||
|
|
||||||
});
|
});
|
||||||
|
|
||||||
|
}());
|
Loading…
Reference in New Issue
Block a user