@5minds/node-red-contrib-processcube-tools 1.2.0 → 1.2.1

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.
Files changed (48) hide show
  1. package/.mocharc.json +5 -0
  2. package/dist/email-receiver/email-receiver.d.ts +3 -0
  3. package/{email-receiver → dist/email-receiver}/email-receiver.html +4 -82
  4. package/dist/email-receiver/email-receiver.js +342 -0
  5. package/dist/email-receiver/email-receiver.js.map +1 -0
  6. package/dist/email-sender/email-sender.d.ts +3 -0
  7. package/{email-sender → dist/email-sender}/email-sender.html +24 -106
  8. package/dist/email-sender/email-sender.js +193 -0
  9. package/dist/email-sender/email-sender.js.map +1 -0
  10. package/dist/html-to-text/html-to-text.d.ts +3 -0
  11. package/{processcube-html-to-text/processcube-html-to-text.html → dist/html-to-text/html-to-text.html} +3 -3
  12. package/dist/html-to-text/html-to-text.js +40 -0
  13. package/dist/html-to-text/html-to-text.js.map +1 -0
  14. package/dist/imap-config/imap-config.d.ts +3 -0
  15. package/dist/imap-config/imap-config.html +139 -0
  16. package/dist/imap-config/imap-config.js +22 -0
  17. package/dist/imap-config/imap-config.js.map +1 -0
  18. package/dist/index.d.ts +2 -0
  19. package/dist/index.js +19 -0
  20. package/dist/index.js.map +1 -0
  21. package/dist/interfaces/EmailReceiverMessage.d.ts +20 -0
  22. package/dist/interfaces/EmailReceiverMessage.js +3 -0
  23. package/dist/interfaces/EmailReceiverMessage.js.map +1 -0
  24. package/dist/interfaces/EmailSenderNodeProperties.d.ts +22 -0
  25. package/dist/interfaces/EmailSenderNodeProperties.js +3 -0
  26. package/dist/interfaces/EmailSenderNodeProperties.js.map +1 -0
  27. package/dist/interfaces/FetchState.d.ts +11 -0
  28. package/dist/interfaces/FetchState.js +3 -0
  29. package/dist/interfaces/FetchState.js.map +1 -0
  30. package/dist/interfaces/ImapConnectionConfig.d.ts +16 -0
  31. package/dist/interfaces/ImapConnectionConfig.js +3 -0
  32. package/dist/interfaces/ImapConnectionConfig.js.map +1 -0
  33. package/dist/smtp-config/smtp-config.d.ts +3 -0
  34. package/dist/smtp-config/smtp-config.html +138 -0
  35. package/dist/smtp-config/smtp-config.js +22 -0
  36. package/dist/smtp-config/smtp-config.js.map +1 -0
  37. package/package.json +28 -10
  38. package/tsconfig.json +23 -0
  39. package/email-receiver/email-receiver.js +0 -304
  40. package/email-sender/email-sender.js +0 -178
  41. package/examples/.gitkeep +0 -0
  42. package/processcube-html-to-text/processcube-html-to-text.js +0 -22
  43. package/test/helpers/email-receiver.mocks.js +0 -447
  44. package/test/helpers/email-sender.mocks.js +0 -368
  45. package/test/integration/email-receiver.integration.test.js +0 -515
  46. package/test/integration/email-sender.integration.test.js +0 -239
  47. package/test/unit/email-receiver.unit.test.js +0 -304
  48. package/test/unit/email-sender.unit.test.js +0 -570
package/.mocharc.json ADDED
@@ -0,0 +1,5 @@
1
+ {
2
+ "require": ["ts-node/register"],
3
+ "spec": "src/test/**/*.test.ts",
4
+ "timeout": 5000
5
+ }
@@ -0,0 +1,3 @@
1
+ import { NodeInitializer } from 'node-red';
2
+ declare const nodeInit: NodeInitializer;
3
+ export = nodeInit;
@@ -4,27 +4,13 @@
4
4
  color: '#02AFD6',
5
5
  defaults: {
6
6
  name: { value: '' },
7
- host: { value: '', required: true, validate: RED.validators.typedInput('hostType') },
8
- hostType: { value: 'str' },
9
- port: { value: '', required: true, validate: RED.validators.typedInput('portType') },
10
- portType: { value: 'num' },
11
- tls: { value: true, required: true, validate: RED.validators.typedInput('tlsType') },
12
- tlsType: { value: 'bool' },
13
- user: { value: '', required: true, validate: RED.validators.typedInput('userType') },
14
- userType: { value: 'str' },
15
- password: { value: '', required: true },
16
- passwordType: { value: 'env', required: true },
7
+ imapConfig: { value: '', type: 'imap-config', required: true },
17
8
  folder: { value: '', required: true, validate: RED.validators.typedInput('folderType') },
18
9
  folderType: { value: 'json' },
19
10
  markseen: { value: true, validate: RED.validators.typedInput('markseenType') },
20
11
  markseenType: { value: 'bool' },
21
- sendstatus: { value: true },
22
12
  },
