[pmg-devel] [PATCH pmg-gui 2/2] Add DKIM Tab to MailProxy configuration

Stoiko Ivanov s.ivanov at proxmox.com
Mon Oct 7 21:28:59 CEST 2019


This adds another panel to the MailProxy configuration for DKIM-Settings.
Additionally the index-template now includes the css-file from
proxmox-widget-toolkit (for the pmx-hint user-class), needed in the
Settings-panel.

The Panel consists of 2 Grids:
* DKIM Settings
* DKIM Domains

DKIMDomains is a list of domains, currently like RelayDomains (hence the
code-reuse).

The DKIM settings grid binds to the dkim-related settings in pmg.conf, but the
edit-window for the selector uses the /config/dkim/selector route in the
PMG-API.

Additionally 2 checks for invalid configurations are excluded (you cannot
enable DKIM-Signing without creating a private key first)

The warnings were inspired by PVE's handling of EFIDisks and BIOS.

Finally the 'View DNS Record' button displays the DKIM TXT record for the
current key in the same format that opendkim-genkey writes it out.

Signed-off-by: Stoiko Ivanov <s.ivanov at proxmox.com>
---
 js/DKIMSettings.js           | 207 +++++++++++++++++++++++++++++++++++
 js/MailProxyConfiguration.js |   5 +
 js/MailProxyDKIMPanel.js     |  43 ++++++++
 js/Makefile                  |   2 +
 pmg-index.html.tt            |   1 +
 5 files changed, 258 insertions(+)
 create mode 100644 js/DKIMSettings.js
 create mode 100644 js/MailProxyDKIMPanel.js

