From 84a3b20839bd3efa9685232418caeda4df1f60fd Mon Sep 17 00:00:00 2001 From: Christine Spang Date: Tue, 21 Feb 2017 16:15:07 -0800 Subject: [PATCH] [client-sync] Refresh SMTP client when auth credentials change Summary: Previously, we would create a nodemailer SMTP transport object when the sync worker booted up. The transport object would be passed the account SMTP credentials at the time of object creation. If the Google auth token later expired, we would continue to try to send mail using the expired token, resulting in "Invalid login" failures. This patch makes it so we refresh the transport object if the auth token changes, and also turns on SMTP connection pooling to limit simultaneous SMTP connections (& maybe make sending multiple messages faster). Fixes T7891 Test Plan: manual Reviewers: juan, halla Reviewed By: juan, halla Subscribers: mark Maniphest Tasks: T7891 Differential Revision: https://phab.nylas.com/D3997 --- .../src/local-sync-worker/sync-worker.es6 | 13 +++++++++---- packages/isomorphic-core/src/sendmail-client.es6 | 2 +- 2 files changed, 10 insertions(+), 5 deletions(-) diff --git a/packages/client-sync/src/local-sync-worker/sync-worker.es6 b/packages/client-sync/src/local-sync-worker/sync-worker.es6 index cd5928121..74946946c 100644 --- a/packages/client-sync/src/local-sync-worker/sync-worker.es6 +++ b/packages/client-sync/src/local-sync-worker/sync-worker.es6 @@ -29,13 +29,13 @@ class SyncWorker { this._db = db; this._manager = parentManager; this._conn = null; + this._smtp = null; this._account = account; this._currentTask = null this._mailListenerConn = null this._interruptible = new Interruptible() this._localDeltas = new LocalSyncDeltaEmitter(db, account.id) this._logger = global.Logger.forAccount(account) - this._smtp = new SendmailClient(this._account, this._logger) this._startTime = Date.now() this._lastSyncTime = null @@ -219,7 +219,7 @@ class SyncWorker { async _ensureConnection() { const newCredentials = await this._ensureAccessToken() - if (!newCredentials && this._conn) { + if (!newCredentials && this._conn && this._smtp) { // We already have a connection and we don't need to update the // credentials return this._conn.connect(); @@ -235,9 +235,14 @@ class SyncWorker { if (!settings || !settings.imap_host) { throw new Error("_ensureConnection: There are no IMAP connection settings for this account."); } - if (!credentials) { - throw new Error("_ensureConnection: There are no IMAP connection credentials for this account."); + if (!settings.smtp_host && !settings.smtp_custom_config) { + throw new Error("_ensureConnection: There are no SMTP connection settings for this account."); } + if (!credentials) { + throw new Error("_ensureConnection: There are no IMAP/SMTP connection credentials for this account."); + } + + this._smtp = new SendmailClient(this._account, this._logger) this._socketTimeout = this._getIMAPSocketTimeout() const conn = new IMAPConnection({ diff --git a/packages/isomorphic-core/src/sendmail-client.es6 b/packages/isomorphic-core/src/sendmail-client.es6 index 941e506ef..c37ae89b1 100644 --- a/packages/isomorphic-core/src/sendmail-client.es6 +++ b/packages/isomorphic-core/src/sendmail-client.es6 @@ -13,7 +13,7 @@ const formatParticipants = (participants) => { class SendmailClient { constructor(account, logger) { - this._transporter = nodemailer.createTransport(account.smtpConfig()); + this._transporter = nodemailer.createTransport(Object.assign(account.smtpConfig(), {pool: true})); this._logger = logger; }