source: node_modules/nodemailer/lib/sendmail-transport/index.js@ 81bc7da

finki-main main
Last change on this file since 81bc7da was 81bc7da, checked in by Klimentina Efremova <klimentina08642@…>, 3 months ago

Initial commit

  • Property mode set to 100644
File size: 6.4 KB
Line 
1'use strict';
2
3const spawn = require('child_process').spawn;
4const packageData = require('../../package.json');
5const shared = require('../shared');
6
7/**
8 * Generates a Transport object for Sendmail
9 *
10 * Possible options can be the following:
11 *
12 * * **path** optional path to sendmail binary
13 * * **newline** either 'windows' or 'unix'
14 * * **args** an array of arguments for the sendmail binary
15 *
16 * @constructor
17 * @param {Object} optional config parameter for Sendmail
18 */
19class SendmailTransport {
20 constructor(options) {
21 options = options || {};
22
23 // use a reference to spawn for mocking purposes
24 this._spawn = spawn;
25
26 this.options = options || {};
27
28 this.name = 'Sendmail';
29 this.version = packageData.version;
30
31 this.path = 'sendmail';
32 this.args = false;
33 this.winbreak = false;
34
35 this.logger = shared.getLogger(this.options, {
36 component: this.options.component || 'sendmail'
37 });
38
39 if (options) {
40 if (typeof options === 'string') {
41 this.path = options;
42 } else if (typeof options === 'object') {
43 if (options.path) {
44 this.path = options.path;
45 }
46 if (Array.isArray(options.args)) {
47 this.args = options.args;
48 }
49 this.winbreak = ['win', 'windows', 'dos', '\r\n'].includes((options.newline || '').toString().toLowerCase());
50 }
51 }
52 }
53
54 /**
55 * <p>Compiles a mailcomposer message and forwards it to handler that sends it.</p>
56 *
57 * @param {Object} emailMessage MailComposer object
58 * @param {Function} callback Callback function to run when the sending is completed
59 */
60 send(mail, done) {
61 // Sendmail strips this header line by itself
62 mail.message.keepBcc = true;
63
64 let envelope = mail.data.envelope || mail.message.getEnvelope();
65 let messageId = mail.message.messageId();
66 let args;
67 let sendmail;
68 let returned;
69
70 const hasInvalidAddresses = []
71 .concat(envelope.from || [])
72 .concat(envelope.to || [])
73 .some(addr => /^-/.test(addr));
74 if (hasInvalidAddresses) {
75 return done(new Error('Can not send mail. Invalid envelope addresses.'));
76 }
77
78 if (this.args) {
79 // force -i to keep single dots
80 args = ['-i'].concat(this.args).concat(envelope.to);
81 } else {
82 args = ['-i'].concat(envelope.from ? ['-f', envelope.from] : []).concat(envelope.to);
83 }
84
85 let callback = err => {
86 if (returned) {
87 // ignore any additional responses, already done
88 return;
89 }
90 returned = true;
91 if (typeof done === 'function') {
92 if (err) {
93 return done(err);
94 } else {
95 return done(null, {
96 envelope: mail.data.envelope || mail.message.getEnvelope(),
97 messageId,
98 response: 'Messages queued for delivery'
99 });
100 }
101 }
102 };
103
104 try {
105 sendmail = this._spawn(this.path, args);
106 } catch (E) {
107 this.logger.error(
108 {
109 err: E,
110 tnx: 'spawn',
111 messageId
112 },
113 'Error occurred while spawning sendmail. %s',
114 E.message
115 );
116 return callback(E);
117 }
118
119 if (sendmail) {
120 sendmail.on('error', err => {
121 this.logger.error(
122 {
123 err,
124 tnx: 'spawn',
125 messageId
126 },
127 'Error occurred when sending message %s. %s',
128 messageId,
129 err.message
130 );
131 callback(err);
132 });
133
134 sendmail.once('exit', code => {
135 if (!code) {
136 return callback();
137 }
138 let err;
139 if (code === 127) {
140 err = new Error('Sendmail command not found, process exited with code ' + code);
141 } else {
142 err = new Error('Sendmail exited with code ' + code);
143 }
144
145 this.logger.error(
146 {
147 err,
148 tnx: 'stdin',
149 messageId
150 },
151 'Error sending message %s to sendmail. %s',
152 messageId,
153 err.message
154 );
155 callback(err);
156 });
157 sendmail.once('close', callback);
158
159 sendmail.stdin.on('error', err => {
160 this.logger.error(
161 {
162 err,
163 tnx: 'stdin',
164 messageId
165 },
166 'Error occurred when piping message %s to sendmail. %s',
167 messageId,
168 err.message
169 );
170 callback(err);
171 });
172
173 let recipients = [].concat(envelope.to || []);
174 if (recipients.length > 3) {
175 recipients.push('...and ' + recipients.splice(2).length + ' more');
176 }
177 this.logger.info(
178 {
179 tnx: 'send',
180 messageId
181 },
182 'Sending message %s to <%s>',
183 messageId,
184 recipients.join(', ')
185 );
186
187 let sourceStream = mail.message.createReadStream();
188 sourceStream.once('error', err => {
189 this.logger.error(
190 {
191 err,
192 tnx: 'stdin',
193 messageId
194 },
195 'Error occurred when generating message %s. %s',
196 messageId,
197 err.message
198 );
199 sendmail.kill('SIGINT'); // do not deliver the message
200 callback(err);
201 });
202
203 sourceStream.pipe(sendmail.stdin);
204 } else {
205 return callback(new Error('sendmail was not found'));
206 }
207 }
208}
209
210module.exports = SendmailTransport;
Note: See TracBrowser for help on using the repository browser.