23
13
  inputs: 1,
24
- // outputs: function () {
25
- // const sendstatus = this.sendstatus === true || this.sendstatus === 'true';
26
- // return sendstatus ? 2 : 1;
27
- // },
28
14
  outputs: 2,
29
15
  outputLabels: function (index) {
30
16
  if (index === 0) {
@@ -39,36 +25,6 @@
39
25
  return this.name || 'E-Mail Receiver';
40
26
  },
41
27
  oneditprepare: function () {
42
- $('#node-input-host').typedInput({
43
- default: 'str',
44
- types: ['str', 'msg', 'flow', 'global', 'env'],
45
- typeField: '#node-input-hostType',
46
- });
47
-
48
- $('#node-input-port').typedInput({
49
- default: 'num',
50
- types: ['num', 'msg', 'flow', 'global', 'env'],
51
- typeField: '#node-input-portType',
52
- });
53
-
54
- $('#node-input-tls').typedInput({
55
- default: 'bool',
56
- types: ['bool', 'msg', 'flow', 'global', 'env'],
57
- typeField: '#node-input-tlsType',
58
- });
59
-
60
- $('#node-input-user').typedInput({
61
- default: 'str',
62
- types: ['str', 'msg', 'flow', 'global', 'env'],
63
- typeField: '#node-input-userType',
64
- });
65
-
66
- $('#node-input-password').typedInput({
67
- default: 'env',
68
- types: ['msg', 'flow', 'global', 'env'],
69
- typeField: '#node-input-passwordType',
70
- });
71
-
72
28
  $('#node-input-folder').typedInput({
73
29
  default: 'json',
74
30
  types: ['msg', 'flow', 'global', 'json', 'jsonata', 'env'],
@@ -91,38 +47,13 @@
91
47
  </div>
92
48
 
93
49
  <div class="form-row">
94
- <label for="node-input-host"><i class="fa fa-server"></i> IMAP Host</label>
95
- <input type="text" id="node-input-host" placeholder="imap.gmail.com" />
96
- <input type="hidden" id="node-input-hostType" />
97
- </div>
98
-
99
- <div class="form-row">
100
- <label for="node-input-port"><i class="fa fa-terminal"></i> Port</label>
101
- <input type="text" id="node-input-port" placeholder="993" />
102
- <input type="hidden" id="node-input-portType" />
103
- </div>
104
-
105
- <div class="form-row">
106
- <label for="node-input-tls"><i class="fa fa-lock"></i> Use TLS</label>
107
- <input type="text" id="node-input-tls" />
108
- <input type="hidden" id="node-input-tlsType" />
109
- </div>
110
-
111
- <div class="form-row">
112
- <label for="node-input-user"><i class="fa fa-user"></i> User</label>
113
- <input type="text" id="node-input-user" />
114
- <input type="hidden" id="node-input-userType" />
115
- </div>
116
-
117
- <div class="form-row">
118
- <label for="node-input-password"><i class="fa fa-key"></i> Password</label>
119
- <input type="text" id="node-input-password" />
120
- <input type="hidden" id="node-input-passwordType" />
50
+ <label for="node-input-imapConfig"><i class="fa fa-server"></i> IMAP Server</label>
51
+ <input type="text" id="node-input-imapConfig" />
121
52
  </div>
122
53
 
123
54
  <div class="form-row">
124
55
  <label for="node-input-folder"><i class="fa fa-folder-open"></i> Folder(s)</label>
125
- <input type="text" id="node-input-folder" placeholder="[INBOX]" />
56
+ <input type="text" id="node-input-folder" placeholder='["INBOX"]' />
126
57
  <input type="hidden" id="node-input-folderType" />
127
58
  </div>
128
59
 
@@ -131,15 +62,6 @@
131
62
  <input type="text" id="node-input-markseen" />
132
63
  <input type="hidden" id="node-input-markseenType" />
133
64
  </div>
134
- <div class="form-row" style="margin-bottom: 3px;">
135
- <input
136
- type="checkbox"
137
- checked
138
- id="node-input-sendstatus"
139
- style="display: inline-block; width: auto; vertical-align: top; margin-left: 5px;"
140
- />
141
- <label style="width:auto" for="node-input-sendstatus">Send status</label>
142
- </div>
143
65
  </script>
144
66
 
145
67
  <script type="text/html" data-help-name="email-receiver">
@@ -0,0 +1,342 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ const node_imap_1 = __importDefault(require("node-imap"));
6
+ const mailparser_1 = require("mailparser");
7
+ // Default dependencies - production values
8
+ const defaultDependencies = {
9
+ ImapClient: node_imap_1.default,
10
+ mailParser: mailparser_1.simpleParser,
11
+ };
12
+ function toBoolean(val, defaultValue = false) {
13
+ if (typeof val === 'boolean')
14
+ return val;
15
+ if (typeof val === 'number')
16
+ return val !== 0;
17
+ if (typeof val === 'string') {
18
+ const v = val.trim().toLowerCase();
19
+ if (['true', '1', 'yes', 'on'].includes(v))
20
+ return true;
21
+ if (['false', '0', 'no', 'off'].includes(v))
22
+ return false;
23
+ }
24
+ return defaultValue;
25
+ }
26
+ const nodeInit = (RED, dependencies = defaultDependencies) => {
27
+ function EmailReceiverNode(config) {
28
+ RED.nodes.createNode(this, config);
29
+ const node = this;
30
+ // Store configuration validation error without failing construction
31
+ let configError = null;
32
+ // Get the IMAP config node
33
+ const imapConfigNode = RED.nodes.getNode(config.imapConfig);
34
+ try {
35
+ // Validate IMAP config node exists
36
+ if (!imapConfigNode) {
37
+ throw new Error('IMAP configuration node is not configured');
38
+ }
39
+ // Validate folder configuration
40
+ if (typeof config.folder === 'number') {
41
+ throw new Error("The 'folders' property must be an array of strings.");
42
+ }
43
+ if (Array.isArray(config.folder)) {
44
+ if (!config.folder.every((f) => typeof f === 'string')) {
45
+ throw new Error("The 'folders' property must be an array of strings.");
46
+ }
47
+ }
48
+ else if (typeof config.folder !== 'string' && config.folder !== undefined) {
49
+ throw new Error("The 'folders' property must be an array of strings.");
50
+ }
51
+ }
52
+ catch (error) {
53
+ configError = error instanceof Error ? error : new Error(String(error));
54
+ node.status({ fill: 'red', shape: 'ring', text: 'config error' });
55
+ // Store error for test framework to detect
56
+ node.configError = configError;
57
+ // Emit error immediately during construction for test framework
58
+ // Use setImmediate to ensure node is fully constructed first
59
+ setImmediate(() => {
60
+ node.error(configError.message);
61
+ });
62
+ }
63
+ node.on('input', (msg, send, done) => {
64
+ send =
65
+ send ||
66
+ function (m) {
67
+ node.send(m);
68
+ };
69
+ done =
70
+ done ||
71
+ function (err) {
72
+ if (err)
73
+ node.error(err, msg);
74
+ };
75
+ // If there's a configuration error, report it and don't proceed
76
+ if (configError) {
77
+ node.error(configError.message);
78
+ done(configError);
79
+ return;
80
+ }
81
+ try {
82
+ // Get configuration from config node
83
+ const imap_markSeen = RED.util.evaluateNodeProperty(String(config.markseen), config.markseenType, node, msg);
84
+ const imap_folder = RED.util.evaluateNodeProperty(String(config.folder), config.folderType, node, msg);
85
+ let folders;
86
+ if (Array.isArray(imap_folder)) {
87
+ folders = imap_folder;
88
+ }
89
+ else if (typeof imap_folder === 'string') {
90
+ folders = imap_folder
91
+ .split(',')
92
+ .map((f) => f.trim())
93
+ .filter((f) => f.length > 0);
94
+ }
95
+ else {
96
+ throw new Error("The 'folders' property must be an array of strings.");
97
+ }
98
+ // Evaluate user and password from config node (supports env and global)
99
+ const imap_user = RED.util.evaluateNodeProperty(imapConfigNode.user, imapConfigNode.userType || 'env', imapConfigNode, msg);
100
+ const imap_password = RED.util.evaluateNodeProperty(imapConfigNode.password, imapConfigNode.passwordType || 'env', imapConfigNode, msg);
101
+ const finalConfig = {
102
+ host: imapConfigNode.host,
103
+ port: imapConfigNode.port,
104
+ tls: imapConfigNode.tls,
105
+ user: imap_user,
106
+ password: imap_password,
107
+ folders: folders,
108
+ markSeen: toBoolean(imap_markSeen, true),
109
+ connTimeout: imapConfigNode.connTimeout,
110
+ authTimeout: imapConfigNode.authTimeout,
111
+ keepalive: imapConfigNode.keepalive,
112
+ autotls: imapConfigNode.autotls,
113
+ tlsOptions: { rejectUnauthorized: imapConfigNode.rejectUnauthorized },
114
+ };
115
+ // Enhanced validation after property evaluation
116
+ if (!finalConfig.user ||
117
+ !finalConfig.password ||
118
+ !finalConfig.port ||
119
+ !finalConfig.host ||
120
+ !finalConfig.folders ||
121
+ finalConfig.folders.length === 0) {
122
+ const missingFields = [];
123
+ if (!finalConfig.user)
124
+ missingFields.push('user');
125
+ if (!finalConfig.password)
126
+ missingFields.push('password');
127
+ if (!finalConfig.port)
128
+ missingFields.push('port');
129
+ if (!finalConfig.host)
130
+ missingFields.push('host');
131
+ if (!finalConfig.folders || finalConfig.folders.length === 0)
132
+ missingFields.push('folders');
133
+ throw new Error(`Missing required IMAP config: ${missingFields.join(', ')}. Aborting.`);
134
+ }
135
+ const fetchEmails = (fetchConfig, onMail) => {
136
+ // Use injected dependency instead of direct import
137
+ const imap = new dependencies.ImapClient({
138
+ user: fetchConfig.user,
139
+ password: fetchConfig.password,
140
+ host: fetchConfig.host,
141
+ port: fetchConfig.port,
142
+ tls: fetchConfig.tls,
143
+ connTimeout: fetchConfig.connTimeout,
144
+ authTimeout: fetchConfig.authTimeout,
145
+ keepalive: fetchConfig.keepalive,
146
+ autotls: fetchConfig.autotls,
147
+ tlsOptions: fetchConfig.tlsOptions,
148
+ });
149
+ const state = {
150
+ totalFolders: fetchConfig.folders.length,
151
+ processedFolders: 0,
152
+ folderCount: {},
153
+ successes: 0,
154
+ failures: 0,
155
+ totalMails: 0,
156
+ errors: [],
157
+ };
158
+ const updateStatus = (color, text) => {
159
+ node.status({ fill: color, shape: 'dot', text });
160
+ };
161
+ const finalizeSession = (error = null) => {
162
+ if (error) {
163
+ state.errors.push(error);
164
+ node.error('IMAP session terminated: ' + error.message);
165
+ node.status({ fill: 'red', shape: 'ring', text: 'connection error' });
166
+ node.send([
167
+ null,
168
+ {
169
+ payload: {
170
+ status: 'error',
171
+ message: error.message,
172
+ errors: state.errors,
173
+ },
174
+ },
175
+ ]);
176
+ done(error);
177
+ }
178
+ else if (state.failures > 0) {
179
+ node.status({
180
+ fill: 'red',
181
+ shape: 'dot',
182
+ text: `Done, ${state.totalMails} mails from ${state.successes}/${state.totalFolders} folders. ${state.failures} failed.`,
183
+ });
184
+ node.send([
185
+ null,
186
+ {
187
+ payload: {
188
+ status: 'warning',
189
+ total: state.totalMails,
190
+ successes: state.successes,
191
+ failures: state.failures,
192
+ totalFolders: state.totalFolders,
193
+ errors: state.errors,
194
+ },
195
+ },
196
+ ]);
197
+ }
198
+ else {
199
+ node.status({
200
+ fill: 'green',
201
+ shape: 'dot',
202
+ text: `Done, fetched ${state.totalMails} mails from ${fetchConfig.folders.join(', ')}.`,
203
+ });
204
+ node.send([
205
+ null,
206
+ {
207
+ payload: {
208
+ status: 'success',
209
+ total: state.totalMails,
210
+ folderCount: state.folderCount,
211
+ folders: folders.join(', '),
212
+ },
213
+ },
214
+ ]);
215
+ }
216
+ if (imap && imap.state !== 'disconnected') {
217
+ imap.end();
218
+ }
219
+ };
220
+ const fetchFromFolder = (folder) => {
221
+ updateStatus('yellow', `Fetching from "${folder}"...`);
222
+ imap.openBox(folder, false, (err, box) => {
223
+ if (err) {
224
+ node.error(`Could not open folder "${folder}": ${err.message}`);
225
+ state.failures++;
226
+ state.processedFolders++;
227
+ return startNextFolder();
228
+ }
229
+ state.folderCount[folder] = 0;
230
+ imap.search(['UNSEEN'], (err, results) => {
231
+ if (err) {
232
+ node.error(`Search failed in folder "${folder}": ${err.message}`);
233
+ state.failures++;
234
+ state.processedFolders++;
235
+ return startNextFolder();
236
+ }
237
+ if (!results || !results.length) {
238
+ state.successes++;
239
+ state.processedFolders++;
240
+ return startNextFolder();
241
+ }
242
+ state.totalMails += results.length;
243
+ const fetch = imap.fetch(results, { bodies: '', markSeen: finalConfig.markSeen });
244
+ fetch.on('message', (msg, seqno) => {
245
+ msg.on('body', (stream) => {
246
+ // Use injected dependency instead of direct import
247
+ dependencies.mailParser(stream, (err, parsed) => {
248
+ var _a, _b;
249
+ if (err) {
250
+ node.error(`Parse error for email from folder "${folder}": ${err.message}`);
251
+ return;
252
+ }
253
+ const outMsg = {
254
+ topic: parsed.subject || '',
255
+ payload: parsed.text || '',
256
+ html: parsed.html || '',
257
+ from: ((_a = parsed.replyTo) === null || _a === void 0 ? void 0 : _a.text) || ((_b = parsed.from) === null || _b === void 0 ? void 0 : _b.text) || '',
258
+ date: parsed.date,
259
+ folder,
260
+ header: parsed.headers,
261
+ attachments: (parsed.attachments || []).map((att) => ({
262
+ contentType: att.contentType,
263
+ fileName: att.filename,
264
+ contentDisposition: att.contentDisposition,
265
+ generatedFileName: att.cid || att.checksum,
266
+ contentId: att.cid,
267
+ checksum: att.checksum,
268
+ length: att.size,
269
+ content: att.content,
270
+ })),
271
+ };
272
+ state.folderCount[folder] = (state.folderCount[folder] || 0) + 1;
273
+ onMail(outMsg);
274
+ });
275
+ });
276
+ if (fetchConfig.markSeen) {
277
+ msg.once('attributes', (attrs) => {
278
+ imap.addFlags(attrs.uid, 'SEEN', (err) => {
279
+ if (err) {
280
+ node.error(`Failed to mark message UID ${attrs.uid} as seen: ${err.message}`);
281
+ }
282
+ });
283
+ });
284
+ }
285
+ });
286
+ fetch.once('error', (err) => {
287
+ node.error(`Fetch error in folder "${folder}": ${err.message}`);
288
+ });
289
+ fetch.once('end', () => {
290
+ state.successes++;
291
+ state.processedFolders++;
292
+ updateStatus('green', `Fetched ${results.length} from "${folder}".`);
293
+ startNextFolder();
294
+ });
295
+ });
296
+ });
297
+ };
298
+ const startNextFolder = () => {
299
+ if (state.processedFolders >= state.totalFolders) {
300
+ finalizeSession();
301
+ }
302
+ else {
303
+ fetchFromFolder(fetchConfig.folders[state.processedFolders]);
304
+ }
305
+ };
306
+ imap.once('ready', () => {
307
+ node.status({ fill: 'green', shape: 'dot', text: 'connected' });
308
+ startNextFolder();
309
+ });
310
+ imap.once('error', (err) => {
311
+ finalizeSession(err);
312
+ });
313
+ imap.once('end', () => {
314
+ updateStatus('green', 'IMAP connection ended.');
315
+ });
316
+ try {
317
+ updateStatus('yellow', 'Connecting to IMAP...');
318
+ imap.connect();
319
+ }
320
+ catch (err) {
321
+ const error = err instanceof Error ? err : new Error(String(err));
322
+ updateStatus('red', 'Connection error: ' + error.message);
323
+ done(error);
324
+ return;
325
+ }
326
+ };
327
+ fetchEmails(finalConfig, (mail) => {
328
+ send(mail);
329
+ });
330
+ done();
331
+ }
332
+ catch (error) {
333
+ node.status({ fill: 'red', shape: 'ring', text: 'config error' });
334
+ done(error instanceof Error ? error : new Error(String(error)));
335
+ }
336
+ });
337
+ node.on('close', () => { });
338
+ }
339
+ RED.nodes.registerType('email-receiver', EmailReceiverNode);
340
+ };
341
+ module.exports = nodeInit;
342
+ //# sourceMappingURL=email-receiver.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"email-receiver.js","sourceRoot":"","sources":["../../src/email-receiver/email-receiver.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,3 @@
1
+ import { NodeInitializer } from 'node-red';
2
+ declare const EmailSenderNode: NodeInitializer;
3
+ export = EmailSenderNode;