diff --git a/src/js/controller/mail-list.js b/src/js/controller/mail-list.js index db67bdf..b090553 100644 --- a/src/js/controller/mail-list.js +++ b/src/js/controller/mail-list.js @@ -67,9 +67,21 @@ define(function(require) { emailDao.getBody({ folder: getFolder().path, message: email - }, function(error) { + }, function(err) { + if (err) { + $scope.onError(err); + return; + } + + // display fetched body $scope.$apply(); - $scope.onError(error); + + // automatically decrypt if it's the selected email + if (email === $scope.state.mailList.selected) { + emailDao.decryptMessageContent({ + message: email + }, $scope.onError); + } }); }; @@ -83,19 +95,16 @@ define(function(require) { return; } + $scope.state.mailList.selected = email; + $scope.state.read.toggle(true); + // if we're in the outbox, don't decrypt as usual if (getFolder().type !== 'Outbox') { emailDao.decryptMessageContent({ message: email - }, function(error) { - $scope.$apply(); - $scope.onError(error); - }); + }, $scope.onError); } - $scope.state.mailList.selected = email; - $scope.state.read.toggle(true); - // if the email is unread, please sync the new state. // otherweise forget about it. if (!email.unread) { @@ -121,7 +130,7 @@ define(function(require) { // if we're in the outbox, don't do an imap sync if (getFolder().type === 'Outbox') { updateStatus('Last update: ', new Date()); - displayEmails(outboxBo.pendingEmails); + selectFirstMessage(outboxBo.pendingEmails); return; } @@ -150,7 +159,7 @@ define(function(require) { } // sort emails - displayEmails(getFolder().messages); + selectFirstMessage(getFolder().messages); // display last update updateStatus('Last update: ', new Date()); $scope.$apply(); @@ -227,7 +236,7 @@ define(function(require) { if (!window.chrome || !chrome.identity) { updateStatus('Last update: ', new Date()); getFolder().messages = createDummyMails(); - displayEmails(getFolder().messages); + selectFirstMessage(getFolder().messages); return; } @@ -236,11 +245,14 @@ define(function(require) { // if we're in the outbox, read directly from there. if (getFolder().type === 'Outbox') { updateStatus('Last update: ', new Date()); - displayEmails(outboxBo.pendingEmails); + selectFirstMessage(outboxBo.pendingEmails); return; } - displayEmails(getFolder().messages); + // unselect selection from old folder + $scope.select(); + // display and select first + selectFirstMessage(getFolder().messages); $scope.synchronize(); }); @@ -274,7 +286,7 @@ define(function(require) { $scope.lastUpdate = (time) ? time : ''; } - function displayEmails(emails) { + function selectFirstMessage(emails) { if (!emails || emails.length < 1) { $scope.select(); return; @@ -395,6 +407,8 @@ define(function(require) { this.sentDate = new Date('Thu Sep 19 2013 20:41:23 GMT+0200 (CEST)'); this.subject = 'Getting started'; // Subject line this.body = 'Here are a few pointers to help you get started with Whiteout Mail.\n\n# Write encrypted message\n- You can compose a message by clicking on the compose button on the upper right (keyboard shortcut is "n" for a new message or "r" to reply).\n- When typing the recipient\'s email address, secure recipients are marked with a blue label and insecure recipients are red.\n- When sending an email to insecure recipients, the default behavior for Whiteout Mail is to invite them to the service and only send the message content in an encrypted form, once they have joined.\n\n# Advanced features\n- To verify a recipient\'s PGP key, you can hover over the blue label containing their email address and their key fingerprint will be displayed.\n- To view your own key fingerprint, open the account view in the navigation bar on the left. You can compare these with your correspondants over a second channel such as a phonecall.\n\nWe hope this helped you to get started with Whiteout Mail.\n\nYour Whiteout Networks team'; // plaintext body + this.encrypted = true; + this.decrypted = true; }; var dummys = [new Email(true, true), new Email(true, false, true, true), new Email(false, true, true), new Email(false, true), new Email(false), new Email(false), new Email(false), new Email(false), new Email(false), new Email(false), new Email(false), new Email(false), new Email(false), new Email(false), new Email(false), new Email(false), new Email(false), new Email(false)]; diff --git a/src/js/controller/read.js b/src/js/controller/read.js index e14ce25..e3e004e 100644 --- a/src/js/controller/read.js +++ b/src/js/controller/read.js @@ -17,7 +17,7 @@ define(function(require) { keychain = appController._keychain; // set default value so that the popover height is correct on init - $scope.fingerprint = 'XXXX XXXX XXXX XXXX XXXX XXXX XXXX XXXX XXXX XXXX'; + $scope.keyId = 'XXXXXXXX'; $scope.state.read = { open: false, @@ -30,18 +30,22 @@ define(function(require) { return line.replace(/>/g, '').trim().length === 0; }; - $scope.getFingerprint = function(address) { - $scope.fingerprint = 'Fingerprint cannot be displayed. Public key not found for that user.'; + $scope.getKeyId = function(address) { + $scope.keyId = 'unknown user'; keychain.getReceiverPublicKey(address, function(err, pubkey) { if (err) { $scope.onError(err); return; } - var fpr = crypto.getFingerprint(pubkey.publicKey); - var formatted = fpr.slice(0, 4) + ' ' + fpr.slice(4, 8) + ' ' + fpr.slice(8, 12) + ' ' + fpr.slice(12, 16) + ' ' + fpr.slice(16, 20) + ' ' + fpr.slice(20, 24) + ' ' + fpr.slice(24, 28) + ' ' + fpr.slice(28, 32) + ' ' + fpr.slice(32, 36) + ' ' + fpr.slice(36); + if (!pubkey) { + return; + } - $scope.fingerprint = formatted; + var fpr = crypto.getFingerprint(pubkey.publicKey); + var formatted = fpr.slice(32); + + $scope.keyId = formatted; $scope.$apply(); }); }; diff --git a/src/js/controller/write.js b/src/js/controller/write.js index 2ac820a..9484c2c 100644 --- a/src/js/controller/write.js +++ b/src/js/controller/write.js @@ -17,7 +17,7 @@ define(function(require) { emailDao = appController._emailDao; // set default value so that the popover height is correct on init - $scope.fingerprint = 'XXXX XXXX XXXX XXXX XXXX XXXX XXXX XXXX XXXX XXXX'; + $scope.keyId = 'XXXXXXXX'; // // Init @@ -130,17 +130,17 @@ define(function(require) { }); }; - $scope.getFingerprint = function(recipient) { - $scope.fingerprint = 'Fingerprint cannot be displayed. Public key not found for that user.'; + $scope.getKeyId = function(recipient) { + $scope.keyId = 'Key not found for that user.'; if (!recipient.key) { return; } var fpr = crypto.getFingerprint(recipient.key.publicKey); - var formatted = fpr.slice(0, 4) + ' ' + fpr.slice(4, 8) + ' ' + fpr.slice(8, 12) + ' ' + fpr.slice(12, 16) + ' ' + fpr.slice(16, 20) + ' ' + fpr.slice(20, 24) + ' ' + fpr.slice(24, 28) + ' ' + fpr.slice(28, 32) + ' ' + fpr.slice(32, 36) + ' ' + fpr.slice(36); + var formatted = fpr.slice(32); - $scope.fingerprint = formatted; + $scope.keyId = formatted; }; /** diff --git a/src/js/util/error.js b/src/js/util/error.js index 71c3e7f..025c4e3 100644 --- a/src/js/util/error.js +++ b/src/js/util/error.js @@ -6,6 +6,7 @@ define(function() { er.attachHandler = function(scope) { scope.$root.onError = function(options) { if (!options) { + scope.$apply(); return; } diff --git a/src/sass/components/_mail-list.scss b/src/sass/components/_mail-list.scss index 5538eeb..4d4f24e 100755 --- a/src/sass/components/_mail-list.scss +++ b/src/sass/components/_mail-list.scss @@ -11,6 +11,7 @@ } li { + position: relative; display: block; margin-bottom: 7px; padding: $padding-vertical $padding-horizontal; @@ -26,10 +27,20 @@ font-weight: normal; margin: 0; } + + .encrypted { + position: absolute; + color: $color-grey-medium; + line-height: 30px; + top: $padding-vertical; + right: $padding-vertical; + } + p { font-size: $font-size-small; margin: 0; } + .head { position: relative; padding-right: 6.5em; @@ -64,6 +75,7 @@ margin-left: -1.3em; } } + .body { color: $color-grey; height: 2.5em; @@ -122,6 +134,9 @@ h3 { color: $color-white; } + .encrypted { + color: $color-white; + } .head { .subject { color: $color-white; diff --git a/src/sass/views/_read.scss b/src/sass/views/_read.scss index 6b11241..00c5e12 100644 --- a/src/sass/views/_read.scss +++ b/src/sass/views/_read.scss @@ -85,6 +85,43 @@ height: 100%; overflow-y: scroll; + .working { + margin: 0 auto; + height: 100%; + width: 230px; + display: table; + + .container { + display: table-cell; + vertical-align: middle; + + .spinner { + position: relative; + + div { + position: absolute; + top: 0; + left: 0; + height: 30px; + width: 30px; + animation: rotation .6s linear infinite; + border-left: 5px solid $color-grey-light; + border-right: 5px solid $color-grey-light; + border-bottom: 5px solid $color-grey-light; + border-top: 5px solid $color-grey; + border-radius: 100%; + } + } + + h1 { + margin: 0; + padding-left: 40px; + line-height: 30px; + color: $color-grey-input; + } + } + } + .line { word-wrap: break-word; diff --git a/src/tpl/login-initial.html b/src/tpl/login-initial.html index 3e30773..e50b568 100644 --- a/src/tpl/login-initial.html +++ b/src/tpl/login-initial.html @@ -6,7 +6,7 @@
-

Set passphrase. The passphrase protects your keypair. If you forget your passphrase you will not be able to recover your messages.

+

Set passphrase. The passphrase protects your private key. If you forget your passphrase you will not be able to recover your messages.


@@ -45,7 +45,7 @@

A passphrase is like a password but longer.

If your device is lost or stolen the passphrase protects the contents of your mailbox.

-

The passphrase should consist of multiple words that are easy to remember.

+

It must be at least 10 characters long and contain one special character or digit.

You cannot change your passphrase at a later time.

\ No newline at end of file diff --git a/src/tpl/mail-list.html b/src/tpl/mail-list.html index 105b15e..20b008b 100644 --- a/src/tpl/mail-list.html +++ b/src/tpl/mail-list.html @@ -12,6 +12,7 @@
  • {{email.from[0].name || email.from[0].address}}

    +

    {{email.subject || 'No subject'}}

    diff --git a/src/tpl/read.html b/src/tpl/read.html index 9e8231a..86a17bd 100644 --- a/src/tpl/read.html +++ b/src/tpl/read.html @@ -6,17 +6,17 @@
    -

    {{(state.mailList.selected.subject) ? state.mailList.selected.subject + ((!state.mailList.selected.encrypted) ? ' (not encrypted)' : '') : 'No subject'}}

    +

    {{(state.mailList.selected.subject) ? state.mailList.selected.subject : 'No subject'}}

    {{state.mailList.selected.sentDate | date:'EEEE, MMM d, yyyy h:mm a'}}

    - From: {{u.name || u.address}} + From: {{u.name || u.address}}

    - To: {{u.name || u.address}} + To: {{u.name || u.address}}

    - Cc: {{u.name || u.address}} + Cc: {{u.name || u.address}}

    @@ -35,21 +35,25 @@
    - -
    -
    -
    This message contains encrypted content.
    -
    - -
    {{line}}
    -
    +
    +
    + +
    {{line}}
    +
    +
    +
    +
    + +

    Loading...

    +

    Decrypting...

    +
    +
    -
    PGP Fingerprint
    -
    {{fingerprint}}
    +
    PGP key: {{keyId}}
    diff --git a/src/tpl/write.html b/src/tpl/write.html index d901543..aeff5d8 100644 --- a/src/tpl/write.html +++ b/src/tpl/write.html @@ -10,13 +10,13 @@

    To: - +

    Cc: - +

    @@ -61,7 +61,7 @@
    -
    PGP Fingerprint
    -
    {{fingerprint}}
    +
    PGP key ID
    +
    {{keyId}}
\ No newline at end of file