3 console
.log("Starting PMG Manager");
6 Ext
.define('PMG.Utils', {
9 // this singleton contains miscellaneous utilities
11 // use in panels with object spread (...) operator, for example:
12 // ...PMG.Utils.onlineHelpTool('sysadmin_certificate_management'),
13 onlineHelpTool: function(blockid
) {
14 let info
= Proxmox
.Utils
.get_help_info(blockid
);
15 if (info
=== undefined) {
16 info
= Proxmox
.Utils
.get_help_info('pmg_documentation_index');
17 if (info
=== undefined) {
18 throw "get_help_info failed"; // should not happen
22 let docsURI
= window
.location
.origin
+ info
.link
;
23 let title
= info
.title
|| gettext('Help');
25 title
+= ' - ' + info
.subtitle
;
32 handler
: () => window
.open(docsURI
),
38 senderText
: gettext('Sender'),
39 receiverText
: gettext('Receiver'),
40 scoreText
: gettext('Score'),
43 root
: gettext('Superuser'),
44 admin
: gettext('Administrator'),
45 helpdesk
: gettext('Help Desk'),
46 qmanager
: gettext('Quarantine Manager'),
47 audit
: gettext('Auditor'),
50 format_user_role: function(role
) {
51 return PMG
.Utils
.user_role_text
[role
] || role
;
55 who
: gettext('Who Objects'),
56 what
: gettext('What Objects'),
57 when
: gettext('When Objects'),
58 action
: gettext('Action Objects'),
59 from: gettext('From'),
64 who
: '<span class="fa fa-fw fa-user-circle"></span> ',
65 what
: '<span class="fa fa-fw fa-cube"></span> ',
66 when
: '<span class="fa fa-fw fa-clock-o"></span> ',
67 action
: '<span class="fa fa-fw fa-flag"></span> ',
68 from: '<span class="fa fa-fw fa-user-circle"></span> ',
69 to
: '<span class="fa fa-fw fa-user-circle"></span> ',
83 icon_status_map_class
: {
94 icon_status_map_color
: {
101 format_status_icon: function(status
) {
102 var icon
= PMG
.Utils
.icon_status_map_class
[status
] || 'question-circle';
103 var color
= PMG
.Utils
.icon_status_map_color
[status
] || '';
104 return '<i class="fa fa-' + icon
+ ' ' + color
+ '"></i> ';
107 format_oclass: function(oclass
) {
108 var icon
= PMG
.Utils
.oclass_icon
[oclass
] || '';
109 var text
= PMG
.Utils
.oclass_text
[oclass
] || oclass
;
113 rule_direction_text
: {
116 2: gettext('In & Out'),
119 rule_direction_icon
: {
120 0: '<span class="fa fa-fw fa-long-arrow-left"></span> ',
121 1: '<span class="fa fa-fw fa-long-arrow-right"></span> ',
122 2: '<span class="fa fa-fw fa-exchange"></span> ',
125 format_rule_direction: function(dir
) {
126 var icon
= PMG
.Utils
.rule_direction_icon
[dir
] || '';
127 var text
= PMG
.Utils
.rule_direction_text
[dir
] || dir
;
131 format_otype: function(otype
) {
132 let editor
= PMG
.Utils
.object_editors
[otype
];
133 let iconCls
= 'fa fa-question-circle';
135 return `<span class="fa-fw ${editor.iconCls || iconCls}"></span> ${editor.subject}`;
137 return `<span class="fa-fw ${iconCls}"></span> unknown`;
140 format_ldap_protocol: function(p
) {
141 if (p
=== undefined) { return 'LDAP'; }
142 if (p
=== 'ldap') { return 'LDAP'; }
143 if (p
=== 'ldaps') { return 'LDAPS'; }
144 if (p
=== 'ldap+starttls') { return 'LDAP+STARTTLS'; }
148 convert_field_to_per_min: function(value
, record
) {
149 return value
/ (record
.data
.timespan
/ 60);
154 onlineHelp
: 'pmg_mailfilter_regex',
155 iconCls
: 'fa fa-filter',
156 xtype
: 'proxmoxWindowEdit',
158 subject
: gettext("Regular Expression"),
166 fieldLabel
: gettext("Regular Expression"),
169 xtype
: 'pmgRegexTester',
170 fieldLabel
: gettext('Test String'),
173 regexFieldReference
: 'regex',
178 onlineHelp
: 'pmgconfig_ldap',
179 iconCls
: 'fa fa-users',
180 xtype
: 'pmgLDAPGroupEditor',
182 subject
: gettext("LDAP Group"),
185 onlineHelp
: 'pmgconfig_ldap',
186 iconCls
: 'fa fa-user',
187 xtype
: 'pmgLDAPUserEditor',
189 subject
: gettext("LDAP User"),
192 onlineHelp
: 'pmg_mailfilter_regex',
193 iconCls
: 'fa fa-filter',
194 xtype
: 'proxmoxWindowEdit',
195 subdir
: 'receiver_regex',
196 subject
: gettext("Regular Expression"),
204 fieldLabel
: gettext("Regular Expression"),
209 onlineHelp
: 'pmg_mailfilter_who',
210 iconCls
: 'fa fa-envelope-o',
211 xtype
: 'proxmoxWindowEdit',
213 subject
: gettext("E-Mail"),
219 fieldLabel
: gettext("E-Mail"),
224 onlineHelp
: 'pmg_mailfilter_who',
225 iconCls
: 'fa fa-envelope-o',
226 xtype
: 'proxmoxWindowEdit',
228 subject
: gettext("E-Mail"),
235 fieldLabel
: gettext("E-Mail"),
240 onlineHelp
: 'pmg_mailfilter_who',
241 iconCls
: 'fa fa-globe',
242 xtype
: 'proxmoxWindowEdit',
244 subject
: gettext("Domain"),
250 fieldLabel
: gettext("Domain"),
255 onlineHelp
: 'pmg_mailfilter_who',
256 iconCls
: 'fa fa-globe',
257 xtype
: 'proxmoxWindowEdit',
258 subdir
: 'receiver_domain',
259 subject
: gettext("Domain"),
266 fieldLabel
: gettext("Domain"),
271 onlineHelp
: 'pmg_mailfilter_who',
272 iconCls
: 'fa fa-globe',
273 xtype
: 'proxmoxWindowEdit',
275 subject
: gettext("IP Address"),
281 fieldLabel
: gettext("IP Address"),
286 onlineHelp
: 'pmg_mailfilter_who',
287 iconCls
: 'fa fa-globe',
288 xtype
: 'proxmoxWindowEdit',
290 subject
: gettext("IP Network"),
296 fieldLabel
: gettext("IP Network"),
301 onlineHelp
: 'pmg_mailfilter_when',
302 iconCls
: 'fa fa-clock-o',
303 xtype
: 'proxmoxWindowEdit',
305 subject
: gettext("TimeFrame"),
311 fieldLabel
: gettext("Start Time"),
317 fieldLabel
: gettext("End Time"),
322 onlineHelp
: 'pmg_mailfilter_what',
323 iconCls
: 'fa fa-bullhorn',
324 xtype
: 'proxmoxWindowEdit',
325 subdir
: 'spamfilter',
326 subject
: gettext('Spam Filter'),
329 xtype
: 'proxmoxintegerfield',
333 fieldLabel
: gettext('Level'),
338 onlineHelp
: 'pmg_mailfilter_what',
339 iconCls
: 'fa fa-bug',
340 xtype
: 'proxmoxWindowEdit',
341 subdir
: 'virusfilter',
342 subject
: gettext('Virus Filter'),
344 // there are no parameters to give, so we simply submit it
346 show: function(win
) {
352 onlineHelp
: 'pmg_mailfilter_regex',
353 iconCls
: 'fa fa-code',
354 xtype
: 'proxmoxWindowEdit',
355 subdir
: 'matchfield',
356 subject
: gettext('Match Field'),
364 fieldLabel
: gettext('Field'),
372 fieldLabel
: gettext('Value'),
376 fieldLabel
: gettext('Test String'),
377 xtype
: 'pmgRegexTester',
378 regexFieldReference
: 'value',
383 onlineHelp
: 'pmg_mailfilter_what',
384 iconCls
: 'fa fa-file-image-o',
385 xtype
: 'proxmoxWindowEdit',
386 subdir
: 'contenttype',
388 subject
: gettext('Content Type Filter'),
392 displayField
: 'text',
394 valueField
: 'mimetype',
402 url
: '/api2/json/config/mimetypes',
405 fieldLabel
: gettext('Content Type'),
407 matchFieldWidth
: false,
409 change: function(cb
, value
) {
411 me
.up().down('displayfield').setValue(value
);
416 xtype
: 'displayfield',
417 fieldLabel
: gettext('Value'),
425 onlineHelp
: 'pmg_mailfilter_regex',
426 iconCls
: 'fa fa-file-o',
427 xtype
: 'proxmoxWindowEdit',
428 subdir
: 'filenamefilter',
430 subject
: gettext('Match Filename'),
435 reference
: 'filename',
436 fieldLabel
: gettext('Filename'),
442 fieldLabel
: gettext('Test String'),
444 xtype
: 'pmgRegexTester',
445 regexFieldReference
: 'filename',
450 onlineHelp
: 'pmg_mailfilter_what',
451 iconCls
: 'fa fa-file-archive-o',
452 xtype
: 'proxmoxWindowEdit',
453 subdir
: 'archivefilter',
455 subject
: gettext('Archive Filter'),
459 displayField
: 'text',
461 valueField
: 'mimetype',
469 url
: '/api2/json/config/mimetypes',
472 fieldLabel
: gettext('Content Type'),
474 matchFieldWidth
: false,
476 change: function(cb
, value
) {
478 me
.up().down('displayfield').setValue(value
);
483 xtype
: 'displayfield',
484 fieldLabel
: gettext('Value'),
492 onlineHelp
: 'pmg_mailfilter_regex',
493 iconCls
: 'fa fa-file-archive-o',
494 xtype
: 'proxmoxWindowEdit',
495 subdir
: 'archivefilenamefilter',
497 subject
: gettext('Match Archive Filename'),
502 reference
: 'filename',
503 fieldLabel
: gettext('Filename'),
509 fieldLabel
: gettext('Test String'),
511 xtype
: 'pmgRegexTester',
512 regexFieldReference
: 'filename',
517 onlineHelp
: 'pmg_mailfilter_action',
518 xtype
: 'proxmoxWindowEdit',
519 subdir
: 'notification',
520 subject
: gettext('Notification'),
527 fieldLabel
: gettext('Name'),
530 xtype
: 'textareafield',
532 fieldLabel
: gettext("Comment"),
539 fieldLabel
: gettext('Receiver'),
545 value
: 'Notification: __SUBJECT__',
546 fieldLabel
: gettext('Subject'),
555 "Proxmox Notifcation:\n\n" +
556 "Sender: __SENDER__\n" +
557 "Receiver: __RECEIVERS__\n" +
558 "Targets: __TARGETS__\n\n" +
559 "Subject: __SUBJECT__\n\n" +
560 "Matching Rule: __RULE__\n\n" +
561 "__RULE_INFO__\n\n" +
564 fieldLabel
: gettext('Body'),
567 xtype
: 'proxmoxcheckbox',
569 fieldLabel
: gettext("Attach orig. Mail"),
574 onlineHelp
: 'pmg_mailfilter_action',
575 xtype
: 'proxmoxWindowEdit',
577 subject
: gettext('Header Attribute'),
584 fieldLabel
: gettext('Name'),
587 xtype
: 'textareafield',
589 fieldLabel
: gettext("Comment"),
595 fieldLabel
: gettext('Field'),
602 fieldLabel
: gettext('Value'),
607 onlineHelp
: 'pmg_mailfilter_action',
608 xtype
: 'proxmoxWindowEdit',
610 subject
: gettext('BCC'),
617 fieldLabel
: gettext('Name'),
620 xtype
: 'textareafield',
622 fieldLabel
: gettext("Comment"),
628 fieldLabel
: gettext("Target"),
631 xtype
: 'proxmoxcheckbox',
634 fieldLabel
: gettext("send orig. Mail"),
640 onlineHelp
: 'pmg_mailfilter_action',
641 xtype
: 'proxmoxWindowEdit',
642 subdir
: 'removeattachments',
643 subject
: gettext('Remove Attachments'),
653 fieldLabel
: gettext('Name'),
656 xtype
: 'textareafield',
658 fieldLabel
: gettext("Comment"),
661 xtype
: 'textareafield',
665 fieldLabel
: gettext("Text Replacement"),
668 xtype
: 'proxmoxcheckbox',
671 fieldLabel
: gettext("Remove all attachments"),
674 xtype
: 'proxmoxcheckbox',
677 fieldLabel
: gettext("Copy original mail to Attachment Quarantine"),
682 onlineHelp
: 'pmg_mailfilter_action',
683 xtype
: 'proxmoxWindowEdit',
684 subdir
: 'disclaimer',
685 subject
: gettext('Disclaimer'),
692 fieldLabel
: gettext('Name'),
695 xtype
: 'textareafield',
697 fieldLabel
: gettext("Comment"),
700 xtype
: 'textareafield',
704 fieldLabel
: gettext("Disclaimer"),
710 updateLoginData: function(data
) {
711 Proxmox
.CSRFPreventionToken
= data
.CSRFPreventionToken
;
712 Proxmox
.UserName
= data
.username
;
713 Ext
.util
.Cookies
.set('PMGAuthCookie', data
.ticket
, null, '/', null, true);
716 quarantineActionExtracted
: false,
718 extractQuarantineAction: function() {
719 if (PMG
.Utils
.quarantineActionExtracted
) {
723 PMG
.Utils
.quarantineActionExtracted
= true;
725 let qs
= Ext
.Object
.fromQueryString(location
.search
);
727 let cselect
= qs
.cselect
;
728 let action
= qs
.action
;
729 let dateString
= qs
.date
;
732 let date
= new Date(dateString
).getTime()/1000;
734 // set from date for QuarantineList
735 PMG
.QuarantineList
.from = date
;
743 var newsearch
= Ext
.Object
.toQueryString(qs
);
745 var newurl
= location
.protocol
+ "//" + location
.host
+ location
.pathname
;
746 if (newsearch
) { newurl
+= '?' + newsearch
; }
747 newurl
+= location
.hash
;
749 if (window
.history
) {
750 window
.history
.pushState({ path
: newurl
}, '', newurl
);
753 if (action
|| cselect
) {
762 doQuarantineAction: function(action
, id
, callback
) {
763 Proxmox
.Utils
.API2Request({
764 url
: '/quarantine/content/',
770 failure: function(response
, opts
) {
771 Ext
.Msg
.alert(gettext('Error'), response
.htmlStatus
);
773 success: function(response
, opts
) {
774 let count
= id
.split(';').length
;
776 ? gettext("Action '{0}' for '{1}' items successful")
777 : gettext("Action '{0}' successful")
779 let message
= Ext
.String
.format(fmt
, action
, count
);
780 let title
= Ext
.String
.format("{0} successful", Ext
.String
.capitalize(action
));
787 slideBackDuration
: 250,
788 slideBackAnimation
: 'easeOut',
789 iconCls
: 'fa fa-check',
794 if (Ext
.isFunction(callback
)) {
801 render_filetype: function(value
) {
802 let iconCls
= 'fa-file-o';
803 let text
= Proxmox
.Utils
.unknownText
;
806 return `<i class='fa ${iconCls}'></i> ${text}`;
809 text
= value
.toString().toLowerCase();
810 const type
= text
.split('/')[0];
817 iconCls
= `fa-file-${type}-o`;
819 case 'application': {
820 const subtypes
= ['excel', 'pdf', 'word', 'powerpoint'];
821 let found
= subtypes
.find(st
=> text
.includes(st
));
822 if (found
!== undefined) {
823 iconCls
= `fa-file-${found}-o`;
830 return `<i class='fa ${iconCls}'></i> ${text}`;
833 sender_renderer: function(value
, metaData
, rec
) {
834 var subject
= Ext
.htmlEncode(value
);
835 var from = Ext
.htmlEncode(rec
.data
.from);
836 var sender
= Ext
.htmlEncode(rec
.data
.sender
);
838 from = Ext
.String
.format(gettext("{0} on behalf of {1}"),
841 return '<small>' + from + '</small><br>' + subject
;
844 constructor: function() {
847 // do whatever you want here
848 Proxmox
.Utils
.override_task_descriptions({
849 applycustomscores
: ['', gettext('Apply custom SpamAssassin scores')],
850 avupdate
: ['', gettext('ClamAV update')],
851 backup
: ['', gettext('Backup')],
852 clustercreate
: ['', gettext('Create Cluster')],
853 clusterjoin
: ['', gettext('Join Cluster')],
854 restore
: ['', gettext('Restore')],
855 saupdate
: ['', gettext('SpamAssassin update')],
860 Ext
.define('PMG.Async', {
863 // Returns a Promise which executes a quarantine action when awaited.
864 // Shows a Toast message box once completed, if batchNumber and batchTotal
865 // are set, they will be included into the title of that toast.
866 doQAction: function(action
, ids
, batchNumber
, batchTotal
) {
867 if (!Ext
.isArray(ids
)) {
870 return Proxmox
.Async
.api2({
871 url
: '/quarantine/content/',
879 let count
= ids
.length
;
881 ? gettext("Action '{0}' for '{1}' items successful")
882 : gettext("Action '{0}' successful")
884 let message
= Ext
.String
.format(fmt
, action
, count
);
885 let titleFmt
= batchNumber
!== undefined && batchTotal
> 1
886 ? gettext("{0} ({1}/{2}) successful")
887 : gettext("{0} successful")
889 let title
= Ext
.String
.format(
891 Ext
.String
.capitalize(action
),
901 slideBackDuration
: 250,
902 slideBackAnimation
: 'easeOut',
903 iconCls
: 'fa fa-check',
908 response
=> Proxmox
.Utils
.alertResponseFailure(response
),