diff --git a/src/js/controller/mail-list.js b/src/js/controller/mail-list.js index 55731c1..ef224df 100644 --- a/src/js/controller/mail-list.js +++ b/src/js/controller/mail-list.js @@ -20,7 +20,12 @@ define(function(require) { // push handler if (emailDao) { emailDao.onIncomingMessage = function(email) { - if (email.subject.indexOf(str.subjectPrefix) === -1) { + if (!email.subject) { + return; + } + + if (email.subject.indexOf(str.subjectPrefix) === -1 || + email.subject === str.subjectPrefix + str.verificationSubject) { return; } diff --git a/src/js/dao/email-dao.js b/src/js/dao/email-dao.js index 7ce5d38..8352354 100644 --- a/src/js/dao/email-dao.js +++ b/src/js/dao/email-dao.js @@ -486,9 +486,8 @@ define(function(require) { return; } - // imap filtering may not be sufficient, since google filters out - // non-alphabetical characters - if (message.subject.indexOf(str.subjectPrefix) === -1) { + // imap filtering is insufficient, since google ignores non-alphabetical characters + if (message.subject.indexOf(str.subjectPrefix.trim()) === -1) { syncNextItem(); return; } @@ -718,7 +717,7 @@ define(function(require) { } function verify(email, localCallback) { - var uuid, index, verifyUrlPrefix = config.cloudUrl + config.verificationUrl; + var uuid, isValidUuid, index, verifyUrlPrefix = config.cloudUrl + config.verificationUrl; if (!email.unread) { // don't bother if the email was already marked as read @@ -733,8 +732,14 @@ define(function(require) { return; } - uuid = email.body.substr(index + verifyUrlPrefix.length, config.verificationUuidLength); + isValidUuid = new RegExp('[0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{12}').test(uuid); + if (!isValidUuid) { + // there's no valid uuid in the email, so forget about that, too. + localCallback(); + return; + } + self._keychain.verifyPublicKey(uuid, function(err) { if (err) { localCallback({ diff --git a/src/js/dao/publickey-dao.js b/src/js/dao/publickey-dao.js index d9177d6..0674d76 100644 --- a/src/js/dao/publickey-dao.js +++ b/src/js/dao/publickey-dao.js @@ -14,7 +14,15 @@ define(function() { this._restDao.get({ uri: uri, type: 'text' - }, callback); + }, function(err, res, status) { + if (err && err.code === 400) { + // there was an attempt to verify a non-existing public key + callback(); + return; + } + + callback(err, res, status); + }); }; /** diff --git a/test/new-unit/email-dao-test.js b/test/new-unit/email-dao-test.js index 0b32534..f596085 100644 --- a/test/new-unit/email-dao-test.js +++ b/test/new-unit/email-dao-test.js @@ -15,6 +15,7 @@ define(function(require) { var emailAddress, passphrase, asymKeySize, mockkeyId, dummyEncryptedMail, dummyDecryptedMail, mockKeyPair, account, publicKey, verificationMail, verificationUuid, + corruptedVerificationMail, corruptedVerificationUuid, nonWhitelistedMail; beforeEach(function(done) { @@ -35,7 +36,7 @@ define(function(require) { unread: false, answered: false }; - verificationUuid = 'OMFG_FUCKING_BASTARD_UUID_FROM_HELL!'; + verificationUuid = '9A858952-17EE-4273-9E74-D309EAFDFAFB'; verificationMail = { from: [{ name: 'Whiteout Test', @@ -49,6 +50,20 @@ define(function(require) { unread: true, answered: false }; + corruptedVerificationUuid = 'OMFG_FUCKING_BASTARD_UUID_FROM_HELL!'; + corruptedVerificationMail = { + from: [{ + name: 'Whiteout Test', + address: 'whiteout.test@t-online.de' + }], // sender address + to: [{ + address: 'safewithme.testuser@gmail.com' + }], // list of receivers + subject: "[whiteout] New public key uploaded", // Subject line + body: 'yadda yadda bla blabla foo bar https://keys.whiteout.io/verify/' + corruptedVerificationUuid, // plaintext body + unread: true, + answered: false + }; dummyDecryptedMail = { uid: 1234, from: [{ @@ -193,7 +208,9 @@ define(function(require) { // initFolders listFolderStub = sinon.stub(dao, '_imapListFolders'); - listFolderStub.yields({code:42}); + listFolderStub.yields({ + code: 42 + }); dao.init({ account: account @@ -1666,7 +1683,6 @@ define(function(require) { dao.sync({ folder: folder }, function(err) { - if (invocations === 0) { expect(err).to.not.exist; expect(dao._account.busy).to.be.true; @@ -1714,7 +1730,6 @@ define(function(require) { dao.sync({ folder: folder }, function(err) { - if (invocations === 0) { expect(err).to.not.exist; expect(dao._account.busy).to.be.true; @@ -1761,7 +1776,6 @@ define(function(require) { dao.sync({ folder: folder }, function(err) { - if (invocations === 0) { expect(err).to.not.exist; expect(dao._account.busy).to.be.true; @@ -1814,6 +1828,59 @@ define(function(require) { markReadStub = sinon.stub(dao, '_imapMark'); imapDeleteStub = sinon.stub(dao, '_imapDeleteMessage'); + dao.sync({ + folder: folder + }, function(err) { + if (invocations === 0) { + expect(err).to.not.exist; + expect(dao._account.busy).to.be.true; + invocations++; + return; + } + + expect(err).to.not.exist; + expect(dao._account.busy).to.be.false; + expect(dao._account.folders[0].messages).to.be.empty; + expect(localListStub.calledOnce).to.be.true; + expect(imapSearchStub.calledThrice).to.be.true; + expect(imapGetStub.calledOnce).to.be.true; + expect(keychainStub.verifyPublicKey.called).to.be.false; + expect(markReadStub.called).to.be.false; + expect(imapDeleteStub.called).to.be.false; + + done(); + }); + }); + + it('should not bother about corrupted authentication mails', function(done) { + var invocations, folder, localListStub, imapSearchStub, imapGetStub, markReadStub, imapDeleteStub; + + invocations = 0; + folder = 'FOLDAAAA'; + dao._account.folders = [{ + type: 'Folder', + path: folder, + messages: [] + }]; + + localListStub = sinon.stub(dao, '_localListMessages').yields(null, []); + imapSearchStub = sinon.stub(dao, '_imapSearch'); + imapSearchStub.withArgs({ + folder: folder + }).yields(null, [corruptedVerificationMail.uid]); + imapSearchStub.withArgs({ + folder: folder, + unread: true + }).yields(null, []); + imapSearchStub.withArgs({ + folder: folder, + answered: true + }).yields(null, []); + + imapGetStub = sinon.stub(dao, '_imapGetMessage').yields(null, corruptedVerificationMail); + markReadStub = sinon.stub(dao, '_imapMark'); + imapDeleteStub = sinon.stub(dao, '_imapDeleteMessage'); + dao.sync({ folder: folder }, function(err) { @@ -1838,7 +1905,7 @@ define(function(require) { }); }); - it('should not bother about corrupted authentication mails', function(done) { + it('should not bother about corrupted authentication mails no verification link', function(done) { var invocations, folder, localListStub, imapSearchStub, imapGetStub, markReadStub, imapDeleteStub; diff --git a/test/new-unit/publickey-dao-test.js b/test/new-unit/publickey-dao-test.js index 3ac5705..8e9930f 100644 --- a/test/new-unit/publickey-dao-test.js +++ b/test/new-unit/publickey-dao-test.js @@ -49,12 +49,23 @@ define(function(require) { it('should fail', function(done) { restDaoStub.get.yields(42); - pubkeyDao.get('id', function(err) { + pubkeyDao.verify('id', function(err) { expect(err).to.exist; done(); }); }); + it('should not error for 400', function(done) { + restDaoStub.get.yields({ + code: 400 + }); + + pubkeyDao.verify('id', function(err) { + expect(err).to.not.exist; + done(); + }); + }); + it('should work', function(done) { var uuid = 'c621e328-8548-40a1-8309-adf1955e98a9'; restDaoStub.get.yields(null);