From 47f1f440d726d579f8645ec999ad7797cac2c192 Mon Sep 17 00:00:00 2001 From: Evan Morikawa Date: Tue, 31 Jan 2017 18:00:42 -0800 Subject: [PATCH] [local-sync] fixed issue where single digit date would create dupes --- .../src/local-sync-worker/sync-worker.es6 | 7 ++++++- packages/local-sync/src/models/message.js | 8 ++++++++ packages/local-sync/src/models/thread.js | 6 +++++- .../local-sync/src/shared/message-factory.js | 17 ++++++++++++++--- 4 files changed, 33 insertions(+), 5 deletions(-) diff --git a/packages/local-sync/src/local-sync-worker/sync-worker.es6 b/packages/local-sync/src/local-sync-worker/sync-worker.es6 index 06aa3de21..edf32a2c6 100644 --- a/packages/local-sync/src/local-sync-worker/sync-worker.es6 +++ b/packages/local-sync/src/local-sync-worker/sync-worker.es6 @@ -93,8 +93,13 @@ class SyncWorker { isSending: {$not: true}, }, }) + const noFolderImapUID = await Message.findAll({ + where: { + folderImapUID: null, + }, + }) const affectedThreadIds = new Set(); - await Promise.map(orphans, (msg) => { + await Promise.map(orphans.concat(noFolderImapUID), (msg) => { affectedThreadIds.add(msg.threadId); return msg.destroy(); }); diff --git a/packages/local-sync/src/models/message.js b/packages/local-sync/src/models/message.js index cfd6b109d..c4286f3ba 100644 --- a/packages/local-sync/src/models/message.js +++ b/packages/local-sync/src/models/message.js @@ -97,6 +97,14 @@ module.exports = (sequelize, Sequelize) => { return crypto.createHash('sha256').update(data, 'utf8').digest('hex'); }, + dateString(strOrDate) { + let date = strOrDate; + if (typeof strOrDate === 'string') { + date = new Date(Date.parse(strOrDate)); + } + return date.toUTCString().replace(/GMT/, '+0000') + }, + buildHeaderMessageId(id) { return `<${id}@nylas-mail.nylas.com>` }, diff --git a/packages/local-sync/src/models/thread.js b/packages/local-sync/src/models/thread.js index f37ddb280..84c84c2f9 100644 --- a/packages/local-sync/src/models/thread.js +++ b/packages/local-sync/src/models/thread.js @@ -55,7 +55,11 @@ module.exports = (sequelize, Sequelize) => { await Promise.all(messages.map(async (msg) => { const labels = await msg.getLabels({attributes: ['id']}) - labels.forEach(({id}) => labelIds.add(id)); + labels.forEach(({id}) => { + if (!id) return; + labelIds.add(id); + }) + if (!msg.folderId) return; folderIds.add(msg.folderId) })); diff --git a/packages/local-sync/src/shared/message-factory.js b/packages/local-sync/src/shared/message-factory.js index 138497d16..87f3207e5 100644 --- a/packages/local-sync/src/shared/message-factory.js +++ b/packages/local-sync/src/shared/message-factory.js @@ -297,10 +297,21 @@ async function parseFromImap(imapMessage, desiredParts, {db, accountId, folder}) gThrId: parsedHeaders['x-gm-thrid'], subject: parsedHeaders.subject ? parsedHeaders.subject[0] : '(no subject)', } + + + /** + * mimelib will return a string date with the leading zero of single + * digit dates truncated. e.g. February 1 instead of February 01. When + * we set Message Date headers, we use javascript's `toUTCString` which + * zero pads digit dates. To make the hashes line up, we need to ensure + * that the date string used in the ID generation is also zero-padded. + */ + const messageForHashing = Utils.deepClone(parsedMessage) + messageForHashing.date = Message.dateString(parsedMessage.date); // Inversely to `buildForSend`, we leave the date header as it is so that the // format is consistent for the generative IDs, then convert it to a Date object - parsedMessage.id = Message.hash(parsedMessage) - parsedMessage.date = new Date(Date.parse(parsedMessage.date)) + parsedMessage.id = Message.hash(messageForHashing) + parsedMessage.date = new Date(Date.parse(parsedMessage.date)); parsedMessage.snippet = parseSnippet(parsedMessage.body); @@ -397,7 +408,7 @@ async function buildForSend(db, json) { // the date header with this modified UTC string // https://github.com/nodemailer/buildmail/blob/master/lib/buildmail.js#L470 const messageForHashing = Utils.deepClone(message) - messageForHashing.date = date.toUTCString().replace(/GMT/, '+0000') + messageForHashing.date = Message.dateString(date) message.id = Message.hash(messageForHashing) message.body = replaceMessageIdInBodyTrackingLinks(message.id, message.body) const instance = Message.build(message)