mirror of https://github.com/moparisthebest/mail
Refactor app controllers
This commit is contained in:
parent
085b104521
commit
eab07041f0
|
@ -1,6 +1,6 @@
|
||||||
'use strict';
|
'use strict';
|
||||||
|
|
||||||
var AccountCtrl = function($scope, auth, keychain, pgp, appConfig, download, dialog) {
|
var AccountCtrl = function($scope, $q, auth, keychain, pgp, appConfig, download, dialog) {
|
||||||
var userId = auth.emailAddress;
|
var userId = auth.emailAddress;
|
||||||
if (!userId) {
|
if (!userId) {
|
||||||
return;
|
return;
|
||||||
|
@ -34,12 +34,13 @@ var AccountCtrl = function($scope, auth, keychain, pgp, appConfig, download, dia
|
||||||
//
|
//
|
||||||
|
|
||||||
$scope.exportKeyFile = function() {
|
$scope.exportKeyFile = function() {
|
||||||
keychain.getUserKeyPair(userId, function(err, keys) {
|
return $q(function(resolve) {
|
||||||
if (err) {
|
resolve();
|
||||||
dialog.error(err);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
}).then(function() {
|
||||||
|
return keychain.getUserKeyPair(userId);
|
||||||
|
|
||||||
|
}).then(function(keys) {
|
||||||
var keyId = keys.publicKey._id;
|
var keyId = keys.publicKey._id;
|
||||||
var file = 'whiteout_mail_' + userId + '_' + keyId.substring(8, keyId.length);
|
var file = 'whiteout_mail_' + userId + '_' + keyId.substring(8, keyId.length);
|
||||||
|
|
||||||
|
@ -48,7 +49,8 @@ var AccountCtrl = function($scope, auth, keychain, pgp, appConfig, download, dia
|
||||||
filename: file + '.asc',
|
filename: file + '.asc',
|
||||||
contentType: 'text/plain'
|
contentType: 'text/plain'
|
||||||
});
|
});
|
||||||
});
|
|
||||||
|
}).catch(dialog.error);
|
||||||
};
|
};
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
|
@ -2,7 +2,7 @@
|
||||||
|
|
||||||
var JUNK_FOLDER_TYPE = 'Junk';
|
var JUNK_FOLDER_TYPE = 'Junk';
|
||||||
|
|
||||||
var ActionBarCtrl = function($scope, email, dialog, status) {
|
var ActionBarCtrl = function($scope, $q, email, dialog, status) {
|
||||||
|
|
||||||
//
|
//
|
||||||
// scope functions
|
// scope functions
|
||||||
|
@ -23,12 +23,20 @@ var ActionBarCtrl = function($scope, email, dialog, status) {
|
||||||
// show message
|
// show message
|
||||||
status.update('Moving message...');
|
status.update('Moving message...');
|
||||||
|
|
||||||
email.moveMessage({
|
return $q(function(resolve) {
|
||||||
|
resolve();
|
||||||
|
|
||||||
|
}).then(function() {
|
||||||
|
return email.moveMessage({
|
||||||
folder: currentFolder(),
|
folder: currentFolder(),
|
||||||
destination: destination,
|
destination: destination,
|
||||||
message: message
|
message: message
|
||||||
}, function(err) {
|
});
|
||||||
if (err) {
|
|
||||||
|
}).then(function() {
|
||||||
|
status.update('Online');
|
||||||
|
|
||||||
|
}).catch(function(err) {
|
||||||
// show errors where appropriate
|
// show errors where appropriate
|
||||||
if (err.code === 42) {
|
if (err.code === 42) {
|
||||||
$scope.select(message);
|
$scope.select(message);
|
||||||
|
@ -36,11 +44,7 @@ var ActionBarCtrl = function($scope, email, dialog, status) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
status.update('Error during move!');
|
status.update('Error during move!');
|
||||||
dialog.error(err);
|
return dialog.error(err);
|
||||||
return;
|
|
||||||
}
|
|
||||||
status.update('Message moved.');
|
|
||||||
$scope.$apply();
|
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -83,11 +87,19 @@ var ActionBarCtrl = function($scope, email, dialog, status) {
|
||||||
status.setReading(false);
|
status.setReading(false);
|
||||||
status.update('Deleting message...');
|
status.update('Deleting message...');
|
||||||
|
|
||||||
email.deleteMessage({
|
return $q(function(resolve) {
|
||||||
|
resolve();
|
||||||
|
|
||||||
|
}).then(function() {
|
||||||
|
return email.deleteMessage({
|
||||||
folder: currentFolder(),
|
folder: currentFolder(),
|
||||||
message: message
|
message: message
|
||||||
}, function(err) {
|
});
|
||||||
if (err) {
|
|
||||||
|
}).then(function() {
|
||||||
|
status.update('Online');
|
||||||
|
|
||||||
|
}).catch(function(err) {
|
||||||
// show errors where appropriate
|
// show errors where appropriate
|
||||||
if (err.code === 42) {
|
if (err.code === 42) {
|
||||||
$scope.select(message);
|
$scope.select(message);
|
||||||
|
@ -95,11 +107,7 @@ var ActionBarCtrl = function($scope, email, dialog, status) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
status.update('Error during delete!');
|
status.update('Error during delete!');
|
||||||
dialog.error(err);
|
return dialog.error(err);
|
||||||
return;
|
|
||||||
}
|
|
||||||
status.update('Message deleted.');
|
|
||||||
$scope.$apply();
|
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -130,25 +138,29 @@ var ActionBarCtrl = function($scope, email, dialog, status) {
|
||||||
|
|
||||||
var originalState = message.unread;
|
var originalState = message.unread;
|
||||||
message.unread = unread;
|
message.unread = unread;
|
||||||
email.setFlags({
|
|
||||||
|
return $q(function(resolve) {
|
||||||
|
resolve();
|
||||||
|
|
||||||
|
}).then(function() {
|
||||||
|
return email.setFlags({
|
||||||
folder: currentFolder(),
|
folder: currentFolder(),
|
||||||
message: message
|
message: message
|
||||||
}, function(err) {
|
});
|
||||||
if (err && err.code === 42) {
|
|
||||||
|
}).then(function() {
|
||||||
|
status.update('Online');
|
||||||
|
|
||||||
|
}).catch(function(err) {
|
||||||
|
if (err.code === 42) {
|
||||||
// offline, restore
|
// offline, restore
|
||||||
message.unread = originalState;
|
message.unread = originalState;
|
||||||
status.update('Unable to mark message in offline mode!');
|
status.update('Unable to mark message in offline mode!');
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (err) {
|
|
||||||
status.update('Error on sync!');
|
status.update('Error on sync!');
|
||||||
dialog.error(err);
|
return dialog.error(err);
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
status.update('Online');
|
|
||||||
$scope.$apply();
|
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -176,25 +188,29 @@ var ActionBarCtrl = function($scope, email, dialog, status) {
|
||||||
|
|
||||||
var originalState = message.flagged;
|
var originalState = message.flagged;
|
||||||
message.flagged = flagged;
|
message.flagged = flagged;
|
||||||
email.setFlags({
|
|
||||||
|
return $q(function(resolve) {
|
||||||
|
resolve();
|
||||||
|
|
||||||
|
}).then(function() {
|
||||||
|
return email.setFlags({
|
||||||
folder: currentFolder(),
|
folder: currentFolder(),
|
||||||
message: message
|
message: message
|
||||||
}, function(err) {
|
});
|
||||||
if (err && err.code === 42) {
|
|
||||||
|
}).then(function() {
|
||||||
|
status.update('Online');
|
||||||
|
|
||||||
|
}).catch(function(err) {
|
||||||
|
if (err.code === 42) {
|
||||||
// offline, restore
|
// offline, restore
|
||||||
message.unread = originalState;
|
message.unread = originalState;
|
||||||
status.update('Unable to ' + (flagged ? 'add star to' : 'remove star from') + ' message in offline mode!');
|
status.update('Unable to ' + (flagged ? 'add star to' : 'remove star from') + ' message in offline mode!');
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (err) {
|
|
||||||
status.update('Error on sync!');
|
status.update('Error on sync!');
|
||||||
dialog.error(err);
|
return dialog.error(err);
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
status.update('Online');
|
|
||||||
$scope.$apply();
|
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -208,12 +224,27 @@ var ActionBarCtrl = function($scope, email, dialog, status) {
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This method is called when the user changes the searchText
|
||||||
|
*/
|
||||||
|
$scope.displaySearchResults = function(searchText) {
|
||||||
|
$scope.$root.$broadcast('search', searchText);
|
||||||
|
};
|
||||||
|
|
||||||
|
//
|
||||||
|
// scope state
|
||||||
|
//
|
||||||
|
|
||||||
// share local scope functions with root state
|
// share local scope functions with root state
|
||||||
$scope.state.actionBar = {
|
$scope.state.actionBar = {
|
||||||
markMessage: $scope.markMessage,
|
markMessage: $scope.markMessage,
|
||||||
flagMessage: $scope.flagMessage
|
flagMessage: $scope.flagMessage
|
||||||
};
|
};
|
||||||
|
|
||||||
|
//
|
||||||
|
// Helper functions
|
||||||
|
//
|
||||||
|
|
||||||
function currentFolder() {
|
function currentFolder() {
|
||||||
return $scope.state.nav.currentFolder;
|
return $scope.state.nav.currentFolder;
|
||||||
}
|
}
|
||||||
|
@ -223,13 +254,6 @@ var ActionBarCtrl = function($scope, email, dialog, status) {
|
||||||
return message.checked;
|
return message.checked;
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* This method is called when the user changes the searchText
|
|
||||||
*/
|
|
||||||
$scope.displaySearchResults = function(searchText) {
|
|
||||||
$scope.$root.$broadcast('search', searchText);
|
|
||||||
};
|
|
||||||
};
|
};
|
||||||
|
|
||||||
module.exports = ActionBarCtrl;
|
module.exports = ActionBarCtrl;
|
|
@ -4,7 +4,7 @@
|
||||||
// Controller
|
// Controller
|
||||||
//
|
//
|
||||||
|
|
||||||
var ContactsCtrl = function($scope, keychain, pgp, dialog) {
|
var ContactsCtrl = function($scope, $q, keychain, pgp, dialog) {
|
||||||
|
|
||||||
//
|
//
|
||||||
// scope state
|
// scope state
|
||||||
|
@ -13,7 +13,7 @@ var ContactsCtrl = function($scope, keychain, pgp, dialog) {
|
||||||
$scope.state.contacts = {
|
$scope.state.contacts = {
|
||||||
toggle: function(to) {
|
toggle: function(to) {
|
||||||
$scope.state.lightbox = (to) ? 'contacts' : undefined;
|
$scope.state.lightbox = (to) ? 'contacts' : undefined;
|
||||||
$scope.listKeys();
|
return $scope.listKeys();
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -22,22 +22,21 @@ var ContactsCtrl = function($scope, keychain, pgp, dialog) {
|
||||||
//
|
//
|
||||||
|
|
||||||
$scope.listKeys = function() {
|
$scope.listKeys = function() {
|
||||||
keychain.listLocalPublicKeys(function(err, keys) {
|
return $q(function(resolve) {
|
||||||
if (err) {
|
resolve();
|
||||||
dialog.error(err);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
keys.forEach(addParams);
|
}).then(function() {
|
||||||
|
return keychain.listLocalPublicKeys();
|
||||||
|
|
||||||
$scope.keys = keys;
|
}).then(function(keys) {
|
||||||
$scope.$apply();
|
// add params to key objects
|
||||||
|
keys.forEach(function(key) {
|
||||||
function addParams(key) {
|
|
||||||
var params = pgp.getKeyParams(key.publicKey);
|
var params = pgp.getKeyParams(key.publicKey);
|
||||||
_.extend(key, params);
|
_.extend(key, params);
|
||||||
}
|
|
||||||
});
|
});
|
||||||
|
$scope.keys = keys;
|
||||||
|
|
||||||
|
}).catch(dialog.error);
|
||||||
};
|
};
|
||||||
|
|
||||||
$scope.getFingerprint = function(key) {
|
$scope.getFingerprint = function(key) {
|
||||||
|
@ -74,27 +73,17 @@ var ContactsCtrl = function($scope, keychain, pgp, dialog) {
|
||||||
imported: true // mark manually imported keys
|
imported: true // mark manually imported keys
|
||||||
};
|
};
|
||||||
|
|
||||||
keychain.saveLocalPublicKey(pubkey, function(err) {
|
return keychain.saveLocalPublicKey(pubkey).then(function() {
|
||||||
if (err) {
|
|
||||||
dialog.error(err);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
// update displayed keys
|
// update displayed keys
|
||||||
$scope.listKeys();
|
return $scope.listKeys();
|
||||||
});
|
}).catch(dialog.error);
|
||||||
};
|
};
|
||||||
|
|
||||||
$scope.removeKey = function(key) {
|
$scope.removeKey = function(key) {
|
||||||
keychain.removeLocalPublicKey(key._id, function(err) {
|
return keychain.removeLocalPublicKey(key._id).then(function() {
|
||||||
if (err) {
|
|
||||||
dialog.error(err);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
// update displayed keys
|
// update displayed keys
|
||||||
$scope.listKeys();
|
return $scope.listKeys();
|
||||||
});
|
}).catch(dialog.error);
|
||||||
};
|
};
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
|
@ -11,7 +11,7 @@ var INIT_DISPLAY_LEN = 50,
|
||||||
FOLDER_TYPE_INBOX = 'Inbox',
|
FOLDER_TYPE_INBOX = 'Inbox',
|
||||||
NOTIFICATION_INBOX_TIMEOUT = 5000;
|
NOTIFICATION_INBOX_TIMEOUT = 5000;
|
||||||
|
|
||||||
var MailListCtrl = function($scope, $timeout, $location, $filter, status, notification, email, keychain, dialog, search, dummy) {
|
var MailListCtrl = function($scope, $timeout, $location, $filter, $q, status, notification, email, keychain, dialog, search, dummy) {
|
||||||
|
|
||||||
//
|
//
|
||||||
// scope state
|
// scope state
|
||||||
|
@ -55,23 +55,26 @@ var MailListCtrl = function($scope, $timeout, $location, $filter, status, notifi
|
||||||
//
|
//
|
||||||
|
|
||||||
$scope.getBody = function(message) {
|
$scope.getBody = function(message) {
|
||||||
email.getBody({
|
return $q(function(resolve) {
|
||||||
|
resolve();
|
||||||
|
|
||||||
|
}).then(function() {
|
||||||
|
return email.getBody({
|
||||||
folder: currentFolder(),
|
folder: currentFolder(),
|
||||||
message: message
|
message: message
|
||||||
}, function(err) {
|
});
|
||||||
if (err && err.code !== 42) {
|
|
||||||
dialog.error(err);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
// display fetched body
|
|
||||||
$scope.$digest();
|
|
||||||
|
|
||||||
|
}).then(function() {
|
||||||
// automatically decrypt if it's the selected message
|
// automatically decrypt if it's the selected message
|
||||||
if (message === currentMessage()) {
|
if (message === currentMessage()) {
|
||||||
email.decryptBody({
|
return email.decryptBody({
|
||||||
message: message
|
message: message
|
||||||
}, dialog.error);
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
}).catch(function(err) {
|
||||||
|
if (err.code !== 42) {
|
||||||
|
dialog.error(err);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
@ -93,19 +96,20 @@ var MailListCtrl = function($scope, $timeout, $location, $filter, status, notifi
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
keychain.refreshKeyForUserId({
|
return $q(function(resolve) {
|
||||||
|
resolve();
|
||||||
|
|
||||||
|
}).then(function() {
|
||||||
|
return keychain.refreshKeyForUserId({
|
||||||
userId: message.from[0].address
|
userId: message.from[0].address
|
||||||
}, onKeyRefreshed);
|
});
|
||||||
|
|
||||||
function onKeyRefreshed(err) {
|
}).then(function() {
|
||||||
if (err) {
|
return email.decryptBody({
|
||||||
dialog.error(err);
|
|
||||||
}
|
|
||||||
|
|
||||||
email.decryptBody({
|
|
||||||
message: message
|
message: message
|
||||||
}, dialog.error);
|
});
|
||||||
|
|
||||||
|
}).then(function() {
|
||||||
// if the message is unread, please sync the new state.
|
// if the message is unread, please sync the new state.
|
||||||
// otherweise forget about it.
|
// otherweise forget about it.
|
||||||
if (!message.unread) {
|
if (!message.unread) {
|
||||||
|
@ -119,12 +123,13 @@ var MailListCtrl = function($scope, $timeout, $location, $filter, status, notifi
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
$scope.state.actionBar.markMessage(message, false, true);
|
return $scope.state.actionBar.markMessage(message, false, true);
|
||||||
}
|
|
||||||
|
}).catch(dialog.error);
|
||||||
};
|
};
|
||||||
|
|
||||||
$scope.flag = function(message, flagged) {
|
$scope.flag = function(message, flagged) {
|
||||||
$scope.state.actionBar.flagMessage(message, flagged);
|
return $scope.state.actionBar.flagMessage(message, flagged);
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -164,7 +169,7 @@ var MailListCtrl = function($scope, $timeout, $location, $filter, status, notifi
|
||||||
}
|
}
|
||||||
|
|
||||||
// display and select first
|
// display and select first
|
||||||
openCurrentFolder();
|
return openCurrentFolder();
|
||||||
});
|
});
|
||||||
|
|
||||||
$scope.watchMessages = $scope.$watchCollection('state.nav.currentFolder.messages', function(messages) {
|
$scope.watchMessages = $scope.$watchCollection('state.nav.currentFolder.messages', function(messages) {
|
||||||
|
@ -246,10 +251,10 @@ var MailListCtrl = function($scope, $timeout, $location, $filter, status, notifi
|
||||||
*/
|
*/
|
||||||
$scope.watchOnline = $scope.$watch('account.online', function(isOnline) {
|
$scope.watchOnline = $scope.$watch('account.online', function(isOnline) {
|
||||||
// wait one cycle for the status display controllers to init
|
// wait one cycle for the status display controllers to init
|
||||||
$timeout(function() {
|
return $timeout(function() {
|
||||||
if (isOnline) {
|
if (isOnline) {
|
||||||
status.update('Online');
|
status.update('Online');
|
||||||
openCurrentFolder();
|
return openCurrentFolder();
|
||||||
} else {
|
} else {
|
||||||
status.update('Offline mode');
|
status.update('Offline mode');
|
||||||
}
|
}
|
||||||
|
@ -265,18 +270,24 @@ var MailListCtrl = function($scope, $timeout, $location, $filter, status, notifi
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
email.openFolder({
|
return $q(function(resolve) {
|
||||||
|
resolve();
|
||||||
|
|
||||||
|
}).then(function() {
|
||||||
|
return email.openFolder({
|
||||||
folder: currentFolder()
|
folder: currentFolder()
|
||||||
}, function(error) {
|
}).catch(function(err) {
|
||||||
|
// don't display err for offline case
|
||||||
|
if (err.code !== 42) {
|
||||||
|
throw err;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
}).then(function() {
|
||||||
// dont wait until scroll to load visible mail bodies
|
// dont wait until scroll to load visible mail bodies
|
||||||
$scope.loadVisibleBodies();
|
$scope.loadVisibleBodies();
|
||||||
|
|
||||||
// don't display error for offline case
|
}).catch(dialog.error);
|
||||||
if (error && error.code === 42) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
dialog.error(error);
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
function currentFolder() {
|
function currentFolder() {
|
||||||
|
|
|
@ -11,7 +11,7 @@ var NOTIFICATION_SENT_TIMEOUT = 2000;
|
||||||
// Controller
|
// Controller
|
||||||
//
|
//
|
||||||
|
|
||||||
var NavigationCtrl = function($scope, $location, account, email, outbox, notification, appConfig, dialog, dummy) {
|
var NavigationCtrl = function($scope, $location, $q, account, email, outbox, notification, appConfig, dialog, dummy) {
|
||||||
if (!$location.search().dev && !account.isLoggedIn()) {
|
if (!$location.search().dev && !account.isLoggedIn()) {
|
||||||
$location.path('/'); // init app
|
$location.path('/'); // init app
|
||||||
return;
|
return;
|
||||||
|
@ -102,13 +102,19 @@ var NavigationCtrl = function($scope, $location, account, email, outbox, notific
|
||||||
});
|
});
|
||||||
ob.count = count;
|
ob.count = count;
|
||||||
|
|
||||||
email.refreshFolder({
|
return $q(function(resolve) {
|
||||||
|
resolve();
|
||||||
|
|
||||||
|
}).then(function() {
|
||||||
|
return email.refreshFolder({
|
||||||
folder: ob
|
folder: ob
|
||||||
}, dialog.error);
|
});
|
||||||
|
|
||||||
|
}).catch(dialog.error);
|
||||||
};
|
};
|
||||||
|
|
||||||
$scope.logout = function() {
|
$scope.logout = function() {
|
||||||
dialog.confirm({
|
return dialog.confirm({
|
||||||
title: str.logoutTitle,
|
title: str.logoutTitle,
|
||||||
message: str.logoutMessage,
|
message: str.logoutMessage,
|
||||||
callback: function(confirm) {
|
callback: function(confirm) {
|
||||||
|
|
|
@ -2,7 +2,7 @@
|
||||||
|
|
||||||
var util = require('crypto-lib').util;
|
var util = require('crypto-lib').util;
|
||||||
|
|
||||||
var PrivateKeyUploadCtrl = function($scope, keychain, pgp, dialog, auth) {
|
var PrivateKeyUploadCtrl = function($scope, $q, keychain, pgp, dialog, auth) {
|
||||||
|
|
||||||
//
|
//
|
||||||
// scope state
|
// scope state
|
||||||
|
@ -19,16 +19,15 @@ var PrivateKeyUploadCtrl = function($scope, keychain, pgp, dialog, auth) {
|
||||||
// show syncing status
|
// show syncing status
|
||||||
$scope.step = 4;
|
$scope.step = 4;
|
||||||
// check if key is already synced
|
// check if key is already synced
|
||||||
$scope.checkServerForKey(function(privateKeySynced) {
|
return $scope.checkServerForKey().then(function(privateKeySynced) {
|
||||||
if (privateKeySynced) {
|
if (privateKeySynced) {
|
||||||
// close lightbox
|
// close lightbox
|
||||||
$scope.state.lightbox = undefined;
|
$scope.state.lightbox = undefined;
|
||||||
// show message
|
// show message
|
||||||
dialog.info({
|
return dialog.info({
|
||||||
title: 'Info',
|
title: 'Info',
|
||||||
message: 'Your PGP key has already been synced.'
|
message: 'Your PGP key has already been synced.'
|
||||||
});
|
});
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// show sync ui if key is not synced
|
// show sync ui if key is not synced
|
||||||
|
@ -41,24 +40,19 @@ var PrivateKeyUploadCtrl = function($scope, keychain, pgp, dialog, auth) {
|
||||||
// scope functions
|
// scope functions
|
||||||
//
|
//
|
||||||
|
|
||||||
$scope.checkServerForKey = function(callback) {
|
$scope.checkServerForKey = function() {
|
||||||
var keyParams = pgp.getKeyParams();
|
var keyParams = pgp.getKeyParams();
|
||||||
keychain.hasPrivateKey({
|
|
||||||
|
return $q(function(resolve) {
|
||||||
|
resolve();
|
||||||
|
|
||||||
|
}).then(function() {
|
||||||
|
return keychain.hasPrivateKey({
|
||||||
userId: keyParams.userId,
|
userId: keyParams.userId,
|
||||||
keyId: keyParams._id
|
keyId: keyParams._id
|
||||||
}, function(err, privateKeySynced) {
|
|
||||||
if (err) {
|
|
||||||
dialog.error(err);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (privateKeySynced) {
|
|
||||||
callback(privateKeySynced);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
callback();
|
|
||||||
});
|
});
|
||||||
|
|
||||||
|
}).catch(dialog.error);
|
||||||
};
|
};
|
||||||
|
|
||||||
$scope.displayUploadUi = function() {
|
$scope.displayUploadUi = function() {
|
||||||
|
@ -82,29 +76,37 @@ var PrivateKeyUploadCtrl = function($scope, keychain, pgp, dialog, auth) {
|
||||||
return true;
|
return true;
|
||||||
};
|
};
|
||||||
|
|
||||||
$scope.setDeviceName = function(callback) {
|
$scope.setDeviceName = function() {
|
||||||
keychain.setDeviceName($scope.deviceName, callback);
|
return $q(function(resolve) {
|
||||||
|
resolve();
|
||||||
|
|
||||||
|
}).then(function() {
|
||||||
|
return keychain.setDeviceName($scope.deviceName);
|
||||||
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
$scope.encryptAndUploadKey = function(callback) {
|
$scope.encryptAndUploadKey = function() {
|
||||||
var userId = auth.emailAddress;
|
var userId = auth.emailAddress;
|
||||||
var code = $scope.code;
|
var code = $scope.code;
|
||||||
|
|
||||||
// register device to keychain service
|
// register device to keychain service
|
||||||
keychain.registerDevice({
|
return $q(function(resolve) {
|
||||||
userId: userId
|
resolve();
|
||||||
}, function(err) {
|
|
||||||
if (err) {
|
|
||||||
dialog.error(err);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
}).then(function() {
|
||||||
|
// register the device
|
||||||
|
return keychain.registerDevice({
|
||||||
|
userId: userId
|
||||||
|
});
|
||||||
|
|
||||||
|
}).then(function() {
|
||||||
// encrypt private PGP key using code and upload
|
// encrypt private PGP key using code and upload
|
||||||
keychain.uploadPrivateKey({
|
return keychain.uploadPrivateKey({
|
||||||
userId: userId,
|
userId: userId,
|
||||||
code: code
|
code: code
|
||||||
}, callback);
|
|
||||||
});
|
});
|
||||||
|
|
||||||
|
}).catch(dialog.error);
|
||||||
};
|
};
|
||||||
|
|
||||||
$scope.goBack = function() {
|
$scope.goBack = function() {
|
||||||
|
@ -126,23 +128,13 @@ var PrivateKeyUploadCtrl = function($scope, keychain, pgp, dialog, auth) {
|
||||||
|
|
||||||
if ($scope.step === 3) {
|
if ($scope.step === 3) {
|
||||||
// set device name to local storage
|
// set device name to local storage
|
||||||
$scope.setDeviceName(function(err) {
|
return $scope.setDeviceName().then(function() {
|
||||||
if (err) {
|
|
||||||
dialog.error(err);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
// show spinner
|
// show spinner
|
||||||
$scope.step++;
|
$scope.step++;
|
||||||
$scope.$apply();
|
|
||||||
|
|
||||||
// init key sync
|
// init key sync
|
||||||
$scope.encryptAndUploadKey(function(err) {
|
return $scope.encryptAndUploadKey();
|
||||||
if (err) {
|
|
||||||
dialog.error(err);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
}).then(function() {
|
||||||
// close sync dialog
|
// close sync dialog
|
||||||
$scope.state.privateKeyUpload.toggle(false);
|
$scope.state.privateKeyUpload.toggle(false);
|
||||||
// show success message
|
// show success message
|
||||||
|
@ -150,8 +142,8 @@ var PrivateKeyUploadCtrl = function($scope, keychain, pgp, dialog, auth) {
|
||||||
title: 'Success',
|
title: 'Success',
|
||||||
message: 'Whiteout Keychain setup successful!'
|
message: 'Whiteout Keychain setup successful!'
|
||||||
});
|
});
|
||||||
});
|
|
||||||
});
|
}).catch(dialog.error);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -4,7 +4,7 @@
|
||||||
// Controller
|
// Controller
|
||||||
//
|
//
|
||||||
|
|
||||||
var ReadCtrl = function($scope, $location, email, invitation, outbox, pgp, keychain, appConfig, download, auth, dialog) {
|
var ReadCtrl = function($scope, $location, $q, email, invitation, outbox, pgp, keychain, appConfig, download, auth, dialog) {
|
||||||
|
|
||||||
var str = appConfig.string;
|
var str = appConfig.string;
|
||||||
|
|
||||||
|
@ -52,25 +52,24 @@ var ReadCtrl = function($scope, $location, email, invitation, outbox, pgp, keych
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return $q(function(resolve) {
|
||||||
$scope.keyId = 'Searching...';
|
$scope.keyId = 'Searching...';
|
||||||
keychain.getReceiverPublicKey(address, function(err, pubkey) {
|
resolve();
|
||||||
if (err) {
|
|
||||||
dialog.error(err);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
}).then(function() {
|
||||||
|
return keychain.getReceiverPublicKey(address);
|
||||||
|
|
||||||
|
}).then(function(pubkey) {
|
||||||
if (!pubkey) {
|
if (!pubkey) {
|
||||||
$scope.keyId = 'User has no key. Click to invite.';
|
$scope.keyId = 'User has no key. Click to invite.';
|
||||||
$scope.$apply();
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
var fpr = pgp.getFingerprint(pubkey.publicKey);
|
var fpr = pgp.getFingerprint(pubkey.publicKey);
|
||||||
var formatted = fpr.slice(32);
|
var formatted = fpr.slice(32);
|
||||||
|
|
||||||
$scope.keyId = 'PGP key: ' + formatted;
|
$scope.keyId = 'PGP key: ' + formatted;
|
||||||
$scope.$apply();
|
|
||||||
});
|
}).catch(dialog.error);
|
||||||
};
|
};
|
||||||
|
|
||||||
$scope.$watch('state.mailList.selected', function(mail) {
|
$scope.$watch('state.mailList.selected', function(mail) {
|
||||||
|
@ -89,24 +88,20 @@ var ReadCtrl = function($scope, $location, email, invitation, outbox, pgp, keych
|
||||||
function checkPublicKey(user) {
|
function checkPublicKey(user) {
|
||||||
user.secure = undefined;
|
user.secure = undefined;
|
||||||
|
|
||||||
if (!keychain) {
|
return $q(function(resolve) {
|
||||||
return;
|
resolve();
|
||||||
}
|
|
||||||
|
|
||||||
keychain.getReceiverPublicKey(user.address, function(err, pubkey) {
|
}).then(function() {
|
||||||
if (err) {
|
return keychain.getReceiverPublicKey(user.address);
|
||||||
dialog.error(err);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (pubkey && pubkey.publicKey) {
|
}).then(function(pubkey) {
|
||||||
|
if (pubkey.publicKey) {
|
||||||
user.secure = true;
|
user.secure = true;
|
||||||
} else {
|
} else {
|
||||||
user.secure = false;
|
user.secure = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
$scope.$apply();
|
}).catch(dialog.error);
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
$scope.download = function(attachment) {
|
$scope.download = function(attachment) {
|
||||||
|
@ -122,11 +117,18 @@ var ReadCtrl = function($scope, $location, email, invitation, outbox, pgp, keych
|
||||||
|
|
||||||
var folder = $scope.state.nav.currentFolder;
|
var folder = $scope.state.nav.currentFolder;
|
||||||
var message = $scope.state.mailList.selected;
|
var message = $scope.state.mailList.selected;
|
||||||
email.getAttachment({
|
|
||||||
|
return $q(function(resolve) {
|
||||||
|
resolve();
|
||||||
|
|
||||||
|
}).then(function() {
|
||||||
|
return email.getAttachment({
|
||||||
folder: folder,
|
folder: folder,
|
||||||
uid: message.uid,
|
uid: message.uid,
|
||||||
attachment: attachment
|
attachment: attachment
|
||||||
}, dialog.error);
|
});
|
||||||
|
|
||||||
|
}).catch(dialog.error);
|
||||||
};
|
};
|
||||||
|
|
||||||
$scope.invite = function(user) {
|
$scope.invite = function(user) {
|
||||||
|
@ -135,20 +137,20 @@ var ReadCtrl = function($scope, $location, email, invitation, outbox, pgp, keych
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
$scope.keyId = 'Sending invitation...';
|
|
||||||
|
|
||||||
var sender = auth.emailAddress,
|
var sender = auth.emailAddress,
|
||||||
recipient = user.address;
|
recipient = user.address;
|
||||||
|
|
||||||
invitation.invite({
|
return $q(function(resolve) {
|
||||||
|
$scope.keyId = 'Sending invitation...';
|
||||||
|
resolve();
|
||||||
|
|
||||||
|
}).then(function() {
|
||||||
|
return invitation.invite({
|
||||||
recipient: recipient,
|
recipient: recipient,
|
||||||
sender: sender
|
sender: sender
|
||||||
}, function(err) {
|
});
|
||||||
if (err) {
|
|
||||||
dialog.error(err);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
}).then(function() {
|
||||||
var invitationMail = {
|
var invitationMail = {
|
||||||
from: [{
|
from: [{
|
||||||
address: sender
|
address: sender
|
||||||
|
@ -161,10 +163,10 @@ var ReadCtrl = function($scope, $location, email, invitation, outbox, pgp, keych
|
||||||
subject: str.invitationSubject,
|
subject: str.invitationSubject,
|
||||||
body: str.invitationMessage
|
body: str.invitationMessage
|
||||||
};
|
};
|
||||||
|
|
||||||
// send invitation mail
|
// send invitation mail
|
||||||
outbox.put(invitationMail, dialog.error);
|
return outbox.put(invitationMail);
|
||||||
});
|
|
||||||
|
}).catch(dialog.error);
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
'use strict';
|
'use strict';
|
||||||
|
|
||||||
var SetPassphraseCtrl = function($scope, pgp, keychain, dialog) {
|
var SetPassphraseCtrl = function($scope, $q, pgp, keychain, dialog) {
|
||||||
|
|
||||||
//
|
//
|
||||||
// scope variables
|
// scope variables
|
||||||
|
@ -76,27 +76,25 @@ var SetPassphraseCtrl = function($scope, pgp, keychain, dialog) {
|
||||||
|
|
||||||
$scope.setPassphrase = function() {
|
$scope.setPassphrase = function() {
|
||||||
var keyId = pgp.getKeyParams()._id;
|
var keyId = pgp.getKeyParams()._id;
|
||||||
keychain.lookupPrivateKey(keyId, function(err, savedKey) {
|
|
||||||
if (err) {
|
|
||||||
dialog.error(err);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
pgp.changePassphrase({
|
return $q(function(resolve) {
|
||||||
|
resolve();
|
||||||
|
|
||||||
|
}).then(function() {
|
||||||
|
return keychain.lookupPrivateKey(keyId);
|
||||||
|
|
||||||
|
}).then(function(savedKey) {
|
||||||
|
// change passphrase
|
||||||
|
return pgp.changePassphrase({
|
||||||
privateKeyArmored: savedKey.encryptedKey,
|
privateKeyArmored: savedKey.encryptedKey,
|
||||||
oldPassphrase: $scope.oldPassphrase,
|
oldPassphrase: $scope.oldPassphrase,
|
||||||
newPassphrase: $scope.newPassphrase
|
newPassphrase: $scope.newPassphrase
|
||||||
}, onPassphraseChanged);
|
}).catch(function(err) {
|
||||||
});
|
|
||||||
};
|
|
||||||
|
|
||||||
function onPassphraseChanged(err, newPrivateKeyArmored) {
|
|
||||||
if (err) {
|
|
||||||
err.showBugReporter = false;
|
err.showBugReporter = false;
|
||||||
dialog.error(err);
|
throw err;
|
||||||
return;
|
});
|
||||||
}
|
|
||||||
|
|
||||||
|
}).then(function(newPrivateKeyArmored) {
|
||||||
// persist new armored key
|
// persist new armored key
|
||||||
var keyParams = pgp.getKeyParams(newPrivateKeyArmored);
|
var keyParams = pgp.getKeyParams(newPrivateKeyArmored);
|
||||||
var privateKey = {
|
var privateKey = {
|
||||||
|
@ -105,23 +103,17 @@ var SetPassphraseCtrl = function($scope, pgp, keychain, dialog) {
|
||||||
userIds: keyParams.userIds,
|
userIds: keyParams.userIds,
|
||||||
encryptedKey: newPrivateKeyArmored
|
encryptedKey: newPrivateKeyArmored
|
||||||
};
|
};
|
||||||
|
return keychain.saveLocalPrivateKey(privateKey);
|
||||||
|
|
||||||
keychain.saveLocalPrivateKey(privateKey, onKeyPersisted);
|
}).then(function() {
|
||||||
}
|
|
||||||
|
|
||||||
function onKeyPersisted(err) {
|
|
||||||
if (err) {
|
|
||||||
dialog.error(err);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
$scope.state.setPassphrase.toggle(false);
|
$scope.state.setPassphrase.toggle(false);
|
||||||
$scope.$apply();
|
return dialog.info({
|
||||||
dialog.info({
|
|
||||||
title: 'Success',
|
title: 'Success',
|
||||||
message: 'Passphrase change complete.'
|
message: 'Passphrase change complete.'
|
||||||
});
|
});
|
||||||
}
|
|
||||||
|
}).catch(dialog.error);
|
||||||
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
module.exports = SetPassphraseCtrl;
|
module.exports = SetPassphraseCtrl;
|
|
@ -218,18 +218,17 @@ var WriteCtrl = function($scope, $window, $filter, $q, appConfig, auth, keychain
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// keychain is undefined in local dev environment
|
|
||||||
if (keychain) {
|
|
||||||
// check if to address is contained in known public keys
|
// check if to address is contained in known public keys
|
||||||
// when we write an email, we always need to work with the latest keys available
|
// when we write an email, we always need to work with the latest keys available
|
||||||
keychain.refreshKeyForUserId({
|
return $q(function(resolve) {
|
||||||
userId: recipient.address
|
resolve();
|
||||||
}, function(err, key) {
|
|
||||||
if (err) {
|
|
||||||
dialog.error(err);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
}).then(function() {
|
||||||
|
return keychain.refreshKeyForUserId({
|
||||||
|
userId: recipient.address
|
||||||
|
});
|
||||||
|
|
||||||
|
}).then(function(key) {
|
||||||
if (key) {
|
if (key) {
|
||||||
// compare again since model could have changed during the roundtrip
|
// compare again since model could have changed during the roundtrip
|
||||||
var matchingUserId = _.findWhere(key.userIds, {
|
var matchingUserId = _.findWhere(key.userIds, {
|
||||||
|
@ -241,11 +240,9 @@ var WriteCtrl = function($scope, $window, $filter, $q, appConfig, auth, keychain
|
||||||
recipient.secure = true;
|
recipient.secure = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
$scope.checkSendStatus();
|
$scope.checkSendStatus();
|
||||||
$scope.$digest();
|
|
||||||
});
|
}).catch(dialog.error);
|
||||||
}
|
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -347,12 +344,13 @@ var WriteCtrl = function($scope, $window, $filter, $q, appConfig, auth, keychain
|
||||||
}
|
}
|
||||||
|
|
||||||
// persist the email to disk for later sending
|
// persist the email to disk for later sending
|
||||||
outbox.put(message, function(err) {
|
return $q(function(resolve) {
|
||||||
if (err) {
|
resolve();
|
||||||
dialog.error(err);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
}).then(function() {
|
||||||
|
return outbox.put(message);
|
||||||
|
|
||||||
|
}).then(function() {
|
||||||
// if we need to synchronize replyTo.answered = true to imap,
|
// if we need to synchronize replyTo.answered = true to imap,
|
||||||
// let's do that. otherwise, we're done
|
// let's do that. otherwise, we're done
|
||||||
if (!$scope.replyTo || $scope.replyTo.answered) {
|
if (!$scope.replyTo || $scope.replyTo.answered) {
|
||||||
|
@ -360,20 +358,16 @@ var WriteCtrl = function($scope, $window, $filter, $q, appConfig, auth, keychain
|
||||||
}
|
}
|
||||||
|
|
||||||
$scope.replyTo.answered = true;
|
$scope.replyTo.answered = true;
|
||||||
email.setFlags({
|
return email.setFlags({
|
||||||
folder: currentFolder(),
|
folder: currentFolder(),
|
||||||
message: $scope.replyTo
|
message: $scope.replyTo
|
||||||
}, function(err) {
|
});
|
||||||
if (err && err.code !== 42) {
|
|
||||||
|
}).catch(function(err) {
|
||||||
|
if (err.code !== 42) {
|
||||||
dialog.error(err);
|
dialog.error(err);
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// offline or no error, let's apply the ui changes
|
|
||||||
$scope.$apply();
|
|
||||||
});
|
});
|
||||||
});
|
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
//
|
//
|
||||||
|
@ -389,37 +383,29 @@ var WriteCtrl = function($scope, $window, $filter, $q, appConfig, auth, keychain
|
||||||
};
|
};
|
||||||
|
|
||||||
$scope.lookupAddressBook = function(query) {
|
$scope.lookupAddressBook = function(query) {
|
||||||
var deferred = $q.defer();
|
return $q(function(resolve) {
|
||||||
|
resolve();
|
||||||
|
|
||||||
if (!$scope.addressBookCache) {
|
}).then(function() {
|
||||||
// populate address book cache
|
if ($scope.addressBookCache) {
|
||||||
keychain.listLocalPublicKeys(function(err, keys) {
|
|
||||||
if (err) {
|
|
||||||
dialog.error(err);
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
// populate address book cache
|
||||||
|
return keychain.listLocalPublicKeys().then(function(keys) {
|
||||||
$scope.addressBookCache = keys.map(function(key) {
|
$scope.addressBookCache = keys.map(function(key) {
|
||||||
return {
|
return {
|
||||||
address: key.userId
|
address: key.userId
|
||||||
};
|
};
|
||||||
});
|
});
|
||||||
filter();
|
|
||||||
});
|
});
|
||||||
|
|
||||||
} else {
|
}).then(function() {
|
||||||
filter();
|
// filter the address book cache
|
||||||
}
|
return $scope.addressBookCache.filter(function(i) {
|
||||||
|
|
||||||
// query address book cache
|
|
||||||
function filter() {
|
|
||||||
var addresses = $scope.addressBookCache.filter(function(i) {
|
|
||||||
return i.address.indexOf(query) !== -1;
|
return i.address.indexOf(query) !== -1;
|
||||||
});
|
});
|
||||||
deferred.resolve(addresses);
|
|
||||||
}
|
|
||||||
|
|
||||||
return deferred.promise;
|
}).catch(dialog.error);
|
||||||
};
|
};
|
||||||
|
|
||||||
//
|
//
|
||||||
|
|
Loading…
Reference in New Issue