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"),
690 xtype
: 'proxmoxKVComboBox',
692 fieldLabel
: gettext("Position"),
696 ['end', gettext('End')],
697 ['start', gettext('Start')],
701 xtype
: 'proxmoxcheckbox',
702 name
: 'add-separator',
703 fieldLabel
: gettext("Add Separator"),
711 updateLoginData: function(data
) {
712 Proxmox
.CSRFPreventionToken
= data
.CSRFPreventionToken
;
713 Proxmox
.UserName
= data
.username
;
714 Ext
.util
.Cookies
.set('PMGAuthCookie', data
.ticket
, null, '/', null, true);
717 quarantineActionExtracted
: false,
719 extractQuarantineAction: function() {
720 if (PMG
.Utils
.quarantineActionExtracted
) {
724 PMG
.Utils
.quarantineActionExtracted
= true;
726 let qs
= Ext
.Object
.fromQueryString(location
.search
);
728 let cselect
= qs
.cselect
;
729 let action
= qs
.action
;
730 let dateString
= qs
.date
;
733 let date
= new Date(dateString
).getTime()/1000;
735 // set from date for QuarantineList
736 PMG
.QuarantineList
.from = date
;
744 var newsearch
= Ext
.Object
.toQueryString(qs
);
746 var newurl
= location
.protocol
+ "//" + location
.host
+ location
.pathname
;
747 if (newsearch
) { newurl
+= '?' + newsearch
; }
748 newurl
+= location
.hash
;
750 if (window
.history
) {
751 window
.history
.pushState({ path
: newurl
}, '', newurl
);
754 if (action
|| cselect
) {
763 doQuarantineAction: function(action
, id
, callback
) {
764 Proxmox
.Utils
.API2Request({
765 url
: '/quarantine/content/',
771 failure: function(response
, opts
) {
772 Ext
.Msg
.alert(gettext('Error'), response
.htmlStatus
);
774 success: function(response
, opts
) {
775 let count
= id
.split(';').length
;
777 ? gettext("Action '{0}' for '{1}' items successful")
778 : gettext("Action '{0}' successful")
780 let message
= Ext
.String
.format(fmt
, action
, count
);
781 let title
= Ext
.String
.format("{0} successful", Ext
.String
.capitalize(action
));
788 slideBackDuration
: 250,
789 slideBackAnimation
: 'easeOut',
790 iconCls
: 'fa fa-check',
795 if (Ext
.isFunction(callback
)) {
802 render_filetype: function(value
) {
803 let iconCls
= 'fa-file-o';
804 let text
= Proxmox
.Utils
.unknownText
;
807 return `<i class='fa ${iconCls}'></i> ${text}`;
810 text
= value
.toString().toLowerCase();
811 const type
= text
.split('/')[0];
818 iconCls
= `fa-file-${type}-o`;
820 case 'application': {
821 const subtypes
= ['excel', 'pdf', 'word', 'powerpoint'];
822 let found
= subtypes
.find(st
=> text
.includes(st
));
823 if (found
!== undefined) {
824 iconCls
= `fa-file-${found}-o`;
831 return `<i class='fa ${iconCls}'></i> ${text}`;
834 render_envelope: function(value
, { data
}, render_receiver
) {
835 let subject
= Ext
.htmlEncode(value
);
836 let from = Ext
.htmlEncode(data
.from);
838 let sender
= Ext
.htmlEncode(data
.sender
);
839 from = Ext
.String
.format(gettext("{0} on behalf of {1}"), sender
, from);
841 if (render_receiver
) {
842 let receiver
= Ext
.htmlEncode(data
.receiver
);
843 return `<small>${from}<br>To: ${receiver}</small><br>${subject}`;
845 return `<small>${from}</small><br>${subject}`;
848 render_sender
: (value
, _meta
, rec
) => PMG
.Utils
.render_envelope(value
, rec
, false),
849 render_sender_receiver
: (value
, _meta
, rec
) => PMG
.Utils
.render_envelope(value
, rec
, true),
851 constructor: function() {
854 // do whatever you want here
855 Proxmox
.Utils
.override_task_descriptions({
856 applycustomscores
: ['', gettext('Apply custom SpamAssassin scores')],
857 avupdate
: ['', gettext('ClamAV update')],
858 backup
: ['', gettext('Backup')],
859 clustercreate
: ['', gettext('Create Cluster')],
860 clusterjoin
: ['', gettext('Join Cluster')],
861 restore
: ['', gettext('Restore')],
862 saupdate
: ['', gettext('SpamAssassin update')],
867 Ext
.define('PMG.Async', {
870 // Returns a Promise which executes a quarantine action when awaited.
871 // Shows a Toast message box once completed, if batchNumber and batchTotal
872 // are set, they will be included into the title of that toast.
873 doQAction: function(action
, ids
, batchNumber
, batchTotal
) {
874 if (!Ext
.isArray(ids
)) {
877 return Proxmox
.Async
.api2({
878 url
: '/quarantine/content/',
886 let count
= ids
.length
;
888 ? gettext("Action '{0}' for '{1}' items successful")
889 : gettext("Action '{0}' successful")
891 let message
= Ext
.String
.format(fmt
, action
, count
);
892 let titleFmt
= batchNumber
!== undefined && batchTotal
> 1
893 ? gettext("{0} ({1}/{2}) successful")
894 : gettext("{0} successful")
896 let title
= Ext
.String
.format(
898 Ext
.String
.capitalize(action
),
908 slideBackDuration
: 250,
909 slideBackAnimation
: 'easeOut',
910 iconCls
: 'fa fa-check',
915 response
=> Proxmox
.Utils
.alertResponseFailure(response
),
921 Ext
.apply(Ext
.form
.field
.VTypes
, {
922 // matches the pmg-email-address in pmg-api
923 PMGMail: function(v
) {
924 return (/^[^\s\\@]+@[^\s/\\@]+$/).test(v
);
926 PMGMailText
: gettext('Example') + ": user@example.com",