mirror of
https://github.com/moparisthebest/mail
synced 2024-11-22 08:52:15 -05:00
refactored folder structure
This commit is contained in:
parent
13ee758c8d
commit
5ee864fe01
10
README.md
10
README.md
@ -1,4 +1,12 @@
|
||||
html5-mail
|
||||
==========
|
||||
|
||||
HTML5 Mail App with Client-side Encryption
|
||||
HTML5 Mail App with Client-side Encryption
|
||||
|
||||
## Getting started
|
||||
Required packages: nodejs, npm
|
||||
|
||||
npm install express
|
||||
node server.js 8080 --dev
|
||||
|
||||
browse to http://localhost:8080
|
@ -1,32 +0,0 @@
|
||||
/**
|
||||
* A simple development server for serving static files using node.js
|
||||
* Required packages: nodejs, npm
|
||||
* 1. npm install express
|
||||
* 2. node dev_server.js 8080
|
||||
* 3. browse to http://localhost:8080
|
||||
*/
|
||||
|
||||
var express = require('express'),
|
||||
port, app;
|
||||
|
||||
// set port
|
||||
if (process.argv[2]) {
|
||||
port = process.argv[2];
|
||||
} else {
|
||||
port = 8080;
|
||||
}
|
||||
|
||||
// Server setup
|
||||
app = express();
|
||||
app.configure(function(){
|
||||
app.use(express['static'](__dirname));
|
||||
app.use(function(req, res, next) {
|
||||
res.set('Content-Security-Policy', "script-src 'self' 'unsafe-eval'; object-src 'none'; style-src 'self' 'unsafe-inline'");
|
||||
return next();
|
||||
});
|
||||
app.use(express['static'](__dirname + '/src'));
|
||||
});
|
||||
|
||||
// start server
|
||||
app.listen(port);
|
||||
console.log(' > listening on http://localhost:' + port);
|
@ -1,15 +0,0 @@
|
||||
{
|
||||
"name": "Whiteout",
|
||||
"description": "HTML5 Mail with an encrypted message store both locally and in the cloud",
|
||||
"launch_path": "/html5-mail/src/",
|
||||
"icons": {
|
||||
"128": "/html5-mail/src/css/images/key-128.png"
|
||||
},
|
||||
"developer": {
|
||||
"name": "Whiteout Networks GmbH",
|
||||
"url": "http://whiteout.io"
|
||||
},
|
||||
"appcache_path": "/html5-mail/src/manifest.appcache",
|
||||
"csp": "script-src 'self' 'unsafe-eval'; object-src 'none'; style-src 'self' 'unsafe-inline'",
|
||||
"default_locale": "en"
|
||||
}
|
49
server.js
Normal file
49
server.js
Normal file
@ -0,0 +1,49 @@
|
||||
/**
|
||||
* A simple server for serving static files using node.js
|
||||
*/
|
||||
|
||||
var express = require('express'),
|
||||
fs = require('fs'),
|
||||
port, app, prot, dev;
|
||||
|
||||
// set port
|
||||
if (process.argv[2]) {
|
||||
port = process.argv[2];
|
||||
} else {
|
||||
port = 8080;
|
||||
}
|
||||
|
||||
if (process.argv[3] === '--dev') {
|
||||
// development server
|
||||
dev = true;
|
||||
prot = 'http';
|
||||
app = express();
|
||||
} else {
|
||||
// production server
|
||||
dev = false;
|
||||
prot = 'https';
|
||||
app = express({
|
||||
ca: fs.readFileSync('./ssl/sub.class1.server.ca.pem'),
|
||||
key: fs.readFileSync('./ssl/ssl.key'),
|
||||
cert: fs.readFileSync('./ssl/ssl.crt')
|
||||
});
|
||||
}
|
||||
|
||||
// Server setup
|
||||
app.configure(function() {
|
||||
// active content security policy for production
|
||||
if (!dev) {
|
||||
app.use(function(req, res, next) {
|
||||
var csp = "script-src 'self' 'unsafe-eval'; object-src 'none'; style-src 'self' 'unsafe-inline'";
|
||||
res.set('Content-Security-Policy', csp);
|
||||
res.set('X-Content-Security-Policy', csp);
|
||||
res.set('X-WebKit-CSP', csp);
|
||||
return next();
|
||||
});
|
||||
}
|
||||
app.use(express['static'](__dirname + '/src'));
|
||||
});
|
||||
|
||||
// start server
|
||||
app.listen(port);
|
||||
console.log(' > listening on ' + prot + '://localhost:' + port);
|
@ -1,23 +1,28 @@
|
||||
'use strict';
|
||||
var app;
|
||||
|
||||
/**
|
||||
* Create the application namespace
|
||||
*/
|
||||
var app = {
|
||||
model: {},
|
||||
view: {},
|
||||
dao: {},
|
||||
crypto:{},
|
||||
util: {}
|
||||
};
|
||||
(function() {
|
||||
'use strict';
|
||||
|
||||
/**
|
||||
* Global app configurations
|
||||
*/
|
||||
app.config = {
|
||||
cloudUrl: 'https://whiteout-io.appspot.com',
|
||||
symKeySize: 128,
|
||||
symIvSize: 104,
|
||||
asymKeySize: 2048,
|
||||
workerPath: 'js'
|
||||
};
|
||||
/**
|
||||
* Create the application namespace
|
||||
*/
|
||||
app = {
|
||||
model: {},
|
||||
view: {},
|
||||
dao: {},
|
||||
crypto: {},
|
||||
util: {}
|
||||
};
|
||||
|
||||
/**
|
||||
* Global app configurations
|
||||
*/
|
||||
app.config = {
|
||||
cloudUrl: 'https://whiteout-io.appspot.com',
|
||||
symKeySize: 128,
|
||||
symIvSize: 104,
|
||||
asymKeySize: 2048,
|
||||
workerPath: 'js'
|
||||
};
|
||||
|
||||
}());
|
@ -1,79 +1,92 @@
|
||||
'use strict';
|
||||
(function() {
|
||||
'use strict';
|
||||
|
||||
var AppRouter = Backbone.Router.extend({
|
||||
app.Router = Backbone.Router.extend({
|
||||
|
||||
routes:{
|
||||
'': 'login',
|
||||
'compose': 'compose',
|
||||
'accounts/:userId/folders': 'folders',
|
||||
'accounts/:userId/folders/:folder': 'messagelist',
|
||||
'accounts/:userId/folders/:folder/read/:messageId': 'read'
|
||||
},
|
||||
routes: {
|
||||
'': 'login',
|
||||
'compose': 'compose',
|
||||
'accounts/:userId/folders': 'folders',
|
||||
'accounts/:userId/folders/:folder': 'messagelist',
|
||||
'accounts/:userId/folders/:folder/read/:messageId': 'read'
|
||||
},
|
||||
|
||||
initialize: function () {
|
||||
},
|
||||
|
||||
login: function() {
|
||||
// init email dao and dependencies
|
||||
var util = new app.crypto.Util(window, null);
|
||||
var jsonDao = new app.dao.LawnchairDAO(window);
|
||||
var crypto = new app.crypto.Crypto(window, util);
|
||||
var cloudstorage = new app.dao.CloudStorage(window, $);
|
||||
var devicestorage = new app.dao.DeviceStorage(util, crypto, jsonDao, null);
|
||||
this.emailDao = new app.dao.EmailDAO(_, crypto, devicestorage, cloudstorage);
|
||||
|
||||
var loginView = new app.view.LoginView({dao: this.emailDao});
|
||||
this.changePage(loginView);
|
||||
},
|
||||
|
||||
compose: function() {
|
||||
var composeView = new app.view.ComposeView();
|
||||
this.changePage(composeView);
|
||||
},
|
||||
|
||||
folders: function(userId) {
|
||||
var folderListView = new app.view.FolderListView({account: userId});
|
||||
this.changePage(folderListView);
|
||||
},
|
||||
|
||||
messagelist: function(userId, folder) {
|
||||
var self = this;
|
||||
var messageListView = new app.view.MessageListView({account: userId, folder: folder, dao: this.emailDao});
|
||||
self.changePage(messageListView);
|
||||
messageListView.loadItems();
|
||||
},
|
||||
|
||||
read: function(userId, folder, messageId) {
|
||||
var readView = new app.view.ReadView({
|
||||
folder: folder,
|
||||
messageId: decodeURIComponent(messageId),
|
||||
dao: this.emailDao
|
||||
});
|
||||
this.changePage(readView);
|
||||
readView.renderBody();
|
||||
},
|
||||
initialize: function() {},
|
||||
|
||||
changePage: function (page) {
|
||||
// render the page and append it to the DOM
|
||||
var pageEl = $(page.el);
|
||||
pageEl.attr('data-role', 'page');
|
||||
page.render();
|
||||
$('body').append(pageEl);
|
||||
|
||||
// handle back click
|
||||
pageEl.on('vmousedown', '#backBtn', function(e) {
|
||||
e.preventDefault();
|
||||
window.history.back();
|
||||
});
|
||||
|
||||
// change page for link buttons on vmousedown instead of waiting on vmouseup
|
||||
pageEl.on('vmousedown', 'a[data-role="button"]', function(e) {
|
||||
e.preventDefault();
|
||||
var href = $(e.currentTarget).attr('href');
|
||||
window.location = href;
|
||||
});
|
||||
|
||||
$.mobile.changePage(pageEl, {changeHash:false, reverse:false});
|
||||
}
|
||||
login: function() {
|
||||
// init email dao and dependencies
|
||||
var util = new app.crypto.Util(window, null);
|
||||
var jsonDao = new app.dao.LawnchairDAO(window);
|
||||
var crypto = new app.crypto.Crypto(window, util);
|
||||
var cloudstorage = new app.dao.CloudStorage(window, $);
|
||||
var devicestorage = new app.dao.DeviceStorage(util, crypto, jsonDao, null);
|
||||
this.emailDao = new app.dao.EmailDAO(_, crypto, devicestorage, cloudstorage);
|
||||
|
||||
});
|
||||
var loginView = new app.view.LoginView({
|
||||
dao: this.emailDao
|
||||
});
|
||||
this.changePage(loginView);
|
||||
},
|
||||
|
||||
compose: function() {
|
||||
var composeView = new app.view.ComposeView();
|
||||
this.changePage(composeView);
|
||||
},
|
||||
|
||||
folders: function(userId) {
|
||||
var folderListView = new app.view.FolderListView({
|
||||
account: userId
|
||||
});
|
||||
this.changePage(folderListView);
|
||||
},
|
||||
|
||||
messagelist: function(userId, folder) {
|
||||
var self = this;
|
||||
var messageListView = new app.view.MessageListView({
|
||||
account: userId,
|
||||
folder: folder,
|
||||
dao: this.emailDao
|
||||
});
|
||||
self.changePage(messageListView);
|
||||
messageListView.loadItems();
|
||||
},
|
||||
|
||||
read: function(userId, folder, messageId) {
|
||||
var readView = new app.view.ReadView({
|
||||
folder: folder,
|
||||
messageId: decodeURIComponent(messageId),
|
||||
dao: this.emailDao
|
||||
});
|
||||
this.changePage(readView);
|
||||
readView.renderBody();
|
||||
},
|
||||
|
||||
changePage: function(page) {
|
||||
// render the page and append it to the DOM
|
||||
var pageEl = $(page.el);
|
||||
pageEl.attr('data-role', 'page');
|
||||
page.render();
|
||||
$('body').append(pageEl);
|
||||
|
||||
// handle back click
|
||||
pageEl.on('vmousedown', '#backBtn', function(e) {
|
||||
e.preventDefault();
|
||||
window.history.back();
|
||||
});
|
||||
|
||||
// change page for link buttons on vmousedown instead of waiting on vmouseup
|
||||
pageEl.on('vmousedown', 'a[data-role="button"]', function(e) {
|
||||
e.preventDefault();
|
||||
var href = $(e.currentTarget).attr('href');
|
||||
window.location = href;
|
||||
});
|
||||
|
||||
$.mobile.changePage(pageEl, {
|
||||
changeHash: false,
|
||||
reverse: false
|
||||
});
|
||||
}
|
||||
|
||||
});
|
||||
|
||||
}());
|
@ -1,15 +1,18 @@
|
||||
'use strict';
|
||||
(function() {
|
||||
'use strict';
|
||||
|
||||
$(document).on('mobileinit', function () {
|
||||
console.log('mobileinit');
|
||||
$.mobile.ajaxEnabled = false;
|
||||
$.mobile.linkBindingEnabled = false;
|
||||
$.mobile.hashListeningEnabled = false;
|
||||
$.mobile.pushStateEnabled = false;
|
||||
$.mobile.defaultPageTransition = 'none';
|
||||
$(document).on('mobileinit', function() {
|
||||
console.log('mobileinit');
|
||||
$.mobile.ajaxEnabled = false;
|
||||
$.mobile.linkBindingEnabled = false;
|
||||
$.mobile.hashListeningEnabled = false;
|
||||
$.mobile.pushStateEnabled = false;
|
||||
$.mobile.defaultPageTransition = 'none';
|
||||
|
||||
// Remove page from DOM when it's being replaced
|
||||
$(document).on('pagehide', 'div[data-role="page"]', function (event, ui) {
|
||||
$(event.currentTarget).remove();
|
||||
// Remove page from DOM when it's being replaced
|
||||
$(document).on('pagehide', 'div[data-role="page"]', function(event, ui) {
|
||||
$(event.currentTarget).remove();
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
}());
|
124
src/js/loader.js
124
src/js/loader.js
@ -1,69 +1,71 @@
|
||||
'use strict';
|
||||
(function() {
|
||||
'use strict';
|
||||
|
||||
/**
|
||||
* The Template Loader. Used to asynchronously load templates located in separate .html files
|
||||
*/
|
||||
app.util.tpl = {
|
||||
/**
|
||||
* The Template Loader. Used to asynchronously load templates located in separate .html files
|
||||
*/
|
||||
app.util.tpl = {
|
||||
|
||||
// Hash of preloaded templates for the app
|
||||
templates:{},
|
||||
// Hash of preloaded templates for the app
|
||||
templates: {},
|
||||
|
||||
// Recursively pre-load all the templates for the app.
|
||||
loadTemplates:function (names, callback) {
|
||||
var that = this;
|
||||
// Recursively pre-load all the templates for the app.
|
||||
loadTemplates: function(names, callback) {
|
||||
var that = this;
|
||||
|
||||
var loadTemplate = function (index) {
|
||||
var name = names[index];
|
||||
console.log('Loading template: ' + name);
|
||||
$.get('tpl/' + name + '.html', function (data) {
|
||||
that.templates[name] = data;
|
||||
index++;
|
||||
if (index < names.length) {
|
||||
loadTemplate(index);
|
||||
} else {
|
||||
callback();
|
||||
}
|
||||
});
|
||||
};
|
||||
var loadTemplate = function(index) {
|
||||
var name = names[index];
|
||||
console.log('Loading template: ' + name);
|
||||
$.get('tpl/' + name + '.html', function(data) {
|
||||
that.templates[name] = data;
|
||||
index++;
|
||||
if (index < names.length) {
|
||||
loadTemplate(index);
|
||||
} else {
|
||||
callback();
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
loadTemplate(0);
|
||||
},
|
||||
loadTemplate(0);
|
||||
},
|
||||
|
||||
// Get template by name from hash of preloaded templates
|
||||
get:function (name) {
|
||||
return this.templates[name];
|
||||
}
|
||||
// Get template by name from hash of preloaded templates
|
||||
get: function(name) {
|
||||
return this.templates[name];
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
/**
|
||||
* Load templates and start the application
|
||||
*/
|
||||
$(document).ready(function() {
|
||||
// are we running in native app or in browser?
|
||||
var isBrowser = false;
|
||||
if(document.URL.indexOf("http://") !== -1) {
|
||||
isBrowser = true;
|
||||
}
|
||||
|
||||
if(!isBrowser) {
|
||||
document.addEventListener("deviceready", onDeviceReady, false);
|
||||
} else {
|
||||
onDeviceReady();
|
||||
}
|
||||
|
||||
function onDeviceReady() {
|
||||
console.log('Starting in Browser: ' + isBrowser);
|
||||
app.util.tpl.loadTemplates([
|
||||
'login',
|
||||
'compose',
|
||||
'folderlist',
|
||||
'messagelist',
|
||||
'messagelistitem',
|
||||
'read'
|
||||
], function () {
|
||||
var router = new AppRouter();
|
||||
Backbone.history.start();
|
||||
});
|
||||
};
|
||||
});
|
||||
|
||||
/**
|
||||
* Load templates and start the application
|
||||
*/
|
||||
$(document).ready(function() {
|
||||
// are we running in native app or in browser?
|
||||
var isBrowser = false;
|
||||
if (document.URL.indexOf("http://") !== -1) {
|
||||
isBrowser = true;
|
||||
}
|
||||
|
||||
if (!isBrowser) {
|
||||
document.addEventListener("deviceready", onDeviceReady, false);
|
||||
} else {
|
||||
onDeviceReady();
|
||||
}
|
||||
|
||||
function onDeviceReady() {
|
||||
console.log('Starting in Browser: ' + isBrowser);
|
||||
app.util.tpl.loadTemplates([
|
||||
'login',
|
||||
'compose',
|
||||
'folderlist',
|
||||
'messagelist',
|
||||
'messagelistitem',
|
||||
'read'], function() {
|
||||
var router = new app.Router();
|
||||
Backbone.history.start();
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
}());
|
15
src/manifest.webapp
Normal file
15
src/manifest.webapp
Normal file
@ -0,0 +1,15 @@
|
||||
{
|
||||
"name": "Whiteout",
|
||||
"description": "HTML5 Mail with an encrypted message store both locally and in the cloud",
|
||||
"launch_path": "/html5-mail/src/",
|
||||
"icons": {
|
||||
"128": "/html5-mail/src/css/images/key-128.png"
|
||||
},
|
||||
"developer": {
|
||||
"name": "Whiteout Networks GmbH",
|
||||
"url": "http://whiteout.io"
|
||||
},
|
||||
"appcache_path": "/html5-mail/src/manifest.appcache",
|
||||
"csp": "script-src 'self' 'unsafe-eval'; object-src 'none'; style-src 'self' 'unsafe-inline'",
|
||||
"default_locale": "en"
|
||||
}
|
@ -7,19 +7,19 @@ var cloudstoragedao_test = {
|
||||
ivSize: 104
|
||||
};
|
||||
|
||||
asyncTest("Init", 1, function() {
|
||||
asyncTest("Init", 1, function() {
|
||||
// init dependencies
|
||||
var util = new app.crypto.Util(window, uuid);
|
||||
var jsonDao = new app.dao.LawnchairDAO(window);
|
||||
cloudstoragedao_test.crypto = new app.crypto.Crypto(window, util);
|
||||
cloudstoragedao_test.storage = new app.dao.DeviceStorage(cloudstoragedao_test.crypto, jsonDao, null);
|
||||
cloudstoragedao_test.storage = new app.dao.DeviceStorage(util, cloudstoragedao_test.crypto, jsonDao, null);
|
||||
cloudstoragedao_test.cloudstorage = new app.dao.CloudStorage(window, $);
|
||||
cloudstoragedao_test.emailDao = new app.dao.EmailDAO(_, cloudstoragedao_test.crypto, cloudstoragedao_test.storage, cloudstoragedao_test.cloudstorage);
|
||||
|
||||
|
||||
// clear db before tests
|
||||
jsonDao.clear(function(err) {
|
||||
ok(!err, 'DB cleared. Error status: ' + err);
|
||||
|
||||
|
||||
start();
|
||||
});
|
||||
});
|
||||
@ -28,7 +28,7 @@ asyncTest("Init", 1, function() {
|
||||
asyncTest("Get user secret key from cloud", 1, function() {
|
||||
cloudstoragedao_test.cloudstorage.getUserSecretKey(cloudstoragedao_test.user, function(err) {
|
||||
ok(!err, 'Get/Sync key from cloud');
|
||||
|
||||
|
||||
start();
|
||||
}, function() {
|
||||
cloudstoragedao_test.storage.clear(function(err) {
|
||||
@ -42,21 +42,21 @@ asyncTest("Get user secret key from cloud", 1, function() {
|
||||
asyncTest("Persist user secret key to cloud", 1, function() {
|
||||
cloudstoragedao_test.cloudstorage.persistUserSecretKey(cloudstoragedao_test.user, function(err) {
|
||||
ok(!err, 'Persist key to cloud');
|
||||
|
||||
|
||||
start();
|
||||
});
|
||||
});
|
||||
|
||||
asyncTest("Sync emails from cloud", 3, function() {
|
||||
|
||||
|
||||
var account = new app.model.Account({
|
||||
emailAddress: cloudstoragedao_test.user,
|
||||
symKeySize: cloudstoragedao_test.keySize,
|
||||
symIvSize: cloudstoragedao_test.ivSize
|
||||
});
|
||||
|
||||
|
||||
cloudstoragedao_test.emailDao.init(account, cloudstoragedao_test.password, function() {
|
||||
ok(true, 'Init complete');
|
||||
ok(true, 'Init complete');
|
||||
|
||||
cloudstoragedao_test.emailDao.syncFromCloud('inbox', function(res) {
|
||||
ok(!res, 'Synced items');
|
74
src/test/integration/index.html
Normal file
74
src/test/integration/index.html
Normal file
@ -0,0 +1,74 @@
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<title>JavaScript Integration Tests</title>
|
||||
<link rel="stylesheet" href="../qunit-1.11.0.css">
|
||||
</head>
|
||||
<body>
|
||||
<div id="qunit"></div>
|
||||
<div id="qunit-fixture"></div>
|
||||
|
||||
<script>
|
||||
// clear session storage of failed tests, so async order is correct after fail & refresh
|
||||
window.sessionStorage.clear();
|
||||
</script>
|
||||
|
||||
<!-- dependencies -->
|
||||
<script src="../../lib/cordova-2.5.0.js"></script>
|
||||
<script src="../qunit-1.11.0.js"></script>
|
||||
<script src="../../lib/jquery-1.8.2.min.js"></script>
|
||||
<script src="../../lib/underscore-1.4.4.min.js"></script>
|
||||
<script src="../../lib/backbone-0.9.10.min.js"></script>
|
||||
<script src="../../lib/lawnchair/lawnchair-git.min.js"></script>
|
||||
<script src="../../lib/lawnchair/lawnchair-adapter-indexed-db-git.js"></script>
|
||||
<script src="../../lib/lawnchair/lawnchair-adapter-webkit-sqlite-git.js"></script>
|
||||
|
||||
<script src="../../lib/crypto-js/core.js"></script>
|
||||
<script src="../../lib/crypto-js/enc-base64.js"></script>
|
||||
<script src="../../lib/crypto-js/cipher-core.js"></script>
|
||||
<script src="../../lib/crypto-js/aes.js"></script>
|
||||
<script src="../../lib/crypto-js/sha1.js"></script>
|
||||
<script src="../../lib/crypto-js/hmac.js"></script>
|
||||
<script src="../../lib/crypto-js/pbkdf2.js"></script>
|
||||
|
||||
<script src="../../lib/sjcl/sjcl.js"></script>
|
||||
<script src="../../lib/sjcl/sha256.js"></script>
|
||||
<script src="../../lib/sjcl/random.js"></script>
|
||||
<script src="../../lib/sjcl/bitArray.js"></script>
|
||||
<script src="../../lib/sjcl/codecBase64.js"></script>
|
||||
<script src="../../lib/sjcl/codecString.js"></script>
|
||||
<script src="../../lib/sjcl/aes.js"></script>
|
||||
<script src="../../lib/sjcl/ccm.js"></script>
|
||||
|
||||
<script src="../../lib/uuid.js"></script>
|
||||
<script src="../../lib/openpgp.min.js"></script>
|
||||
|
||||
<script src="../../js/app-config.js"></script>
|
||||
<script>
|
||||
app.config.workerPath = '../../js';
|
||||
app.config.cloudUrl = 'http://localhost:8888';
|
||||
</script>
|
||||
|
||||
<script src="../../js/model/email-model.js"></script>
|
||||
<script src="../../js/model/folder-model.js"></script>
|
||||
<script src="../../js/model/account-model.js"></script>
|
||||
|
||||
<script src="../../js/crypto/util.js"></script>
|
||||
<script src="../../js/crypto/pbkdf2.js"></script>
|
||||
<script src="../../js/crypto/aes-cbc.js"></script>
|
||||
<script src="../../js/crypto/aes-ccm.js"></script>
|
||||
<script src="../../js/crypto/aes-gcm.js"></script>
|
||||
<script src="../../js/crypto/crypto.js"></script>
|
||||
|
||||
<script src="../../js/dao/localstorage-dao.js"></script>
|
||||
<script src="../../js/dao/lawnchair-dao.js"></script>
|
||||
<script src="../../js/dao/devicestorage.js"></script>
|
||||
<script src="../../js/dao/cloudstorage-dao.js"></script>
|
||||
<script src="../../js/dao/email-dao.js"></script>
|
||||
|
||||
<!-- tests -->
|
||||
<script src="cloudstorage-dao-test.js"></script>
|
||||
|
||||
</body>
|
||||
</html>
|
@ -7,7 +7,7 @@ var emaildao_test = {
|
||||
ivSize: 104
|
||||
};
|
||||
|
||||
asyncTest("Init", 2, function() {
|
||||
asyncTest("Init", 2, function() {
|
||||
// init dependencies
|
||||
var util = new app.crypto.Util(window, uuid);
|
||||
var jsonDao = new app.dao.LawnchairDAO(window);
|
||||
@ -15,55 +15,57 @@ asyncTest("Init", 2, function() {
|
||||
emaildao_test.storage = new app.dao.DeviceStorage(util, emaildao_test.crypto, jsonDao, null);
|
||||
// cloud storage stub
|
||||
var cloudstorageStub = {
|
||||
getUserSecretKey: function(emailAdress, callback) { callback(); }
|
||||
getUserSecretKey: function(emailAdress, callback) {
|
||||
callback();
|
||||
}
|
||||
};
|
||||
emaildao_test.emailDao = new app.dao.EmailDAO(_, emaildao_test.crypto, emaildao_test.storage, cloudstorageStub);
|
||||
|
||||
|
||||
// generate test data
|
||||
emaildao_test.list = new TestData().getEmailCollection(100);
|
||||
|
||||
|
||||
var account = new app.model.Account({
|
||||
emailAddress: emaildao_test.user,
|
||||
symKeySize: emaildao_test.keySize,
|
||||
symIvSize: emaildao_test.ivSize
|
||||
});
|
||||
|
||||
|
||||
emaildao_test.emailDao.init(account, emaildao_test.password, function() {
|
||||
equal(emaildao_test.emailDao.account.get('emailAddress'), emaildao_test.user, 'Email DAO Account');
|
||||
|
||||
|
||||
// clear db before tests
|
||||
jsonDao.clear(function(err) {
|
||||
ok(!err, 'DB cleared. Error status: ' + err);
|
||||
|
||||
|
||||
start();
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
asyncTest("Persist test emails", 2, function() {
|
||||
asyncTest("Persist test emails", 2, function() {
|
||||
emaildao_test.crypto.aesEncryptListForUser(emaildao_test.list.toJSON(), function(encryptedList) {
|
||||
equal(encryptedList.length, emaildao_test.list.length, 'Encrypt list');
|
||||
|
||||
|
||||
// add sent date to encrypted items
|
||||
for (var i = 0; i < encryptedList.length; i++) {
|
||||
encryptedList[i].sentDate = emaildao_test.list.at(i).get('sentDate');
|
||||
}
|
||||
|
||||
|
||||
emaildao_test.storage.storeEcryptedList(encryptedList, 'email_inbox', function() {
|
||||
ok(true, 'Store encrypted list');
|
||||
|
||||
start();
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
asyncTest("List Email models", 1, function() {
|
||||
emaildao_test.emailDao.listItems('inbox', 0, emaildao_test.list.length, function(collection) {
|
||||
var gotten = collection.toJSON(),
|
||||
reference = emaildao_test.list.toJSON();
|
||||
|
||||
|
||||
deepEqual(gotten, reference, 'Compare collection');
|
||||
|
||||
|
||||
start();
|
||||
});
|
||||
});
|
||||
@ -73,4 +75,4 @@ asyncTest("Get item", 1, function() {
|
||||
var mail = emaildao_test.emailDao.getItem('inbox', item.id);
|
||||
deepEqual(mail.toJSON(), item, 'Item correct');
|
||||
start();
|
||||
});
|
||||
});
|
81
src/test/unit/index.html
Normal file
81
src/test/unit/index.html
Normal file
@ -0,0 +1,81 @@
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<title>JavaScript Unit Tests</title>
|
||||
<link rel="stylesheet" href="../qunit-1.11.0.css">
|
||||
</head>
|
||||
<body>
|
||||
<div id="qunit"></div>
|
||||
<div id="qunit-fixture"></div>
|
||||
|
||||
<script>
|
||||
// clear session storage of failed tests, so async order is correct after fail & refresh
|
||||
window.sessionStorage.clear();
|
||||
</script>
|
||||
|
||||
<!-- dependencies -->
|
||||
<script src="../../lib/cordova-2.5.0.js"></script>
|
||||
<script src="../qunit-1.11.0.js"></script>
|
||||
<script src="../../lib/jquery-1.8.2.min.js"></script>
|
||||
<script src="../../lib/underscore-1.4.4.min.js"></script>
|
||||
<script src="../../lib/backbone-0.9.10.min.js"></script>
|
||||
<script src="../../lib/lawnchair/lawnchair-git.min.js"></script>
|
||||
<script src="../../lib/lawnchair/lawnchair-adapter-indexed-db-git.js"></script>
|
||||
<script src="../../lib/lawnchair/lawnchair-adapter-webkit-sqlite-git.js"></script>
|
||||
|
||||
<script src="../../lib/crypto-js/core.js"></script>
|
||||
<script src="../../lib/crypto-js/enc-base64.js"></script>
|
||||
<script src="../../lib/crypto-js/cipher-core.js"></script>
|
||||
<script src="../../lib/crypto-js/aes.js"></script>
|
||||
<script src="../../lib/crypto-js/sha1.js"></script>
|
||||
<script src="../../lib/crypto-js/hmac.js"></script>
|
||||
<script src="../../lib/crypto-js/pbkdf2.js"></script>
|
||||
|
||||
<script src="../../lib/sjcl/sjcl.js"></script>
|
||||
<script src="../../lib/sjcl/sha256.js"></script>
|
||||
<script src="../../lib/sjcl/random.js"></script>
|
||||
<script src="../../lib/sjcl/bitArray.js"></script>
|
||||
<script src="../../lib/sjcl/codecBase64.js"></script>
|
||||
<script src="../../lib/sjcl/codecString.js"></script>
|
||||
<script src="../../lib/sjcl/aes.js"></script>
|
||||
<script src="../../lib/sjcl/ccm.js"></script>
|
||||
|
||||
<script src="../../lib/uuid.js"></script>
|
||||
<script src="../../lib/openpgp.min.js"></script>
|
||||
|
||||
<script src="../../js/app-config.js"></script>
|
||||
<script>
|
||||
app.config.workerPath = '../../js';
|
||||
app.config.cloudUrl = 'http://localhost:8888';
|
||||
</script>
|
||||
|
||||
<script src="../../js/model/email-model.js"></script>
|
||||
<script src="../../js/model/folder-model.js"></script>
|
||||
<script src="../../js/model/account-model.js"></script>
|
||||
|
||||
<script src="../../js/crypto/util.js"></script>
|
||||
<script src="../../js/crypto/pbkdf2.js"></script>
|
||||
<script src="../../js/crypto/aes-cbc.js"></script>
|
||||
<script src="../../js/crypto/aes-ccm.js"></script>
|
||||
<script src="../../js/crypto/aes-gcm.js"></script>
|
||||
<script src="../../js/crypto/crypto.js"></script>
|
||||
|
||||
<script src="../../js/dao/localstorage-dao.js"></script>
|
||||
<script src="../../js/dao/lawnchair-dao.js"></script>
|
||||
<script src="../../js/dao/devicestorage.js"></script>
|
||||
<script src="../../js/dao/cloudstorage-dao.js"></script>
|
||||
<script src="../../js/dao/email-dao.js"></script>
|
||||
|
||||
<!-- tests -->
|
||||
<script src="../test-data.js"></script>
|
||||
<script src="util-test.js"></script>
|
||||
<script src="aes-test.js"></script>
|
||||
<script src="crypto-test.js"></script>
|
||||
<script src="localstorage-dao-test.js"></script>
|
||||
<script src="lawnchair-dao-test.js"></script>
|
||||
<script src="devicestorage-test.js"></script>
|
||||
<script src="email-dao-test.js"></script>
|
||||
|
||||
</body>
|
||||
</html>
|
@ -1,74 +0,0 @@
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<title>JavaScript Integration Tests</title>
|
||||
<link rel="stylesheet" href="../qunit-1.11.0.css">
|
||||
</head>
|
||||
<body>
|
||||
<div id="qunit"></div>
|
||||
<div id="qunit-fixture"></div>
|
||||
|
||||
<script>
|
||||
// clear session storage of failed tests, so async order is correct after fail & refresh
|
||||
window.sessionStorage.clear();
|
||||
</script>
|
||||
|
||||
<!-- dependencies -->
|
||||
<script src="../../src/lib/cordova-2.5.0.js"></script>
|
||||
<script src="../qunit-1.11.0.js"></script>
|
||||
<script src="../../src/lib/jquery-1.8.2.min.js"></script>
|
||||
<script src="../../src/lib/underscore-1.4.4.min.js"></script>
|
||||
<script src="../../src/lib/backbone-0.9.10.min.js"></script>
|
||||
<script src="../../src/lib/lawnchair/lawnchair-git.min.js"></script>
|
||||
<script src="../../src/lib/lawnchair/lawnchair-adapter-indexed-db-git.js"></script>
|
||||
<script src="../../src/lib/lawnchair/lawnchair-adapter-webkit-sqlite-git.js"></script>
|
||||
|
||||
<script src="../../src/lib/crypto-js/core.js"></script>
|
||||
<script src="../../src/lib/crypto-js/enc-base64.js"></script>
|
||||
<script src="../../src/lib/crypto-js/cipher-core.js"></script>
|
||||
<script src="../../src/lib/crypto-js/aes.js"></script>
|
||||
<script src="../../src/lib/crypto-js/sha1.js"></script>
|
||||
<script src="../../src/lib/crypto-js/hmac.js"></script>
|
||||
<script src="../../src/lib/crypto-js/pbkdf2.js"></script>
|
||||
|
||||
<script src="../../src/lib/sjcl/sjcl.js"></script>
|
||||
<script src="../../src/lib/sjcl/sha256.js"></script>
|
||||
<script src="../../src/lib/sjcl/random.js"></script>
|
||||
<script src="../../src/lib/sjcl/bitArray.js"></script>
|
||||
<script src="../../src/lib/sjcl/codecBase64.js"></script>
|
||||
<script src="../../src/lib/sjcl/codecString.js"></script>
|
||||
<script src="../../src/lib/sjcl/aes.js"></script>
|
||||
<script src="../../src/lib/sjcl/ccm.js"></script>
|
||||
|
||||
<script src="../../src/lib/uuid.js"></script>
|
||||
<script src="../../src/lib/openpgp.min.js"></script>
|
||||
|
||||
<script src="../../src/js/app-config.js"></script>
|
||||
<script>
|
||||
app.config.workerPath = '../../src/js';
|
||||
app.config.cloudUrl = 'http://localhost:8888';
|
||||
</script>
|
||||
|
||||
<script src="../../src/js/model/email-model.js"></script>
|
||||
<script src="../../src/js/model/folder-model.js"></script>
|
||||
<script src="../../src/js/model/account-model.js"></script>
|
||||
|
||||
<script src="../../src/js/crypto/util.js"></script>
|
||||
<script src="../../src/js/crypto/pbkdf2.js"></script>
|
||||
<script src="../../src/js/crypto/aes-cbc.js"></script>
|
||||
<script src="../../src/js/crypto/aes-ccm.js"></script>
|
||||
<script src="../../src/js/crypto/aes-gcm.js"></script>
|
||||
<script src="../../src/js/crypto/crypto.js"></script>
|
||||
|
||||
<script src="../../src/js/dao/localstorage-dao.js"></script>
|
||||
<script src="../../src/js/dao/lawnchair-dao.js"></script>
|
||||
<script src="../../src/js/dao/devicestorage.js"></script>
|
||||
<script src="../../src/js/dao/cloudstorage-dao.js"></script>
|
||||
<script src="../../src/js/dao/email-dao.js"></script>
|
||||
|
||||
<!-- tests -->
|
||||
<script src="cloudstorage-dao-test.js"></script>
|
||||
|
||||
</body>
|
||||
</html>
|
@ -1,81 +0,0 @@
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<title>JavaScript Unit Tests</title>
|
||||
<link rel="stylesheet" href="../qunit-1.11.0.css">
|
||||
</head>
|
||||
<body>
|
||||
<div id="qunit"></div>
|
||||
<div id="qunit-fixture"></div>
|
||||
|
||||
<script>
|
||||
// clear session storage of failed tests, so async order is correct after fail & refresh
|
||||
window.sessionStorage.clear();
|
||||
</script>
|
||||
|
||||
<!-- dependencies -->
|
||||
<script src="../../src/lib/cordova-2.5.0.js"></script>
|
||||
<script src="../qunit-1.11.0.js"></script>
|
||||
<script src="../../src/lib/jquery-1.8.2.min.js"></script>
|
||||
<script src="../../src/lib/underscore-1.4.4.min.js"></script>
|
||||
<script src="../../src/lib/backbone-0.9.10.min.js"></script>
|
||||
<script src="../../src/lib/lawnchair/lawnchair-git.min.js"></script>
|
||||
<script src="../../src/lib/lawnchair/lawnchair-adapter-indexed-db-git.js"></script>
|
||||
<script src="../../src/lib/lawnchair/lawnchair-adapter-webkit-sqlite-git.js"></script>
|
||||
|
||||
<script src="../../src/lib/crypto-js/core.js"></script>
|
||||
<script src="../../src/lib/crypto-js/enc-base64.js"></script>
|
||||
<script src="../../src/lib/crypto-js/cipher-core.js"></script>
|
||||
<script src="../../src/lib/crypto-js/aes.js"></script>
|
||||
<script src="../../src/lib/crypto-js/sha1.js"></script>
|
||||
<script src="../../src/lib/crypto-js/hmac.js"></script>
|
||||
<script src="../../src/lib/crypto-js/pbkdf2.js"></script>
|
||||
|
||||
<script src="../../src/lib/sjcl/sjcl.js"></script>
|
||||
<script src="../../src/lib/sjcl/sha256.js"></script>
|
||||
<script src="../../src/lib/sjcl/random.js"></script>
|
||||
<script src="../../src/lib/sjcl/bitArray.js"></script>
|
||||
<script src="../../src/lib/sjcl/codecBase64.js"></script>
|
||||
<script src="../../src/lib/sjcl/codecString.js"></script>
|
||||
<script src="../../src/lib/sjcl/aes.js"></script>
|
||||
<script src="../../src/lib/sjcl/ccm.js"></script>
|
||||
|
||||
<script src="../../src/lib/uuid.js"></script>
|
||||
<script src="../../src/lib/openpgp.min.js"></script>
|
||||
|
||||
<script src="../../src/js/app-config.js"></script>
|
||||
<script>
|
||||
app.config.workerPath = '../../src/js';
|
||||
app.config.cloudUrl = 'http://localhost:8888';
|
||||
</script>
|
||||
|
||||
<script src="../../src/js/model/email-model.js"></script>
|
||||
<script src="../../src/js/model/folder-model.js"></script>
|
||||
<script src="../../src/js/model/account-model.js"></script>
|
||||
|
||||
<script src="../../src/js/crypto/util.js"></script>
|
||||
<script src="../../src/js/crypto/pbkdf2.js"></script>
|
||||
<script src="../../src/js/crypto/aes-cbc.js"></script>
|
||||
<script src="../../src/js/crypto/aes-ccm.js"></script>
|
||||
<script src="../../src/js/crypto/aes-gcm.js"></script>
|
||||
<script src="../../src/js/crypto/crypto.js"></script>
|
||||
|
||||
<script src="../../src/js/dao/localstorage-dao.js"></script>
|
||||
<script src="../../src/js/dao/lawnchair-dao.js"></script>
|
||||
<script src="../../src/js/dao/devicestorage.js"></script>
|
||||
<script src="../../src/js/dao/cloudstorage-dao.js"></script>
|
||||
<script src="../../src/js/dao/email-dao.js"></script>
|
||||
|
||||
<!-- tests -->
|
||||
<script src="../test-data.js"></script>
|
||||
<script src="util-test.js"></script>
|
||||
<script src="aes-test.js"></script>
|
||||
<script src="crypto-test.js"></script>
|
||||
<script src="localstorage-dao-test.js"></script>
|
||||
<script src="lawnchair-dao-test.js"></script>
|
||||
<script src="devicestorage-test.js"></script>
|
||||
<script src="email-dao-test.js"></script>
|
||||
|
||||
</body>
|
||||
</html>
|
Loading…
Reference in New Issue
Block a user