422a01b3607655003889ad6c361b9f019a8623c4
[motion.git] / server / config / smtp / smtp.js
1 'use strict';
2
3 var _ = require('lodash');
4 var nodemailer = require('nodemailer');
5 var smtpTransport = require('nodemailer-smtp-transport');
6
7 var Contact = require('../../models').Contact;
8 var MailRoom = require('../../models').MailRoom;
9 var MailMessage = require('../../models').MailMessage;
10 var ContactEmail = require('../../models').ContactEmail;
11 var MailServerOut = require('../../models').MailServerOut;
12
13 module.exports = {
14   create: function (doc) {
15
16     var _smtp;
17     var _doc;
18
19     function onSave(doc) {
20       console.log("MAIL - Account " + doc.username + " SMTP CREATE");
21       _doc = doc;
22       _smtp = nodemailer.createTransport(smtpTransport({
23         host: doc.host,
24         port: doc.port,
25         secure: doc.ssl,
26         debug: true,
27         auth: {
28           user: doc.username,
29           pass: doc.password
30         }
31       }));
32     }
33
34     function onUpdate(doc) {
35       if (_smtp.transporter.options.auth.user === doc.username) {
36         console.log("MAIL - Account " + doc.username + " SMTP UPDATE");
37         _smtp = null;
38         _smtp = nodemailer.createTransport(smtpTransport({
39           host: doc.host,
40           port: doc.port,
41           secure: doc.ssl,
42           debug: true,
43           auth: {
44             user: doc.username,
45             pass: doc.password
46           }
47         }));
48       }
49     }
50
51     function onRemove(doc) {
52       if (_smtp.transporter.options.auth.user === doc.username) {
53         console.log("[MAIL - Account " + doc.username + " SMTP DESTROY");
54         _smtp = null;
55       }
56     }
57
58     function onSend(mailMessage, options) {
59       if (mailMessage.changed('status') && mailMessage.status === 'SENDING' && _smtp.transporter.options.auth.user === mailMessage.from) {
60         console.log('onSend', mailMessage.from);
61         var _mRoom;
62         var _mMessage = mailMessage;
63         var _mFrom, _mTo, _mCc, _mBcc;
64
65         if (_mMessage.inReplyTo) {
66           return MailMessage
67             .findOne({
68               where: {
69                 messageId: _mMessage.inReplyTo
70               }
71             })
72             .then(function (mailMessageParent) {
73               return mailMessageParent
74                 .getMailRoom();
75             })
76             .then(function (mailRoom) {
77               _mRoom = mailRoom;
78               return mailRoom
79                 .addMailMessage(_mMessage, {
80                   transaction: options ? options.transaction : null
81                 });
82             })
83             .then(function () {
84               return ContactEmail
85                 .findOrCreate({
86                   where: {
87                     email: _mMessage.from
88                   },
89                   defaults: {
90                     email: _mMessage.from
91                   },
92                   transaction: options ? options.transaction : null
93                 });
94             })
95             .spread(function (mFrom, created) {
96               var promises = [];
97               var tos = _mMessage.to ? _mMessage.to.split(';') : [];
98               _mFrom = mFrom;
99
100               tos.forEach(function (email) {
101                 promises.push(ContactEmail
102                   .findOrCreate({
103                     where: {
104                       email: email
105                     },
106                     defaults: {
107                       email: email
108                     },
109                     transaction: options ? options.transaction : null
110                   }));
111               });
112
113               return promises;
114             })
115             .all()
116             .then(function (mTo) {
117               var promises = [];
118               var ccs = _mMessage.cc ? _mMessage.cc.split(';') : [];
119               _mTo = _.map(mTo, function (elm) {
120                 return elm[0];
121               });
122
123               ccs.forEach(function (email) {
124                 promises.push(ContactEmail
125                   .findOrCreate({
126                     where: {
127                       email: email
128                     },
129                     defaults: {
130                       email: email
131                     },
132                     transaction: options ? options.transaction : null
133                   }));
134               });
135
136               return promises;
137             })
138             .all()
139             .then(function (mCc) {
140               var promises = [];
141               var bccs = _mMessage.bcc ? _mMessage.bcc.split(';') : [];
142               _mCc = _.map(mCc, function (elm) {
143                 return elm[0];
144               });
145
146               bccs.forEach(function (email) {
147                 promises.push(ContactEmail
148                   .findOrCreate({
149                     where: {
150                       email: email
151                     },
152                     defaults: {
153                       email: email
154                     },
155                     transaction: options ? options.transaction : null
156                   }));
157               });
158
159               return promises;
160             })
161             .all()
162             .then(function (mBcc) {
163               _mBcc = _.map(mBcc, function (elm) {
164                 return elm[0];
165               });
166
167               return;
168             })
169             .then(function () {
170               return _mMessage
171                 .setFrom(_mFrom, {
172                   transaction: options ? options.transaction : null
173                 });
174             })
175             .then(function () {
176               return _mMessage
177                 .setTo(_mTo, {
178                   transaction: options ? options.transaction : null
179                 });
180             })
181             .then(function () {
182               return _mMessage
183                 .setCc(_mCc, {
184                   transaction: options ? options.transaction : null
185                 });
186             })
187             .then(function () {
188               return _mMessage
189                 .setBcc(_mBcc, {
190                   transaction: options ? options.transaction : null
191                 });
192             })
193             .then(function () {
194               var mail = {
195                 status: _mMessage.status,
196                 from: _mMessage.from,
197                 to: _mMessage.to,
198                 cc: _mMessage.cc,
199                 subject: _mMessage.subject,
200                 html: _mMessage.html,
201                 text: _mMessage.text,
202                 headers: {
203                   'X-Laziness-level': 1000
204                 }
205               };
206
207               if (_mMessage.MailAttachments) {
208                 mail.attachments = _.map(_mMessage.MailAttachments, function (elm) {
209                   return {
210                     path: elm.path
211                   }
212                 });
213               }
214
215               return new Promise(function (resolve, reject) {
216                 _smtp.sendMail(mail, function (err, info) {
217                   if (err) {
218                     return reject(err);
219                   } else {
220                     resolve(info);
221                   }
222                 });
223               });
224             })
225             .then(function (info) {
226               return _mMessage
227                 .update({
228                   messageId: info.messageId,
229                   status: 'SENT'
230                 }, {
231                   transaction: options ? options.transaction : null
232                 });
233             });
234         } else {
235           return MailRoom
236             .findOrCreate({
237               where: {
238                 id: _mMessage.MailRoomId
239               },
240               defaults: {
241                 subject: _mMessage.subject,
242                 from: _mMessage.from,
243                 status: 'OPEN',
244                 MailAccountId: _doc.MailAccountId
245               },
246               transaction: options ? options.transaction : null
247             })
248             .spread(function (mailRoom) {
249               _mRoom = mailRoom;
250               return mailRoom
251                 .addMailMessage(_mMessage, {
252                   transaction: options ? options.transaction : null
253                 });
254             })
255             .then(function () {
256               return ContactEmail
257                 .findOrCreate({
258                   where: {
259                     email: _mMessage.from
260                   },
261                   defaults: {
262                     email: _mMessage.from,
263                   },
264                   transaction: options ? options.transaction : null
265                 });
266             })
267             .spread(function (mFrom) {
268               var promises = [];
269               var tos = _mMessage.to ? _mMessage.to.split(';') : [];
270               _mFrom = mFrom;
271
272               tos.forEach(function (email) {
273                 promises.push(ContactEmail
274                   .findOrCreate({
275                     where: {
276                       email: email
277                     },
278                     defaults: {
279                       email: email
280                     },
281                     transaction: options ? options.transaction : null
282                   }));
283               });
284
285               return promises;
286             })
287             .all()
288             .then(function (mTo) {
289               var promises = [];
290               var ccs = _mMessage.cc ? _mMessage.cc.split(';') : [];
291               _mTo = _.map(mTo, function (elm) {
292                 return elm[0];
293               });
294
295               ccs.forEach(function (email) {
296                 promises.push(ContactEmail
297                   .findOrCreate({
298                     where: {
299                       email: email
300                     },
301                     defaults: {
302                       email: email
303                     },
304                     transaction: options ? options.transaction : null
305                   }));
306               });
307
308               return promises;
309             })
310             .all()
311             .then(function (mCc) {
312               var promises = [];
313               var bccs = _mMessage.bcc ? _mMessage.bcc.split(';') : [];
314               _mCc = _.map(mCc, function (elm) {
315                 return elm[0];
316               });
317
318               bccs.forEach(function (email) {
319                 promises.push(ContactEmail
320                   .findOrCreate({
321                     where: {
322                       email: email
323                     },
324                     defaults: {
325                       email: email
326                     },
327                     transaction: options ? options.transaction : null
328                   }));
329               });
330
331               return promises;
332             })
333             .all()
334             .then(function (mBcc) {
335               _mBcc = _.map(mBcc, function (elm) {
336                 return elm[0];
337               });
338
339               return;
340             })
341             .then(function () {
342               return _mMessage
343                 .setFrom(_mFrom, {
344                   transaction: options ? options.transaction : null
345                 });
346             })
347             .then(function () {
348               return _mMessage
349                 .setTo(_mTo, {
350                   transaction: options ? options.transaction : null
351                 });
352             })
353             .then(function () {
354               return _mMessage
355                 .setCc(_mCc, {
356                   transaction: options ? options.transaction : null
357                 });
358             })
359             .then(function () {
360               return _mMessage
361                 .setBcc(_mBcc, {
362                   transaction: options ? options.transaction : null
363                 });
364             })
365             .then(function () {
366               var mail = {
367                 status: _mMessage.status,
368                 from: _mMessage.from,
369                 to: _mMessage.to,
370                 cc: _mMessage.cc,
371                 subject: _mMessage.subject,
372                 html: _mMessage.html,
373                 text: _mMessage.text,
374                 headers: {
375                   'X-Laziness-level': 1000
376                 }
377               };
378
379               if (_mMessage.MailAttachments) {
380                 mail.attachments = _.map(_mMessage.MailAttachments, function (elm) {
381                   return {
382                     path: elm.path
383                   }
384                 });
385               }
386
387               return new Promise(function (resolve, reject) {
388                 _smtp.sendMail(mail, function (err, info) {
389                   if (err) {
390                     return reject(err);
391                   } else {
392                     resolve(info);
393                   }
394                 });
395               });
396             })
397             .then(function (info) {
398               return _mMessage
399                 .update({
400                   messageId: info.messageId,
401                   status: 'SENT'
402                 }, {
403                   transaction: options ? options.transaction : null
404                 });
405             });
406         }
407       }
408     }
409
410     onSave(doc);
411
412     // HANDLE ACCOUNT UPDATE/DELETE
413     MailServerOut.afterUpdate(function (doc) {
414       onUpdate(doc);
415     });
416     MailServerOut.afterDestroy(function (doc) {
417       onRemove(doc);
418     });
419     // HANDLE SEND MAIL
420     MailMessage.afterCreate(function (doc, options) {
421       return onSend(doc, options);
422     });
423     // HANDLE SEND MAIL
424     // MailMessage.afterUpdate(function (doc) {
425     //   // onSend(doc);
426     // });
427   }
428 };