@brickert/kerio-connect-api 0.0.6 → 0.0.8

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/index.d.ts CHANGED
@@ -83,6 +83,7 @@ export interface GenericResponse {
83
83
  result?: Array;
84
84
  token?: string;
85
85
  detail?: string;
86
+ deleteItems?: number;
86
87
  }
87
88
  };
88
89
  }
@@ -108,6 +109,8 @@ export class Kerio extends WebClient {
108
109
  Session: Session;
109
110
  Logs: Logs;
110
111
  Domains: Domains;
112
+ Users: Users;
113
+ MessageQueues: MessageQueues;
111
114
 
112
115
  login(user: KerioUser): void;
113
116
 
@@ -348,4 +351,155 @@ export interface DKIMRecord {
348
351
  * @example 'abcdefg1234567'
349
352
  */
350
353
  raw_public_key: string;
351
- }
354
+ }
355
+
356
+ export class Users extends KerioModules {
357
+ /**
358
+ * Get a Mapped Array of KerioUserItems indexed by their ID for the specified domain name
359
+ * @param {string} domainName Name of the domain
360
+ * @returns {Promise<Map<import('../index.d.ts').KerioUserID, import('../index.d.ts').KerioUserItem>>}
361
+ */
362
+ list(domainName: string): Promise<Map<KerioUserID, KerioUserItem>>;
363
+
364
+ /**
365
+ * Get statistics of the Kerio User. Such as mailbox size and last login timestamp in server's local time zone
366
+ * @param kerioUserID Kerio user UUID
367
+ */
368
+ getStatistics(kerioUserID: KerioUserID): Promise<KerioUserStatistic>;
369
+ }
370
+
371
+ /**
372
+ * @example "keriodb://user/1234-5678-901-2345/1234-5678-901"
373
+ */
374
+ export type KerioUserID = string;
375
+
376
+ export interface KerioUserItem {
377
+ id: string;
378
+ domainId: string;
379
+ loginName: string;
380
+ fullName: string;
381
+ description: string;
382
+ enabled: boolean;
383
+ primaryEmailAddress: string; //loginName + domainName;
384
+ }
385
+
386
+ export interface KerioUserStatistic {
387
+ storage: {
388
+ items: number;
389
+ value: number;
390
+ units: "Bytes" | string;
391
+ },
392
+ lastLogin: string; //YYYY-MM-DD HH:MM in local server time
393
+ loginCount: {
394
+ pop3: number;
395
+ pop3s: number;
396
+ imap: number;
397
+ imaps: number;
398
+ http: number;
399
+ https: number;
400
+ ldap: number;
401
+ ldaps: number;
402
+ nntp: number;
403
+ nntps: number;
404
+ activeSync: number;
405
+ secureActiveSync: number;
406
+ xmpp: number;
407
+ xmpps: number;
408
+ }
409
+ }
410
+
411
+ export class MessageQueues extends KerioModules {
412
+ /**
413
+ * Get a Mapped Array of KerioMessageItems indexed by their ID for messages that are pending to be processed
414
+ * @returns {Promise<Map<import('../index.d.ts').KerioMessageID, import('../index.d.ts').KerioMessageItem>>}
415
+ */
416
+ pending(): Promise<Map<KerioMessageID, KerioMessageItem>>;
417
+
418
+ /**
419
+ * Remove select message(s) that are held in queue/processing queue.
420
+ * @param messageId Single or Array of KerioMessageID(s)
421
+ * @returns {Promise<number>} Number of successfully removed messages
422
+ */
423
+ removeFromQueue(messageId: KerioMessageID | Array<KerioMessageID>): Promise<number>;
424
+
425
+ /**
426
+ * Remove all message(s) in the queue pending to be processed
427
+ * @returns {Promise<number>} Number of successfully removed messages
428
+ */
429
+ flushQueue(): Promise<number>;
430
+
431
+ /**
432
+ * Manually trigger sending these message(s) before their scheduled re-attempt
433
+ * @param messageId Single or Array of KerioMessageID(s)
434
+ * @returns {Promise<void>} Returns void. Access Kerio.MessageQueues.pending() to see any changes, messages not listed there are successfully being placed into the processed queue.
435
+ */
436
+ trySendingNow(messageId: KerioMessageID | Array<KerioMessageID>): Promise<void>;
437
+
438
+ /**
439
+ * Get a Mapped Array of KerioMessageItems indexed by their ID for a snapshot of the server's activity on processing messages
440
+ * @returns {Promise<Map<import('../index.d.ts').KerioMessageID, import('../index.d.ts').KerioMessageProcessedItem>>}
441
+ */
442
+ processing(): Promise<Map<KerioMessageID, KerioMessageProcessedItem>>;
443
+
444
+ /**
445
+ * Manually process message(s) now from their current stage.
446
+ * @returns {Promise<void>} Returns void. Access Kerio.MessageQueues.procesing() to see any changes, messages not listed there are successfully delivered to the destination server.
447
+ */
448
+ tryProcessingNow(): Promise<void>;
449
+ }
450
+
451
+ /**
452
+ * @example "1a2b3c4d-00000"
453
+ */
454
+ export type KerioMessageID = string;
455
+
456
+ export interface KerioMessageItem {
457
+ id: KerioMessageID;
458
+ status: string;
459
+ time: {
460
+ creationTime: string; //YYYY-MM-DD HH:MM of server's timezone
461
+ nextTry: string; //YYYY-MM-DD HH:MM of server's timezone
462
+ };
463
+ messageSize: {
464
+ value: number;
465
+ units: "Bytes"
466
+ };
467
+ headers: {
468
+ from: string;
469
+ to: string;
470
+ };
471
+ authSender: {
472
+ address: string; //Authorized SMTP user email address
473
+ ip: string; //Authorized SMTP user ip address
474
+ }
475
+ }
476
+
477
+ export interface KerioMessageProcessedItem {
478
+ id: KerioMessageID;
479
+ status: {
480
+ progress: number; //Current progress in the current status stage
481
+ stage: KerioMessageProcessStatusEnum;
482
+ timeInCurrentStatus: string; //in HH:MM:SS format
483
+ };
484
+ messageSize: {
485
+ value: number;
486
+ units: "Bytes"
487
+ };
488
+ headers: {
489
+ from: string;
490
+ to: string;
491
+ destination: string; //Target SMTP server FQDN
492
+ };
493
+
494
+ }
495
+
496
+ /**
497
+ * msExecuting: General execution/starting state.
498
+ * msBackup: Message is being backed up.
499
+ * msContentFiltering: Passing through content/spam filters.
500
+ * msAntivirusControl: Being scanned for viruses.
501
+ * msLocalDelivering: Delivering to a mailbox on the local server.
502
+ * msSmtpDelivering: Attempting delivery to the next hop SMTP server.
503
+ * msFinishing: Finalizing the delivery/cleanup process.
504
+ */
505
+ export type KerioMessageProcessStatusEnum = "msExecuting" | "msBackup" | "msContentFiltering" | "msAntivirusControl" | "msLocalDelivering" | "msSmtpDelivering" | "msFinishing";
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@brickert/kerio-connect-api",
3
- "version": "0.0.6",
3
+ "version": "0.0.8",
4
4
  "description": "An unofficial API wrapper for Kerio Connect Mail Server jsonrpc Admin API.",
