diff --git a/Gruntfile.js b/Gruntfile.js index e6d7413..fa57114 100644 --- a/Gruntfile.js +++ b/Gruntfile.js @@ -93,7 +93,7 @@ module.exports = function(grunt) { tasks: ['copy:lib', 'manifest'] }, app: { - files: ['src/*.js', 'src/**/*.html', 'src/**/*.json', 'src/img/**/*', 'src/font/**/*'], + files: ['src/*.js', 'src/**/*.html', 'src/**/*.json', 'src/manifest.*', 'src/img/**/*', 'src/font/**/*'], tasks: ['copy:app', 'copy:ca', 'copy:tpl', 'copy:img', 'copy:font', 'manifest-dev', 'manifest'] } }, @@ -179,7 +179,7 @@ module.exports = function(grunt) { app: { expand: true, cwd: 'src/', - src: ['*.html', '*.js', '*.json'], + src: ['*.html', '*.js', '*.json', 'manifest.*'], dest: 'dist/' }, integration: { @@ -220,7 +220,7 @@ module.exports = function(grunt) { timestamp: true, hash: true, cache: ['socket.io/socket.io.js'], - exclude: ['appcache.manifest'], + exclude: ['appcache.manifest', 'manifest.webapp'], master: ['index.html'] }, src: ['**/*.*'], diff --git a/server.js b/server.js index 23c12c2..fcb4872 100644 --- a/server.js +++ b/server.js @@ -71,7 +71,6 @@ app.disable('x-powered-by'); // var port = process.env.PORT || 8585, - oneDay = 86400000, development = process.argv[2] === '--dev'; // set HTTP headers @@ -81,7 +80,14 @@ app.use(function(req, res, next) { // CSP var iframe = development ? "http://" + req.hostname + ":" + port : "https://" + req.hostname; // allow iframe to load assets res.set('Content-Security-Policy', "default-src 'self' " + iframe + "; object-src 'none'; connect-src *; style-src 'self' 'unsafe-inline' " + iframe + "; img-src 'self' data:"); - return next(); + // set Cache-control Header (for AppCache) + res.set('Cache-control', 'public, max-age=0'); + next(); +}); + +app.use('/appcache.manifest', function(req, res, next) { + res.set('Cache-control', 'no-cache'); + next(); }); // redirect all http traffic to https @@ -97,9 +103,7 @@ app.use(function(req, res, next) { app.use(compression()); // server static files -app.use(express.static(__dirname + '/dist', { - maxAge: oneDay -})); +app.use(express.static(__dirname + '/dist')); // // Socket.io proxy diff --git a/src/js/app-controller.js b/src/js/app-controller.js index 3011948..f515f91 100644 --- a/src/js/app-controller.js +++ b/src/js/app-controller.js @@ -173,24 +173,7 @@ define(function(require) { }; self.checkForUpdate = function() { - if (!window.chrome || !chrome.runtime || !chrome.runtime.onUpdateAvailable) { - return; - } - - // check for update and restart - chrome.runtime.onUpdateAvailable.addListener(function(details) { - axe.debug("Updating to version " + details.version); - chrome.runtime.reload(); - }); - chrome.runtime.requestUpdateCheck(function(status) { - if (status === "update_found") { - axe.debug("Update pending..."); - } else if (status === "no_update") { - axe.debug("No update found."); - } else if (status === "throttled") { - axe.debug("Checking updates too frequently."); - } - }); + self._updateHandler.checkForUpdate(self.onError); }; /** diff --git a/src/js/app.js b/src/js/app.js index 0051cda..cfb3fd9 100644 --- a/src/js/app.js +++ b/src/js/app.js @@ -1,3 +1,19 @@ +'use strict'; + +// Check if a new ApaCache is available on page load. +if (typeof window.applicationCache !== 'undefined') { + window.onload = function() { + window.applicationCache.onupdateready = function() { + if (window.applicationCache.status === window.applicationCache.UPDATEREADY) { + // Browser downloaded a new app cache + if (window.confirm('A new version of Whiteout Mail is available. Restart the app to update?')) { + window.location.reload(); + } + } + }; + }; +} + // hey Angular, we're bootstrapping manually! window.name = 'NG_DEFER_BOOTSTRAP!'; @@ -54,8 +70,6 @@ requirejs([ backButtonUtil, FastClick ) { - 'use strict'; - // reset window.name window.name = util.UUID(); diff --git a/src/js/controller/login.js b/src/js/controller/login.js index e366398..72be59a 100644 --- a/src/js/controller/login.js +++ b/src/js/controller/login.js @@ -4,8 +4,6 @@ define(function(require) { var appController = require('js/app-controller'); var LoginCtrl = function($scope, $location) { - // check for app update - appController.checkForUpdate(); // start main application controller appController.start({ @@ -16,6 +14,9 @@ define(function(require) { return; } + // check for app update + appController.checkForUpdate(); + initializeUser(); }); diff --git a/src/js/util/update/update-handler.js b/src/js/util/update/update-handler.js index a622128..a34252a 100644 --- a/src/js/util/update/update-handler.js +++ b/src/js/util/update/update-handler.js @@ -1,7 +1,8 @@ define(function(require) { 'use strict'; - var cfg = require('js/app-config').config, + var axe = require('axe'), + cfg = require('js/app-config').config, updateV1 = require('js/util/update/update-v1'), updateV2 = require('js/util/update/update-v2'), updateV3 = require('js/util/update/update-v3'), @@ -92,5 +93,40 @@ define(function(require) { executeNextUpdate(); }; + /** + * Check application version and update correspondingly + */ + UpdateHandler.prototype.checkForUpdate = function(dialog) { + // Chrome Packaged App + if (typeof window.chrome !== 'undefined' && chrome.runtime && chrome.runtime.onUpdateAvailable) { + // check for Chrome app update and restart + chrome.runtime.onUpdateAvailable.addListener(function(details) { + axe.debug('New Chrome App update... requesting reload.'); + // Chrome downloaded a new app version + dialog({ + title: 'Update available', + message: 'A new version ' + details.version + ' of the app is available. Restart the app to update?', + positiveBtnStr: 'Restart', + negativeBtnStr: 'Not now', + showNegativeBtn: true, + callback: function(agree) { + if (agree) { + chrome.runtime.reload(); + } + } + }); + }); + chrome.runtime.requestUpdateCheck(function(status) { + if (status === "update_found") { + axe.debug("Update pending..."); + } else if (status === "no_update") { + axe.debug("No update found."); + } else if (status === "throttled") { + axe.debug("Checking updates too frequently."); + } + }); + } + }; + return UpdateHandler; }); \ No newline at end of file diff --git a/src/manifest.webapp b/src/manifest.webapp new file mode 100644 index 0000000..82b2c0f --- /dev/null +++ b/src/manifest.webapp @@ -0,0 +1,26 @@ +{ + "name": "Whiteout Mail", + "description": "Simple and elegant email client with integrated end-to-end encryption. Keeping your emails safe has never been so easy.", + "version": "0.17.1.0", + "launch_path": "/index.html", + "icons": { + "128": "/img/icon-128.png" + }, + "developer": { + "name": "Whiteout Networks GmbH", + "url": "https://whiteout.io" + }, + "default_locale": "en", + "type": "privileged", + "permissions": { + "tcp-socket": { + "description": "Required to connect to mail servers via IMAP/SMTP" + }, + "desktop-notification": { + "description": "Required to show notifications on incoming mails." + }, + "storage": { + "description": "Required to store messages for offline use." + } + } +} \ No newline at end of file diff --git a/src/sass/_scaffolding.scss b/src/sass/_scaffolding.scss index ac8a627..b76ff3d 100755 --- a/src/sass/_scaffolding.scss +++ b/src/sass/_scaffolding.scss @@ -35,6 +35,8 @@ textarea { line-height: inherit; -webkit-font-smoothing: antialiased; -moz-osx-font-smoothing: grayscale; + // disable box shadow on firefox + background-image: none; } fieldset {