@5minds/node-red-contrib-processcube-tools 1.0.1-feature-c82263-mffckkf9 → 1.0.1-feature-122227-mfgey2et

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/.env.template ADDED
@@ -0,0 +1,4 @@
1
+ EMAIL_SEND_PORT=
2
+ EMAIL_SEND_HOST=
3
+ EMAIL_SEND_USER=
4
+ EMAIL_SEND_PASSWORD=
@@ -0,0 +1,258 @@
1
+ <script type="text/javascript">
2
+ RED.nodes.registerType('email-sender', {
3
+ category: 'ProcessCube Tools',
4
+ color: '#02AFD6',
5
+ defaults: {
6
+ name: { value: "" },
7
+ // Mail fields
8
+ sender: { value: "Stoelting Ticket-System", required: true, validate: RED.validators.typedInput("senderType") },
9
+ senderType: { value: "str" },
10
+ address: { value: "", required: true, validate: RED.validators.typedInput("addressType") },
11
+ addressType: { value: "str" },
12
+ to: { value: "", required: true, validate: RED.validators.typedInput("toType") },
13
+ toType: { value: "str" },
14
+ cc: { value: "", validate: RED.validators.typedInput("ccType") },
15
+ ccType: { value: "str" },
16
+ bcc: { value: "", validate: RED.validators.typedInput("bccType") },
17
+ bccType: { value: "str" },
18
+ subject: { value: "", required: true, validate: RED.validators.typedInput("subjectType") },
19
+ subjectType: { value: "str" },
20
+ htmlContent: { value: "", required: true, validate: RED.validators.typedInput("htmlContentType") },
21
+ htmlContentType: { value: "str" },
22
+ attachments: { value: "", required: false },
23
+ attachmentsType: { value: "msg" },
24
+
25
+ // SMTP-Fields
26
+ host: { value: "", required: true, validate: RED.validators.typedInput("hostType") },
27
+ hostType: { value: "str" },
28
+ port: { value: "", required: true, validate: RED.validators.typedInput("portType") },
29
+ portType: { value: "num" },
30
+ user: { value: "", required: true, validate: RED.validators.typedInput("userType") },
31
+ userType: { value: "str" },
32
+ password: { value: "", required: true, type: "password" },
33
+ passwordType: { value: "env", required: true },
34
+ secure: { value: "", required: true, validate: RED.validators.typedInput("secureType") },
35
+ secureType: { value: "bool" },
36
+ rejectUnauthorized: { value: "", required: true, validate: RED.validators.typedInput("rejectUnauthorizedType") },
37
+ rejectUnauthorizedType: { value: "bool" }
38
+ },
39
+ inputs: 1,
40
+ outputs: 1,
41
+ icon: "font-awesome/fa-paper-plane",
42
+ label: function() {
43
+ return this.name || "Email Sender";
44
+ },
45
+ oneditprepare: function() {
46
+ // Mail Fields
47
+ $('#node-input-sender').typedInput({
48
+ default: 'str',
49
+ types: ['str', 'msg', 'flow', 'global', 'env'],
50
+ typeField: '#node-input-senderType'
51
+ });
52
+ $('#node-input-address').typedInput({
53
+ default: 'str',
54
+ types: ['str', 'msg', 'flow', 'global', 'env'],
55
+ typeField: '#node-input-addressType'
56
+ });
57
+ $('#node-input-to').typedInput({
58
+ default: 'str',
59
+ types: ['str', 'msg', 'flow', 'global', 'env'],
60
+ typeField: '#node-input-toType'
61
+ });
62
+ $('#node-input-cc').typedInput({
63
+ default: 'str',
64
+ types: ['str', 'msg', 'flow', 'global', 'env'],
65
+ typeField: '#node-input-ccType'
66
+ });
67
+ $('#node-input-bcc').typedInput({
68
+ default: 'str',
69
+ types: ['str', 'msg', 'flow', 'global', 'env'],
70
+ typeField: '#node-input-bccType'
71
+ });
72
+ $('#node-input-subject').typedInput({
73
+ default: 'str',
74
+ types: ['str', 'msg', 'flow', 'global', 'env'],
75
+ typeField: '#node-input-subjectType'
76
+ });
77
+ $('#node-input-htmlContent').typedInput({
78
+ default: 'str',
79
+ types: ['str', 'msg', 'flow', 'global', 'json'],
80
+ typeField: '#node-input-htmlContentType'
81
+ });
82
+ $('#node-input-attachments').typedInput({
83
+ default: 'msg',
84
+ types: ['msg', 'flow', 'global'],
85
+ typeField: '#node-input-attachmentsType'
86
+ });
87
+
88
+ // SMTP Fields
89
+ $('#node-input-host').typedInput({
90
+ default: 'str',
91
+ types: ['str', 'msg', 'flow', 'global', 'env'],
92
+ typeField: '#node-input-hostType'
93
+ });
94
+ $('#node-input-port').typedInput({
95
+ default: 'num',
96
+ types: ['num', 'msg', 'flow', 'global', 'env'],
97
+ typeField: '#node-input-portType'
98
+ });
99
+ $('#node-input-user').typedInput({
100
+ default: 'str',
101
+ types: ['str', 'msg', 'flow', 'global', 'env'],
102
+ typeField: '#node-input-userType'
103
+ });
104
+ $('#node-input-password').typedInput({
105
+ default: 'env',
106
+ types: ['msg', 'flow', 'global', 'env'],
107
+ typeField: '#node-input-passwordType'
108
+ });
109
+ $('#node-input-secure').typedInput({
110
+ default: 'bool',
111
+ types: ['bool', 'msg', 'flow', 'global', 'env'],
112
+ typeField: '#node-input-secureType'
113
+ });
114
+ $('#node-input-rejectUnauthorized').typedInput({
115
+ default: 'bool',
116
+ types: ['bool', 'msg', 'flow', 'global', 'env'],
117
+ typeField: '#node-input-rejectUnauthorizedType'
118
+ });
119
+ }
120
+ });
121
+ </script>
122
+
123
+ <script type="text/html" data-template-name="email-sender">
124
+ <div class="form-row">
125
+ <label for="node-input-name"><i class="fa fa-tag"></i> Name</label>
126
+ <input type="text" id="node-input-name" placeholder="Name">
127
+ </div>
128
+
129
+ <h3>Mail Configuration</h3>
130
+ <div class="form-row">
131
+ <label for="node-input-sender"><i class="fa fa-user"></i> Sender</label>
132
+ <input type="text" id="node-input-sender" placeholder="John Doe">
133
+ <input type="hidden" id="node-input-senderType">
134
+ </div>
135
+ <div class="form-row">
136
+ <label for="node-input-address"><i class="fa fa-envelope"></i> Address</label>
137
+ <input type="text" id="node-input-address" placeholder="john.doe@example.com">
138
+ <input type="hidden" id="node-input-addressType">
139
+ </div>
140
+ <div class="form-row">
141
+ <label for="node-input-to"><i class="fa fa-user"></i> To</label>
142
+ <input type="text" id="node-input-to" placeholder="my.test@example.com">
143
+ <input type="hidden" id="node-input-toType">
144
+ </div>
145
+ <div class="form-row">
146
+ <label for="node-input-cc"><i class="fa fa-user-plus"></i> CC</label>
147
+ <input type="text" id="node-input-cc">
148
+ <input type="hidden" id="node-input-ccType">
149
+ </div>
150
+ <div class="form-row">
151
+ <label for="node-input-bcc"><i class="fa fa-user-secret"></i> BCC</label>
152
+ <input type="text" id="node-input-bcc">
153
+ <input type="hidden" id="node-input-bccType">
154
+ </div>
155
+ <div class="form-row">
156
+ <label for="node-input-subject"><i class="fa fa-info-circle"></i> Subject</label>
157
+ <input type="text" id="node-input-subject">
158
+ <input type="hidden" id="node-input-subjectType">
159
+ </div>
160
+ <div class="form-row">
161
+ <label for="node-input-htmlContent"><i class="fa fa-file-code-o"></i> HTML Content</label>
162
+ <input type="text" id="node-input-htmlContent">
163
+ <input type="hidden" id="node-input-htmlContentType">
164
+ </div>
165
+ <div class="form-row">
166
+ <label for="node-input-attachments"><i class="fa fa-paperclip"></i> Attachments</label>
167
+ <input type="text" id="node-input-attachments">
168
+ <input type="hidden" id="node-input-attachmentsType">
169
+ </div>
170
+
171
+ <h3>SMTP Configuration</h3>
172
+ <div class="form-row">
173
+ <label for="node-input-host"><i class="fa fa-server"></i> Host</label>
174
+ <input type="text" id="node-input-host" placeholder="smtp.gmail.com">
175
+ <input type="hidden" id="node-input-hostType">
176
+ </div>
177
+ <div class="form-row">
178
+ <label for="node-input-port"><i class="fa fa-plug"></i> Port</label>
179
+ <input type="text" id="node-input-port" placeholder="587">
180
+ <input type="hidden" id="node-input-portType">
181
+ </div>
182
+ <div class="form-row">
183
+ <label for="node-input-user"><i class="fa fa-user"></i> User</label>
184
+ <input type="text" id="node-input-user" placeholder="test.user@config.com">
185
+ <input type="hidden" id="node-input-userType">
186
+ </div>
187
+ <div class="form-row">
188
+ <label for="node-input-password"><i class="fa fa-lock"></i> Password</label>
189
+ <input type="password" id="node-input-password">
190
+ <input type="hidden" id="node-input-passwordType">
191
+ </div>
192
+ <div class="form-row">
193
+ <label for="node-input-secure"><i class="fa fa-shield"></i> SSL/TLS (Secure)</label>
194
+ <input type="text" id="node-input-secure">
195
+ <input type="hidden" id="node-input-secureType">
196
+ </div>
197
+ <div class="form-row">
198
+ <label for="node-input-rejectUnauthorized"><i class="fa fa-ban"></i> Reject Unauthorized</label>
199
+ <input type="text" id="node-input-rejectUnauthorized">
200
+ <input type="hidden" id="node-input-rejectUnauthorizedType">
201
+ </div>
202
+ </script>
203
+
204
+ <script type="text/html" data-help-name="email-sender">
205
+ <p>A custom node to send emails using an SMTP server. The configuration for each field can be sourced from a fixed value, or from a <code>msg</code>, <code>flow</code>, <code>global</code>, or <code>env</code> variable.</p>
206
+
207
+ <h3>Configuration</h3>
208
+ <p>Every field on the configuration panel is a <b>typed input</b>. Use the dropdown menu next to each field to select the source of its value. Note that <b>Sender</b>, <b>Address</b>, <b>To</b>, <b>Subject</b>, and <b>HTML Content</b> are required fields and must be configured before the node can be deployed.</p>
209
+
210
+ <h4>Mail Configuration</h4>
211
+ <dl class="message-properties">
212
+ <dt>Sender <span class="property-type">string | variable</span></dt>
213
+ <dd>The name of the sender, as displayed to the recipient.</dd>
214
+
215
+ <dt>Address <span class="property-type">string | variable</span></dt>
216
+ <dd>The sender's email address.</dd>
217
+
218
+ <dt>To <span class="property-type">string | variable</span></dt>
219
+ <dd>The primary recipient's email address. Separate multiple addresses with a comma.</dd>
220
+
221
+ <dt>CC <span class="property-type">string | variable</span></dt>
222
+ <dd>Addresses to be carbon-copied on the email.</dd>
223
+
224
+ <dt>BCC <span class="property-type">string | variable</span></dt>
225
+ <dd>Addresses to be blind-carbon-copied on the email.</dd>
226
+
227
+ <dt>Subject <span class="property-type">string | variable</span></dt>
228
+ <dd>The subject line of the email.</dd>
229
+
230
+ <dt>HTML Content <span class="property-type">string | variable</span></dt>
231
+ <dd>The HTML body of the email.</dd>
232
+
233
+ <dt>Attachments <span class="property-type">array | variable</span></dt>
234
+ <dd>A list of file attachments. This should be a variable containing an array of attachment objects.</dd>
235
+
236
+ </dl>
237
+
238
+ <h4>SMTP Configuration</h4>
239
+ <dl class="message-properties">
240
+ <dt>Host <span class="property-type">string | variable</span></dt>
241
+ <dd>The hostname or IP address of the SMTP server.</dd>
242
+
243
+ <dt>Port <span class="property-type">number | variable</span></dt>
244
+ <dd>The port number of the SMTP server.</dd>
245
+
246
+ <dt>User <span class="property-type">string | variable</span></dt>
247
+ <dd>The username for SMTP authentication.</dd>
248
+
249
+ <dt>Password <span class="property-type">string | variable</span></dt>
250
+ <dd>The password for SMTP authentication.</dd>
251
+
252
+ <dt>SSL/TLS (Secure) <span class="property-type">boolean | variable</span></dt>
253
+ <dd>Use a secure connection. Set to <code>true</code> for SSL/TLS, <code>false</code> for a non-secure connection.</dd>
254
+
255
+ <dt>Reject Unauthorized <span class="property-type">boolean | variable</span></dt>
256
+ <dd>If <code>true</code>, the server's certificate is rejected if it's not authorized by a trusted CA.</dd>
257
+ </dl>
258
+ </script>
@@ -0,0 +1,114 @@
1
+ module.exports = function(RED) {
2
+ "use strict";
3
+ const nodemailer = require("nodemailer");
4
+
5
+ function EmailSenderNode(config) {
6
+ RED.nodes.createNode(this, config);
7
+ var node = this;
8
+
9
+ node.on('input', function(msg, send, done) {
10
+ send = send || function() { node.send.apply(node, arguments); };
11
+ done = done || function(err) { if (err) node.error(err, msg); };
12
+
13
+ // Retrieve and evaluate mail configuration values
14
+ const sender = RED.util.evaluateNodeProperty(config.sender, config.senderType, node, msg);
15
+ const address = RED.util.evaluateNodeProperty(config.address, config.addressType, node, msg);
16
+ const to = RED.util.evaluateNodeProperty(config.to, config.toType, node, msg);
17
+ const cc = RED.util.evaluateNodeProperty(config.cc, config.ccType, node, msg) || "";
18
+ const bcc = RED.util.evaluateNodeProperty(config.bcc, config.bccType, node, msg) || "";
19
+ const subject = RED.util.evaluateNodeProperty(config.subject, config.subjectType, node, msg) || msg.topic || "Message from Node-RED";
20
+ const htmlContent = RED.util.evaluateNodeProperty(config.htmlContent, config.htmlContentType, node, msg);
21
+ const attachments = RED.util.evaluateNodeProperty(config.attachments, config.attachmentsType, node, msg);
22
+
23
+ // Retrieve and evaluate SMTP configuration values
24
+ const host = RED.util.evaluateNodeProperty(config.host, config.hostType, node, msg);
25
+ const port = RED.util.evaluateNodeProperty(config.port, config.portType, node, msg);
26
+ const user = RED.util.evaluateNodeProperty(config.user, config.userType, node, msg);
27
+ const password = RED.util.evaluateNodeProperty(config.password, config.passwordType, node, msg);
28
+ const secure = RED.util.evaluateNodeProperty(config.secure, config.secureType, node, msg);
29
+ const rejectUnauthorized = RED.util.evaluateNodeProperty(config.rejectUnauthorized, config.rejectUnauthorizedType, node, msg);
30
+
31
+ // Handle attachments and format them for Nodemailer
32
+ let processedAttachments = [];
33
+ if (attachments) {
34
+ // Check if it's a single attachment or an array
35
+ const attachmentArray = Array.isArray(attachments) ? attachments : [attachments];
36
+
37
+ for (const attachment of attachmentArray) {
38
+ try {
39
+ // Assuming the attachment object has a 'filename' and 'content' property
40
+ if (attachment.filename && attachment.content) {
41
+ processedAttachments.push({
42
+ filename: attachment.filename,
43
+ content: attachment.content
44
+ });
45
+ } else {
46
+ node.warn("Attachment object is missing 'filename' or 'content' property and will be ignored.");
47
+ }
48
+ } catch (e) {
49
+ node.error("Failed to process attachment: " + e.message);
50
+ }
51
+ }
52
+ }
53
+
54
+ // Create SMTP transporter
55
+ const transporter = nodemailer.createTransport({
56
+ host: host,
57
+ port: port,
58
+ secure: secure,
59
+ auth: {
60
+ user: user,
61
+ pass: password
62
+ },
63
+ tls: {
64
+ rejectUnauthorized: rejectUnauthorized
65
+ }
66
+ });
67
+
68
+ // Create email object
69
+ const mailOptions = {
70
+ from: {
71
+ name: sender,
72
+ address: address
73
+ },
74
+ to: to,
75
+ cc: cc,
76
+ bcc: bcc,
77
+ subject: subject,
78
+ html: Buffer.from(htmlContent, 'utf-8'),
79
+ attachments: processedAttachments
80
+ };
81
+
82
+ // Send email
83
+ transporter.sendMail(mailOptions, (error, info) => {
84
+ if (error) {
85
+ node.status({ fill: "red", shape: "dot", text: "error sending" });
86
+ done(error);
87
+ } else {
88
+ node.log('Email sent: ' + info.response);
89
+ msg.payload = info;
90
+
91
+ if (msg.payload.accepted && msg.payload.accepted.length > 0) {
92
+ msg.payload = msg.input;
93
+ node.status({ fill: "green", shape: "dot", text: "sent" });
94
+ send(msg);
95
+ done();
96
+ } else if (msg.payload.rejected && msg.payload.rejected.length > 0) {
97
+ msg.error = { result: msg.payload.rejected };
98
+ node.status({ fill: "red", shape: "dot", text: "rejected" });
99
+ done(new Error('Email rejected: ' + msg.payload.rejected.join(', ')));
100
+ } else if (msg.payload.pending && msg.payload.pending.length > 0) {
101
+ msg.error = { result: msg.payload.pending };
102
+ node.status({ fill: "yellow", shape: "dot", text: "pending" });
103
+ done(new Error('Email pending: ' + msg.payload.pending.join(', ')));
104
+ } else {
105
+ node.status({ fill: "red", shape: "dot", text: "unknown error" });
106
+ done(new Error('Unknown error while sending email.'));
107
+ }
108
+ }
109
+ });
110
+ });
111
+ }
112
+
113
+ RED.nodes.registerType("email-sender", EmailSenderNode);
114
+ };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@5minds/node-red-contrib-processcube-tools",
3
- "version": "1.0.1-feature-c82263-mffckkf9",
3
+ "version": "1.0.1-feature-122227-mfgey2et",
4
4
  "license": "MIT",
