mirror of
https://github.com/moparisthebest/mail
synced 2024-11-25 18:32:20 -05:00
invite user when clicking on red address label
This commit is contained in:
parent
badea7ab8a
commit
3d6a4698ce
@ -53,15 +53,15 @@ define(function(require) {
|
||||
subjectPrefix: '[whiteout] ',
|
||||
fallbackSubject: '(no subject)',
|
||||
invitationSubject: 'Invitation to a private conversation',
|
||||
invitationMessage: 'Hi,\n\nI would like to invite you to a private conversation!\n\nPlease install the Whiteout Mail application. This application is used to read and write messages securely with strong encryption applied.\n\nGo to the Whiteout Networks homepage to learn more and to download the application: https://whiteout.io\n\n',
|
||||
message: 'Hi,\n\nthis is a private conversation. To read my encrypted message below, simply open it in Whiteout Mail.\n\nOpen Whiteout Mail: https://chrome.google.com/webstore/detail/jjgghafhamholjigjoghcfcekhkonijg\n\n',
|
||||
invitationMessage: 'Hi,\n\nI would like to invite you to a private conversation!\n\nPlease install the Whiteout Mail application. This application is used to read and write messages securely with strong encryption applied.\n\nGo to the Whiteout Networks homepage to learn more and to download the application: https://whiteout.io',
|
||||
message: 'Hi,\n\nthis is a private conversation. To read my encrypted message below, simply open it in Whiteout Mail.\nOpen Whiteout Mail: https://chrome.google.com/webstore/detail/jjgghafhamholjigjoghcfcekhkonijg',
|
||||
cryptPrefix: '-----BEGIN PGP MESSAGE-----',
|
||||
cryptSuffix: '-----END PGP MESSAGE-----',
|
||||
signature: '\n\n\n--\nSent from Whiteout Mail - get the app for easy end-to-end encryption\nhttps://whiteout.io\n\n',
|
||||
signature: '\n\n\n--\nSent from Whiteout Mail - PGP encryption for the rest of us.\nhttps://whiteout.io\n\n',
|
||||
webSite: 'http://whiteout.io',
|
||||
verificationSubject: 'New public key uploaded',
|
||||
sendBtnClear: 'Send',
|
||||
sendBtnSecure: 'Secure send'
|
||||
sendBtnSecure: 'Send securely'
|
||||
};
|
||||
|
||||
return app;
|
||||
|
@ -32,8 +32,10 @@ define(function(require) {
|
||||
* @param {Function} callback(error, pendingMailsCount) Callback that informs you about the count of pending mails.
|
||||
*/
|
||||
OutboxBO.prototype.startChecking = function(callback) {
|
||||
// remember global callback
|
||||
this._onError = callback;
|
||||
// start periodic checking of outbox
|
||||
this._intervalId = setInterval(this._processOutbox.bind(this, callback), config.checkOutboxInterval);
|
||||
this._intervalId = setInterval(this._processOutbox.bind(this, this._onError), config.checkOutboxInterval);
|
||||
};
|
||||
|
||||
/**
|
||||
@ -65,7 +67,7 @@ define(function(require) {
|
||||
// check if there are unregistered recipients
|
||||
function checkRecipients(recipients) {
|
||||
var after = _.after(recipients.length, function() {
|
||||
encryptAndPersist();
|
||||
checkEncrypt();
|
||||
});
|
||||
|
||||
// find out if there are unregistered users
|
||||
@ -87,11 +89,10 @@ define(function(require) {
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
function encryptAndPersist() {
|
||||
function checkEncrypt() {
|
||||
// only encrypt if all recipients have public keys
|
||||
if (mail.publicKeysArmored.length < allReaders.length) {
|
||||
self._devicestorage.storeList([mail], outboxDb, callback);
|
||||
storeAndForward(mail);
|
||||
return;
|
||||
}
|
||||
|
||||
@ -105,7 +106,21 @@ define(function(require) {
|
||||
return;
|
||||
}
|
||||
|
||||
self._devicestorage.storeList([mail], outboxDb, callback);
|
||||
storeAndForward(mail);
|
||||
});
|
||||
}
|
||||
|
||||
function storeAndForward(mail) {
|
||||
// store in outbox
|
||||
self._devicestorage.storeList([mail], outboxDb, function(err) {
|
||||
if (err) {
|
||||
callback(err);
|
||||
return;
|
||||
}
|
||||
|
||||
callback();
|
||||
// don't wait for next round
|
||||
self._processOutbox(self._onError);
|
||||
});
|
||||
}
|
||||
};
|
||||
|
@ -20,7 +20,7 @@ define(function(require) {
|
||||
keychain = appController._keychain;
|
||||
|
||||
// set default value so that the popover height is correct on init
|
||||
$scope.keyId = 'XXXXXXXX';
|
||||
$scope.keyId = 'No key found.';
|
||||
|
||||
$scope.state.read = {
|
||||
open: false,
|
||||
@ -34,7 +34,7 @@ define(function(require) {
|
||||
};
|
||||
|
||||
$scope.getKeyId = function(address) {
|
||||
$scope.keyId = 'unknown user';
|
||||
$scope.keyId = 'Searching...';
|
||||
keychain.getReceiverPublicKey(address, function(err, pubkey) {
|
||||
if (err) {
|
||||
$scope.onError(err);
|
||||
@ -42,13 +42,15 @@ define(function(require) {
|
||||
}
|
||||
|
||||
if (!pubkey) {
|
||||
$scope.keyId = 'User has no key. Click to invite.';
|
||||
$scope.$apply();
|
||||
return;
|
||||
}
|
||||
|
||||
var fpr = crypto.getFingerprint(pubkey.publicKey);
|
||||
var formatted = fpr.slice(32);
|
||||
|
||||
$scope.keyId = formatted;
|
||||
$scope.keyId = 'PGP key: ' + formatted;
|
||||
$scope.$apply();
|
||||
});
|
||||
};
|
||||
@ -116,10 +118,20 @@ define(function(require) {
|
||||
}
|
||||
};
|
||||
|
||||
$scope.inviteUser = function(address) {
|
||||
$scope.invite = function(user) {
|
||||
// only invite non-pgp users
|
||||
if (user.secure) {
|
||||
return;
|
||||
}
|
||||
|
||||
$scope.keyId = 'Sending invitation...';
|
||||
|
||||
var sender = emailDao._account.emailAddress,
|
||||
recipient = user.address;
|
||||
|
||||
invitationDao.invite({
|
||||
recipient: address,
|
||||
sender: emailDao._account.emailAddress
|
||||
recipient: recipient,
|
||||
sender: sender
|
||||
}, function(err) {
|
||||
if (err) {
|
||||
$scope.onError(err);
|
||||
@ -127,8 +139,14 @@ define(function(require) {
|
||||
}
|
||||
|
||||
var invitationMail = {
|
||||
from: [emailDao._account.emailAddress],
|
||||
to: [address],
|
||||
from: [{
|
||||
address: sender
|
||||
}],
|
||||
to: [{
|
||||
address: recipient
|
||||
}],
|
||||
cc: [],
|
||||
bcc: [],
|
||||
subject: str.invitationSubject,
|
||||
body: str.invitationMessage
|
||||
};
|
||||
|
@ -1037,7 +1037,7 @@ define(function(require) {
|
||||
// mime encode, sign, encrypt and send email via smtp
|
||||
self._pgpMailer.send({
|
||||
encrypt: true,
|
||||
cleartextMessage: str.message,
|
||||
cleartextMessage: str.message + str.signature,
|
||||
mail: options.email,
|
||||
publicKeysArmored: options.email.publicKeysArmored
|
||||
}, callback);
|
||||
|
@ -9,14 +9,14 @@
|
||||
<p class="subject" ng-click="state.read.toggle(false)">{{(state.mailList.selected.subject) ? state.mailList.selected.subject : 'No subject'}}</p>
|
||||
<p class="date">{{state.mailList.selected.sentDate | date:'EEEE, MMM d, yyyy h:mm a'}}</p>
|
||||
<p class="address">
|
||||
From: <span ng-repeat="u in state.mailList.selected.from" class="label" ng-class="{'label-primary': u.secure === false}" data-icon-append="{{(u.secure === false) ? '' : ''}}" ng-mouseover="getKeyId(u.address)" popover="#fingerprint-info">{{u.name || u.address}}</span>
|
||||
From: <span ng-repeat="u in state.mailList.selected.from" class="label" ng-class="{'label-primary': u.secure === false}" data-icon-append="{{(u.secure === false) ? '' : ''}}" ng-mouseover="getKeyId(u.address)" ng-click="invite(u)" popover="#fingerprint-info">{{u.name || u.address}}</span>
|
||||
</p>
|
||||
<p class="address">
|
||||
To: <span ng-repeat="u in state.mailList.selected.to" class="label" ng-class="{'label-primary': u.secure === false}" data-icon-append="{{(u.secure === false) ? '' : ''}}" ng-mouseover="getKeyId(u.address)" popover="#fingerprint-info">{{u.name || u.address}}</span>
|
||||
To: <span ng-repeat="u in state.mailList.selected.to" class="label" ng-class="{'label-primary': u.secure === false}" data-icon-append="{{(u.secure === false) ? '' : ''}}" ng-mouseover="getKeyId(u.address)" ng-click="invite(u)" popover="#fingerprint-info">{{u.name || u.address}}</span>
|
||||
</p>
|
||||
<div ng-switch="state.mailList.selected.cc !== undefined">
|
||||
<p class="address" ng-switch-when="true">
|
||||
Cc: <span ng-repeat="u in state.mailList.selected.cc" class="label" ng-class="{'label-primary': u.secure === false}" data-icon-append="{{(u.secure === false) ? '' : ''}}" ng-mouseover="getKeyId(u.address)" popover="#fingerprint-info">{{u.name || u.address}}</span>
|
||||
Cc: <span ng-repeat="u in state.mailList.selected.cc" class="label" ng-class="{'label-primary': u.secure === false}" data-icon-append="{{(u.secure === false) ? '' : ''}}" ng-mouseover="getKeyId(u.address)" ng-click="invite(u)" popover="#fingerprint-info">{{u.name || u.address}}</span>
|
||||
</p>
|
||||
</div>
|
||||
</div><!--/.headers-->
|
||||
@ -54,6 +54,6 @@
|
||||
<!-- popovers -->
|
||||
<div id="fingerprint-info" class="popover right" ng-controller="PopoverCtrl">
|
||||
<div class="arrow"></div>
|
||||
<div class="popover-content"><b>PGP key:</b> {{keyId}}</div>
|
||||
<div class="popover-content">{{keyId}}</div>
|
||||
</div><!--/.popover-->
|
||||
</div><!--/.view-read-->
|
||||
|
@ -5,8 +5,7 @@ define(function(require) {
|
||||
OutboxBO = require('js/bo/outbox'),
|
||||
KeychainDAO = require('js/dao/keychain-dao'),
|
||||
EmailDAO = require('js/dao/email-dao'),
|
||||
DeviceStorageDAO = require('js/dao/devicestorage-dao'),
|
||||
InvitationDAO = require('js/dao/invitation-dao');
|
||||
DeviceStorageDAO = require('js/dao/devicestorage-dao');
|
||||
|
||||
chai.Assertion.includeStack = true;
|
||||
|
||||
@ -25,7 +24,6 @@ define(function(require) {
|
||||
};
|
||||
devicestorageStub = sinon.createStubInstance(DeviceStorageDAO);
|
||||
keychainStub = sinon.createStubInstance(KeychainDAO);
|
||||
invitationDaoStub = sinon.createStubInstance(InvitationDAO);
|
||||
outbox = new OutboxBO(emailDaoStub, keychainStub, devicestorageStub, invitationDaoStub);
|
||||
});
|
||||
|
||||
@ -46,7 +44,7 @@ define(function(require) {
|
||||
});
|
||||
|
||||
describe('put', function() {
|
||||
it('should encrypt and store a mail', function(done) {
|
||||
it('should not encrypt and store a mail', function(done) {
|
||||
var mail, senderKey, receiverKey;
|
||||
|
||||
senderKey = {
|
||||
@ -75,9 +73,51 @@ define(function(require) {
|
||||
keychainStub.getReceiverPublicKey.withArgs(mail.to[0].address).yieldsAsync(null, receiverKey);
|
||||
keychainStub.getReceiverPublicKey.withArgs(mail.to[1].address).yieldsAsync();
|
||||
|
||||
devicestorageStub.storeList.withArgs([mail]).yieldsAsync();
|
||||
|
||||
outbox.put(mail, function(error) {
|
||||
expect(error).to.not.exist;
|
||||
|
||||
expect(mail.publicKeysArmored.length).to.equal(2);
|
||||
expect(emailDaoStub.encrypt.called).to.be.false;
|
||||
expect(devicestorageStub.storeList.calledOnce).to.be.true;
|
||||
|
||||
done();
|
||||
});
|
||||
});
|
||||
|
||||
it('should encrypt and store a mail', function(done) {
|
||||
var mail, senderKey, receiverKey;
|
||||
|
||||
senderKey = {
|
||||
publicKey: 'SENDER PUBLIC KEY'
|
||||
};
|
||||
receiverKey = {
|
||||
publicKey: 'RECEIVER PUBLIC KEY'
|
||||
};
|
||||
mail = {
|
||||
from: [{
|
||||
name: 'member',
|
||||
address: 'member@whiteout.io'
|
||||
}],
|
||||
to: [{
|
||||
name: 'member',
|
||||
address: 'member'
|
||||
}, {
|
||||
name: 'notamember',
|
||||
address: 'notamember'
|
||||
}],
|
||||
cc: [],
|
||||
bcc: []
|
||||
};
|
||||
|
||||
keychainStub.getReceiverPublicKey.withArgs(mail.from[0].address).yieldsAsync(null, senderKey);
|
||||
keychainStub.getReceiverPublicKey.withArgs(mail.to[0].address).yieldsAsync(null, receiverKey);
|
||||
keychainStub.getReceiverPublicKey.withArgs(mail.to[1].address).yieldsAsync(null, receiverKey);
|
||||
|
||||
emailDaoStub.encrypt.withArgs({
|
||||
mail: mail,
|
||||
publicKeysArmored: [senderKey.publicKey, receiverKey.publicKey]
|
||||
publicKeysArmored: [senderKey.publicKey, receiverKey.publicKey, receiverKey.publicKey]
|
||||
}).yieldsAsync();
|
||||
|
||||
devicestorageStub.storeList.withArgs([mail]).yieldsAsync();
|
||||
@ -85,8 +125,9 @@ define(function(require) {
|
||||
outbox.put(mail, function(error) {
|
||||
expect(error).to.not.exist;
|
||||
|
||||
expect(mail.publicKeysArmored.length).to.equal(2);
|
||||
expect(mail.unregisteredUsers.length).to.equal(1);
|
||||
expect(mail.publicKeysArmored.length).to.equal(3);
|
||||
expect(emailDaoStub.encrypt.calledOnce).to.be.true;
|
||||
expect(devicestorageStub.storeList.calledOnce).to.be.true;
|
||||
|
||||
done();
|
||||
});
|
||||
@ -162,28 +203,8 @@ define(function(require) {
|
||||
keychainStub.getReceiverPublicKey.withArgs(notinvited.unregisteredUsers[0].address).yieldsAsync();
|
||||
keychainStub.getReceiverPublicKey.withArgs(newlyjoined.unregisteredUsers[0].address).yieldsAsync(null, newlyjoinedKey);
|
||||
|
||||
invitationDaoStub.check.withArgs({
|
||||
recipient: invited.to[0].address,
|
||||
sender: invited.from[0].address
|
||||
}).yieldsAsync(null, InvitationDAO.INVITE_PENDING);
|
||||
|
||||
invitationDaoStub.check.withArgs({
|
||||
recipient: notinvited.to[0].address,
|
||||
sender: notinvited.from[0].address
|
||||
}).yieldsAsync(null, InvitationDAO.INVITE_MISSING);
|
||||
|
||||
invitationDaoStub.invite.withArgs({
|
||||
recipient: notinvited.to[0].address,
|
||||
sender: notinvited.from[0].address
|
||||
}).yieldsAsync(null, InvitationDAO.INVITE_SUCCESS);
|
||||
|
||||
emailDaoStub.sendPlaintext.yieldsAsync();
|
||||
|
||||
emailDaoStub.reEncrypt.withArgs({
|
||||
mail: newlyjoined,
|
||||
publicKeysArmored: [newlyjoinedKey.publicKey]
|
||||
}).yieldsAsync(null, newlyjoined);
|
||||
|
||||
emailDaoStub.sendEncrypted.withArgs({
|
||||
email: newlyjoined
|
||||
}).yieldsAsync();
|
||||
|
Loading…
Reference in New Issue
Block a user