forked from Tropicalista/lucee-cfimap
-
Notifications
You must be signed in to change notification settings - Fork 0
/
imap.cfc
256 lines (222 loc) · 11.6 KB
/
imap.cfc
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
/**
*
* @author Francesco Pepe
* @description
*
*/
component output="false" displayname="cfimap" {
this.metadata.hint="(partial) implementation of cfimap";
this.metadata.attributetype="fixed";
this.metadata.attributes={
Action : { required:true, type:"string", hint="[DELETE|DELETEFOLDER|CREATEFOLDER|OPEN|CLOSE|RENAMEFOLDER|LISTALLFOLDERS|MARKREAD|MOVEMAIL|GETALL|GETHEADERONLY]"},
Attachmentpath : { required:false, type:"string", hint="pathname (Todo: byte array)"},
Connection: { required:false, type:"string", hint="Specifies the variable name for the connection/session."},
Folder: { required:false, type:"string", hint="Specifies the folder name where messages are retrieved, moved, or deleted"},
GenerateUniqueFilenames: { required:false, type:"boolean", hint="Ensures that unique file names are generated for each attachment file. Default = NO"},
MaxRows: { required:false, type:"boolean", hint="Specifies the number of rows to be marked as read, deleted, or moved across folders."},
MessageNumber: { required:false, type:"string", default:"", hint="Specifies the message number or a comma delimited list of message numbers for retrieval, deletion, marking mail as read, or moving mails."},
Name: { required:false, type:"string", hint="Specifies the name for the query object that contains the retrieved message information."},
NewFolder: { required:false, type:"string", hint="Specifies the name of the new folder when you rename a folder or the name of the destination folder where all mails move."},
Password: { required:false, type:"string", hint="Specifies the password for assessing the users’ e-mail account."},
Port: { required:false, type:"string", hint="Specifies the IMAP port number. Use 143 for non-secure connections and 993 for secured connections."},
Recurse: { required:false, type:"boolean", hint="Specifies whether ColdFusion runs the CFIMAP command in subfolders. Recurse works for action=”ListAllFolders”. When recurse is set to ”true”, ColdFusion parses through all folders and subfolders and returns folder/subfolder names and mail information."},
Secure: { required:false, type:"boolean", hint="Specifies whether the IMAP server uses a Secure Sockets Layer."},
Server: { required:false, type:"string", hint="Specifies the IMAP server identifier. You can assign a host name or an IP address as the IMAP server identifier."},
StartRow: { required:false, type:"string", hint="Defines the first row number for reading or deleting. If you have specified the UID or MessageNumber attribute, then StartRow is ignored. You can also specify StartRow for moving mails."},
StopOnError: { required:false, type:"string", hint="Specifies whether to ignore the exceptions for this operation. When the value is true, it stops processing, displays an appropriate error."},
Timeout: { required:false, type:"string", hint="Specifies the number of seconds to wait before timing out connection to IMAP server. An error message is displayed when timeout occurs."},
Uid: { required:false, type:"string", default: "", hint="Specifies the unique ID or a comma-delimited list of Uids to retrieve, delete, and move mails. If you set invalid Uids, then they are ignored."},
Username: { required:false, type:"string", hint="Specifies the user name. Typically, the user name is same the e-mail login."}
};
this.metadata.requiredAttributesPerAction = {
GetAll: ['name','connection'],
GetHeaderOnly: ['name'],
ListAllFolders: ['name'],
CreateFolder: ['folder'],
RenameFolder: ['folder','newFolder'],
DeleteFolder: ['folder'],
Close: ['connection'],
Open: ['connection','server','username','password'],
MoveMail: ['newFolder'],
Delete: ['connection','UID']
}
/**
*
* @hint invoked after tag is constructed
* @parent the parent cfc custom tag, if there is one
*
*/
public function init( required boolean hasEndTag = false, component parent ){
variables.hasEndTag = arguments.hasEndTag;
variables.parent = arguments.parent;
variables.imap = new imap.imap();
return this;
}
public boolean function onStartTag( required struct attributes, required struct caller ){
// check for action
if ( !StructKeyExists( arguments.attributes, 'action' ) ) {
throw( message="missing parameter", detail="'action' not passed in" );
}
if( structKeyExists( this.metadata.requiredAttributesPerAction, arguments.attributes.action ) ){
var attrName = "";
loop array="#this.metadata.requiredAttributesPerAction[arguments.attributes.action]#" index="attrName" {
if( not structKeyExists( arguments.attributes, attrName ) ){
throw (message="Attribute validation error for tag CFIMAP: when action is '#arguments.attributes.action#', the atribute [#attrName#] is required!");
}
}
}else{
throw( type="application", message="CFIMAP does not have an action '#htmleditformat(action)#'!", detail="Only actions '#structKeyList(this.metadata.requiredAttributesPerAction)#' are available." );
}
// check for source
switch(arguments.attributes.action) {
case "open":
//check passing attributes passed in
if (
!StructKeyExists( arguments.attributes, 'server' ) ||
!StructKeyExists( arguments.attributes, 'connection' ) ||
!StructKeyExists( arguments.attributes, 'username' ) ||
!StructKeyExists( arguments.attributes, 'password' )
)
{
throw( type="application", message="Attribute validation error", detail="It has an invalid attribute combination." );
}
// check optional arguments
if (! StructKeyExists(arguments.attributes, 'timeout')) {
arguments.attributes.timeout = 60;
}
if (! StructKeyExists(arguments.attributes, 'port')) {
arguments.attributes.port = 143;
}
if (! StructKeyExists(arguments.attributes, 'secure')) {
arguments.attributes.secure = false;
}
arguments.caller[arguments.attributes.connection] = variables.imap.connect(
arguments.attributes.connection,
arguments.attributes.username,
arguments.attributes.password,
arguments.attributes.server,
arguments.attributes.secure,
arguments.attributes.timeout,
arguments.attributes.port
);
break;
case "createFolder":
//check passing attributes passed in
if ( !StructKeyExists(arguments.attributes, 'connection') ){
throw( type="application", message="Attribute validation error", detail="Attribute connection is required." );
}
if ( !StructKeyExists(arguments.attributes, 'folder') ){
throw( type="application", message="Attribute validation error", detail="It has an invalid attribute combination." );
}
variables.imap.createFolder(
arguments.caller[arguments.attributes.connection],
arguments.attributes.folder
);
break;
case "deleteFolder":
//check passing attributes passed in
if ( !StructKeyExists(arguments.attributes, 'folder') ){
throw( type="application", message="Attribute validation error", detail="It has an invalid attribute combination." );
}
variables.imap.deleteFolder(
arguments.caller[arguments.attributes.connection],
arguments.attributes.folder
);
break;
case "renameFolder":
//check passing attributes passed in
if ( !StructKeyExists(arguments.attributes, 'folder') ){
throw( type="application", message="Attribute validation error", detail="Attribute folder is required." );
}
if ( !StructKeyExists(arguments.attributes, 'newFolder') ){
throw( type="application", message="Attribute validation error", detail="Attribute newFolder is required." );
}
variables.imap.renameFolder(
arguments.caller[arguments.attributes.connection],
arguments.attributes.folder,
arguments.attributes.newFolder
);
break;
case "ListAllFolders":
//check passing attributes passed in
if ( !StructKeyExists(arguments.attributes, 'name') || !StructKeyExists(arguments.attributes, 'connection') ) {
throw( type="application", message="Attribute validation error", detail="It has an invalid attribute combination." );
}
if( !StructKeyExists(arguments.attributes, 'folder') ){
arguments.attributes['folder'] = "";
}
arguments.caller[arguments.attributes.name] = variables.imap.ListAllFolders(
arguments.caller[arguments.attributes.connection],
arguments.attributes.folder
);
break;
case "delete":
//check passing attributes passed in
if ( !StructKeyExists(arguments.attributes, 'connection') ) {
throw( type="application", message="Attribute validation error", detail="It has an invalid attribute combination." );
}
variables.imap.delete( arguments.caller[arguments.attributes.connection], arguments.attributes.folder, arguments.attributes.MessageNumber, arguments.attributes.uid );
break;
case "markread":
//check passing attributes passed in
if ( !StructKeyExists(arguments.attributes, 'connection') ) {
throw( type="application", message="Attribute validation error", detail="It has an invalid attribute combination." );
}
variables.imap.markread( arguments.caller[arguments.attributes.connection], arguments.attributes.folder );
break;
case "movemail":
//check passing attributes passed in
if ( !StructKeyExists(arguments.attributes, 'connection') ||
!StructKeyExists(arguments.attributes, 'newFolder') ||
!StructKeyExists(arguments.attributes, 'messageNumber')
){
throw( type="application", message="Attribute validation error", detail="It has an invalid attribute combination." );
}
variables.imap.movemail( arguments.caller[arguments.attributes.connection], arguments.attributes.newFolder, arguments.attributes.messageNumber, arguments.attributes.uid, arguments.attributes.folder );
break;
case "getheaderonly":
//check passing attributes passed in
if ( !StructKeyExists(arguments.attributes, 'connection') ||
!StructKeyExists(arguments.attributes, 'name')
){
throw( type="application", message="Attribute validation error for tag CFIMAP", detail="It has an invalid attribute combination." );
}
arguments.caller[arguments.attributes.name] = variables.imap.getHeaderOnly(
arguments.caller[arguments.attributes.connection],
arguments.attributes.folder ?: "",
arguments.attributes.startRow ?: 1,
arguments.attributes.maxRows ?: "",
arguments.attributes.uid ?: "",
arguments.attributes.messageNumber ?: ""
);
break;
case "getall":
//check passing attributes passed in
if ( !StructKeyExists(arguments.attributes, 'connection') ||
!StructKeyExists(arguments.attributes, 'name')
){
throw( type="application", message="Attribute validation error for tag CFIMAP", detail="It has an invalid attribute combination." );
}
arguments.caller[arguments.attributes.name] = variables.imap.getAll(
arguments.caller[arguments.attributes.connection],
arguments.attributes.folder ?: "",
arguments.attributes.startRow ?: "",
arguments.attributes.maxRow ?: "",
arguments.attributes.uid ?: "",
arguments.attributes.messageNumber ?: "",
arguments.attributes.attachmentPath ?: ""
);
break;
case "close":
//check passing attributes passed in
if ( !StructKeyExists(arguments.attributes, 'connection') ) {
throw( type="application", message="Attribute validation error", detail="It has an invalid attribute combination." );
}
variables.imap.close( arguments.caller[arguments.attributes.connection] );
break;
default:
throw(type="application", message="unsupported action", detail="valid action=[DELETE|DELETEFOLDER|CREATEFOLDER|OPEN|CLOSE|RENAMEFOLDER|LISTALLFOLDERS|MARKREAD|MOVEMAIL|GETALL|GETHEADERONLY]");
}
return true;
}
}