@hyperbytes/wappler-imap-manager 1.0.0
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/CHANGELOG.md +4 -0
- package/LICENSE.md +21 -0
- package/README.md +10 -0
- package/package.json +22 -0
- package/server_connect/modules/imapcount.hjson +126 -0
- package/server_connect/modules/imapcount.js +53 -0
- package/server_connect/modules/imapcount.php +17 -0
- package/server_connect/modules/imapcreatefolder.hjson +124 -0
- package/server_connect/modules/imapcreatefolder.js +46 -0
- package/server_connect/modules/imapcreatefolder.php +17 -0
- package/server_connect/modules/imapdelete.hjson +148 -0
- package/server_connect/modules/imapdelete.js +73 -0
- package/server_connect/modules/imapdelete.php +17 -0
- package/server_connect/modules/imapdeletefolder.hjson +125 -0
- package/server_connect/modules/imapdeletefolder.js +65 -0
- package/server_connect/modules/imapdeletefolder.php +17 -0
- package/server_connect/modules/imapdirlist.hjson +122 -0
- package/server_connect/modules/imapdirlist.js +57 -0
- package/server_connect/modules/imapdirlist.php +17 -0
- package/server_connect/modules/imapexpunge.hjson +115 -0
- package/server_connect/modules/imapexpunge.js +63 -0
- package/server_connect/modules/imapexpunge.php +17 -0
- package/server_connect/modules/imapflag.hjson +153 -0
- package/server_connect/modules/imapflag.js +81 -0
- package/server_connect/modules/imapflag.php +17 -0
- package/server_connect/modules/imapgetattachments.hjson +159 -0
- package/server_connect/modules/imapgetattachments.js +94 -0
- package/server_connect/modules/imapgetattachments.php +17 -0
- package/server_connect/modules/imapgetrawheaders.hjson +120 -0
- package/server_connect/modules/imapgetrawheaders.js +121 -0
- package/server_connect/modules/imapgetrawheaders.php +17 -0
- package/server_connect/modules/imapmailcontent.hjson +192 -0
- package/server_connect/modules/imapmailcontent.js +113 -0
- package/server_connect/modules/imapmailcontent.php +17 -0
- package/server_connect/modules/imapmailheaders.hjson +174 -0
- package/server_connect/modules/imapmailheaders.js +184 -0
- package/server_connect/modules/imapmailheaders.php +71 -0
- package/server_connect/modules/imapmovefolder.hjson +158 -0
- package/server_connect/modules/imapmovefolder.js +86 -0
- package/server_connect/modules/imapmovefolder.php +17 -0
- package/server_connect/modules/imapremoveflag.hjson +151 -0
- package/server_connect/modules/imapremoveflag.js +72 -0
- package/server_connect/modules/imapremoveflag.php +17 -0
- package/server_connect/modules/imapsaveasdraft.hjson +202 -0
- package/server_connect/modules/imapsaveasdraft.js +184 -0
- package/server_connect/modules/imapsaveflag.php +17 -0
- package/server_connect/modules/imapsendmail.hjson +190 -0
- package/server_connect/modules/imapsendmail.js +171 -0
- package/server_connect/modules/imapsendmail.php +17 -0
- package/server_connect/modules/imapstore.hjson +160 -0
- package/server_connect/modules/imapstore.js +63 -0
- package/server_connect/modules/imapstore.php +17 -0
- package/server_connect/modules/imapsubscribe.hjson +128 -0
- package/server_connect/modules/imapsubscribe.js +43 -0
- package/server_connect/modules/imapsubscribe.php +17 -0
- package/server_connect/modules/imapsubscribedlist.hjson +122 -0
- package/server_connect/modules/imapsubscribedlist.js +57 -0
- package/server_connect/modules/imapsubscribedlist.php +17 -0
- package/server_connect/modules/imaptrashperms.hjson +115 -0
- package/server_connect/modules/imaptrashperms.js +51 -0
- package/server_connect/modules/imaptrashperms.php +17 -0
- package/server_connect/modules/imapunsubscribedlist.hjson +122 -0
- package/server_connect/modules/imapunsubscribedlist.js +80 -0
- package/server_connect/modules/imapunsubscribedlist.php +17 -0
- package/server_connect/modules/testfile.hjsonx +134 -0
- package/server_connect/modules/testfile.js +28 -0
- package/server_connect/modules/testfile_bug.hjsonx +141 -0
- package/server_connect/modules/testfile_bug.js +8 -0
|
@@ -0,0 +1,184 @@
|
|
|
1
|
+
const Imap = require('imap');
|
|
2
|
+
|
|
3
|
+
exports.imapmailheaders = async function (options, name) {
|
|
4
|
+
const IMAP_HOST = this.parseOptional(options.imap_host, '*', process.env.IMAP_HOST);
|
|
5
|
+
const IMAP_PASSWORD = this.parseOptional(options.imap_password, '*', process.env.IMAP_PASSWORD);
|
|
6
|
+
const IMAP_USER = this.parseOptional(options.imap_usesr, '*', process.env.IMAP_USER);
|
|
7
|
+
const IMAP_PORT = this.parseOptional(options.imap_port, '*', process.env.IMAP_PORT);
|
|
8
|
+
const imap_tlsstring = this.parseOptional(options.imap_tls, '*', process.env.IMAP_TLS).toLowerCase();
|
|
9
|
+
const IMAP_TLS = (imap_tlsstring == 'true');
|
|
10
|
+
|
|
11
|
+
const offset = this.parseOptional(options.offset, '*', 0);
|
|
12
|
+
const payload = this.parseOptional(options.payload, '*', 25);
|
|
13
|
+
const mailbox = this.parseOptional(options.mailbox, '*', 'INBOX');
|
|
14
|
+
|
|
15
|
+
return new Promise((resolve) => {
|
|
16
|
+
const imap = new Imap({
|
|
17
|
+
user: IMAP_USER,
|
|
18
|
+
password: IMAP_PASSWORD,
|
|
19
|
+
host: IMAP_HOST,
|
|
20
|
+
port: IMAP_PORT,
|
|
21
|
+
tls: IMAP_TLS,
|
|
22
|
+
});
|
|
23
|
+
|
|
24
|
+
const messages = [];
|
|
25
|
+
|
|
26
|
+
function openInbox(cb) {
|
|
27
|
+
imap.openBox(mailbox, true, cb);
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
imap.once('ready', function () {
|
|
31
|
+
openInbox(function (err, box) {
|
|
32
|
+
if (err) {
|
|
33
|
+
imap.end();
|
|
34
|
+
return resolve({ data: [], status: 401 });
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
if (box.messages.total === 0) {
|
|
38
|
+
imap.end();
|
|
39
|
+
return resolve({ data: [], status: 200 });
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
const totalMessages = box.messages.total;
|
|
43
|
+
let end = Math.max(totalMessages - (offset * payload), 1);
|
|
44
|
+
let start = Math.max(end - payload, 1);
|
|
45
|
+
|
|
46
|
+
if (start > end || start < 1) {
|
|
47
|
+
imap.end();
|
|
48
|
+
return resolve({ data: [], status: 400 });
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
const tofetch = `${start}:${end}`;
|
|
52
|
+
|
|
53
|
+
const f = imap.seq.fetch(tofetch, {
|
|
54
|
+
bodies: 'HEADER.FIELDS (FROM TO CC BCC SUBJECT DATE MESSAGE-ID RECEIVED)',
|
|
55
|
+
struct: true,
|
|
56
|
+
});
|
|
57
|
+
|
|
58
|
+
f.on('message', function (msg, seqno) {
|
|
59
|
+
let messageData = {
|
|
60
|
+
id: seqno,
|
|
61
|
+
uid: null,
|
|
62
|
+
headers: {},
|
|
63
|
+
flags: [],
|
|
64
|
+
attachmentCount: 0,
|
|
65
|
+
uidvalidity: box.uidvalidity,
|
|
66
|
+
mailbox: mailbox
|
|
67
|
+
|
|
68
|
+
};
|
|
69
|
+
|
|
70
|
+
msg.on('body', function (stream) {
|
|
71
|
+
let buffer = '';
|
|
72
|
+
stream.on('data', function (chunk) {
|
|
73
|
+
buffer += chunk.toString('utf8');
|
|
74
|
+
});
|
|
75
|
+
stream.once('end', function () {
|
|
76
|
+
let headers = Imap.parseHeader(buffer);
|
|
77
|
+
|
|
78
|
+
console.log("Extracted headers:", headers);
|
|
79
|
+
|
|
80
|
+
if (headers.date) {
|
|
81
|
+
headers.messagedate = new Intl.DateTimeFormat('en-GB', {
|
|
82
|
+
year: 'numeric',
|
|
83
|
+
month: '2-digit',
|
|
84
|
+
day: '2-digit',
|
|
85
|
+
hour: '2-digit',
|
|
86
|
+
minute: '2-digit',
|
|
87
|
+
second: '2-digit',
|
|
88
|
+
timeZone: 'UTC',
|
|
89
|
+
}).format(new Date(headers.date));
|
|
90
|
+
|
|
91
|
+
delete headers.Date;
|
|
92
|
+
} else if (headers.received && headers.received.length > 0) {
|
|
93
|
+
console.log("Checking Received headers for fallback date...");
|
|
94
|
+
|
|
95
|
+
const receivedTimestamps = headers.received.map(receivedHeader => {
|
|
96
|
+
const match = receivedHeader.match(/\b(\w{3}, )?\d{1,2} \w{3} \d{4} \d{2}:\d{2}:\d{2} (\w+|\+\d{4})\b/);
|
|
97
|
+
return match ? match[0] : null;
|
|
98
|
+
}).filter(Boolean);
|
|
99
|
+
|
|
100
|
+
if (receivedTimestamps.length > 0) {
|
|
101
|
+
headers.messagedate = new Intl.DateTimeFormat('en-GB', {
|
|
102
|
+
year: 'numeric',
|
|
103
|
+
month: '2-digit',
|
|
104
|
+
day: '2-digit',
|
|
105
|
+
hour: '2-digit',
|
|
106
|
+
minute: '2-digit',
|
|
107
|
+
second: '2-digit',
|
|
108
|
+
timeZone: 'UTC',
|
|
109
|
+
}).format(new Date(receivedTimestamps[receivedTimestamps.length - 1]));
|
|
110
|
+
} else {
|
|
111
|
+
headers.messagedate = 'Unknown Date';
|
|
112
|
+
}
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
messageData.headers = {
|
|
116
|
+
from: headers['from'],
|
|
117
|
+
to: headers['to'],
|
|
118
|
+
cc: headers['cc'] || [],
|
|
119
|
+
bcc: headers['bcc'] || [],
|
|
120
|
+
subject: headers['subject'],
|
|
121
|
+
'message-id': headers['message-id'],
|
|
122
|
+
messagedate: headers.messagedate
|
|
123
|
+
};
|
|
124
|
+
});
|
|
125
|
+
});
|
|
126
|
+
|
|
127
|
+
msg.once('attributes', function (attrs) {
|
|
128
|
+
messageData.flags = attrs.flags;
|
|
129
|
+
messageData.uid = attrs.uid;
|
|
130
|
+
|
|
131
|
+
if (!messageData.headers.messagedate && attrs.date) {
|
|
132
|
+
messageData.headers.messagedate = new Intl.DateTimeFormat('en-GB', {
|
|
133
|
+
year: 'numeric',
|
|
134
|
+
month: '2-digit',
|
|
135
|
+
day: '2-digit',
|
|
136
|
+
hour: '2-digit',
|
|
137
|
+
minute: '2-digit',
|
|
138
|
+
second: '2-digit',
|
|
139
|
+
timeZone: 'UTC',
|
|
140
|
+
}).format(new Date(attrs.date));
|
|
141
|
+
}
|
|
142
|
+
|
|
143
|
+
if (attrs.struct) {
|
|
144
|
+
function countAttachments(struct) {
|
|
145
|
+
return struct.reduce((count, part) => {
|
|
146
|
+
if (Array.isArray(part)) {
|
|
147
|
+
return count + countAttachments(part);
|
|
148
|
+
}
|
|
149
|
+
return part.disposition && part.disposition.type.toLowerCase() === 'attachment' ? count + 1 : count;
|
|
150
|
+
}, 0);
|
|
151
|
+
}
|
|
152
|
+
messageData.attachmentCount = countAttachments(attrs.struct);
|
|
153
|
+
}
|
|
154
|
+
});
|
|
155
|
+
|
|
156
|
+
msg.once('end', function () {
|
|
157
|
+
console.log("Final message data before pushing:", messageData);
|
|
158
|
+
messages.push(messageData);
|
|
159
|
+
});
|
|
160
|
+
});
|
|
161
|
+
|
|
162
|
+
f.once('error', function () {
|
|
163
|
+
resolve({ data: [], status: 400 });
|
|
164
|
+
});
|
|
165
|
+
|
|
166
|
+
f.once('end', function () {
|
|
167
|
+
imap.end();
|
|
168
|
+
resolve({ data: messages.reverse(), status: 200 });
|
|
169
|
+
});
|
|
170
|
+
});
|
|
171
|
+
});
|
|
172
|
+
|
|
173
|
+
imap.once('error', function () {
|
|
174
|
+
resolve({ data: [], status: 401 });
|
|
175
|
+
});
|
|
176
|
+
|
|
177
|
+
imap.once('end', function () {
|
|
178
|
+
console.log('IMAP connection closed.');
|
|
179
|
+
});
|
|
180
|
+
|
|
181
|
+
imap.connect();
|
|
182
|
+
});
|
|
183
|
+
};
|
|
184
|
+
|
|
@@ -0,0 +1,71 @@
|
|
|
1
|
+
<?php
|
|
2
|
+
|
|
3
|
+
namespace modules;
|
|
4
|
+
|
|
5
|
+
use \lib\core\Module;
|
|
6
|
+
|
|
7
|
+
class custom extends Module
|
|
8
|
+
|
|
9
|
+
<?php
|
|
10
|
+
public function imapMailHeaders($options, $name) {
|
|
11
|
+
$IMAP_HOST = $options['imap_host'] ?? getenv('IMAP_HOST');
|
|
12
|
+
$IMAP_PASSWORD = $options['imap_password'] ?? getenv('IMAP_PASSWORD');
|
|
13
|
+
$IMAP_USER = $options['imap_usesr'] ?? getenv('IMAP_USER');
|
|
14
|
+
$IMAP_PORT = $options['imap_port'] ?? getenv('IMAP_PORT');
|
|
15
|
+
$IMAP_TLS = strtolower($options['imap_tls'] ?? getenv('IMAP_TLS')) === 'true';
|
|
16
|
+
|
|
17
|
+
$offset = $options['offset'] ?? 0;
|
|
18
|
+
$payload = $options['payload'] ?? 25;
|
|
19
|
+
$mailbox = $options['mailbox'] ?? 'INBOX';
|
|
20
|
+
|
|
21
|
+
$imap = imap_open("{" . $IMAP_HOST . ":" . $IMAP_PORT . ($IMAP_TLS ? "/ssl" : "") . "}INBOX", $IMAP_USER, $IMAP_PASSWORD);
|
|
22
|
+
|
|
23
|
+
if (!$imap) {
|
|
24
|
+
return ['data' => [], 'status' => 401];
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
$messages = [];
|
|
28
|
+
$totalMessages = imap_num_msg($imap);
|
|
29
|
+
|
|
30
|
+
if ($totalMessages === 0) {
|
|
31
|
+
imap_close($imap);
|
|
32
|
+
return ['data' => [], 'status' => 200];
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
$end = max($totalMessages - ($offset * $payload), 1);
|
|
36
|
+
$start = max($end - $payload, 1);
|
|
37
|
+
|
|
38
|
+
if ($start > $end || $start < 1) {
|
|
39
|
+
imap_close($imap);
|
|
40
|
+
return ['data' => [], 'status' => 400];
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
for ($i = $start; $i <= $end; $i++) {
|
|
44
|
+
$headers = imap_headerinfo($imap, $i);
|
|
45
|
+
$messageData = [
|
|
46
|
+
'id' => $i,
|
|
47
|
+
'uid' => imap_uid($imap, $i),
|
|
48
|
+
'headers' => [
|
|
49
|
+
'from' => $headers->fromaddress,
|
|
50
|
+
'to' => $headers->toaddress ?? '',
|
|
51
|
+
'cc' => $headers->ccaddress ?? '',
|
|
52
|
+
'bcc' => $headers->bccaddress ?? '',
|
|
53
|
+
'subject' => $headers->subject,
|
|
54
|
+
'message-id' => $headers->message_id ?? '',
|
|
55
|
+
'messagedate' => date('Y-m-d H:i:s', strtotime($headers->date))
|
|
56
|
+
],
|
|
57
|
+
'flags' => imap_fetch_overview($imap, $i)[0]->flags ?? [],
|
|
58
|
+
'attachmentCount' => count(imap_mime_header_decode($headers->subject)),
|
|
59
|
+
'uidvalidity' => imap_uid($imap, $i),
|
|
60
|
+
'mailbox' => $mailbox
|
|
61
|
+
];
|
|
62
|
+
|
|
63
|
+
$messages[] = $messageData;
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
imap_close($imap);
|
|
67
|
+
return ['data' => array_reverse($messages), 'status' => 200];
|
|
68
|
+
}
|
|
69
|
+
?>
|
|
70
|
+
|
|
71
|
+
|
|
@@ -0,0 +1,158 @@
|
|
|
1
|
+
[{
|
|
2
|
+
type: 'imapmovefolder-imapmovefolder',
|
|
3
|
+
module : 'imapmovefolder',
|
|
4
|
+
action : 'imapmovefolder',
|
|
5
|
+
groupTitle : 'Mailer',
|
|
6
|
+
groupIcon : 'fas fa-envelope comp-general',
|
|
7
|
+
title : 'IMAP Move Folder',
|
|
8
|
+
icon : 'fas fa-solid fa-list comp-exec',
|
|
9
|
+
dataPickObject: true,
|
|
10
|
+
usedModules : {
|
|
11
|
+
node: {
|
|
12
|
+
'imap' : '^8.8.19',
|
|
13
|
+
'mailparser' : '^3.7.2'
|
|
14
|
+
}
|
|
15
|
+
},
|
|
16
|
+
dataScheme: [
|
|
17
|
+
{ type: "number",name: "uid"},
|
|
18
|
+
{ type: "text",name: "mailbox"},
|
|
19
|
+
{ type: "text",name: "destination"},
|
|
20
|
+
{ type: "number",name: "uidvalidity"},
|
|
21
|
+
{ type: "number",name: "status"}
|
|
22
|
+
],
|
|
23
|
+
properties : [
|
|
24
|
+
{
|
|
25
|
+
group: 'IMAP Inputs',
|
|
26
|
+
variables: [
|
|
27
|
+
|
|
28
|
+
{ name: 'actionName',
|
|
29
|
+
optionName: 'name',
|
|
30
|
+
title: 'Name',
|
|
31
|
+
type: 'text',
|
|
32
|
+
required: true,
|
|
33
|
+
baseName: "imap"
|
|
34
|
+
},
|
|
35
|
+
{ name: 'selector', optionName: 'selector', title: 'IAMP Settings Selection',
|
|
36
|
+
type: 'droplist',
|
|
37
|
+
values: [
|
|
38
|
+
{title: 'Use ENV ', value: 'ENV' ,show:[],hide:['imap_msg','imap_host','imap_user','imap_password','imap_port','imap_tls']},
|
|
39
|
+
{title: 'Enable Manual Overrides', value: 'MANUAL',hide:[],show:['imap_msg','imap_host','imap_user','imap_password','imap_port','imap_tls'] },
|
|
40
|
+
|
|
41
|
+
|
|
42
|
+
],
|
|
43
|
+
defaultValue: 'ENV',
|
|
44
|
+
help: 'Choose your TLS settings.',
|
|
45
|
+
initValue: "ENV"
|
|
46
|
+
},
|
|
47
|
+
|
|
48
|
+
{name: 'imap_msg',
|
|
49
|
+
optionName: 'imap_msg',
|
|
50
|
+
title: 'IMAP password',
|
|
51
|
+
type: 'static',
|
|
52
|
+
help: 'IMAP .ENV OVERRIDE SETTINGS'
|
|
53
|
+
},
|
|
54
|
+
|
|
55
|
+
{name: 'imap_host',
|
|
56
|
+
optionName: 'imap_host',
|
|
57
|
+
title: 'IMAP Host',
|
|
58
|
+
type: 'text',
|
|
59
|
+
defaultValue: "", initDisplay: 'none',
|
|
60
|
+
serverDataBindings: true,
|
|
61
|
+
help: 'The IMAP Host Server'
|
|
62
|
+
},
|
|
63
|
+
{name: 'imap_user',
|
|
64
|
+
optionName: 'imap_user',
|
|
65
|
+
title: 'IMAP User',
|
|
66
|
+
type: 'text',
|
|
67
|
+
defaultValue: "", initDisplay: 'none',
|
|
68
|
+
serverDataBindings: true,
|
|
69
|
+
help: 'The IMAP user'
|
|
70
|
+
},
|
|
71
|
+
|
|
72
|
+
{name: 'imap_password',
|
|
73
|
+
optionName: 'imap_password',
|
|
74
|
+
title: 'IMAP password',
|
|
75
|
+
type: 'text',
|
|
76
|
+
defaultValue: "", initDisplay: 'none',
|
|
77
|
+
serverDataBindings: true,
|
|
78
|
+
help: 'The IMAP password'
|
|
79
|
+
},
|
|
80
|
+
{name: 'imap_port',
|
|
81
|
+
optionName: 'imap_port',
|
|
82
|
+
title: 'IMAP Port',
|
|
83
|
+
type: 'text',
|
|
84
|
+
defaultValue: "", initDisplay: 'none',
|
|
85
|
+
serverDataBindings: true,
|
|
86
|
+
help: 'The IMAP port'
|
|
87
|
+
},
|
|
88
|
+
{ name: 'imap_tls', optionName: 'imap_tls', title: 'TLS Settings',
|
|
89
|
+
type: 'droplist',
|
|
90
|
+
values: [
|
|
91
|
+
{title: 'Use ENV if available', value: 'ENV' },
|
|
92
|
+
{title: 'True', value: 'True' },
|
|
93
|
+
{title: 'False', value: 'False' },
|
|
94
|
+
|
|
95
|
+
],
|
|
96
|
+
defaultValue: 'ENV', initDisplay: 'none',
|
|
97
|
+
help: 'Choose your TLS settings.',
|
|
98
|
+
initValue: "ENV"
|
|
99
|
+
},
|
|
100
|
+
|
|
101
|
+
{name: 'imap_msg2',
|
|
102
|
+
optionName: 'imap_msg2',
|
|
103
|
+
title: '',
|
|
104
|
+
type: 'static',
|
|
105
|
+
help: 'API ACTION SETTINGS'
|
|
106
|
+
},
|
|
107
|
+
{ name: 'uid',
|
|
108
|
+
optionName: 'uid',
|
|
109
|
+
title: 'Message UID',
|
|
110
|
+
type: 'text',
|
|
111
|
+
required: true,
|
|
112
|
+
defaultValue: "",
|
|
113
|
+
serverDataBindings: true,
|
|
114
|
+
help: 'uid of the message'
|
|
115
|
+
},
|
|
116
|
+
{ name: 'uidvalidity',
|
|
117
|
+
optionName: 'uidvalidity',
|
|
118
|
+
title: 'uidValidity',
|
|
119
|
+
type: 'text',
|
|
120
|
+
required: true,
|
|
121
|
+
defaultValue: "0",
|
|
122
|
+
serverDataBindings: true,
|
|
123
|
+
help: 'The uidValidity key of the email'
|
|
124
|
+
},
|
|
125
|
+
{ name: 'mailbox',
|
|
126
|
+
optionName: 'mailbox',
|
|
127
|
+
title: 'mailbox',
|
|
128
|
+
type: 'text',
|
|
129
|
+
required: true,
|
|
130
|
+
defaultValue: "INBOX",
|
|
131
|
+
serverDataBindings: true,
|
|
132
|
+
help: 'The mailbox containing the email'
|
|
133
|
+
},
|
|
134
|
+
|
|
135
|
+
{ name: 'dirto',
|
|
136
|
+
optionName: 'dirto',
|
|
137
|
+
title: 'To Mailbox',
|
|
138
|
+
type: 'text',
|
|
139
|
+
required: true,
|
|
140
|
+
defaultValue: "",
|
|
141
|
+
serverDataBindings: true,
|
|
142
|
+
help: 'To box'
|
|
143
|
+
},
|
|
144
|
+
|
|
145
|
+
|
|
146
|
+
{ name: 'output',
|
|
147
|
+
optionName: 'output',
|
|
148
|
+
title: 'Output',
|
|
149
|
+
type: 'boolean',
|
|
150
|
+
defaultValue: false
|
|
151
|
+
}
|
|
152
|
+
|
|
153
|
+
]
|
|
154
|
+
},
|
|
155
|
+
|
|
156
|
+
]
|
|
157
|
+
}
|
|
158
|
+
]
|
|
@@ -0,0 +1,86 @@
|
|
|
1
|
+
const Imap = require('imap');
|
|
2
|
+
|
|
3
|
+
exports.imapmovefolder = async function (options) {
|
|
4
|
+
const IMAP_HOST = this.parseOptional(options.imap_host, '*', process.env.IMAP_HOST);
|
|
5
|
+
const IMAP_PASSWORD = this.parseOptional(options.imap_password, '*', process.env.IMAP_PASSWORD);
|
|
6
|
+
const IMAP_USER = this.parseOptional(options.imap_user, '*', process.env.IMAP_USER);
|
|
7
|
+
const IMAP_PORT = this.parseOptional(options.imap_port, '*', process.env.IMAP_PORT);
|
|
8
|
+
const imap_tlsstring = this.parseOptional(options.imap_tls, '*', process.env.IMAP_TLS).toLowerCase();
|
|
9
|
+
const IMAP_TLS = (imap_tlsstring == 'true');
|
|
10
|
+
|
|
11
|
+
const uid = this.parseRequired(options.uid, '*', "No message UID specified");
|
|
12
|
+
const uidvalidity = Number(this.parseRequired(options.uidvalidity, '*', "No UIDVALIDITY specified"));
|
|
13
|
+
const mailbox = this.parseRequired(options.mailbox, '*', "No Mailbox specified");
|
|
14
|
+
const dirto = this.parseRequired(options.dirto, '*', "No destination Mailbox specified");
|
|
15
|
+
|
|
16
|
+
return new Promise((resolve) => {
|
|
17
|
+
const imap = new Imap({
|
|
18
|
+
user: IMAP_USER,
|
|
19
|
+
password: IMAP_PASSWORD,
|
|
20
|
+
host: IMAP_HOST,
|
|
21
|
+
port: IMAP_PORT,
|
|
22
|
+
tls: IMAP_TLS
|
|
23
|
+
});
|
|
24
|
+
|
|
25
|
+
imap.once('ready', () => {
|
|
26
|
+
console.log(`Connected to IMAP. Opening mailbox: ${mailbox}`);
|
|
27
|
+
|
|
28
|
+
imap.openBox(mailbox, false, (err, box) => {
|
|
29
|
+
if (err) {
|
|
30
|
+
imap.end();
|
|
31
|
+
return resolve({ uid: null, mailbox: mailbox, destination: dirto, uidValidityDest: "", status: 401 });
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
// Validate UIDVALIDITY
|
|
35
|
+
if (box.uidvalidity !== uidvalidity) {
|
|
36
|
+
imap.end();
|
|
37
|
+
return resolve({ uid: null, mailbox: mailbox, destination: dirto, uidvalidity: "", status: 401 });
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
console.log(`Mailbox UIDVALIDITY verified (${uidvalidity}). Searching for UID ${uid}...`);
|
|
41
|
+
|
|
42
|
+
imap.search([['UID', uid]], (searchErr, results) => {
|
|
43
|
+
if (searchErr || results.length === 0) {
|
|
44
|
+
imap.end();
|
|
45
|
+
return resolve({ uid: null, mailbox: mailbox, destination: dirto, uidvalidity: "", status: 404 });
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
console.log(`Found UID ${uid}, moving to ${dirto}...`);
|
|
49
|
+
imap.move(uid.toString(), dirto, (moveErr) => {
|
|
50
|
+
if (moveErr) {
|
|
51
|
+
imap.end();
|
|
52
|
+
return resolve({ uid: uid, mailbox: mailbox, destination: dirto, uidvalidity: "", status: 401 });
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
// Open the destination mailbox to retrieve the new UID and UIDVALIDITY
|
|
56
|
+
imap.openBox(dirto, false, (destErr, destBox) => {
|
|
57
|
+
if (destErr) {
|
|
58
|
+
imap.end();
|
|
59
|
+
return resolve({ uid: null, mailbox: mailbox, destination: dirto, uidvalidity: "", status: 401 });
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
const uidValidityDest = destBox.uidvalidity;
|
|
63
|
+
|
|
64
|
+
// Search for the latest message in the destination mailbox
|
|
65
|
+
imap.search(['ALL'], (searchDestErr, destResults) => {
|
|
66
|
+
imap.end();
|
|
67
|
+
if (searchDestErr || destResults.length === 0) {
|
|
68
|
+
return resolve({ uid: null, mailbox: mailbox, destination: dirto, uidvalidity: "", status: 404 });
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
const newUid = Math.max(...destResults); // Get the highest UID (latest message)
|
|
72
|
+
resolve({ uid: newUid, mailbox: mailbox, destination: dirto, uidvalidity: uidValidityDest, status: 200 });
|
|
73
|
+
});
|
|
74
|
+
});
|
|
75
|
+
});
|
|
76
|
+
});
|
|
77
|
+
});
|
|
78
|
+
});
|
|
79
|
+
|
|
80
|
+
imap.once('error', () => resolve({ uid: null, mailbox: mailbox, destination: dirto, uidvalidityDest: "", status: 401 }));
|
|
81
|
+
|
|
82
|
+
imap.once('end', () => console.log('IMAP connection closed.'));
|
|
83
|
+
|
|
84
|
+
imap.connect();
|
|
85
|
+
});
|
|
86
|
+
};
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
<?php
|
|
2
|
+
|
|
3
|
+
namespace modules;
|
|
4
|
+
|
|
5
|
+
use \lib\core\Module;
|
|
6
|
+
|
|
7
|
+
class custom extends Module
|
|
8
|
+
{
|
|
9
|
+
public function imapmovefolder($options, $name) {
|
|
10
|
+
|
|
11
|
+
$myObj->response = "This function is not yet available in PHP";
|
|
12
|
+
|
|
13
|
+
return json_encode($myObj);
|
|
14
|
+
}
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
?>
|
|
@@ -0,0 +1,151 @@
|
|
|
1
|
+
[{
|
|
2
|
+
type: 'imapremoveflag-imapremoveflag',
|
|
3
|
+
module : 'imapremoveflag',
|
|
4
|
+
action : 'imapremoveflag',
|
|
5
|
+
groupTitle : 'Mailer',
|
|
6
|
+
groupIcon : 'fas fa-envelope comp-general',
|
|
7
|
+
title : 'IMAP Remove flag by UID',
|
|
8
|
+
icon : 'fas fa-solid fa-minus comp-exec',
|
|
9
|
+
dataPickObject: true,
|
|
10
|
+
usedModules : {
|
|
11
|
+
node: {
|
|
12
|
+
'imap' : '^8.8.19',
|
|
13
|
+
'mailparser' : '^3.7.2'
|
|
14
|
+
}
|
|
15
|
+
},
|
|
16
|
+
|
|
17
|
+
properties : [
|
|
18
|
+
{
|
|
19
|
+
group: 'IMAP Inputs',
|
|
20
|
+
variables: [
|
|
21
|
+
|
|
22
|
+
{ name: 'actionName',
|
|
23
|
+
optionName: 'name',
|
|
24
|
+
title: 'Name',
|
|
25
|
+
type: 'text',
|
|
26
|
+
required: true,
|
|
27
|
+
baseName: "imap"
|
|
28
|
+
},
|
|
29
|
+
{ name: 'selector', optionName: 'selector', title: 'IAMP Settings Selection',
|
|
30
|
+
type: 'droplist',
|
|
31
|
+
values: [
|
|
32
|
+
{title: 'Use ENV ', value: 'ENV' ,show:[],hide:['imap_msg','imap_host','imap_user','imap_password','imap_port','imap_tls']},
|
|
33
|
+
{title: 'Enable Manual Overrides', value: 'MANUAL',hide:[],show:['imap_msg','imap_host','imap_user','imap_password','imap_port','imap_tls'] },
|
|
34
|
+
|
|
35
|
+
|
|
36
|
+
],
|
|
37
|
+
defaultValue: 'ENV',
|
|
38
|
+
help: 'Choose your TLS settings.',
|
|
39
|
+
initValue: "ENV"
|
|
40
|
+
},
|
|
41
|
+
|
|
42
|
+
{name: 'imap_msg',
|
|
43
|
+
optionName: 'imap_msg',
|
|
44
|
+
title: 'IMAP password',
|
|
45
|
+
type: 'static',
|
|
46
|
+
help: 'IMAP .ENV OVERRIDE SETTINGS'
|
|
47
|
+
},
|
|
48
|
+
|
|
49
|
+
{name: 'imap_host',
|
|
50
|
+
optionName: 'imap_host',
|
|
51
|
+
title: 'IMAP Host',
|
|
52
|
+
type: 'text',
|
|
53
|
+
defaultValue: "", initDisplay: 'none',
|
|
54
|
+
serverDataBindings: true,
|
|
55
|
+
help: 'The IMAP Host Server'
|
|
56
|
+
},
|
|
57
|
+
{name: 'imap_user',
|
|
58
|
+
optionName: 'imap_user',
|
|
59
|
+
title: 'IMAP User',
|
|
60
|
+
type: 'text',
|
|
61
|
+
defaultValue: "", initDisplay: 'none',
|
|
62
|
+
serverDataBindings: true,
|
|
63
|
+
help: 'The IMAP user'
|
|
64
|
+
},
|
|
65
|
+
|
|
66
|
+
{name: 'imap_password',
|
|
67
|
+
optionName: 'imap_password',
|
|
68
|
+
title: 'IMAP password',
|
|
69
|
+
type: 'text',
|
|
70
|
+
defaultValue: "", initDisplay: 'none',
|
|
71
|
+
serverDataBindings: true,
|
|
72
|
+
help: 'The IMAP password'
|
|
73
|
+
},
|
|
74
|
+
{name: 'imap_port',
|
|
75
|
+
optionName: 'imap_port',
|
|
76
|
+
title: 'IMAP Port',
|
|
77
|
+
type: 'text',
|
|
78
|
+
defaultValue: "", initDisplay: 'none',
|
|
79
|
+
serverDataBindings: true,
|
|
80
|
+
help: 'The IMAP port'
|
|
81
|
+
},
|
|
82
|
+
{ name: 'imap_tls', optionName: 'imap_tls', title: 'TLS Settings',
|
|
83
|
+
type: 'droplist',
|
|
84
|
+
values: [
|
|
85
|
+
{title: 'Use ENV if available', value: 'ENV' },
|
|
86
|
+
{title: 'True', value: 'True' },
|
|
87
|
+
{title: 'False', value: 'False' },
|
|
88
|
+
|
|
89
|
+
],
|
|
90
|
+
defaultValue: 'ENV', initDisplay: 'none',
|
|
91
|
+
help: 'Choose your TLS settings.',
|
|
92
|
+
initValue: "ENV"
|
|
93
|
+
},
|
|
94
|
+
|
|
95
|
+
{name: 'imap_msg2',
|
|
96
|
+
optionName: 'imap_msg2',
|
|
97
|
+
title: '',
|
|
98
|
+
type: 'static',
|
|
99
|
+
help: 'API ACTION SETTINGS'
|
|
100
|
+
},
|
|
101
|
+
{ name: 'uid',
|
|
102
|
+
optionName: 'uid',
|
|
103
|
+
title: 'uid',
|
|
104
|
+
type: 'text',
|
|
105
|
+
required: true,
|
|
106
|
+
defaultValue: "0",
|
|
107
|
+
serverDataBindings: true,
|
|
108
|
+
help: 'The uid of the email'
|
|
109
|
+
},
|
|
110
|
+
{ name: 'uidvalidity',
|
|
111
|
+
optionName: 'uidvalidity',
|
|
112
|
+
title: 'uidValidity',
|
|
113
|
+
type: 'text',
|
|
114
|
+
required: true,
|
|
115
|
+
defaultValue: "0",
|
|
116
|
+
serverDataBindings: true,
|
|
117
|
+
help: 'The uidValidity key of the email'
|
|
118
|
+
},
|
|
119
|
+
{ name: 'mailbox',
|
|
120
|
+
optionName: 'mailbox',
|
|
121
|
+
title: 'mailbox',
|
|
122
|
+
type: 'text',
|
|
123
|
+
required: true,
|
|
124
|
+
defaultValue: "INBOX",
|
|
125
|
+
serverDataBindings: true,
|
|
126
|
+
help: 'The mailbox containing the email'
|
|
127
|
+
},
|
|
128
|
+
{ name: 'flag',
|
|
129
|
+
optionName: 'flag',
|
|
130
|
+
title: 'Flag to remove',
|
|
131
|
+
type: 'text',
|
|
132
|
+
required: true,
|
|
133
|
+
defaultValue: "//Seen",
|
|
134
|
+
serverDataBindings: true,
|
|
135
|
+
help: 'The flag to remove'
|
|
136
|
+
},
|
|
137
|
+
|
|
138
|
+
|
|
139
|
+
{ name: 'output',
|
|
140
|
+
optionName: 'output',
|
|
141
|
+
title: 'Output',
|
|
142
|
+
type: 'boolean',
|
|
143
|
+
defaultValue: false
|
|
144
|
+
}
|
|
145
|
+
|
|
146
|
+
]
|
|
147
|
+
},
|
|
148
|
+
|
|
149
|
+
]
|
|
150
|
+
}
|
|
151
|
+
]
|