5
5
  "description": "Node-RED tools nodes for ProcessCube",
6
6
  "scripts": {
@@ -37,7 +37,8 @@
37
37
  "version": ">=3.1.9",
38
38
  "nodes": {
39
39
  "EmailReceiver": "email-receiver/email-receiver.js",
40
- "HtmlToText": "processcube-html-to-text.js"
40
+ "EmailSender": "email-sender/email-sender.js",
41
+ "HtmlToText": "processcube-html-to-text/processcube-html-to-text.js"
41
42
  },
42
43
  "examples": "examples"
43
44
  },
@@ -45,18 +46,20 @@
45
46
  "html-to-text": "^9.0.5",
46
47
  "mailparser": "^3.6.8",
47
48
  "node-imap": "^0.9.6",
49
+ "nodemailer": "^7.0.6",
48
50
  "utf7": "^1.0.2"
49
51
  },
50
52
  "devDependencies": {
51
53
  "chai": "^4.3.4",
52
54
  "mocha": "^11.7.2",
53
- "node-red": "^4.1.0",
55
+ "node-red": "^4.0.9",
54
56
  "node-red-node-test-helper": "^0.3.5",
55
57
  "should": "^13.2.3",
56
58
  "sinon": "^11.1.2"
57
59
  },
58
60
  "overrides": {
59
- "semver": ">=7.5.2"
61
+ "semver": ">=7.5.2",
62
+ "axios": ">=1.12.0"
60
63
  },
61
64
  "keywords": [
62
65
  "node-red",