mirror of
https://github.com/moparisthebest/mail
synced 2025-01-31 07:00:17 -05:00
seperate imap and smtp code in email dao
This commit is contained in:
parent
d810416370
commit
7b695d3449
@ -78,7 +78,7 @@ define(function(require) {
|
|||||||
};
|
};
|
||||||
|
|
||||||
//
|
//
|
||||||
// IMAP/SMTP Apis
|
// IMAP Apis
|
||||||
//
|
//
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -100,186 +100,6 @@ define(function(require) {
|
|||||||
self._imapClient.logout(callback);
|
self._imapClient.logout(callback);
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
|
||||||
* Send an email client side via STMP.
|
|
||||||
*/
|
|
||||||
EmailDAO.prototype.smtpSend = function(email, callback) {
|
|
||||||
var self = this,
|
|
||||||
invalidRecipient;
|
|
||||||
|
|
||||||
// validate the email input
|
|
||||||
if (!email.to || !email.from || !email.to[0].address || !email.from[0].address) {
|
|
||||||
callback({
|
|
||||||
errMsg: 'Invalid email object!'
|
|
||||||
});
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
// validate email addresses
|
|
||||||
_.each(email.to, function(i) {
|
|
||||||
if (!util.validateEmailAddress(i.address)) {
|
|
||||||
invalidRecipient = i.address;
|
|
||||||
}
|
|
||||||
});
|
|
||||||
if (invalidRecipient) {
|
|
||||||
callback({
|
|
||||||
errMsg: 'Invalid recipient: ' + invalidRecipient
|
|
||||||
});
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
if (!util.validateEmailAddress(email.from[0].address)) {
|
|
||||||
callback({
|
|
||||||
errMsg: 'Invalid sender: ' + email.from
|
|
||||||
});
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
// only support single recipient for e-2-e encryption
|
|
||||||
// check if receiver has a public key
|
|
||||||
self._keychain.getReveiverPublicKey(email.to[0].address, function(err, receiverPubkey) {
|
|
||||||
if (err) {
|
|
||||||
callback(err);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
// validate public key
|
|
||||||
if (!receiverPubkey) {
|
|
||||||
callback({
|
|
||||||
errMsg: 'User has no public key yet!'
|
|
||||||
});
|
|
||||||
// user hasn't registered a public key yet... invite
|
|
||||||
//self.encryptForNewUser(email, callback);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
// public key found... encrypt and send
|
|
||||||
self.encryptForUser(email, receiverPubkey, callback);
|
|
||||||
});
|
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Encrypt an email asymmetrically for an exisiting user with their public key
|
|
||||||
*/
|
|
||||||
EmailDAO.prototype.encryptForUser = function(email, receiverPubkey, callback) {
|
|
||||||
var self = this,
|
|
||||||
ptItems = bundleForEncryption(email),
|
|
||||||
receiverPubkeys = [receiverPubkey];
|
|
||||||
|
|
||||||
// encrypt the email
|
|
||||||
self._crypto.encryptListForUser(ptItems, receiverPubkeys, function(err, encryptedList) {
|
|
||||||
if (err) {
|
|
||||||
callback(err);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
// bundle encrypted email together for sending
|
|
||||||
bundleEncryptedItems(email, encryptedList);
|
|
||||||
|
|
||||||
self.send(email, callback);
|
|
||||||
});
|
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Encrypt an email symmetrically for a new user, write the secret one time key to the cloudstorage REST service, and send the email client side via SMTP.
|
|
||||||
*/
|
|
||||||
EmailDAO.prototype.encryptForNewUser = function(email, callback) {
|
|
||||||
var self = this,
|
|
||||||
ptItems = bundleForEncryption(email);
|
|
||||||
|
|
||||||
self._crypto.symEncryptList(ptItems, function(err, result) {
|
|
||||||
if (err) {
|
|
||||||
callback(err);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
// bundle encrypted email together for sending
|
|
||||||
bundleEncryptedItems(email, result.list);
|
|
||||||
|
|
||||||
// TODO: write result.key to REST endpoint
|
|
||||||
|
|
||||||
self.send(email, callback);
|
|
||||||
});
|
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Give the email a newly generated UUID, remove its attachments, and bundle all plaintext items to a batchable array for encryption.
|
|
||||||
*/
|
|
||||||
|
|
||||||
function bundleForEncryption(email) {
|
|
||||||
var ptItems = [email];
|
|
||||||
|
|
||||||
// generate a new UUID for the new email
|
|
||||||
email.id = util.UUID();
|
|
||||||
|
|
||||||
// add attachment to encryption batch and remove from email object
|
|
||||||
if (email.attachments) {
|
|
||||||
email.attachments.forEach(function(attachment) {
|
|
||||||
attachment.id = email.id;
|
|
||||||
ptItems.push(attachment);
|
|
||||||
});
|
|
||||||
delete email.attachments;
|
|
||||||
}
|
|
||||||
|
|
||||||
return ptItems;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Frame the encrypted email message and append the encrypted attachments.
|
|
||||||
*/
|
|
||||||
|
|
||||||
function bundleEncryptedItems(email, encryptedList) {
|
|
||||||
var i;
|
|
||||||
|
|
||||||
// replace body and subject of the email with encrypted versions
|
|
||||||
email = frameEncryptedMessage(email, encryptedList[0]);
|
|
||||||
|
|
||||||
// add encrypted attachments
|
|
||||||
if (encryptedList.length > 1) {
|
|
||||||
email.attachments = [];
|
|
||||||
}
|
|
||||||
for (i = 1; i < encryptedList.length; i++) {
|
|
||||||
email.attachments.push({
|
|
||||||
fileName: 'Encrypted Attachment ' + i,
|
|
||||||
contentType: 'application/octet-stream',
|
|
||||||
uint8Array: util.binStr2Uint8Arr(JSON.stringify(encryptedList[i]))
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Frames an encrypted message in base64 Format.
|
|
||||||
*/
|
|
||||||
|
|
||||||
function frameEncryptedMessage(email, ct) {
|
|
||||||
var to, greeting, ctBase64;
|
|
||||||
|
|
||||||
var SUBJECT = str.subject,
|
|
||||||
MESSAGE = str.message + '\n\n\n',
|
|
||||||
PREFIX = str.cryptPrefix + '\n',
|
|
||||||
SUFFIX = '\n' + str.cryptSuffix,
|
|
||||||
SIGNATURE = '\n\n\n' + str.signature + '\n' + str.webSite + '\n\n';
|
|
||||||
|
|
||||||
// get first name of recipient
|
|
||||||
to = (email.to[0].name || email.to[0].address).split('@')[0].split('.')[0].split(' ')[0];
|
|
||||||
greeting = 'Hi ' + to + ',\n\n';
|
|
||||||
|
|
||||||
// build encrypted text body
|
|
||||||
ctBase64 = btoa(JSON.stringify(ct));
|
|
||||||
email.body = greeting + MESSAGE + PREFIX + ctBase64 + SUFFIX + SIGNATURE;
|
|
||||||
email.subject = SUBJECT;
|
|
||||||
|
|
||||||
return email;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Send an actual message object via smtp
|
|
||||||
*/
|
|
||||||
EmailDAO.prototype.send = function(email, callback) {
|
|
||||||
var self = this;
|
|
||||||
|
|
||||||
self._smtpClient.send(email, callback);
|
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* List the folders in the user's IMAP mailbox.
|
* List the folders in the user's IMAP mailbox.
|
||||||
*/
|
*/
|
||||||
@ -564,5 +384,189 @@ define(function(require) {
|
|||||||
}, messageReady);
|
}, messageReady);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
//
|
||||||
|
// SMTP Apis
|
||||||
|
//
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Send an email client side via STMP.
|
||||||
|
*/
|
||||||
|
EmailDAO.prototype.smtpSend = function(email, callback) {
|
||||||
|
var self = this,
|
||||||
|
invalidRecipient;
|
||||||
|
|
||||||
|
// validate the email input
|
||||||
|
if (!email.to || !email.from || !email.to[0].address || !email.from[0].address) {
|
||||||
|
callback({
|
||||||
|
errMsg: 'Invalid email object!'
|
||||||
|
});
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// validate email addresses
|
||||||
|
_.each(email.to, function(i) {
|
||||||
|
if (!util.validateEmailAddress(i.address)) {
|
||||||
|
invalidRecipient = i.address;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
if (invalidRecipient) {
|
||||||
|
callback({
|
||||||
|
errMsg: 'Invalid recipient: ' + invalidRecipient
|
||||||
|
});
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (!util.validateEmailAddress(email.from[0].address)) {
|
||||||
|
callback({
|
||||||
|
errMsg: 'Invalid sender: ' + email.from
|
||||||
|
});
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// only support single recipient for e-2-e encryption
|
||||||
|
// check if receiver has a public key
|
||||||
|
self._keychain.getReveiverPublicKey(email.to[0].address, function(err, receiverPubkey) {
|
||||||
|
if (err) {
|
||||||
|
callback(err);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// validate public key
|
||||||
|
if (!receiverPubkey) {
|
||||||
|
callback({
|
||||||
|
errMsg: 'User has no public key yet!'
|
||||||
|
});
|
||||||
|
// user hasn't registered a public key yet... invite
|
||||||
|
//self.encryptForNewUser(email, callback);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// public key found... encrypt and send
|
||||||
|
self.encryptForUser(email, receiverPubkey, callback);
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Encrypt an email asymmetrically for an exisiting user with their public key
|
||||||
|
*/
|
||||||
|
EmailDAO.prototype.encryptForUser = function(email, receiverPubkey, callback) {
|
||||||
|
var self = this,
|
||||||
|
ptItems = bundleForEncryption(email),
|
||||||
|
receiverPubkeys = [receiverPubkey];
|
||||||
|
|
||||||
|
// encrypt the email
|
||||||
|
self._crypto.encryptListForUser(ptItems, receiverPubkeys, function(err, encryptedList) {
|
||||||
|
if (err) {
|
||||||
|
callback(err);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// bundle encrypted email together for sending
|
||||||
|
bundleEncryptedItems(email, encryptedList);
|
||||||
|
|
||||||
|
self.send(email, callback);
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Encrypt an email symmetrically for a new user, write the secret one time key to the cloudstorage REST service, and send the email client side via SMTP.
|
||||||
|
*/
|
||||||
|
EmailDAO.prototype.encryptForNewUser = function(email, callback) {
|
||||||
|
var self = this,
|
||||||
|
ptItems = bundleForEncryption(email);
|
||||||
|
|
||||||
|
self._crypto.symEncryptList(ptItems, function(err, result) {
|
||||||
|
if (err) {
|
||||||
|
callback(err);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// bundle encrypted email together for sending
|
||||||
|
bundleEncryptedItems(email, result.list);
|
||||||
|
|
||||||
|
// TODO: write result.key to REST endpoint
|
||||||
|
|
||||||
|
self.send(email, callback);
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Give the email a newly generated UUID, remove its attachments, and bundle all plaintext items to a batchable array for encryption.
|
||||||
|
*/
|
||||||
|
|
||||||
|
function bundleForEncryption(email) {
|
||||||
|
var ptItems = [email];
|
||||||
|
|
||||||
|
// generate a new UUID for the new email
|
||||||
|
email.id = util.UUID();
|
||||||
|
|
||||||
|
// add attachment to encryption batch and remove from email object
|
||||||
|
if (email.attachments) {
|
||||||
|
email.attachments.forEach(function(attachment) {
|
||||||
|
attachment.id = email.id;
|
||||||
|
ptItems.push(attachment);
|
||||||
|
});
|
||||||
|
delete email.attachments;
|
||||||
|
}
|
||||||
|
|
||||||
|
return ptItems;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Frame the encrypted email message and append the encrypted attachments.
|
||||||
|
*/
|
||||||
|
|
||||||
|
function bundleEncryptedItems(email, encryptedList) {
|
||||||
|
var i;
|
||||||
|
|
||||||
|
// replace body and subject of the email with encrypted versions
|
||||||
|
email = frameEncryptedMessage(email, encryptedList[0]);
|
||||||
|
|
||||||
|
// add encrypted attachments
|
||||||
|
if (encryptedList.length > 1) {
|
||||||
|
email.attachments = [];
|
||||||
|
}
|
||||||
|
for (i = 1; i < encryptedList.length; i++) {
|
||||||
|
email.attachments.push({
|
||||||
|
fileName: 'Encrypted Attachment ' + i,
|
||||||
|
contentType: 'application/octet-stream',
|
||||||
|
uint8Array: util.binStr2Uint8Arr(JSON.stringify(encryptedList[i]))
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Frames an encrypted message in base64 Format.
|
||||||
|
*/
|
||||||
|
|
||||||
|
function frameEncryptedMessage(email, ct) {
|
||||||
|
var to, greeting, ctBase64;
|
||||||
|
|
||||||
|
var SUBJECT = str.subject,
|
||||||
|
MESSAGE = str.message + '\n\n\n',
|
||||||
|
PREFIX = str.cryptPrefix + '\n',
|
||||||
|
SUFFIX = '\n' + str.cryptSuffix,
|
||||||
|
SIGNATURE = '\n\n\n' + str.signature + '\n' + str.webSite + '\n\n';
|
||||||
|
|
||||||
|
// get first name of recipient
|
||||||
|
to = (email.to[0].name || email.to[0].address).split('@')[0].split('.')[0].split(' ')[0];
|
||||||
|
greeting = 'Hi ' + to + ',\n\n';
|
||||||
|
|
||||||
|
// build encrypted text body
|
||||||
|
ctBase64 = btoa(JSON.stringify(ct));
|
||||||
|
email.body = greeting + MESSAGE + PREFIX + ctBase64 + SUFFIX + SIGNATURE;
|
||||||
|
email.subject = SUBJECT;
|
||||||
|
|
||||||
|
return email;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Send an actual message object via smtp
|
||||||
|
*/
|
||||||
|
EmailDAO.prototype.send = function(email, callback) {
|
||||||
|
var self = this;
|
||||||
|
|
||||||
|
self._smtpClient.send(email, callback);
|
||||||
|
};
|
||||||
|
|
||||||
return EmailDAO;
|
return EmailDAO;
|
||||||
});
|
});
|
Loading…
Reference in New Issue
Block a user