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"),
165 fieldLabel
: gettext("Regex"),
168 xtype
: 'pmgRegexTester',
169 fieldLabel
: gettext('Test String'),
171 regexFieldReference
: 'regex',
176 onlineHelp
: 'pmgconfig_ldap',
177 iconCls
: 'fa fa-users',
178 xtype
: 'pmgLDAPGroupEditor',
180 subject
: gettext("LDAP Group"),
183 onlineHelp
: 'pmgconfig_ldap',
184 iconCls
: 'fa fa-user',
185 xtype
: 'pmgLDAPUserEditor',
187 subject
: gettext("LDAP User"),
190 onlineHelp
: 'pmg_mailfilter_regex',
191 iconCls
: 'fa fa-filter',
192 xtype
: 'proxmoxWindowEdit',
193 subdir
: 'receiver_regex',
194 subject
: gettext("Regular Expression"),
201 fieldLabel
: gettext("Regex"),
206 onlineHelp
: 'pmg_mailfilter_who',
207 iconCls
: 'fa fa-envelope-o',
208 xtype
: 'proxmoxWindowEdit',
210 subject
: gettext("E-Mail"),
216 fieldLabel
: gettext("E-Mail"),
221 onlineHelp
: 'pmg_mailfilter_who',
222 iconCls
: 'fa fa-envelope-o',
223 xtype
: 'proxmoxWindowEdit',
225 subject
: gettext("E-Mail"),
232 fieldLabel
: gettext("E-Mail"),
237 onlineHelp
: 'pmg_mailfilter_who',
238 iconCls
: 'fa fa-globe',
239 xtype
: 'proxmoxWindowEdit',
241 subject
: gettext("Domain"),
247 fieldLabel
: gettext("Domain"),
252 onlineHelp
: 'pmg_mailfilter_who',
253 iconCls
: 'fa fa-globe',
254 xtype
: 'proxmoxWindowEdit',
255 subdir
: 'receiver_domain',
256 subject
: gettext("Domain"),
263 fieldLabel
: gettext("Domain"),
268 onlineHelp
: 'pmg_mailfilter_who',
269 iconCls
: 'fa fa-globe',
270 xtype
: 'proxmoxWindowEdit',
272 subject
: gettext("IP Address"),
278 fieldLabel
: gettext("IP Address"),
283 onlineHelp
: 'pmg_mailfilter_who',
284 iconCls
: 'fa fa-globe',
285 xtype
: 'proxmoxWindowEdit',
287 subject
: gettext("IP Network"),
293 fieldLabel
: gettext("IP Network"),
298 onlineHelp
: 'pmg_mailfilter_when',
299 iconCls
: 'fa fa-clock-o',
300 xtype
: 'proxmoxWindowEdit',
302 subject
: gettext("TimeFrame"),
308 fieldLabel
: gettext("Start Time"),
314 fieldLabel
: gettext("End Time"),
319 onlineHelp
: 'pmg_mailfilter_what',
320 iconCls
: 'fa fa-bullhorn',
321 xtype
: 'proxmoxWindowEdit',
322 subdir
: 'spamfilter',
323 subject
: gettext('Spam Filter'),
326 xtype
: 'proxmoxintegerfield',
330 fieldLabel
: gettext('Level'),
335 onlineHelp
: 'pmg_mailfilter_what',
336 iconCls
: 'fa fa-bug',
337 xtype
: 'proxmoxWindowEdit',
338 subdir
: 'virusfilter',
339 subject
: gettext('Virus Filter'),
341 // there are no parameters to give, so we simply submit it
343 show: function(win
) {
349 onlineHelp
: 'pmg_mailfilter_regex',
350 iconCls
: 'fa fa-code',
351 xtype
: 'proxmoxWindowEdit',
352 subdir
: 'matchfield',
353 subject
: gettext('Match Field'),
360 fieldLabel
: gettext('Field'),
367 fieldLabel
: gettext('Value'),
370 xtype
: 'pmgRegexTester',
371 fieldLabel
: gettext('Test String'),
372 regexFieldReference
: 'value',
377 onlineHelp
: 'pmg_mailfilter_what',
378 iconCls
: 'fa fa-file-image-o',
379 xtype
: 'proxmoxWindowEdit',
380 subdir
: 'contenttype',
382 subject
: gettext('Content Type Filter'),
386 displayField
: 'text',
387 valueField
: 'mimetype',
395 url
: '/api2/json/config/mimetypes',
398 fieldLabel
: gettext('Content Type'),
400 matchFieldWidth
: false,
402 change: function(cb
, value
) {
404 me
.up().down('displayfield').setValue(value
);
409 xtype
: 'displayfield',
410 fieldLabel
: gettext('Value'),
417 onlineHelp
: 'pmg_mailfilter_regex',
418 iconCls
: 'fa fa-file-o',
419 xtype
: 'proxmoxWindowEdit',
420 subdir
: 'filenamefilter',
422 subject
: gettext('Match Filename'),
427 reference
: 'filename',
428 fieldLabel
: gettext('Filename'),
432 xtype
: 'pmgRegexTester',
433 fieldLabel
: gettext('Test String'),
435 regexFieldReference
: 'filename',
440 onlineHelp
: 'pmg_mailfilter_what',
441 iconCls
: 'fa fa-file-archive-o',
442 xtype
: 'proxmoxWindowEdit',
443 subdir
: 'archivefilter',
445 subject
: gettext('Archive Filter'),
449 displayField
: 'text',
450 valueField
: 'mimetype',
458 url
: '/api2/json/config/mimetypes',
461 fieldLabel
: gettext('Content Type'),
463 matchFieldWidth
: false,
465 change: function(cb
, value
) {
467 me
.up().down('displayfield').setValue(value
);
472 xtype
: 'displayfield',
473 fieldLabel
: gettext('Value'),
480 onlineHelp
: 'pmg_mailfilter_regex',
481 iconCls
: 'fa fa-file-archive-o',
482 xtype
: 'proxmoxWindowEdit',
483 subdir
: 'archivefilenamefilter',
485 subject
: gettext('Match Archive Filename'),
490 reference
: 'filename',
491 fieldLabel
: gettext('Filename'),
495 xtype
: 'pmgRegexTester',
496 fieldLabel
: gettext('Test String'),
498 regexFieldReference
: 'filename',
503 onlineHelp
: 'pmg_mailfilter_action',
504 xtype
: 'proxmoxWindowEdit',
505 subdir
: 'notification',
506 subject
: gettext('Notification'),
513 fieldLabel
: gettext('Name'),
516 xtype
: 'textareafield',
518 fieldLabel
: gettext("Comment"),
525 fieldLabel
: gettext('Receiver'),
531 value
: 'Notification: __SUBJECT__',
532 fieldLabel
: gettext('Subject'),
541 "Proxmox Notifcation:\n\n" +
542 "Sender: __SENDER__\n" +
543 "Receiver: __RECEIVERS__\n" +
544 "Targets: __TARGETS__\n\n" +
545 "Subject: __SUBJECT__\n\n" +
546 "Matching Rule: __RULE__\n\n" +
547 "__RULE_INFO__\n\n" +
550 fieldLabel
: gettext('Body'),
553 xtype
: 'proxmoxcheckbox',
555 fieldLabel
: gettext("Attach orig. Mail"),
560 onlineHelp
: 'pmg_mailfilter_action',
561 xtype
: 'proxmoxWindowEdit',
563 subject
: gettext('Header Attribute'),
570 fieldLabel
: gettext('Name'),
573 xtype
: 'textareafield',
575 fieldLabel
: gettext("Comment"),
581 fieldLabel
: gettext('Field'),
588 fieldLabel
: gettext('Value'),
593 onlineHelp
: 'pmg_mailfilter_action',
594 xtype
: 'proxmoxWindowEdit',
596 subject
: gettext('BCC'),
603 fieldLabel
: gettext('Name'),
606 xtype
: 'textareafield',
608 fieldLabel
: gettext("Comment"),
614 fieldLabel
: gettext("Target"),
617 xtype
: 'proxmoxcheckbox',
620 boxLabel
: gettext("Send Original Mail"),
626 onlineHelp
: 'pmg_mailfilter_action',
627 xtype
: 'proxmoxWindowEdit',
628 subdir
: 'removeattachments',
629 subject
: gettext('Remove Attachments'),
636 fieldLabel
: gettext('Name'),
639 xtype
: 'textareafield',
641 fieldLabel
: gettext("Comment"),
644 xtype
: 'textareafield',
648 fieldLabel
: gettext("Text Replacement"),
651 xtype
: 'proxmoxcheckbox',
654 boxLabel
: gettext("Remove all Attachments"),
657 xtype
: 'proxmoxcheckbox',
660 boxLabel
: gettext("Copy original mail to Attachment Quarantine"),
665 onlineHelp
: 'pmg_mailfilter_action',
666 xtype
: 'proxmoxWindowEdit',
667 subdir
: 'disclaimer',
668 subject
: gettext('Disclaimer'),
675 fieldLabel
: gettext('Name'),
678 xtype
: 'textareafield',
680 fieldLabel
: gettext("Comment"),
683 xtype
: 'textareafield',
687 fieldLabel
: gettext("Disclaimer"),
693 updateLoginData: function(data
) {
694 Proxmox
.CSRFPreventionToken
= data
.CSRFPreventionToken
;
695 Proxmox
.UserName
= data
.username
;
696 Ext
.util
.Cookies
.set('PMGAuthCookie', data
.ticket
, null, '/', null, true);
699 quarantineActionExtracted
: false,
701 extractQuarantineAction: function() {
702 if (PMG
.Utils
.quarantineActionExtracted
) {
706 PMG
.Utils
.quarantineActionExtracted
= true;
708 let qs
= Ext
.Object
.fromQueryString(location
.search
);
710 let cselect
= qs
.cselect
;
711 let action
= qs
.action
;
712 let dateString
= qs
.date
;
715 let date
= new Date(dateString
).getTime()/1000;
717 // set from date for QuarantineList
718 PMG
.QuarantineList
.from = date
;
726 var newsearch
= Ext
.Object
.toQueryString(qs
);
728 var newurl
= location
.protocol
+ "//" + location
.host
+ location
.pathname
;
729 if (newsearch
) { newurl
+= '?' + newsearch
; }
730 newurl
+= location
.hash
;
732 if (window
.history
) {
733 window
.history
.pushState({ path
: newurl
}, '', newurl
);
736 if (action
|| cselect
) {
745 doQuarantineAction: function(action
, id
, callback
) {
746 Proxmox
.Utils
.API2Request({
747 url
: '/quarantine/content/',
753 failure: function(response
, opts
) {
754 Ext
.Msg
.alert(gettext('Error'), response
.htmlStatus
);
756 success: function(response
, opts
) {
757 let count
= id
.split(';').length
;
759 ? gettext("Action '{0}' for '{1}' items successful")
760 : gettext("Action '{0}' successful")
762 let message
= Ext
.String
.format(fmt
, action
, count
);
763 let title
= Ext
.String
.format("{0} successful", Ext
.String
.capitalize(action
));
770 slideBackDuration
: 250,
771 slideBackAnimation
: 'easeOut',
772 iconCls
: 'fa fa-check',
777 if (Ext
.isFunction(callback
)) {
784 render_filetype: function(value
) {
785 let iconCls
= 'fa-file-o';
786 let text
= Proxmox
.Utils
.unknownText
;
789 return `<i class='fa ${iconCls}'></i> ${text}`;
792 text
= value
.toString().toLowerCase();
793 const type
= text
.split('/')[0];
800 iconCls
= `fa-file-${type}-o`;
802 case 'application': {
803 const subtypes
= ['excel', 'pdf', 'word', 'powerpoint'];
804 let found
= subtypes
.find(st
=> text
.includes(st
));
805 if (found
!== undefined) {
806 iconCls
= `fa-file-${found}-o`;
813 return `<i class='fa ${iconCls}'></i> ${text}`;
816 addresses_subject_renderer: function(value
, metaData
, rec
, render_receiver
) {
817 let subject
= Ext
.htmlEncode(value
);
818 let from = Ext
.htmlEncode(rec
.data
.from);
819 let sender
= Ext
.htmlEncode(rec
.data
.sender
);
821 from = Ext
.String
.format(gettext("{0} on behalf of {1}"),
824 let ret
= '<small>' + from;
825 if (render_receiver
) {
826 ret
+= '<br>To: ' + Ext
.htmlEncode(rec
.data
.receiver
);
828 ret
+= '</small><br>' + subject
;
832 sender_renderer: function(value
, metaData
, rec
) {
833 return PMG
.Utils
.addresses_subject_renderer(value
, metaData
, rec
, false);
836 sender_receiver_renderer: function(value
, metaData
, rec
) {
837 return PMG
.Utils
.addresses_subject_renderer(value
, metaData
, rec
, true);
840 constructor: function() {
843 // do whatever you want here
844 Proxmox
.Utils
.override_task_descriptions({
845 applycustomscores
: ['', gettext('Apply custom SpamAssassin scores')],
846 avupdate
: ['', gettext('ClamAV update')],
847 backup
: ['', gettext('Backup')],
848 clustercreate
: ['', gettext('Create Cluster')],
849 clusterjoin
: ['', gettext('Join Cluster')],
850 restore
: ['', gettext('Restore')],
851 saupdate
: ['', gettext('SpamAssassin update')],
856 Ext
.define('PMG.Async', {
859 // Returns a Promise which executes a quarantine action when awaited.
860 // Shows a Toast message box once completed, if batchNumber and batchTotal
861 // are set, they will be included into the title of that toast.
862 doQAction: function(action
, ids
, batchNumber
, batchTotal
) {
863 if (!Ext
.isArray(ids
)) {
866 return Proxmox
.Async
.api2({
867 url
: '/quarantine/content/',
875 let count
= ids
.length
;
877 ? gettext("Action '{0}' for '{1}' items successful")
878 : gettext("Action '{0}' successful")
880 let message
= Ext
.String
.format(fmt
, action
, count
);
881 let titleFmt
= batchNumber
!== undefined && batchTotal
> 1
882 ? gettext("{0} ({1}/{2}) successful")
883 : gettext("{0} successful")
885 let title
= Ext
.String
.format(
887 Ext
.String
.capitalize(action
),
897 slideBackDuration
: 250,
898 slideBackAnimation
: 'easeOut',
899 iconCls
: 'fa fa-check',
904 response
=> Proxmox
.Utils
.alertResponseFailure(response
),