diff --git a/js/DKIMSettings.js b/js/DKIMSettings.js
new file mode 100644
index 0000000..889c26e
--- /dev/null
+++ b/js/DKIMSettings.js
@@ -0,0 +1,207 @@
+Ext.define('PMG.DKIMEnableEdit', {
+    extend: 'Proxmox.window.Edit',
+    alias: ['widget.pmgDKIMEnableedit'],
+
+    initComponent: function() {
+	var me = this;
+	var SelectorHint = Ext.createWidget({
+	    xtype: 'displayfield',
+	    userCls: 'pmx-hint',
+	    value: 'You need to create a Selector before enabling DKIM Signing',
+	    hidden: true
+	});
+	var enableCB = Ext.createWidget({
+		xtype: 'proxmoxcheckbox',
+		name: 'dkim_sign',
+			uncheckedValue: 0,
+			defaultValue: 0,
+			checked: false,
+			deleteDefaultValue: false,
+		fieldLabel: me.subject,
+		labelWidth: Proxmox.Utils.compute_min_label_width(me.subject)
+	    });
+
+	var check_selector = function() {
+	    Proxmox.Utils.API2Request({
+		url : '/config/dkim/selector',
+		method : 'GET',
+		failure : function(response, opts) {
+		    Ext.Msg.alert(gettext('Error'), response.htmlStatus);
+		    SelectorHint.setVisible(true);
+		    enableCB.setDisabled(true);
+		},
+	    });
+	};
+	Ext.apply(me, {
+	    items: [
+	    enableCB,
+	    SelectorHint
+	    ],
+	    listeners: {
+		'show': check_selector,
+	    }
+	});
+	me.callParent();
+    }
+});
+
+Ext.define('PMG.SelectorViewer', {
+    extend: 'Proxmox.window.Edit',
+    alias: ['widget.pmgDKIMSelectorview'],
+
+    url: '/config/dkim/selector',
+    title: gettext('Selector'),
+
+    width: 800,
+    resizable: true,
+
+    items: [
+	{
+	    xtype: 'displayfield',
+	    fieldLabel: gettext('Selector'),
+	    name: 'selector'
+	},
+	{
+	    xtype: 'displayfield',
+	    fieldLabel: gettext('Key Size'),
+	    name: 'keysize'
+	},
+	{
+	    xtype: 'textarea',
+	    editable: false,
+	    grow: true,
+	    growMin: 150,
+	    growMax: 400,
+	    fieldLabel: gettext('DNS TXT Record'),
+	    name: 'record'
+	}
+    ],
+
+    initComponent: function() {
+	var me = this;
+	Proxmox.Utils.API2Request({
+	    url : '/config/dkim/selector',
+	    method : 'GET',
+	    failure : function(response, opts) {
+		Ext.Msg.alert(gettext('Error'), response.htmlStatus);
+		me.hide();
+	    },
+	});
+	me.callParent();
+
+	// hide OK/Reset button, because we just want to show data
+	me.down('toolbar[dock=bottom]').setVisible(false);
+    }
+});
+
+Ext.define('PMG.DKIMSettings', {
+    extend: 'Proxmox.grid.ObjectGrid',
+    alias: ['widget.pmgDKIM'],
+
+    monStoreErrors: true,
+
+    initComponent : function() {
+	var me = this;
+
+	me.rows = {};
+	var selector_text = gettext('Selector');
+	me.rows.dkim_selector = {
+	    required: true,
+	    defaultValue: 'pmg',
+	    header: selector_text,
+	    editor: {
+		xtype: 'proxmoxWindowEdit',
+		subject: selector_text,
+		isCreate: true,
+		method: 'POST',
+		url: '/config/dkim/selector',
+		items: [
+		    {
+			xtype: 'displayfield',
+			name: 'warning',
+			userCls: 'pmx-hint',
+			value: gettext('Warning: You need to update the _domainkey DNS records of all signed domains!'),
+			hidden: false
+		    },
+		    {
+			xtype: 'proxmoxtextfield',
+			fieldLabel: selector_text,
+			name: 'selector',
+			allowBlank: false,
+			deleteEmpty: false,
+			required: true
+		    },
+		    {
+			xtype: 'proxmoxKVComboBox',
+			fieldLabel: gettext('Key Size'),
+			name: 'keysize',
+			value: '2048',
+			allowBlank: false,
+			deleteEmpty: false,
+			required: true,
+			comboItems: [
+			    ['1024', '1024'],
+			    ['2048', '2048'],
+			    ['4096', '4096']
+			]
+		    }
+		]
+	    }
+	};
+
+	var enable_sign_text = gettext('Sign Outgoing Mails');
+	me.rows.dkim_sign = {
+	    required: true,
+	    defaultValue: 0,
+	    header: enable_sign_text,
+	    renderer: Proxmox.Utils.format_boolean,
+	    editor: {
+		xtype: 'pmgDKIMEnableedit',
+		subject: enable_sign_text,
+	    }
+	};
+
+	me.add_boolean_row('dkim_sign_all_mail', gettext('Ignore Sender Domain'));
+
+	var baseurl = '/config/admin';
+
+	me.selModel = Ext.create('Ext.selection.RowModel', {});
+
+	Ext.apply(me, {
+	    tbar: [{
+		text: gettext('View DNS Record'),
+		xtype: 'proxmoxButton',
+		disabled: true,
+		handler: function() {
+		    var win = Ext.create('PMG.SelectorViewer', {});
+		    win.load();
+		    win.show();
+		},
+		selModel: me.selModel,
+	    },
+	    {
+		text: gettext('Edit'),
+		xtype: 'proxmoxButton',
+		disabled: true,
+		handler: function() { me.run_editor(); },
+		selModel: me.selModel
+	    }],
+	    url: '/api2/json' + baseurl,
+	    editorConfig: {
+		url: '/api2/extjs' + baseurl
+	    },
+	    interval: 5000,
+	    cwidth1: 200,
+	    listeners: {
+		itemdblclick: me.run_editor
+	    }
+	});
+
+	me.callParent();
+
+	me.on('activate', me.rstore.startUpdate);
+	me.on('destroy', me.rstore.stopUpdate);
+	me.on('deactivate', me.rstore.stopUpdate);
+    }
+});
+
diff --git a/js/MailProxyConfiguration.js b/js/MailProxyConfiguration.js
index 6902cb4..1bacb48 100644
--- a/js/MailProxyConfiguration.js
+++ b/js/MailProxyConfiguration.js
@@ -44,6 +44,11 @@ Ext.define('PMG.MailProxyConfiguration', {
             title: gettext('TLS'),
 	    xtype: 'pmgMailProxyTLSPanel'
 	},
+	{
+	    itemId: 'dkim',
+            title: gettext('DKIM'),
+	    xtype: 'pmgMailProxyDKIMPanel'
+	},
 	{
 	    itemId: 'whitelist',
 	    title: gettext('Whitelist'),
diff --git a/js/MailProxyDKIMPanel.js b/js/MailProxyDKIMPanel.js
new file mode 100644
index 0000000..c69f2e2
--- /dev/null
+++ b/js/MailProxyDKIMPanel.js
@@ -0,0 +1,43 @@
+Ext.define('PMG.DKIMDomains', {
+    extend: 'PMG.RelayDomains',
+    alias: ['widget.pmgDKIMDomains'],
+
+    baseurl: '/config/dkim/domains',
+    domain_desc: gettext('Sign Domain'),
+});
+
+Ext.define('PMG.MailProxyDKIMPanel', {
+    extend: 'Ext.panel.Panel',
+    alias: 'widget.pmgMailProxyDKIMPanel',
+
+    layout: {
+	type: 'vbox',
+	align: 'stretch'
+    },
+
+    bodyPadding: '0 0 10 0',
+    defaults: {
+	collapsible: true,
+	animCollapse: false,
+	margin: '10 10 0 10'
+    },
+
+    initComponent: function() {
+	var me = this;
+
+	var DKIMSettings = Ext.create('PMG.DKIMSettings', {
+	    title: gettext('Settings')
+	});
+
+	var DKIMDomains = Ext.create('PMG.DKIMDomains', {
+	    title: gettext('Sign Domains')
+	});
+
+	me.items = [ DKIMSettings, DKIMDomains ];
+
+	me.callParent();
+
+	DKIMSettings.relayEvents(me, ['activate', 'deactivate', 'destroy']);
+	DKIMDomains.relayEvents(me, ['activate', 'deactivate', 'destroy']);
+    }
+});
diff --git a/js/Makefile b/js/Makefile
index 6f4d449..d245f68 100644
--- a/js/Makefile
+++ b/js/Makefile
@@ -46,6 +46,8 @@ JSSRC=							\
 	Transport.js					\
 	MyNetworks.js					\
 	RelayDomains.js					\
+	DKIMSettings.js					\
+	MailProxyDKIMPanel.js				\
 	MailProxyConfiguration.js			\
 	SpamDetectorLanguages.js			\
 	SpamDetectorOptions.js				\
diff --git a/pmg-index.html.tt b/pmg-index.html.tt
index 1f3bc65..20fa454 100644
--- a/pmg-index.html.tt
+++ b/pmg-index.html.tt
@@ -12,6 +12,7 @@
     <link rel="stylesheet" type="text/css" href="/pve2/ext6/crisp/resources/charts-all.css" />
     <link rel="stylesheet" type="text/css" href="/fontawesome/css/font-awesome.css" />
     <link rel="stylesheet" type="text/css" href="/pve2/css/ext6-pmg.css" />
+    <link rel="stylesheet" type="text/css" href="/pwt/css/ext6-pmx.css" />
     [% IF langfile %]
     <script type='text/javascript' src='/pve2/locale/pmg-lang-[% lang %].js'></script>
     [% ELSE %]
-- 
2.20.1




More information about the pmg-devel mailing list