@5minds/node-red-contrib-processcube-tools 1.2.0 → 1.2.1-feature-b39f1e-mgq5w8ge
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.mocharc.json +5 -0
- package/dist/email-receiver/email-receiver.d.ts +3 -0
- package/{email-receiver → dist/email-receiver}/email-receiver.html +4 -82
- package/dist/email-receiver/email-receiver.js +342 -0
- package/dist/email-receiver/email-receiver.js.map +1 -0
- package/dist/email-sender/email-sender.d.ts +3 -0
- package/{email-sender → dist/email-sender}/email-sender.html +24 -106
- package/dist/email-sender/email-sender.js +193 -0
- package/dist/email-sender/email-sender.js.map +1 -0
- package/dist/html-to-text/html-to-text.d.ts +3 -0
- package/{processcube-html-to-text/processcube-html-to-text.html → dist/html-to-text/html-to-text.html} +3 -3
- package/dist/html-to-text/html-to-text.js +40 -0
- package/dist/html-to-text/html-to-text.js.map +1 -0
- package/dist/imap-config/imap-config.d.ts +3 -0
- package/dist/imap-config/imap-config.html +139 -0
- package/dist/imap-config/imap-config.js +22 -0
- package/dist/imap-config/imap-config.js.map +1 -0
- package/dist/index.d.ts +2 -0
- package/dist/index.js +19 -0
- package/dist/index.js.map +1 -0
- package/dist/interfaces/EmailReceiverMessage.d.ts +20 -0
- package/dist/interfaces/EmailReceiverMessage.js +3 -0
- package/dist/interfaces/EmailReceiverMessage.js.map +1 -0
- package/dist/interfaces/EmailSenderNodeProperties.d.ts +22 -0
- package/dist/interfaces/EmailSenderNodeProperties.js +3 -0
- package/dist/interfaces/EmailSenderNodeProperties.js.map +1 -0
- package/dist/interfaces/FetchState.d.ts +11 -0
- package/dist/interfaces/FetchState.js +3 -0
- package/dist/interfaces/FetchState.js.map +1 -0
- package/dist/interfaces/ImapConnectionConfig.d.ts +16 -0
- package/dist/interfaces/ImapConnectionConfig.js +3 -0
- package/dist/interfaces/ImapConnectionConfig.js.map +1 -0
- package/dist/smtp-config/smtp-config.d.ts +3 -0
- package/dist/smtp-config/smtp-config.html +138 -0
- package/dist/smtp-config/smtp-config.js +22 -0
- package/dist/smtp-config/smtp-config.js.map +1 -0
- package/package.json +28 -10
- package/tsconfig.json +23 -0
- package/email-receiver/email-receiver.js +0 -304
- package/email-sender/email-sender.js +0 -178
- package/examples/.gitkeep +0 -0
- package/processcube-html-to-text/processcube-html-to-text.js +0 -22
- package/test/helpers/email-receiver.mocks.js +0 -447
- package/test/helpers/email-sender.mocks.js +0 -368
- package/test/integration/email-receiver.integration.test.js +0 -515
- package/test/integration/email-sender.integration.test.js +0 -239
- package/test/unit/email-receiver.unit.test.js +0 -304
- package/test/unit/email-sender.unit.test.js +0 -570
|
@@ -11,8 +11,8 @@
|
|
|
11
11
|
validate: RED.validators.typedInput('senderType'),
|
|
12
12
|
},
|
|
13
13
|
senderType: { value: 'str' },
|
|
14
|
-
|
|
15
|
-
|
|
14
|
+
from: { value: '', required: true, validate: RED.validators.typedInput('fromType') },
|
|
15
|
+
fromType: { value: 'str' },
|
|
16
16
|
to: { value: '', required: true, validate: RED.validators.typedInput('toType') },
|
|
17
17
|
toType: { value: 'str' },
|
|
18
18
|
cc: { value: '', validate: RED.validators.typedInput('ccType') },
|
|
@@ -28,23 +28,8 @@
|
|
|
28
28
|
attachments: { value: '', required: false },
|
|
29
29
|
attachmentsType: { value: 'msg' },
|
|
30
30
|
|
|
31
|
-
// SMTP
|
|
32
|
-
|
|
33
|
-
hostType: { value: 'str' },
|
|
34
|
-
port: { value: '', required: true, validate: RED.validators.typedInput('portType') },
|
|
35
|
-
portType: { value: 'num' },
|
|
36
|
-
user: { value: '', required: true, validate: RED.validators.typedInput('userType') },
|
|
37
|
-
userType: { value: 'str' },
|
|
38
|
-
password: { value: '', required: true, type: 'password' },
|
|
39
|
-
passwordType: { value: 'env', required: true },
|
|
40
|
-
secure: { value: '', required: true, validate: RED.validators.typedInput('secureType') },
|
|
41
|
-
secureType: { value: 'bool' },
|
|
42
|
-
rejectUnauthorized: {
|
|
43
|
-
value: '',
|
|
44
|
-
required: true,
|
|
45
|
-
validate: RED.validators.typedInput('rejectUnauthorizedType'),
|
|
46
|
-
},
|
|
47
|
-
rejectUnauthorizedType: { value: 'bool' },
|
|
31
|
+
// SMTP Configuration reference
|
|
32
|
+
smtpConfig: { value: '', required: true, type: 'smtp-config' },
|
|
48
33
|
},
|
|
49
34
|
inputs: 1,
|
|
50
35
|
outputs: 1,
|
|
@@ -59,10 +44,10 @@
|
|
|
59
44
|
types: ['str', 'msg', 'flow', 'global', 'env'],
|
|
60
45
|
typeField: '#node-input-senderType',
|
|
61
46
|
});
|
|
62
|
-
$('#node-input-
|
|
47
|
+
$('#node-input-from').typedInput({
|
|
63
48
|
default: 'str',
|
|
64
49
|
types: ['str', 'msg', 'flow', 'global', 'env'],
|
|
65
|
-
typeField: '#node-input-
|
|
50
|
+
typeField: '#node-input-fromType',
|
|
66
51
|
});
|
|
67
52
|
$('#node-input-to').typedInput({
|
|
68
53
|
default: 'str',
|
|
@@ -99,38 +84,6 @@
|
|
|
99
84
|
types: ['msg', 'flow', 'global'],
|
|
100
85
|
typeField: '#node-input-attachmentsType',
|
|
101
86
|
});
|
|
102
|
-
|
|
103
|
-
// SMTP Fields
|
|
104
|
-
$('#node-input-host').typedInput({
|
|
105
|
-
default: 'str',
|
|
106
|
-
types: ['str', 'msg', 'flow', 'global', 'env'],
|
|
107
|
-
typeField: '#node-input-hostType',
|
|
108
|
-
});
|
|
109
|
-
$('#node-input-port').typedInput({
|
|
110
|
-
default: 'num',
|
|
111
|
-
types: ['num', 'msg', 'flow', 'global', 'env'],
|
|
112
|
-
typeField: '#node-input-portType',
|
|
113
|
-
});
|
|
114
|
-
$('#node-input-user').typedInput({
|
|
115
|
-
default: 'str',
|
|
116
|
-
types: ['str', 'msg', 'flow', 'global', 'env'],
|
|
117
|
-
typeField: '#node-input-userType',
|
|
118
|
-
});
|
|
119
|
-
$('#node-input-password').typedInput({
|
|
120
|
-
default: 'env',
|
|
121
|
-
types: ['msg', 'flow', 'global', 'env'],
|
|
122
|
-
typeField: '#node-input-passwordType',
|
|
123
|
-
});
|
|
124
|
-
$('#node-input-secure').typedInput({
|
|
125
|
-
default: 'bool',
|
|
126
|
-
types: ['bool', 'msg', 'flow', 'global', 'env'],
|
|
127
|
-
typeField: '#node-input-secureType',
|
|
128
|
-
});
|
|
129
|
-
$('#node-input-rejectUnauthorized').typedInput({
|
|
130
|
-
default: 'bool',
|
|
131
|
-
types: ['bool', 'msg', 'flow', 'global', 'env'],
|
|
132
|
-
typeField: '#node-input-rejectUnauthorizedType',
|
|
133
|
-
});
|
|
134
87
|
},
|
|
135
88
|
});
|
|
136
89
|
</script>
|
|
@@ -148,9 +101,9 @@
|
|
|
148
101
|
<input type="hidden" id="node-input-senderType" />
|
|
149
102
|
</div>
|
|
150
103
|
<div class="form-row">
|
|
151
|
-
<label for="node-input-
|
|
152
|
-
<input type="text" id="node-input-
|
|
153
|
-
<input type="hidden" id="node-input-
|
|
104
|
+
<label for="node-input-from"><i class="fa fa-envelope"></i> From</label>
|
|
105
|
+
<input type="text" id="node-input-from" placeholder="john.doe@example.com" />
|
|
106
|
+
<input type="hidden" id="node-input-fromType" />
|
|
154
107
|
</div>
|
|
155
108
|
<div class="form-row">
|
|
156
109
|
<label for="node-input-to"><i class="fa fa-user"></i> To</label>
|
|
@@ -187,37 +140,9 @@
|
|
|
187
140
|
<input type="text" id="node-input-attachments" />
|
|
188
141
|
<input type="hidden" id="node-input-attachmentsType" />
|
|
189
142
|
</div>
|
|
190
|
-
|
|
191
|
-
<h3>SMTP Configuration</h3>
|
|
192
|
-
<div class="form-row">
|
|
193
|
-
<label for="node-input-host"><i class="fa fa-server"></i> Host</label>
|
|
194
|
-
<input type="text" id="node-input-host" placeholder="smtp.gmail.com" />
|
|
195
|
-
<input type="hidden" id="node-input-hostType" />
|
|
196
|
-
</div>
|
|
197
|
-
<div class="form-row">
|
|
198
|
-
<label for="node-input-port"><i class="fa fa-plug"></i> Port</label>
|
|
199
|
-
<input type="text" id="node-input-port" placeholder="587" />
|
|
200
|
-
<input type="hidden" id="node-input-portType" />
|
|
201
|
-
</div>
|
|
202
|
-
<div class="form-row">
|
|
203
|
-
<label for="node-input-user"><i class="fa fa-user"></i> User</label>
|
|
204
|
-
<input type="text" id="node-input-user" placeholder="test.user@config.com" />
|
|
205
|
-
<input type="hidden" id="node-input-userType" />
|
|
206
|
-
</div>
|
|
207
|
-
<div class="form-row">
|
|
208
|
-
<label for="node-input-password"><i class="fa fa-lock"></i> Password</label>
|
|
209
|
-
<input type="text" id="node-input-password" />
|
|
210
|
-
<input type="hidden" id="node-input-passwordType" />
|
|
211
|
-
</div>
|
|
212
|
-
<div class="form-row">
|
|
213
|
-
<label for="node-input-secure"><i class="fa fa-shield"></i> SSL/TLS (Secure)</label>
|
|
214
|
-
<input type="text" id="node-input-secure" />
|
|
215
|
-
<input type="hidden" id="node-input-secureType" />
|
|
216
|
-
</div>
|
|
217
143
|
<div class="form-row">
|
|
218
|
-
<label for="node-input-
|
|
219
|
-
<input type="text" id="node-input-
|
|
220
|
-
<input type="hidden" id="node-input-rejectUnauthorizedType" />
|
|
144
|
+
<label for="node-input-smtpConfig"><i class="fa fa-server"></i> SMTP Config</label>
|
|
145
|
+
<input type="text" id="node-input-smtpConfig" />
|
|
221
146
|
</div>
|
|
222
147
|
</script>
|
|
223
148
|
|
|
@@ -260,7 +185,7 @@
|
|
|
260
185
|
<dd>A descriptive name for the node.</dd>
|
|
261
186
|
<dt>Sender <span class="property-type">string | variable</span></dt>
|
|
262
187
|
<dd>The name displayed as the sender to the recipient.</dd>
|
|
263
|
-
<dt>
|
|
188
|
+
<dt>From <span class="property-type">string | variable</span></dt>
|
|
264
189
|
<dd>The email address from which the email is sent.</dd>
|
|
265
190
|
<dt>To <span class="property-type">string | variable</span></dt>
|
|
266
191
|
<dd>The primary recipient(s) of the email. For multiple recipients, separate addresses with a comma.</dd>
|
|
@@ -283,24 +208,11 @@
|
|
|
283
208
|
|
|
284
209
|
<h4>SMTP Configuration</h4>
|
|
285
210
|
<dl class="message-properties">
|
|
286
|
-
<dt>
|
|
287
|
-
<dd>The hostname of your SMTP server (e.g., <code>smtp.gmail.com</code>).</dd>
|
|
288
|
-
<dt>Port <span class="property-type">number | variable</span></dt>
|
|
289
|
-
<dd>The port number for the SMTP server (e.g., <code>587</code> or <code>465</code>).</dd>
|
|
290
|
-
<dt>User <span class="property-type">string | variable</span></dt>
|
|
291
|
-
<dd>The username for SMTP authentication.</dd>
|
|
292
|
-
<dt>Password <span class="property-type">password | variable</span></dt>
|
|
211
|
+
<dt>SMTP Config <span class="property-type">smtp-config</span></dt>
|
|
293
212
|
<dd>
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
<dt>SSL/TLS (Secure) <span class="property-type">boolean | variable</span></dt>
|
|
298
|
-
<dd>Enables a secure connection. Set this to <code>true</code> to use SSL/TLS encryption.</dd>
|
|
299
|
-
<dt>Reject Unauthorized <span class="property-type">boolean | variable</span></dt>
|
|
300
|
-
<dd>
|
|
301
|
-
If <code>true</code>, the server's certificate is rejected if it isn't authorized by a trusted Certificate
|
|
302
|
-
Authority (CA). Set this to <code>false</code> only if you know the server's certificate is self-signed or
|
|
303
|
-
not from a trusted CA.
|
|
213
|
+
Reference to an SMTP configuration node that contains the server connection settings (host, port, user,
|
|
214
|
+
password, security options). This allows you to reuse the same SMTP configuration across multiple email
|
|
215
|
+
sender nodes.
|
|
304
216
|
</dd>
|
|
305
217
|
</dl>
|
|
306
218
|
|
|
@@ -310,14 +222,20 @@
|
|
|
310
222
|
<b>Dynamic Content</b>: You can use a <b>Template node</b> before the <b>email-sender</b> node to generate
|
|
311
223
|
dynamic HTML content for your emails, using <code>msg</code> properties to fill in placeholders.
|
|
312
224
|
</li>
|
|
225
|
+
<li>
|
|
226
|
+
<b>Data-Driven Emails</b>: Fields like <b>To</b>, <b>Subject</b>, and <b>HTML Content</b> can be left empty
|
|
227
|
+
in the configuration and provided dynamically via message properties (<code>msg.to</code>, <code>msg.topic</code>,
|
|
228
|
+
<code>msg.payload</code>). At least one recipient (to, cc, or bcc) must be specified before sending.
|
|
229
|
+
</li>
|
|
313
230
|
<li>
|
|
314
231
|
<b>Testing</b>: When testing, use a free service like
|
|
315
232
|
<a href="https://mailtrap.io" target="_blank">Mailtrap</a> to avoid sending real emails. This allows you to
|
|
316
233
|
inspect the email and its content without cluttering your inbox.
|
|
317
234
|
</li>
|
|
318
235
|
<li>
|
|
319
|
-
<b>Troubleshooting</b>: If you encounter a <code>
|
|
320
|
-
|
|
236
|
+
<b>Troubleshooting</b>: If you encounter a <code>SMTP configuration node is not configured</code> error, make
|
|
237
|
+
sure you have created and selected an SMTP Config node. Check that the <b>Sender</b> and <b>From</b> fields
|
|
238
|
+
are configured, as these are required.
|
|
321
239
|
</li>
|
|
322
240
|
</ul>
|
|
323
241
|
|
|
@@ -0,0 +1,193 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
+
};
|
|
5
|
+
const nodemailer_1 = __importDefault(require("nodemailer"));
|
|
6
|
+
// Default dependencies - production values
|
|
7
|
+
const defaultDependencies = {
|
|
8
|
+
nodemailer: nodemailer_1.default,
|
|
9
|
+
};
|
|
10
|
+
const EmailSenderNode = (RED, dependencies = defaultDependencies) => {
|
|
11
|
+
function EmailSender(config) {
|
|
12
|
+
RED.nodes.createNode(this, config);
|
|
13
|
+
const node = this;
|
|
14
|
+
// Store configuration validation error without failing construction
|
|
15
|
+
let configError = null;
|
|
16
|
+
// Get the SMTP config node
|
|
17
|
+
const smtpConfigNode = RED.nodes.getNode(config.smtpConfig);
|
|
18
|
+
try {
|
|
19
|
+
// Validate SMTP config node exists
|
|
20
|
+
if (!smtpConfigNode) {
|
|
21
|
+
throw new Error('SMTP configuration node is not configured');
|
|
22
|
+
}
|
|
23
|
+
// Validate only critical fields that can't be provided at runtime
|
|
24
|
+
// Fields like 'to', 'subject', 'htmlContent' can be empty if provided via msg
|
|
25
|
+
const requiredFields = [
|
|
26
|
+
{ name: 'sender', value: config.sender },
|
|
27
|
+
{ name: 'from', value: config.from },
|
|
28
|
+
];
|
|
29
|
+
for (const field of requiredFields) {
|
|
30
|
+
if (field.value === undefined || field.value === null || field.value === '') {
|
|
31
|
+
throw new Error(`Required property '${field.name}' is missing`);
|
|
32
|
+
}
|
|
33
|
+
}
|
|
34
|
+
}
|
|
35
|
+
catch (error) {
|
|
36
|
+
configError = error instanceof Error ? error : new Error(String(error));
|
|
37
|
+
node.status({ fill: 'red', shape: 'ring', text: 'config error' });
|
|
38
|
+
// Store error for test framework to detect
|
|
39
|
+
node.configError = configError;
|
|
40
|
+
// Emit error immediately during construction for test framework
|
|
41
|
+
setImmediate(() => {
|
|
42
|
+
node.error(configError.message);
|
|
43
|
+
});
|
|
44
|
+
}
|
|
45
|
+
const safeEvaluatePropertyAttachment = (cfg, n, m) => {
|
|
46
|
+
if (cfg.attachments && cfg.attachments.trim() !== '') {
|
|
47
|
+
try {
|
|
48
|
+
return RED.util.evaluateNodeProperty(cfg.attachments, cfg.attachmentsType, n, m);
|
|
49
|
+
}
|
|
50
|
+
catch (e) {
|
|
51
|
+
n.error('Failed to evaluate attachments property: ' + e.message, m);
|
|
52
|
+
return null;
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
return null;
|
|
56
|
+
};
|
|
57
|
+
node.on('input', async (msg, send, done) => {
|
|
58
|
+
send =
|
|
59
|
+
send ||
|
|
60
|
+
function () {
|
|
61
|
+
node.send.apply(node, arguments);
|
|
62
|
+
};
|
|
63
|
+
done =
|
|
64
|
+
done ||
|
|
65
|
+
function (err) {
|
|
66
|
+
if (err)
|
|
67
|
+
node.error(err, msg);
|
|
68
|
+
};
|
|
69
|
+
// If there's a configuration error, report it and don't proceed
|
|
70
|
+
if (configError) {
|
|
71
|
+
node.error(configError.message);
|
|
72
|
+
done(configError);
|
|
73
|
+
return;
|
|
74
|
+
}
|
|
75
|
+
try {
|
|
76
|
+
// Retrieve and evaluate all configuration values
|
|
77
|
+
const sender = String(RED.util.evaluateNodeProperty(config.sender, config.senderType, node, msg));
|
|
78
|
+
const from = String(RED.util.evaluateNodeProperty(config.from, config.fromType, node, msg));
|
|
79
|
+
const to = String(RED.util.evaluateNodeProperty(config.to, config.toType, node, msg) || '');
|
|
80
|
+
const cc = String(RED.util.evaluateNodeProperty(config.cc, config.ccType, node, msg) || '');
|
|
81
|
+
const bcc = String(RED.util.evaluateNodeProperty(config.bcc, config.bccType, node, msg) || '');
|
|
82
|
+
const replyTo = String(RED.util.evaluateNodeProperty(config.replyTo, config.replyToType, node, msg) || '');
|
|
83
|
+
const subject = String(RED.util.evaluateNodeProperty(config.subject, config.subjectType, node, msg) ||
|
|
84
|
+
msg.topic ||
|
|
85
|
+
'Message from Node-RED');
|
|
86
|
+
const htmlContent = String(RED.util.evaluateNodeProperty(config.htmlContent, config.htmlContentType, node, msg));
|
|
87
|
+
const attachments = safeEvaluatePropertyAttachment(config, node, msg);
|
|
88
|
+
// Get SMTP Configuration from config node
|
|
89
|
+
const smtp_user = RED.util.evaluateNodeProperty(smtpConfigNode.user, smtpConfigNode.userType || 'env', smtpConfigNode, msg);
|
|
90
|
+
const smtp_password = RED.util.evaluateNodeProperty(smtpConfigNode.password, smtpConfigNode.passwordType || 'env', smtpConfigNode, msg);
|
|
91
|
+
const host = smtpConfigNode.host;
|
|
92
|
+
const port = smtpConfigNode.port;
|
|
93
|
+
const user = String(smtp_user);
|
|
94
|
+
const password = String(smtp_password);
|
|
95
|
+
const secure = smtpConfigNode.secure;
|
|
96
|
+
const rejectUnauthorized = smtpConfigNode.rejectUnauthorized;
|
|
97
|
+
// Runtime validation: at least one recipient must be provided
|
|
98
|
+
if (!to && !cc && !bcc) {
|
|
99
|
+
throw new Error('At least one recipient (to, cc, or bcc) must be specified');
|
|
100
|
+
}
|
|
101
|
+
// Process attachments
|
|
102
|
+
let processedAttachments = [];
|
|
103
|
+
let parsedAttachments = attachments;
|
|
104
|
+
if (typeof parsedAttachments === 'string' && parsedAttachments.trim().startsWith('[')) {
|
|
105
|
+
try {
|
|
106
|
+
parsedAttachments = JSON.parse(parsedAttachments);
|
|
107
|
+
}
|
|
108
|
+
catch (e) {
|
|
109
|
+
throw new Error('Failed to parse attachments JSON: ' + e.message);
|
|
110
|
+
}
|
|
111
|
+
}
|
|
112
|
+
if (parsedAttachments) {
|
|
113
|
+
const attachmentArray = Array.isArray(parsedAttachments) ? parsedAttachments : [parsedAttachments];
|
|
114
|
+
for (const attachment of attachmentArray) {
|
|
115
|
+
if (typeof attachment === 'object' && attachment !== null) {
|
|
116
|
+
if (attachment.filename && attachment.content !== undefined) {
|
|
117
|
+
processedAttachments.push({
|
|
118
|
+
filename: attachment.filename,
|
|
119
|
+
content: attachment.content,
|
|
120
|
+
});
|
|
121
|
+
}
|
|
122
|
+
else {
|
|
123
|
+
throw new Error(`Attachment object is missing 'filename' or 'content' property. Got: ${JSON.stringify(attachment)}`);
|
|
124
|
+
}
|
|
125
|
+
}
|
|
126
|
+
else {
|
|
127
|
+
throw new Error(`Invalid attachment format. Expected object, got: ${typeof attachment}`);
|
|
128
|
+
}
|
|
129
|
+
}
|
|
130
|
+
}
|
|
131
|
+
// Create and send email
|
|
132
|
+
const transporter = dependencies.nodemailer.createTransport({
|
|
133
|
+
host,
|
|
134
|
+
port,
|
|
135
|
+
secure,
|
|
136
|
+
auth: { user, pass: password },
|
|
137
|
+
tls: { rejectUnauthorized },
|
|
138
|
+
});
|
|
139
|
+
const mailOptions = {
|
|
140
|
+
from: { name: sender, address: from },
|
|
141
|
+
to,
|
|
142
|
+
cc,
|
|
143
|
+
bcc,
|
|
144
|
+
replyTo,
|
|
145
|
+
subject,
|
|
146
|
+
html: Buffer.from(htmlContent, 'utf-8'),
|
|
147
|
+
attachments: processedAttachments,
|
|
148
|
+
};
|
|
149
|
+
transporter.sendMail(mailOptions, (error, info) => {
|
|
150
|
+
if (error) {
|
|
151
|
+
node.status({ fill: 'red', shape: 'dot', text: 'error sending' });
|
|
152
|
+
if (error.message &&
|
|
153
|
+
error.message.includes('SSL routines') &&
|
|
154
|
+
error.message.includes('wrong version number')) {
|
|
155
|
+
done(new Error('SSL/TLS connection failed: Wrong version number. This usually means the wrong port or security settings are used. For SMTP: use port 587 with secure=false (STARTTLS) or port 465 with secure=true (SSL/TLS).'));
|
|
156
|
+
}
|
|
157
|
+
else {
|
|
158
|
+
done(error);
|
|
159
|
+
}
|
|
160
|
+
}
|
|
161
|
+
else {
|
|
162
|
+
node.log('Email sent: ' + info.response);
|
|
163
|
+
msg.payload = info;
|
|
164
|
+
if (info.accepted && info.accepted.length > 0) {
|
|
165
|
+
node.status({ fill: 'green', shape: 'dot', text: 'sent' });
|
|
166
|
+
send(msg);
|
|
167
|
+
done();
|
|
168
|
+
}
|
|
169
|
+
else if (info.rejected && info.rejected.length > 0) {
|
|
170
|
+
done(new Error('Email rejected: ' + info.rejected.join(', ')));
|
|
171
|
+
node.status({ fill: 'red', shape: 'dot', text: 'rejected' });
|
|
172
|
+
}
|
|
173
|
+
else if (info.pending && info.pending.length > 0) {
|
|
174
|
+
done(new Error('Email pending: ' + info.pending.join(', ')));
|
|
175
|
+
node.status({ fill: 'yellow', shape: 'dot', text: 'pending' });
|
|
176
|
+
}
|
|
177
|
+
else {
|
|
178
|
+
done(new Error('Unknown error while sending email.'));
|
|
179
|
+
node.status({ fill: 'red', shape: 'dot', text: 'unknown error' });
|
|
180
|
+
}
|
|
181
|
+
}
|
|
182
|
+
});
|
|
183
|
+
}
|
|
184
|
+
catch (error) {
|
|
185
|
+
done(error instanceof Error ? error : new Error(String(error)));
|
|
186
|
+
node.status({ fill: 'red', shape: 'dot', text: 'error' });
|
|
187
|
+
}
|
|
188
|
+
});
|
|
189
|
+
}
|
|
190
|
+
RED.nodes.registerType('email-sender', EmailSender);
|
|
191
|
+
};
|
|
192
|
+
module.exports = EmailSenderNode;
|
|
193
|
+
//# sourceMappingURL=email-sender.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"email-sender.js","sourceRoot":"","sources":["../../src/email-sender/email-sender.ts"],"names":[],"mappings":"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"}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
<script type="text/javascript">
|
|
2
|
-
RED.nodes.registerType('
|
|
2
|
+
RED.nodes.registerType('html-to-text', {
|
|
3
3
|
category: 'ProcessCube Tools',
|
|
4
4
|
color: '#02AFD6',
|
|
5
5
|
defaults: {
|
|
@@ -9,12 +9,12 @@
|
|
|
9
9
|
outputs: 1,
|
|
10
10
|
icon: 'font-awesome/fa-sign-in',
|
|
11
11
|
label: function () {
|
|
12
|
-
return this.name || '
|
|
12
|
+
return this.name || 'html-to-text';
|
|
13
13
|
},
|
|
14
14
|
});
|
|
15
15
|
</script>
|
|
16
16
|
|
|
17
|
-
<script type="text/html" data-template-name="
|
|
17
|
+
<script type="text/html" data-template-name="html-to-text">
|
|
18
18
|
<div class="form-row">
|
|
19
19
|
<label for="node-input-name"><i class="fa fa-tag"></i> Name</label>
|
|
20
20
|
<input type="text" id="node-input-name" placeholder="Name" />
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
const { compile } = require('html-to-text');
|
|
3
|
+
const HtmlToTextNode = function (RED) {
|
|
4
|
+
function HtmlToText(config) {
|
|
5
|
+
RED.nodes.createNode(this, config);
|
|
6
|
+
const node = this;
|
|
7
|
+
const options = {
|
|
8
|
+
wordwrap: 130,
|
|
9
|
+
};
|
|
10
|
+
const compiledConvert = compile(options);
|
|
11
|
+
node.on('input', (msg, send, done) => {
|
|
12
|
+
// Provide default functions if not available (for older Node-RED versions)
|
|
13
|
+
send =
|
|
14
|
+
send ||
|
|
15
|
+
function (m) {
|
|
16
|
+
node.send(m);
|
|
17
|
+
};
|
|
18
|
+
done =
|
|
19
|
+
done ||
|
|
20
|
+
function (err) {
|
|
21
|
+
if (err)
|
|
22
|
+
node.error(err, msg);
|
|
23
|
+
};
|
|
24
|
+
try {
|
|
25
|
+
if (typeof msg.payload !== 'string') {
|
|
26
|
+
throw new Error('Payload is not a string!');
|
|
27
|
+
}
|
|
28
|
+
msg.payload = compiledConvert(msg.payload);
|
|
29
|
+
send(msg);
|
|
30
|
+
done();
|
|
31
|
+
}
|
|
32
|
+
catch (error) {
|
|
33
|
+
done(error instanceof Error ? error : new Error(String(error)));
|
|
34
|
+
}
|
|
35
|
+
});
|
|
36
|
+
}
|
|
37
|
+
RED.nodes.registerType('html-to-text', HtmlToText);
|
|
38
|
+
};
|
|
39
|
+
module.exports = HtmlToTextNode;
|
|
40
|
+
//# sourceMappingURL=html-to-text.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"html-to-text.js","sourceRoot":"","sources":["../../src/html-to-text/html-to-text.ts"],"names":[],"mappings":";AACA,MAAM,EAAE,OAAO,EAAE,GAAG,OAAO,CAAC,cAAc,CAAC,CAAC;AAU5C,MAAM,cAAc,GAAoB,UAAU,GAAG;IACjD,SAAS,UAAU,CAAa,MAAgC;QAC5D,GAAG,CAAC,KAAK,CAAC,UAAU,CAAC,IAAI,EAAE,MAAM,CAAC,CAAC;QACnC,MAAM,IAAI,GAAG,IAAI,CAAC;QAElB,MAAM,OAAO,GAAG;YACZ,QAAQ,EAAE,GAAG;SAChB,CAAC;QAEF,MAAM,eAAe,GAAG,OAAO,CAAC,OAAO,CAAC,CAAC;QAExC,IAAY,CAAC,EAAE,CAAC,OAAO,EAAE,CAAC,GAA0B,EAAE,IAAe,EAAE,IAAe,EAAE,EAAE;YACvF,2EAA2E;YAC3E,IAAI;gBACA,IAAI;oBACJ,UAAU,CAA8B;wBACpC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;oBACjB,CAAC,CAAC;YACN,IAAI;gBACA,IAAI;oBACJ,UAAU,GAAW;wBACjB,IAAI,GAAG;4BAAE,IAAI,CAAC,KAAK,CAAC,GAAG,EAAE,GAAG,CAAC,CAAC;oBAClC,CAAC,CAAC;YAEN,IAAI,CAAC;gBACD,IAAI,OAAO,GAAG,CAAC,OAAO,KAAK,QAAQ,EAAE,CAAC;oBAClC,MAAM,IAAI,KAAK,CAAC,0BAA0B,CAAC,CAAC;gBAChD,CAAC;gBAED,GAAG,CAAC,OAAO,GAAG,eAAe,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC;gBAC3C,IAAI,CAAC,GAAG,CAAC,CAAC;gBACV,IAAI,EAAE,CAAC;YACX,CAAC;YAAC,OAAO,KAAK,EAAE,CAAC;gBACb,IAAI,CAAC,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,IAAI,KAAK,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC;YACpE,CAAC;QACL,CAAC,CAAC,CAAC;IACP,CAAC;IAED,GAAG,CAAC,KAAK,CAAC,YAAY,CAAC,cAAc,EAAE,UAAU,CAAC,CAAC;AACvD,CAAC,CAAC;AAEF,iBAAS,cAAc,CAAC"}
|
|
@@ -0,0 +1,139 @@
|
|
|
1
|
+
<script type="text/javascript">
|
|
2
|
+
RED.nodes.registerType('imap-config', {
|
|
3
|
+
category: 'config',
|
|
4
|
+
defaults: {
|
|
5
|
+
name: { value: '' },
|
|
6
|
+
host: { value: '', required: true },
|
|
7
|
+
port: { value: 993, required: true, validate: RED.validators.number() },
|
|
8
|
+
tls: { value: true, required: true },
|
|
9
|
+
user: { value: '', required: true, validate: RED.validators.typedInput('userType') },
|
|
10
|
+
userType: { value: 'env' },
|
|
11
|
+
password: { value: '', required: true, validate: RED.validators.typedInput('passwordType') },
|
|
12
|
+
passwordType: { value: 'env' },
|
|
13
|
+
connTimeout: { value: 10000, validate: RED.validators.number() },
|
|
14
|
+
authTimeout: { value: 5000, validate: RED.validators.number() },
|
|
15
|
+
keepalive: { value: true },
|
|
16
|
+
autotls: { value: 'never' },
|
|
17
|
+
rejectUnauthorized: { value: false },
|
|
18
|
+
},
|
|
19
|
+
label: function () {
|
|
20
|
+
return this.name || `${this.user}@${this.host}`;
|
|
21
|
+
},
|
|
22
|
+
oneditprepare: function () {
|
|
23
|
+
$('#node-config-input-user').typedInput({
|
|
24
|
+
default: 'env',
|
|
25
|
+
types: ['global', 'env'],
|
|
26
|
+
typeField: '#node-config-input-userType',
|
|
27
|
+
});
|
|
28
|
+
|
|
29
|
+
$('#node-config-input-password').typedInput({
|
|
30
|
+
default: 'env',
|
|
31
|
+
types: ['global', 'env'],
|
|
32
|
+
typeField: '#node-config-input-passwordType',
|
|
33
|
+
});
|
|
34
|
+
},
|
|
35
|
+
});
|
|
36
|
+
</script>
|
|
37
|
+
|
|
38
|
+
<script type="text/html" data-template-name="imap-config">
|
|
39
|
+
<div class="form-row">
|
|
40
|
+
<label for="node-config-input-name"><i class="fa fa-tag"></i> Name</label>
|
|
41
|
+
<input type="text" id="node-config-input-name" placeholder="My IMAP Server" />
|
|
42
|
+
</div>
|
|
43
|
+
|
|
44
|
+
<div class="form-row">
|
|
45
|
+
<label for="node-config-input-host"><i class="fa fa-server"></i> IMAP Host</label>
|
|
46
|
+
<input type="text" id="node-config-input-host" placeholder="imap.gmail.com" />
|
|
47
|
+
</div>
|
|
48
|
+
|
|
49
|
+
<div class="form-row">
|
|
50
|
+
<label for="node-config-input-port"><i class="fa fa-terminal"></i> Port</label>
|
|
51
|
+
<input type="text" id="node-config-input-port" placeholder="993" />
|
|
52
|
+
</div>
|
|
53
|
+
|
|
54
|
+
<div class="form-row">
|
|
55
|
+
<label for="node-config-input-tls"><i class="fa fa-lock"></i> Use TLS</label>
|
|
56
|
+
<input type="checkbox" id="node-config-input-tls" style="display: inline-block; width: auto; vertical-align: top;" />
|
|
57
|
+
</div>
|
|
58
|
+
|
|
59
|
+
<div class="form-row">
|
|
60
|
+
<label for="node-config-input-user"><i class="fa fa-user"></i> User</label>
|
|
61
|
+
<input type="text" id="node-config-input-user" placeholder="IMAP_USER" />
|
|
62
|
+
<input type="hidden" id="node-config-input-userType" />
|
|
63
|
+
</div>
|
|
64
|
+
|
|
65
|
+
<div class="form-row">
|
|
66
|
+
<label for="node-config-input-password"><i class="fa fa-key"></i> Password</label>
|
|
67
|
+
<input type="text" id="node-config-input-password" placeholder="IMAP_PASSWORD" />
|
|
68
|
+
<input type="hidden" id="node-config-input-passwordType" />
|
|
69
|
+
</div>
|
|
70
|
+
|
|
71
|
+
<div class="form-row">
|
|
72
|
+
<label for="node-config-input-connTimeout"><i class="fa fa-clock-o"></i> Connection Timeout (ms)</label>
|
|
73
|
+
<input type="text" id="node-config-input-connTimeout" placeholder="10000" />
|
|
74
|
+
</div>
|
|
75
|
+
|
|
76
|
+
<div class="form-row">
|
|
77
|
+
<label for="node-config-input-authTimeout"><i class="fa fa-clock-o"></i> Auth Timeout (ms)</label>
|
|
78
|
+
<input type="text" id="node-config-input-authTimeout" placeholder="5000" />
|
|
79
|
+
</div>
|
|
80
|
+
|
|
81
|
+
<div class="form-row">
|
|
82
|
+
<label for="node-config-input-keepalive"><i class="fa fa-heart"></i> Keep Alive</label>
|
|
83
|
+
<input type="checkbox" id="node-config-input-keepalive" style="display: inline-block; width: auto; vertical-align: top;" />
|
|
84
|
+
</div>
|
|
85
|
+
|
|
86
|
+
<div class="form-row">
|
|
87
|
+
<label for="node-config-input-autotls"><i class="fa fa-shield"></i> Auto TLS</label>
|
|
88
|
+
<select id="node-config-input-autotls" style="width: 70%;">
|
|
89
|
+
<option value="never">Never</option>
|
|
90
|
+
<option value="always">Always</option>
|
|
91
|
+
<option value="required">Required</option>
|
|
92
|
+
</select>
|
|
93
|
+
</div>
|
|
94
|
+
|
|
95
|
+
<div class="form-row">
|
|
96
|
+
<label for="node-config-input-rejectUnauthorized"><i class="fa fa-certificate"></i> Reject Unauthorized</label>
|
|
97
|
+
<input type="checkbox" id="node-config-input-rejectUnauthorized" style="display: inline-block; width: auto; vertical-align: top;" />
|
|
98
|
+
</div>
|
|
99
|
+
</script>
|
|
100
|
+
|
|
101
|
+
<script type="text/html" data-help-name="imap-config">
|
|
102
|
+
<p>Configuration node for IMAP server connection settings.</p>
|
|
103
|
+
|
|
104
|
+
<h3>Configuration</h3>
|
|
105
|
+
<dl class="message-properties">
|
|
106
|
+
<dt>Name <span class="property-type">string</span></dt>
|
|
107
|
+
<dd>A friendly name for this IMAP configuration.</dd>
|
|
108
|
+
|
|
109
|
+
<dt>IMAP Host <span class="property-type">string</span></dt>
|
|
110
|
+
<dd>The hostname or IP address of the IMAP server (e.g., imap.gmail.com).</dd>
|
|
111
|
+
|
|
112
|
+
<dt>Port <span class="property-type">number</span></dt>
|
|
113
|
+
<dd>The port number for IMAP connection (typically 993 for TLS, 143 for non-TLS).</dd>
|
|
114
|
+
|
|
115
|
+
<dt>Use TLS <span class="property-type">boolean</span></dt>
|
|
116
|
+
<dd>Enable TLS/SSL encryption for the connection.</dd>
|
|
117
|
+
|
|
118
|
+
<dt>User <span class="property-type">string</span></dt>
|
|
119
|
+
<dd>The username for IMAP authentication.</dd>
|
|
120
|
+
|
|
121
|
+
<dt>Password <span class="property-type">string</span></dt>
|
|
122
|
+
<dd>The password for IMAP authentication. This is stored securely as a credential.</dd>
|
|
123
|
+
|
|
124
|
+
<dt>Connection Timeout <span class="property-type">number</span></dt>
|
|
125
|
+
<dd>The connection timeout in milliseconds (default: 10000).</dd>
|
|
126
|
+
|
|
127
|
+
<dt>Auth Timeout <span class="property-type">number</span></dt>
|
|
128
|
+
<dd>The authentication timeout in milliseconds (default: 5000).</dd>
|
|
129
|
+
|
|
130
|
+
<dt>Keep Alive <span class="property-type">boolean</span></dt>
|
|
131
|
+
<dd>Send periodic NOOP commands to keep the connection alive (default: true).</dd>
|
|
132
|
+
|
|
133
|
+
<dt>Auto TLS <span class="property-type">string</span></dt>
|
|
134
|
+
<dd>Controls STARTTLS behavior: never, always, or required (default: never).</dd>
|
|
135
|
+
|
|
136
|
+
<dt>Reject Unauthorized <span class="property-type">boolean</span></dt>
|
|
137
|
+
<dd>Reject connections with invalid TLS certificates (default: false).</dd>
|
|
138
|
+
</dl>
|
|
139
|
+
</script>
|