5
5
  "keywords": [
6
6
  "kerio",
package/src/kerio.js CHANGED
@@ -2,6 +2,8 @@ import { IPAddressGroup } from "./ipaddressgroups.js";
2
2
  import { Logs } from "./logs.js";
3
3
  import { Session } from "./session.js";
4
4
  import { Domains } from "./domains.js";
5
+ import { Users } from "./users.js";
6
+ import { MessageQueues } from "./msgqueues.js";
5
7
  import { WebClient } from "./client.js";
6
8
  import { CronJob } from 'cron';
7
9
  import pino from 'pino';
@@ -25,6 +27,8 @@ export class Kerio extends WebClient {
25
27
  this.Logs = new Logs(this);
26
28
  this.Session = new Session(this);
27
29
  this.Domains = new Domains(this);
30
+ this.Users = new Users(this);
31
+ this.MessageQueues = new MessageQueues(this);
28
32
 
29
33
  this.logger = pino({
30
34
  level: "debug",
@@ -0,0 +1,469 @@
1
+ import { KerioModules } from './modules.js';
2
+
3
+ export class MessageQueues extends KerioModules {
4
+
5
+ /**
6
+ * Get a Mapped Array of KerioMessageItems indexed by their ID for messages that are pending to be processed
7
+ * @returns {Promise<Map<import('../index.d.ts').KerioMessageID, import('../index.d.ts').KerioMessageItem>>}
8
+ */
9
+ async pending() {
10
+ try {
11
+ if (!this.instance.logged_in) {
12
+
13
+ this.reset();
14
+
15
+ throw {
16
+ name: "KerioClientSessionError",
17
+ message: `Kerio session invalid. Try logging in again.`,
18
+ type: 'Kerio',
19
+ from: "Kerio.MessageQueues.queued"
20
+ }
21
+ }
22
+
23
+ let queue_response = await this.sessionedRequest({
24
+ http_method: 'POST',
25
+ api_method: 'Queue.get',
26
+ auth: {
27
+ cookie: this.instance.session_cookie,
28
+ token: this.instance.x_token
29
+ },
30
+ body_params: {
31
+ query: {
32
+ }
33
+ }
34
+ });
35
+
36
+ let response_body = queue_response._body;
37
+
38
+ if (!response_body.result?.errors && !response_body?.error) {
39
+
40
+ var queueMsgsResult = new Map();
41
+
42
+ if (response_body.result.list.length > 0) {
43
+ response_body.result.list.forEach(msg => {
44
+
45
+ queueMsgsResult.set(msg.id, {
46
+ id: msg.id,
47
+ status: msg.status,
48
+ time: {
49
+ created: msg.creationTime,
50
+ nextTry: msg.nextTry
51
+ },
52
+ messageSize: {
53
+ value: msg.messageSize.value,
54
+ units: msg.messageSize.units
55
+ },
56
+ headers: {
57
+ from: msg.from,
58
+ to: msg.to
59
+ },
60
+ authSender: {
61
+ address: msg.authSender,
62
+ ip: msg.senderIp
63
+ }
64
+ });
65
+ });
66
+ }
67
+
68
+ this.instance.logger.debug({
69
+ name: "KerioQueuedMessagesPending",
70
+ message: `listed ${queueMsgsResult.size} queued messages pending to be processed`,
71
+ type: "Kerio",
72
+ from: "Kerio.MessageQueues.queued"
73
+ });
74
+
75
+ return queueMsgsResult;
76
+
77
+ } else {
78
+ throw {
79
+ name: "KerioRequestError",
80
+ message: `Error occured while fetching results from API method 'Queue.get'`,
81
+ type: 'Kerio',
82
+ from: "Kerio.MessageQueues.list"
83
+ }
84
+ }
85
+
86
+ } catch (e) {
87
+ this.instance.logger.error(e);
88
+ throw e;
89
+ }
90
+ }
91
+
92
+ /**
93
+ * Remove select message(s) that are held in the list of queue/processing queue.
94
+ * @param messageId Single or Array of KerioMessageID(s)
95
+ * @returns {Promise<number>} Number of successfully removed messages
96
+ */
97
+ async removeFromQueue(messageId = null) {
98
+ try {
99
+ if (!this.instance.logged_in) {
100
+
101
+ this.reset();
102
+
103
+ throw {
104
+ name: "KerioClientSessionError",
105
+ message: `Kerio session invalid. Try logging in again.`,
106
+ type: 'Kerio',
107
+ from: "Kerio.MessageQueues.removeFromQueue"
108
+ }
109
+ }
110
+
111
+ if (!messageId || (Array.isArray(messageId) && messageId.length == 0)) {
112
+ throw {
113
+ name: "KerioMessageIdError",
114
+ message: `Invalid message ID or array of message IDs while processing API method 'Queue.remove'`,
115
+ type: 'Kerio',
116
+ from: "Kerio.MessageQueues.removeFromQueue"
117
+ }
118
+ }
119
+
120
+ //If single message ID string, convert to array of one element
121
+ if (!Array.isArray(messageId)) {
122
+ messageId = [messageId];
123
+ }
124
+
125
+ let queue_remove_response = await this.sessionedRequest({
126
+ http_method: 'POST',
127
+ api_method: 'Queue.remove',
128
+ auth: {
129
+ cookie: this.instance.session_cookie,
130
+ token: this.instance.x_token
131
+ },
132
+ body_params: {
133
+ query: {
134
+ },
135
+ messageIds: messageId
136
+ }
137
+ });
138
+
139
+ let response_body = queue_remove_response._body;
140
+
141
+ if (!response_body.result?.errors && !response_body?.error) {
142
+
143
+ this.instance.logger.debug({
144
+ name: "KerioQueuedMessagesRemoved",
145
+ message: `Removed ${response_body.result.deleteItems} queued messages that were pending to be processed`,
146
+ type: "Kerio",
147
+ from: "Kerio.MessageQueues.removeFromQueue"
148
+ });
149
+
150
+ return response_body.result.deleteItems;
151
+
152
+ } else {
153
+ throw {
154
+ name: "KerioRequestError",
155
+ message: `Error occured while fetching results from API method 'Queue.remove'`,
156
+ type: 'Kerio',
157
+ from: "Kerio.MessageQueues.removeFromQueue"
158
+ }
159
+ }
160
+
161
+ } catch (e) {
162
+ this.instance.logger.error(e);
163
+ throw e;
164
+ }
165
+ }
166
+
167
+ /**
168
+ * Remove all message(s) in the queue pending to be processed
169
+ * @returns {Promise<number>} Number of successfully removed messages
170
+ */
171
+ async flushQueue() {
172
+ try {
173
+ if (!this.instance.logged_in) {
174
+
175
+ this.reset();
176
+
177
+ throw {
178
+ name: "KerioClientSessionError",
179
+ message: `Kerio session invalid. Try logging in again.`,
180
+ type: 'Kerio',
181
+ from: "Kerio.MessageQueues.flushQueue"
182
+ }
183
+ }
184
+
185
+ let queue_response = await this.sessionedRequest({
186
+ http_method: 'POST',
187
+ api_method: 'Queue.removeAll',
188
+ auth: {
189
+ cookie: this.instance.session_cookie,
190
+ token: this.instance.x_token
191
+ },
192
+ body_params: {
193
+ query: {
194
+ }
195
+ }
196
+ });
197
+
198
+ let response_body = queue_response._body;
199
+
200
+ if (!response_body.result?.errors && !response_body?.error) {
201
+
202
+ this.instance.logger.debug({
203
+ name: "KerioQueuedMessagesFlush",
204
+ message: `Flushed ${response_body.result.deleteItems} queued messages pending to be processed`,
205
+ type: "Kerio",
206
+ from: "Kerio.MessageQueues.flushQueue"
207
+ });
208
+
209
+ return response_body.result.deleteItems;
210
+
211
+ } else {
212
+ throw {
213
+ name: "KerioRequestError",
214
+ message: `Error occured while fetching results from API method 'Queue.removeAll'`,
215
+ type: 'Kerio',
216
+ from: "Kerio.MessageQueues.flushQueue"
217
+ }
218
+ }
219
+
220
+ } catch (e) {
221
+ this.instance.logger.error(e);
222
+ throw e;
223
+ }
224
+ }
225
+
226
+ /**
227
+ * Manually trigger sending these message(s) before their scheduled re-attempt
228
+ * @param messageId Single or Array of KerioMessageID(s)
229
+ * @returns {Promise<void>} Returns void. Access Kerio.MessageQueues.queued() to see any changes, messages not listed there are successfully being placed into the processed queue.
230
+ */
231
+ async trySendingNow(messageId = null) {
232
+ try {
233
+ if (!this.instance.logged_in) {
234
+
235
+ this.reset();
236
+
237
+ throw {
238
+ name: "KerioClientSessionError",
239
+ message: `Kerio session invalid. Try logging in again.`,
240
+ type: 'Kerio',
241
+ from: "Kerio.MessageQueues.trySendingNow"
242
+ }
243
+ }
244
+
245
+ if (!messageId || (Array.isArray(messageId) && messageId.length == 0)) {
246
+ throw {
247
+ name: "KerioMessageIdError",
248
+ message: `Invalid message ID or array of message IDs while processing API method 'Queue.tryToSend'`,
249
+ type: 'Kerio',
250
+ from: "Kerio.MessageQueues.trySendingNow"
251
+ }
252
+ }
253
+
254
+ //If single message ID string, convert to array of one element
255
+ if (!Array.isArray(messageId)) {
256
+ messageId = [messageId];
257
+ }
258
+
259
+ let try_sending_response = await this.sessionedRequest({
260
+ http_method: 'POST',
261
+ api_method: 'Queue.tryToSend',
262
+ auth: {
263
+ cookie: this.instance.session_cookie,
264
+ token: this.instance.x_token
265
+ },
266
+ body_params: {
267
+ query: {
268
+ },
269
+ messageIds: messageId
270
+ }
271
+ });
272
+
273
+ let response_body = try_sending_response._body;
274
+
275
+ if (!response_body.result?.errors && !response_body?.error) {
276
+
277
+ let debug_msg = "";
278
+
279
+ if (Array.isArray(messageId)) {
280
+ debug_msg = `Processing ${messageId.length} specified queued messages right now. Message IDs of '${messageId.join(', ')}'`;
281
+ } else {
282
+ debug_msg = `Processing queued message right now. Message ID of '${messageId}'`;
283
+ }
284
+
285
+ this.instance.logger.debug({
286
+ name: "KerioQueueTrySendingNowAttempt",
287
+ message: debug_msg,
288
+ type: "Kerio",
289
+ from: "Kerio.MessageQueues.trySendingNow"
290
+ });
291
+
292
+ return;
293
+
294
+ } else {
295
+
296
+ if (response_body?.error?.code) {
297
+ switch (response_body?.error?.code) {
298
+ case 1000:
299
+ // One or more Message Ids don't exist or already processed
300
+ // Safe to silently error and return as you are intended to do Kerio.MessageQueues.pending() to check the status after.
301
+ return;
302
+ default:
303
+ throw {
304
+ name: "KerioRequestError",
305
+ message: `Error occured while fetching results from API method 'Queue.tryToSend'`,
306
+ type: 'Kerio',
307
+ from: "Kerio.MessageQueues.trySendingNow"
308
+ }
309
+ }
310
+ }
311
+
312
+ throw {
313
+ name: "KerioRequestError",
314
+ message: `Error occured while fetching results from API method 'Queue.tryToSend'`,
315
+ type: 'Kerio',
316
+ from: "Kerio.MessageQueues.trySendingNow"
317
+ }
318
+ }
319
+
320
+ } catch (e) {
321
+ this.instance.logger.error(e);
322
+ throw e;
323
+ }
324
+ }
325
+
326
+ /**
327
+ * Get a Mapped Array of KerioMessageItems indexed by their ID for a snapshot of the server's activity on processing messages
328
+ * @returns {Promise<Map<import('../index.d.ts').KerioMessageID, import('../index.d.ts').KerioMessageProcessedItem>>}
329
+ */
330
+ async processing() {
331
+ try {
332
+ if (!this.instance.logged_in) {
333
+
334
+ this.reset();
335
+
336
+ throw {
337
+ name: "KerioClientSessionError",
338
+ message: `Kerio session invalid. Try logging in again.`,
339
+ type: 'Kerio',
340
+ from: "Kerio.MessageQueues.processing"
341
+ }
342
+ }
343
+
344
+ let process_response = await this.sessionedRequest({
345
+ http_method: 'POST',
346
+ api_method: 'Queue.getProcessed',
347
+ auth: {
348
+ cookie: this.instance.session_cookie,
349
+ token: this.instance.x_token
350
+ },
351
+ body_params: {
352
+ query: {
353
+ }
354
+ }
355
+ });
356
+
357
+ let response_body = process_response._body;
358
+
359
+ if (!response_body.result?.errors && !response_body?.error) {
360
+
361
+ var processMsgsResult = new Map();
362
+
363
+ if (response_body.result.list.length > 0) {
364
+ response_body.result.list.forEach(msg => {
365
+
366
+ processMsgsResult.set(msg.id, {
367
+ id: msg.id,
368
+ status: {
369
+ progress: msg.percentage,
370
+ stage: msg.status,
371
+ timeInCurrentStatus: msg.time
372
+ },
373
+ messageSize: {
374
+ value: msg.messageSize.value,
375
+ units: msg.messageSize.units
376
+ },
377
+ headers: {
378
+ from: msg.from,
379
+ to: msg.to,
380
+ destination: msg.server
381
+ }
382
+ });
383
+ });
384
+ }
385
+
386
+ this.instance.logger.debug({
387
+ name: "KerioQueuedMessages",
388
+ message: `listed ${processMsgsResult.size} processing messages`,
389
+ type: "Kerio",
390
+ from: "Kerio.MessageQueues.processing"
391
+ });
392
+
393
+ return processMsgsResult;
394
+
395
+ } else {
396
+ throw {
397
+ name: "KerioRequestError",
398
+ message: `Error occured while fetching results from API method 'Queue.get'`,
399
+ type: 'Kerio',
400
+ from: "Kerio.MessageQueues.list"
401
+ }
402
+ }
403
+
404
+ } catch (e) {
405
+ this.instance.logger.error(e);
406
+ throw e;
407
+ }
408
+ }
409
+
410
+ /**
411
+ * Manually process message(s) now from their current stage.
412
+ * @returns {Promise<void>} Returns void. Access Kerio.MessageQueues.procesing() to see any changes, messages not listed there are successfully delivered to the destination server.
413
+ */
414
+ async tryProcessingNow() {
415
+ try {
416
+ if (!this.instance.logged_in) {
417
+
418
+ this.reset();
419
+
420
+ throw {
421
+ name: "KerioClientSessionError",
422
+ message: `Kerio session invalid. Try logging in again.`,
423
+ type: 'Kerio',
424
+ from: "Kerio.MessageQueues.tryProcessingNow"
425
+ }
426
+ }
427
+
428
+ let try_process_response = await this.sessionedRequest({
429
+ http_method: 'POST',
430
+ api_method: 'Queue.run',
431
+ auth: {
432
+ cookie: this.instance.session_cookie,
433
+ token: this.instance.x_token
434
+ },
435
+ body_params: {
436
+ query: {
437
+ }
438
+ }
439
+ });
440
+
441
+ let response_body = try_process_response._body;
442
+
443
+ if (!response_body.result?.errors && !response_body?.error) {
444
+
445
+ this.instance.logger.debug({
446
+ name: "KerioQueueProcessingNow",
447
+ message: `Force processing messages`,
448
+ type: "Kerio",
449
+ from: "Kerio.MessageQueues.tryProcessingNow"
450
+ });
451
+
452
+ return;
453
+
454
+ } else {
455
+ throw {
456
+ name: "KerioRequestError",
457
+ message: `Error occured while fetching results from API method 'Queue.run'`,
458
+ type: 'Kerio',
459
+ from: "Kerio.MessageQueues.tryProcessingNow"
460
+ }
461
+ }
462
+
463
+ } catch (e) {
464
+ this.instance.logger.error(e);
465
+ throw e;
466
+ }
467
+ }
468
+
469
+ }
package/src/users.js ADDED
@@ -0,0 +1,208 @@
1
+ import { KerioModules } from './modules.js';
2
+
3
+ export class Users extends KerioModules {
4
+
5
+ /**
6
+ * Get a Mapped Array of KerioUserItems indexed by their ID for the specified domain name. Does not include aliases or user groups.
7
+ * @param {string} domainName Name of the domain
8
+ * @returns {Promise<Map<import('../index.d.ts').KerioUserID, import('../index.d.ts').KerioUserItem>>}
9
+ */
10
+ async list(domainName = null) {
11
+ try {
12
+ if (!this.instance.logged_in) {
13
+
14
+ this.reset();
15
+
16
+ throw {
17
+ name: "KerioClientSessionError",
18
+ message: `Kerio session invalid. Try logging in again.`,
19
+ type: 'Kerio',
20
+ from: "Kerio.Users.list"
21
+ }
22
+ }
23
+
24
+ if (!domainName) {
25
+ throw {
26
+ name: "KerioDomainNameUserError",
27
+ message: `Invalid Domain Name to find Domain ID while processing API method 'Users.get' for domain '${domainName}'`,
28
+ type: 'Kerio',
29
+ from: "Kerio.Users.list"
30
+ }
31
+ }
32
+
33
+ let domains = await this.instance.Domains.list();
34
+
35
+ if (domains.size != 0) {
36
+
37
+ let domainId = Array.from(domains.values()).find(d => d.name.toLowerCase() == domainName.toLowerCase()).id;
38
+
39
+ let users_response = await this.sessionedRequest({
40
+ http_method: 'POST',
41
+ api_method: 'Users.get',
42
+ auth: {
43
+ cookie: this.instance.session_cookie,
44
+ token: this.instance.x_token
45
+ },
46
+ body_params: {
47
+ query: {
48
+ },
49
+ domainId: domainId
50
+ }
51
+ });
52
+
53
+ let response_body = users_response._body;
54
+
55
+ if (!response_body.result?.errors && !response_body?.error) {
56
+
57
+ var userListResult = new Map();
58
+
59
+ if (response_body.result.list.length > 0) {
60
+
61
+ response_body.result.list.forEach(user => {
62
+ /**
63
+ * @type {import('../index.d.ts').KerioUserItem}
64
+ */
65
+ var obj = {
66
+ id: user.id,
67
+ domainId: user.domainId,
68
+ loginName: user.loginName,
69
+ fullName: user.fullName,
70
+ description: user.description,
71
+ enabled: user.isEnabled,
72
+ primaryEmailAddress: `${user.loginName}@${domainName}`
73
+ }
74
+
75
+ userListResult.set(user.id, obj);
76
+ });
77
+ }
78
+
79
+ return userListResult;
80
+
81
+ } else {
82
+ throw {
83
+ name: "KerioRequestError",
84
+ message: `Error occured while fetching results from API method 'Users.get' for domain ${domainName}`,
85
+ type: 'Kerio',
86
+ from: "Kerio.Users.list"
87
+ }
88
+ }
89
+
90
+ } else {
91
+ throw {
92
+ name: "KerioDomainError",
93
+ message: `Domain Name not found to find Domain ID while processing API method 'Users.get' for domain '${domainName}'`,
94
+ type: 'Kerio',
95
+ from: "Kerio.Users.list"
96
+ }
97
+ }
98
+
99
+ } catch (e) {
100
+ this.instance.logger.error(e);
101
+ throw e;
102
+ }
103
+ }
104
+
105
+ async getStatistics(kerioUserID = null) {
106
+ try {
107
+ if (!this.instance.logged_in) {
108
+
109
+ this.reset();
110
+
111
+ throw {
112
+ name: "KerioClientSessionError",
113
+ message: `Kerio session invalid. Try logging in again.`,
114
+ type: 'Kerio',
115
+ from: "Kerio.Users.getStatistics"
116
+ }
117
+ }
118
+
119
+ if (!kerioUserID || !kerioUserID.startsWith("keriodb://user/")) {
120
+ throw {
121
+ name: "KerioUserIDError",
122
+ message: `Invalid User ID while processing API method 'Users.getStatistics' for user ID '${kerioUserID}'`,
123
+ type: 'Kerio',
124
+ from: "Kerio.Users.getStatistics"
125
+ }
126
+ }
127
+
128
+ let user_stats_response = await this.sessionedRequest({
129
+ http_method: 'POST',
130
+ api_method: 'Users.getStatistics',
131
+ auth: {
132
+ cookie: this.instance.session_cookie,
133
+ token: this.instance.x_token
134
+ },
135
+ body_params: {
136
+ query: {
137
+
138
+ },
139
+ userIds: [
140
+ kerioUserID
141
+ ]
142
+ }
143
+ });
144
+
145
+ let response_body = user_stats_response._body;
146
+
147
+ if (!response_body.result?.errors && !response_body?.error) {
148
+
149
+ if (Array.isArray(response_body.result.list) && response_body.result.list.length > 0) {
150
+
151
+ let _stats = response_body.result.list[0];
152
+
153
+ let res = {
154
+ storage: {
155
+ items: _stats.occupiedSpace.items,
156
+ value: _stats.occupiedSpace.storage.value,
157
+ units: _stats.occupiedSpace.storage.units
158
+ },
159
+ lastLogin: "",
160
+ loginCount: {
161
+ pop3: _stats.pop3.count,
162
+ pop3s: _stats.securePop3.count,
163
+ imap: _stats.imap.count,
164
+ imaps: _stats.secureImap.count,
165
+ http: _stats.http.count,
166
+ https: _stats.secureHttp.count,
167
+ ldap: _stats.ldap.count,
168
+ ldaps: _stats.secureLdap.count,
169
+ nntp: _stats.nntp.count,
170
+ nntps: _stats.secureNntp.count,
171
+ activeSync: _stats.activeSync.count,
172
+ secureActiveSync: _stats.secureActiveSync.count,
173
+ xmpp: _stats.xmpp.count,
174
+ xmpps: _stats.secureXmpp.count
175
+ },
176
+ }
177
+
178
+ let login_timestamps_arr = Object.values(_stats).filter(services => services.lastLogin).map(t => t.lastLogin);
179
+
180
+ //most recent login timestamp YYYY-MM-DD HH:MM in server's local time zone
181
+ res.lastLogin = login_timestamps_arr.sort().at(-1);
182
+
183
+ return res;
184
+
185
+ } else {
186
+ throw {
187
+ name: "KerioUserStatsError",
188
+ message: `User may not exist. No statistics found for user ID ${kerioUserID}`,
189
+ type: 'Kerio',
190
+ from: "Kerio.Users.getStatistics"
191
+ }
192
+ }
193
+
194
+ } else {
195
+ throw {
196
+ name: "KerioRequestError",
197
+ message: `Error occured while fetching results from API method 'User.getStatistics'`,
198
+ type: 'Kerio',
199
+ from: "Kerio.Users.getStatistics"
200
+ }
201
+ }
202
+
203
+ } catch (e) {
204
+ this.instance.logger.error(e);
205
+ throw e;
206
+ }
207
+ }
208
+ }