refactored folder structure

This commit is contained in:
Tankred Hase 2013-04-01 23:23:25 +02:00
parent 13ee758c8d
commit 5ee864fe01
27 changed files with 444 additions and 394 deletions

View File

@ -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

View File

@ -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);

View File

@ -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
View 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);

View File

@ -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'
};
}());

View File

@ -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
});
}
});
}());

View File

@ -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();
});
});
});
}());

View File

@ -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
View 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"
}

View File

@ -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');

View 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>

View File

@ -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
View 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>

View File

@ -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>

View File

@ -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>