]> git.proxmox.com Git - pmg-gui.git/blob - js/Utils.js
quarantine: make annoying success prompt a toast
[pmg-gui.git] / js / Utils.js
1 Ext.ns('PMG');
2
3 console.log("Starting PMG Manager");
4
5
6 Ext.define('PMG.Utils', {
7 singleton: true,
8
9 // this singleton contains miscellaneous utilities
10
11 senderText: gettext('Sender'),
12 receiverText: gettext('Receiver'),
13 scoreText: gettext('Score'),
14
15 user_role_text: {
16 root: gettext('Superuser'),
17 admin: gettext('Administrator'),
18 helpdesk: gettext('Help Desk'),
19 qmanager: gettext('Quarantine Manager'),
20 audit: gettext('Auditor'),
21 },
22
23 format_user_role: function(role) {
24 return PMG.Utils.user_role_text[role] || role;
25 },
26
27 oclass_text: {
28 who: gettext('Who Objects'),
29 what: gettext('What Objects'),
30 when: gettext('When Objects'),
31 action: gettext('Action Objects'),
32 from: gettext('From'),
33 to: gettext('To'),
34 },
35
36 oclass_icon: {
37 who: '<span class="fa fa-fw fa-user-circle"></span> ',
38 what: '<span class="fa fa-fw fa-cube"></span> ',
39 when: '<span class="fa fa-fw fa-clock-o"></span> ',
40 action: '<span class="fa fa-fw fa-flag"></span> ',
41 from: '<span class="fa fa-fw fa-user-circle"></span> ',
42 to: '<span class="fa fa-fw fa-user-circle"></span> ',
43 },
44
45 mail_status_map: {
46 2: 'delivered',
47 4: 'deferred',
48 5: 'bounced',
49 N: 'rejected',
50 G: 'greylisted',
51 A: 'accepted',
52 B: 'blocked',
53 Q: 'quarantine',
54 },
55
56 icon_status_map_class: {
57 2: 'check-circle',
58 4: 'clock-o',
59 5: 'mail-reply',
60 N: 'times-circle',
61 G: 'list',
62 A: 'check',
63 B: 'ban',
64 Q: 'cube',
65 },
66
67 icon_status_map_color: {
68 2: 'green',
69 5: 'gray',
70 A: 'green',
71 B: 'red',
72 },
73
74 format_status_icon: function(status) {
75 var icon = PMG.Utils.icon_status_map_class[status] || 'question-circle';
76 var color = PMG.Utils.icon_status_map_color[status] || '';
77 return '<i class="fa fa-' + icon + ' ' + color + '"></i> ';
78 },
79
80 format_oclass: function(oclass) {
81 var icon = PMG.Utils.oclass_icon[oclass] || '';
82 var text = PMG.Utils.oclass_text[oclass] || oclass;
83 return icon + text;
84 },
85
86 rule_direction_text: {
87 0: gettext('In'),
88 1: gettext('Out'),
89 2: gettext('In & Out'),
90 },
91
92 rule_direction_icon: {
93 0: '<span class="fa fa-fw fa-long-arrow-left"></span> ',
94 1: '<span class="fa fa-fw fa-long-arrow-right"></span> ',
95 2: '<span class="fa fa-fw fa-exchange"></span> ',
96 },
97
98 format_rule_direction: function(dir) {
99 var icon = PMG.Utils.rule_direction_icon[dir] || '';
100 var text = PMG.Utils.rule_direction_text[dir] || dir;
101 return icon + text;
102 },
103
104 format_otype: function(otype) {
105 var editor = PMG.Utils.object_editors[otype];
106 var iconCls = 'fa fa-question-circle';
107 if (editor) {
108 var icon = '<span class="fa-fw ' + (editor.iconCls || iconCls) + '"></span> ';
109 return icon + editor.subject;
110 }
111
112 return '<span class="fa-fw ' + iconCls + '"></span> unknown';
113 },
114
115 format_ldap_protocol: function(p) {
116 if (p === undefined) { return 'LDAP'; }
117 if (p === 'ldap') { return 'LDAP'; }
118 if (p === 'ldaps') { return 'LDAPS'; }
119 if (p === 'ldap+starttls') { return 'LDAP+STARTTLS'; }
120 return 'unknown';
121 },
122
123 convert_field_to_per_min: function(value, record) {
124 return value/(record.data.timespan/60);
125 },
126
127 object_editors: {
128 1000: {
129 onlineHelp: 'pmg_mailfilter_regex',
130 iconCls: 'fa fa-filter',
131 xtype: 'proxmoxWindowEdit',
132 subdir: 'regex',
133 subject: gettext("Regular Expression"),
134 width: 400,
135 items: [
136 {
137 xtype: 'textfield',
138 name: 'regex',
139 labelWidth: 150,
140 reference: 'regex',
141 fieldLabel: gettext("Regular Expression"),
142 },
143 {
144 labelWidth: 150,
145 fieldLabel: gettext('Test String'),
146 xtype: 'pmgRegexTester',
147 wholeMatch: true,
148 regexFieldReference: 'regex',
149 },
150 ],
151 },
152 1005: {
153 onlineHelp: 'pmgconfig_ldap',
154 iconCls: 'fa fa-users',
155 xtype: 'pmgLDAPGroupEditor',
156 subdir: 'ldap',
157 subject: gettext("LDAP Group"),
158 },
159 1006: {
160 onlineHelp: 'pmgconfig_ldap',
161 iconCls: 'fa fa-user',
162 xtype: 'pmgLDAPUserEditor',
163 subdir: 'ldapuser',
164 subject: gettext("LDAP User"),
165 },
166 1009: {
167 onlineHelp: 'pmg_mailfilter_regex',
168 iconCls: 'fa fa-filter',
169 xtype: 'proxmoxWindowEdit',
170 subdir: 'receiver_regex',
171 subject: gettext("Regular Expression"),
172 receivertest: true,
173 width: 400,
174 items: [
175 {
176 xtype: 'textfield',
177 name: 'regex',
178 labelWidth: 150,
179 fieldLabel: gettext("Regular Expression"),
180 },
181 ],
182 },
183 1001: {
184 onlineHelp: 'pmg_mailfilter_who',
185 iconCls: 'fa fa-envelope-o',
186 xtype: 'proxmoxWindowEdit',
187 subdir: 'email',
188 subject: gettext("E-Mail"),
189 width: 400,
190 items: [
191 {
192 xtype: 'textfield',
193 name: 'email',
194 fieldLabel: gettext("E-Mail"),
195 },
196 ],
197 },
198 1007: {
199 onlineHelp: 'pmg_mailfilter_who',
200 iconCls: 'fa fa-envelope-o',
201 xtype: 'proxmoxWindowEdit',
202 subdir: 'receiver',
203 subject: gettext("E-Mail"),
204 receivertest: true,
205 width: 400,
206 items: [
207 {
208 xtype: 'textfield',
209 name: 'email',
210 fieldLabel: gettext("E-Mail"),
211 },
212 ],
213 },
214 1002: {
215 onlineHelp: 'pmg_mailfilter_who',
216 iconCls: 'fa fa-globe',
217 xtype: 'proxmoxWindowEdit',
218 subdir: 'domain',
219 subject: gettext("Domain"),
220 width: 400,
221 items: [
222 {
223 xtype: 'textfield',
224 name: 'domain',
225 fieldLabel: gettext("Domain"),
226 },
227 ],
228 },
229 1008: {
230 onlineHelp: 'pmg_mailfilter_who',
231 iconCls: 'fa fa-globe',
232 xtype: 'proxmoxWindowEdit',
233 subdir: 'receiver_domain',
234 subject: gettext("Domain"),
235 receivertest: true,
236 width: 400,
237 items: [
238 {
239 xtype: 'textfield',
240 name: 'domain',
241 fieldLabel: gettext("Domain"),
242 },
243 ],
244 },
245 1003: {
246 onlineHelp: 'pmg_mailfilter_who',
247 iconCls: 'fa fa-globe',
248 xtype: 'proxmoxWindowEdit',
249 subdir: 'ip',
250 subject: gettext("IP Address"),
251 width: 400,
252 items: [
253 {
254 xtype: 'textfield',
255 name: 'ip',
256 fieldLabel: gettext("IP Address"),
257 },
258 ],
259 },
260 1004: {
261 onlineHelp: 'pmg_mailfilter_who',
262 iconCls: 'fa fa-globe',
263 xtype: 'proxmoxWindowEdit',
264 subdir: 'network',
265 subject: gettext("IP Network"),
266 width: 400,
267 items: [
268 {
269 xtype: 'textfield',
270 name: 'cidr',
271 fieldLabel: gettext("IP Network"),
272 },
273 ],
274 },
275 2000: {
276 onlineHelp: 'pmg_mailfilter_when',
277 iconCls: 'fa fa-clock-o',
278 xtype: 'proxmoxWindowEdit',
279 subdir: 'timeframe',
280 subject: gettext("TimeFrame"),
281 items: [
282 {
283 xtype: 'timefield',
284 name: 'start',
285 format: 'H:i',
286 fieldLabel: gettext("Start Time"),
287 },
288 {
289 xtype: 'timefield',
290 name: 'end',
291 format: 'H:i',
292 fieldLabel: gettext("End Time"),
293 },
294 ],
295 },
296 3000: {
297 onlineHelp: 'pmg_mailfilter_what',
298 iconCls: 'fa fa-bullhorn',
299 xtype: 'proxmoxWindowEdit',
300 subdir: 'spamfilter',
301 subject: gettext('Spam Filter'),
302 items: [
303 {
304 xtype: 'proxmoxintegerfield',
305 name: 'spamlevel',
306 allowBlank: false,
307 minValue: 0,
308 fieldLabel: gettext('Level'),
309 },
310 ],
311 },
312 3001: {
313 onlineHelp: 'pmg_mailfilter_what',
314 iconCls: 'fa fa-bug',
315 xtype: 'proxmoxWindowEdit',
316 subdir: 'virusfilter',
317 subject: gettext('Virus Filter'),
318 uneditable: true,
319 // there are no parameters to give, so we simply submit it
320 listeners: {
321 show: function(win) {
322 win.submit();
323 },
324 },
325 },
326 3002: {
327 onlineHelp: 'pmg_mailfilter_regex',
328 iconCls: 'fa fa-code',
329 xtype: 'proxmoxWindowEdit',
330 subdir: 'matchfield',
331 subject: gettext('Match Field'),
332 width: 400,
333 items: [
334 {
335 xtype: 'textfield',
336 name: 'field',
337 labelWidth: 150,
338 allowBlank: false,
339 fieldLabel: gettext('Field'),
340 },
341 {
342 xtype: 'textfield',
343 reference: 'value',
344 name: 'value',
345 labelWidth: 150,
346 allowBlank: false,
347 fieldLabel: gettext('Value'),
348 },
349 {
350 labelWidth: 150,
351 fieldLabel: gettext('Test String'),
352 xtype: 'pmgRegexTester',
353 regexFieldReference: 'value',
354 },
355 ],
356 },
357 3003: {
358 onlineHelp: 'pmg_mailfilter_what',
359 iconCls: 'fa fa-file-image-o',
360 xtype: 'proxmoxWindowEdit',
361 subdir: 'contenttype',
362 width: 400,
363 subject: gettext('Content Type Filter'),
364 items: [
365 {
366 xtype: 'combobox',
367 displayField: 'text',
368 labelWidth: 150,
369 valueField: 'mimetype',
370 name: 'contenttype',
371 editable: true,
372 queryMode: 'local',
373 store: {
374 autoLoad: true,
375 proxy: {
376 type: 'proxmox',
377 url: '/api2/json/config/mimetypes',
378 },
379 },
380 fieldLabel: gettext('Content Type'),
381 anyMatch: true,
382 matchFieldWidth: false,
383 listeners: {
384 change: function(cb, value) {
385 var me = this;
386 me.up().down('displayfield').setValue(value);
387 },
388 },
389 },
390 {
391 xtype: 'displayfield',
392 fieldLabel: gettext('Value'),
393 labelWidth: 150,
394 allowBlank: false,
395 reset: Ext.emptyFn,
396 },
397 ],
398 },
399 3004: {
400 onlineHelp: 'pmg_mailfilter_regex',
401 iconCls: 'fa fa-file-o',
402 xtype: 'proxmoxWindowEdit',
403 subdir: 'filenamefilter',
404 width: 400,
405 subject: gettext('Match Filename'),
406 items: [
407 {
408 xtype: 'textfield',
409 name: 'filename',
410 reference: 'filename',
411 fieldLabel: gettext('Filename'),
412 labelWidth: 150,
413 allowBlank: false,
414 },
415 {
416 labelWidth: 150,
417 fieldLabel: gettext('Test String'),
418 wholeMatch: true,
419 xtype: 'pmgRegexTester',
420 regexFieldReference: 'filename',
421 },
422 ],
423 },
424 3005: {
425 onlineHelp: 'pmg_mailfilter_what',
426 iconCls: 'fa fa-file-archive-o',
427 xtype: 'proxmoxWindowEdit',
428 subdir: 'archivefilter',
429 width: 400,
430 subject: gettext('Archive Filter'),
431 items: [
432 {
433 xtype: 'combobox',
434 displayField: 'text',
435 labelWidth: 150,
436 valueField: 'mimetype',
437 name: 'contenttype',
438 editable: true,
439 queryMode: 'local',
440 store: {
441 autoLoad: true,
442 proxy: {
443 type: 'proxmox',
444 url: '/api2/json/config/mimetypes',
445 },
446 },
447 fieldLabel: gettext('Content Type'),
448 anyMatch: true,
449 matchFieldWidth: false,
450 listeners: {
451 change: function(cb, value) {
452 var me = this;
453 me.up().down('displayfield').setValue(value);
454 },
455 },
456 },
457 {
458 xtype: 'displayfield',
459 fieldLabel: gettext('Value'),
460 labelWidth: 150,
461 allowBlank: false,
462 reset: Ext.emptyFn,
463 },
464 ],
465 },
466 3006: {
467 onlineHelp: 'pmg_mailfilter_regex',
468 iconCls: 'fa fa-file-archive-o',
469 xtype: 'proxmoxWindowEdit',
470 subdir: 'archivefilenamefilter',
471 width: 400,
472 subject: gettext('Match Archive Filename'),
473 items: [
474 {
475 xtype: 'textfield',
476 name: 'filename',
477 reference: 'filename',
478 fieldLabel: gettext('Filename'),
479 labelWidth: 150,
480 allowBlank: false,
481 },
482 {
483 labelWidth: 150,
484 fieldLabel: gettext('Test String'),
485 wholeMatch: true,
486 xtype: 'pmgRegexTester',
487 regexFieldReference: 'filename',
488 },
489 ],
490 },
491 4002: {
492 onlineHelp: 'pmg_mailfilter_action',
493 xtype: 'proxmoxWindowEdit',
494 subdir: 'notification',
495 subject: gettext('Notification'),
496 width: 400,
497 items: [
498 {
499 xtype: 'textfield',
500 name: 'name',
501 allowBlank: false,
502 fieldLabel: gettext('Name'),
503 },
504 {
505 xtype: 'textareafield',
506 name: 'info',
507 fieldLabel: gettext("Comment"),
508 },
509 {
510 xtype: 'textfield',
511 name: 'to',
512 allowBlank: false,
513 value: '__ADMIN__',
514 fieldLabel: gettext('Receiver'),
515 },
516 {
517 xtype: 'textfield',
518 name: 'subject',
519 allowBlank: false,
520 value: 'Notification: __SUBJECT__',
521 fieldLabel: gettext('Subject'),
522 },
523 {
524 xtype: 'textarea',
525 name: 'body',
526 allowBlank: false,
527 grow: true,
528 growMax: 250,
529 value:
530 "Proxmox Notifcation:\n\n" +
531 "Sender: __SENDER__\n" +
532 "Receiver: __RECEIVERS__\n" +
533 "Targets: __TARGETS__\n\n" +
534 "Subject: __SUBJECT__\n\n" +
535 "Matching Rule: __RULE__\n\n" +
536 "__RULE_INFO__\n\n" +
537 "__VIRUS_INFO__\n" +
538 "__SPAM_INFO__\n",
539 fieldLabel: gettext('Body'),
540 },
541 {
542 xtype: 'proxmoxcheckbox',
543 name: 'attach',
544 fieldLabel: gettext("Attach orig. Mail"),
545 },
546 ],
547 },
548 4003: {
549 onlineHelp: 'pmg_mailfilter_action',
550 xtype: 'proxmoxWindowEdit',
551 subdir: 'field',
552 subject: gettext('Header Attribute'),
553 width: 400,
554 items: [
555 {
556 xtype: 'textfield',
557 name: 'name',
558 allowBlank: false,
559 fieldLabel: gettext('Name'),
560 },
561 {
562 xtype: 'textareafield',
563 name: 'info',
564 fieldLabel: gettext("Comment"),
565 },
566 {
567 xtype: 'textfield',
568 name: 'field',
569 allowBlank: false,
570 fieldLabel: gettext('Field'),
571 },
572 {
573 xtype: 'textfield',
574 reference: 'value',
575 name: 'value',
576 allowBlank: false,
577 fieldLabel: gettext('Value'),
578 },
579 ],
580 },
581 4005: {
582 onlineHelp: 'pmg_mailfilter_action',
583 xtype: 'proxmoxWindowEdit',
584 subdir: 'bcc',
585 subject: gettext('BCC'),
586 width: 400,
587 items: [
588 {
589 xtype: 'textfield',
590 name: 'name',
591 allowBlank: false,
592 fieldLabel: gettext('Name'),
593 },
594 {
595 xtype: 'textareafield',
596 name: 'info',
597 fieldLabel: gettext("Comment"),
598 },
599 {
600 xtype: 'textfield',
601 name: 'target',
602 allowBlank: false,
603 fieldLabel: gettext("Target"),
604 },
605 {
606 xtype: 'proxmoxcheckbox',
607 checked: true,
608 name: 'original',
609 fieldLabel: gettext("send orig. Mail"),
610 },
611 ],
612
613 },
614 4007: {
615 onlineHelp: 'pmg_mailfilter_action',
616 xtype: 'proxmoxWindowEdit',
617 subdir: 'removeattachments',
618 subject: gettext('Remove Attachments'),
619 width: 500,
620 fieldDefaults: {
621 labelWidth: 150,
622 },
623 items: [
624 {
625 xtype: 'textfield',
626 name: 'name',
627 allowBlank: false,
628 fieldLabel: gettext('Name'),
629 },
630 {
631 xtype: 'textareafield',
632 name: 'info',
633 fieldLabel: gettext("Comment"),
634 },
635 {
636 xtype: 'textareafield',
637 name: 'text',
638 grow: true,
639 growMax: 250,
640 fieldLabel: gettext("Text Replacement"),
641 },
642 {
643 xtype: 'proxmoxcheckbox',
644 checked: true,
645 name: 'all',
646 fieldLabel: gettext("Remove all attachments"),
647 },
648 {
649 xtype: 'proxmoxcheckbox',
650 checked: false,
651 name: 'quarantine',
652 fieldLabel: gettext("Copy orignal mail to Attachment Quarantine"),
653 },
654 ],
655 },
656 4009: {
657 onlineHelp: 'pmg_mailfilter_action',
658 xtype: 'proxmoxWindowEdit',
659 subdir: 'disclaimer',
660 subject: gettext('Disclaimer'),
661 width: 400,
662 items: [
663 {
664 xtype: 'textfield',
665 name: 'name',
666 allowBlank: false,
667 fieldLabel: gettext('Name'),
668 },
669 {
670 xtype: 'textareafield',
671 name: 'info',
672 fieldLabel: gettext("Comment"),
673 },
674 {
675 xtype: 'textareafield',
676 name: 'disclaimer',
677 grow: true,
678 growMax: 250,
679 fieldLabel: gettext("Disclaimer"),
680 },
681 ],
682 },
683 },
684
685 updateLoginData: function(data) {
686 Proxmox.CSRFPreventionToken = data.CSRFPreventionToken;
687 Proxmox.UserName = data.username;
688 Ext.util.Cookies.set('PMGAuthCookie', data.ticket, null, '/', null, true);
689 },
690
691 quarantineActionExtracted: false,
692
693 extractQuarantineAction: function() {
694 if (PMG.Utils.quarantineActionExtracted) {
695 return null;
696 }
697
698 PMG.Utils.quarantineActionExtracted = true;
699
700 let qs = Ext.Object.fromQueryString(location.search);
701
702 let cselect = qs.cselect;
703 let action = qs.action;
704 let dateString = qs.date;
705
706 if (dateString) {
707 let date = new Date(dateString).getTime()/1000;
708
709 // set from date for QuarantineList
710 PMG.QuarantineList.from = date;
711 }
712
713 delete qs.cselect;
714 delete qs.action;
715 delete qs.ticket;
716 delete qs.date;
717
718 var newsearch = Ext.Object.toQueryString(qs);
719
720 var newurl = location.protocol + "//" + location.host + location.pathname;
721 if (newsearch) { newurl += '?' + newsearch; }
722 newurl += location.hash;
723
724 if (window.history) {
725 window.history.pushState({ path: newurl }, '', newurl);
726 }
727
728 if (action || cselect) {
729 return {
730 action: action,
731 cselect: cselect,
732 };
733 }
734 return null;
735 },
736
737 doQuarantineAction: function(action, id, callback) {
738 Proxmox.Utils.API2Request({
739 url: '/quarantine/content/',
740 params: {
741 action: action,
742 id: id,
743 },
744 method: 'POST',
745 failure: function(response, opts) {
746 Ext.Msg.alert(gettext('Error'), response.htmlStatus);
747 },
748 success: function(response, opts) {
749 let count = id.split(';').length;
750 let fmt = count > 1
751 ? gettext("Action '{0}' for '{1}' items successful")
752 : gettext("Action '{0}' successful")
753 ;
754 let message = Ext.String.format(fmt, action, count);
755 let title = Ext.String.format("{0} successful", Ext.String.capitalize(action));
756
757 Ext.toast({
758 html: message,
759 title: title,
760 minWidth: 200,
761 hideDuration: 250,
762 slideBackDuration: 250,
763 slideBackAnimation: 'easeOut',
764 iconCls: 'fa fa-check',
765 });
766
767 if (Ext.isFunction(callback)) {
768 callback();
769 }
770 },
771 });
772 },
773
774 render_filetype: function(value) {
775 let iconCls = 'fa-file-o';
776 let text = Proxmox.Utils.unknownText;
777
778 if (!value) {
779 return `<i class='fa ${iconCls}'></i> ${text}`;
780 }
781
782 text = value.toString().toLowerCase();
783 const type = text.split('/')[0];
784
785 switch (type) {
786 case 'audio':
787 case 'image':
788 case 'video':
789 case 'text':
790 iconCls = `fa-file-${type}-o`;
791 break;
792 case 'application': {
793 const subtypes = ['excel', 'pdf', 'word', 'powerpoint'];
794 let found = subtypes.find(st => text.includes(st));
795 if (found !== undefined) {
796 iconCls = `fa-file-${found}-o`;
797 }
798 } break;
799 default:
800 break;
801 }
802
803 return `<i class='fa ${iconCls}'></i> ${text}`;
804 },
805
806 sender_renderer: function(value, metaData, rec) {
807 var subject = Ext.htmlEncode(value);
808 var from = Ext.htmlEncode(rec.data.from);
809 var sender = Ext.htmlEncode(rec.data.sender);
810 if (sender) {
811 /*jslint confusion: true*/
812 /*format is a string above*/
813 from = Ext.String.format(gettext("{0} on behalf of {1}"),
814 sender, from);
815 /*jslint confusion: false*/
816 }
817 return '<small>' + from + '</small><br>' + subject;
818 },
819
820 constructor: function() {
821 var me = this;
822
823 // do whatever you want here
824 },
825 });