From 05f6a55a0b4e16e678e20c3b66588122d4c5669e Mon Sep 17 00:00:00 2001
From: chaptergy <26956711+chaptergy@users.noreply.github.com>
Date: Tue, 6 Oct 2020 14:49:02 +0200
Subject: [PATCH] Adds frontend improvements and fixes
---
frontend/js/app/api.js | 10 ++---
frontend/js/app/nginx/certificates/form.ejs | 18 +++++++--
frontend/js/app/nginx/certificates/form.js | 40 ++++++++++++++-----
.../js/app/nginx/certificates/list/item.ejs | 2 +-
frontend/js/app/nginx/dead/form.ejs | 5 +++
frontend/js/app/nginx/dead/form.js | 28 +++++++++++--
frontend/js/app/nginx/proxy/form.ejs | 5 +++
frontend/js/app/nginx/proxy/form.js | 28 +++++++++++--
frontend/js/app/nginx/redirection/form.ejs | 5 +++
frontend/js/app/nginx/redirection/form.js | 31 +++++++++++---
frontend/js/i18n/messages.json | 4 +-
utils/certbot-dns-plugins.js | 8 +++-
12 files changed, 147 insertions(+), 37 deletions(-)
diff --git a/frontend/js/app/api.js b/frontend/js/app/api.js
index 74356f0..1d7b358 100644
--- a/frontend/js/app/api.js
+++ b/frontend/js/app/api.js
@@ -53,7 +53,7 @@ function fetch(verb, path, data, options) {
contentType: options.contentType || 'application/json; charset=UTF-8',
processData: options.processData || true,
crossDomain: true,
- timeout: options.timeout ? options.timeout : 30000,
+ timeout: options.timeout ? options.timeout : 180000,
xhrFields: {
withCredentials: true
},
@@ -586,8 +586,8 @@ module.exports = {
/**
* @param {Object} data
*/
- create: function (data) {
- return fetch('post', 'nginx/certificates', data);
+ create: function (data, timeout = 180000) {
+ return fetch('post', 'nginx/certificates', data, {timeout});
},
/**
@@ -630,8 +630,8 @@ module.exports = {
* @param {Number} id
* @returns {Promise}
*/
- renew: function (id) {
- return fetch('post', 'nginx/certificates/' + id + '/renew');
+ renew: function (id, timeout = 180000) {
+ return fetch('post', 'nginx/certificates/' + id + '/renew', undefined, {timeout});
}
}
},
diff --git a/frontend/js/app/nginx/certificates/form.ejs b/frontend/js/app/nginx/certificates/form.ejs
index a3d6c07..4c7a596 100644
--- a/frontend/js/app/nginx/certificates/form.ejs
+++ b/frontend/js/app/nginx/certificates/form.ejs
@@ -1,12 +1,20 @@
-
- <%- i18n('ssl', provider) %><% if (meta.dns_provider) { %> - <% dns_providers[meta.dns_provider].display_name } %>
+ <%- i18n('ssl', provider) %><% if (meta.dns_provider) { %> - <%- dns_providers[meta.dns_provider].display_name %><% } %>
<%- formatDbDate(expires_on, 'Do MMMM YYYY, h:mm a') %>
diff --git a/frontend/js/app/nginx/dead/form.ejs b/frontend/js/app/nginx/dead/form.ejs
index 1d01e09..253c4b6 100644
--- a/frontend/js/app/nginx/dead/form.ejs
+++ b/frontend/js/app/nginx/dead/form.ejs
@@ -4,6 +4,7 @@
+
+
+ <%= i18n('ssl', 'stored-as-plaintext-info') %>
+
diff --git a/frontend/js/app/nginx/dead/form.js b/frontend/js/app/nginx/dead/form.js
index 393788d..0df24f7 100644
--- a/frontend/js/app/nginx/dead/form.js
+++ b/frontend/js/app/nginx/dead/form.js
@@ -20,6 +20,7 @@ module.exports = Mn.View.extend({
buttons: '.modal-footer button',
cancel: 'button.cancel',
save: 'button.save',
+ le_error_info: '#le-error-info',
certificate_select: 'select[name="certificate_id"]',
ssl_forced: 'input[name="ssl_forced"]',
hsts_enabled: 'input[name="hsts_enabled"]',
@@ -116,6 +117,7 @@ module.exports = Mn.View.extend({
'click @ui.save': function (e) {
e.preventDefault();
+ this.ui.le_error_info.hide();
if (!this.ui.form[0].checkValidity()) {
$(' ').hide().appendTo(this.ui.form).click().remove();
@@ -130,7 +132,18 @@ module.exports = Mn.View.extend({
data.hsts_subdomains = !!data.hsts_subdomains;
data.http2_support = !!data.http2_support;
data.ssl_forced = !!data.ssl_forced;
- data.meta.dns_challenge = !!data.meta.dns_challenge;
+
+ if (typeof data.meta === 'undefined') data.meta = {};
+ data.meta.letsencrypt_agree = data.meta.letsencrypt_agree == 1;
+ data.meta.dns_challenge = data.meta.dns_challenge == 1;
+
+ if(!data.meta.dns_challenge){
+ data.meta.dns_provider = undefined;
+ data.meta.dns_provider_credentials = undefined;
+ data.meta.propagation_seconds = undefined;
+ } else {
+ if(data.meta.propagation_seconds === '') data.meta.propagation_seconds = undefined;
+ }
if (typeof data.domain_names === 'string' && data.domain_names) {
data.domain_names = data.domain_names.split(',');
@@ -151,8 +164,6 @@ module.exports = Mn.View.extend({
alert(i18n('ssl', 'no-wildcard-without-dns'));
return;
}
-
- data.meta.letsencrypt_agree = data.meta.letsencrypt_agree === '1';
} else {
data.certificate_id = parseInt(data.certificate_id, 10);
}
@@ -181,7 +192,15 @@ module.exports = Mn.View.extend({
});
})
.catch(err => {
- alert(err.message);
+ let more_info = '';
+ if(err.code === 500){
+ try{
+ more_info = JSON.parse(err.debug).debug.stack.join("\n");
+ } catch(e) {}
+ }
+ this.ui.le_error_info[0].innerHTML = `${err.message}${more_info !== '' ? `${more_info} `:''}`;
+ this.ui.le_error_info.show();
+ this.ui.le_error_info[0].scrollIntoView();
this.ui.buttons.prop('disabled', false).removeClass('btn-disabled');
this.ui.save.removeClass('btn-loading');
});
@@ -225,6 +244,7 @@ module.exports = Mn.View.extend({
});
// Certificates
+ this.ui.le_error_info.hide();
this.ui.dns_challenge_content.hide();
this.ui.credentials_file_content.hide();
this.ui.letsencrypt.hide();
diff --git a/frontend/js/app/nginx/proxy/form.ejs b/frontend/js/app/nginx/proxy/form.ejs
index 34f319c..1a49830 100644
--- a/frontend/js/app/nginx/proxy/form.ejs
+++ b/frontend/js/app/nginx/proxy/form.ejs
@@ -4,6 +4,7 @@
+
+
+ <%= i18n('ssl', 'stored-as-plaintext-info') %>
+
diff --git a/frontend/js/app/nginx/proxy/form.js b/frontend/js/app/nginx/proxy/form.js
index 4211050..3c17225 100644
--- a/frontend/js/app/nginx/proxy/form.js
+++ b/frontend/js/app/nginx/proxy/form.js
@@ -29,6 +29,7 @@ module.exports = Mn.View.extend({
save: 'button.save',
add_location_btn: 'button.add_location',
locations_container: '.locations_container',
+ le_error_info: '#le-error-info',
certificate_select: 'select[name="certificate_id"]',
access_list_select: 'select[name="access_list_id"]',
ssl_forced: 'input[name="ssl_forced"]',
@@ -137,6 +138,7 @@ module.exports = Mn.View.extend({
'click @ui.save': function (e) {
e.preventDefault();
+ this.ui.le_error_info.hide();
if (!this.ui.form[0].checkValidity()) {
$(' ').hide().appendTo(this.ui.form).click().remove();
@@ -165,7 +167,18 @@ module.exports = Mn.View.extend({
data.hsts_enabled = !!data.hsts_enabled;
data.hsts_subdomains = !!data.hsts_subdomains;
data.ssl_forced = !!data.ssl_forced;
- data.meta.dns_challenge = !!data.meta.dns_challenge;
+
+ if (typeof data.meta === 'undefined') data.meta = {};
+ data.meta.letsencrypt_agree = data.meta.letsencrypt_agree == 1;
+ data.meta.dns_challenge = data.meta.dns_challenge == 1;
+
+ if(!data.meta.dns_challenge){
+ data.meta.dns_provider = undefined;
+ data.meta.dns_provider_credentials = undefined;
+ data.meta.propagation_seconds = undefined;
+ } else {
+ if(data.meta.propagation_seconds === '') data.meta.propagation_seconds = undefined;
+ }
if (typeof data.domain_names === 'string' && data.domain_names) {
data.domain_names = data.domain_names.split(',');
@@ -186,8 +199,6 @@ module.exports = Mn.View.extend({
alert(i18n('ssl', 'no-wildcard-without-dns'));
return;
}
-
- data.meta.letsencrypt_agree = data.meta.letsencrypt_agree === '1';
} else {
data.certificate_id = parseInt(data.certificate_id, 10);
}
@@ -216,7 +227,15 @@ module.exports = Mn.View.extend({
});
})
.catch(err => {
- alert(err.message);
+ let more_info = '';
+ if(err.code === 500){
+ try{
+ more_info = JSON.parse(err.debug).debug.stack.join("\n");
+ } catch(e) {}
+ }
+ this.ui.le_error_info[0].innerHTML = `${err.message}${more_info !== '' ? `${more_info} `:''}`;
+ this.ui.le_error_info.show();
+ this.ui.le_error_info[0].scrollIntoView();
this.ui.buttons.prop('disabled', false).removeClass('btn-disabled');
this.ui.save.removeClass('btn-loading');
});
@@ -293,6 +312,7 @@ module.exports = Mn.View.extend({
});
// Certificates
+ this.ui.le_error_info.hide();
this.ui.dns_challenge_content.hide();
this.ui.credentials_file_content.hide();
this.ui.letsencrypt.hide();
diff --git a/frontend/js/app/nginx/redirection/form.ejs b/frontend/js/app/nginx/redirection/form.ejs
index f4e4375..3247233 100644
--- a/frontend/js/app/nginx/redirection/form.ejs
+++ b/frontend/js/app/nginx/redirection/form.ejs
@@ -4,6 +4,7 @@
+
+
+ <%= i18n('ssl', 'stored-as-plaintext-info') %>
+
diff --git a/frontend/js/app/nginx/redirection/form.js b/frontend/js/app/nginx/redirection/form.js
index c1c6d9d..5ca3b8d 100644
--- a/frontend/js/app/nginx/redirection/form.js
+++ b/frontend/js/app/nginx/redirection/form.js
@@ -21,6 +21,7 @@ module.exports = Mn.View.extend({
buttons: '.modal-footer button',
cancel: 'button.cancel',
save: 'button.save',
+ le_error_info: '#le-error-info',
certificate_select: 'select[name="certificate_id"]',
ssl_forced: 'input[name="ssl_forced"]',
hsts_enabled: 'input[name="hsts_enabled"]',
@@ -116,6 +117,7 @@ module.exports = Mn.View.extend({
'click @ui.save': function (e) {
e.preventDefault();
+ this.ui.le_error_info.hide();
if (!this.ui.form[0].checkValidity()) {
$(' ').hide().appendTo(this.ui.form).click().remove();
@@ -132,7 +134,18 @@ module.exports = Mn.View.extend({
data.hsts_enabled = !!data.hsts_enabled;
data.hsts_subdomains = !!data.hsts_subdomains;
data.ssl_forced = !!data.ssl_forced;
- data.meta.dns_challenge = !!data.meta.dns_challenge;
+
+ if (typeof data.meta === 'undefined') data.meta = {};
+ data.meta.letsencrypt_agree = data.meta.letsencrypt_agree == 1;
+ data.meta.dns_challenge = data.meta.dns_challenge == 1;
+
+ if(!data.meta.dns_challenge){
+ data.meta.dns_provider = undefined;
+ data.meta.dns_provider_credentials = undefined;
+ data.meta.propagation_seconds = undefined;
+ } else {
+ if(data.meta.propagation_seconds === '') data.meta.propagation_seconds = undefined;
+ }
if (typeof data.domain_names === 'string' && data.domain_names) {
data.domain_names = data.domain_names.split(',');
@@ -152,10 +165,7 @@ module.exports = Mn.View.extend({
if (domain_err) {
alert(i18n('ssl', 'no-wildcard-without-dns'));
return;
- }
-
- data.meta.cloudflare_use = data.meta.cloudflare_use === '1';
- data.meta.letsencrypt_agree = data.meta.letsencrypt_agree === '1';
+ }
} else {
data.certificate_id = parseInt(data.certificate_id, 10);
}
@@ -184,7 +194,15 @@ module.exports = Mn.View.extend({
});
})
.catch(err => {
- alert(err.message);
+ let more_info = '';
+ if(err.code === 500){
+ try{
+ more_info = JSON.parse(err.debug).debug.stack.join("\n");
+ } catch(e) {}
+ }
+ this.ui.le_error_info[0].innerHTML = `${err.message}${more_info !== '' ? `${more_info} `:''}`;
+ this.ui.le_error_info.show();
+ this.ui.le_error_info[0].scrollIntoView();
this.ui.buttons.prop('disabled', false).removeClass('btn-disabled');
this.ui.save.removeClass('btn-loading');
});
@@ -228,6 +246,7 @@ module.exports = Mn.View.extend({
});
// Certificates
+ this.ui.le_error_info.hide();
this.ui.dns_challenge_content.hide();
this.ui.credentials_file_content.hide();
this.ui.letsencrypt.hide();
diff --git a/frontend/js/i18n/messages.json b/frontend/js/i18n/messages.json
index 8826afa..af3e8cb 100644
--- a/frontend/js/i18n/messages.json
+++ b/frontend/js/i18n/messages.json
@@ -109,8 +109,10 @@
"please-choose": "Please Choose...",
"credentials-file-content": "Credentials File Content",
"credentials-file-content-info": "This plugin requires a configuration file containing an API token or other credentials to your provider",
+ "stored-as-plaintext-info": "This data will be stored as plaintext in the database!",
"propagation-seconds": "Propagation Seconds",
- "propagation-seconds-info": "Leave empty to use the plugins default value. Number of seconds to wait for DNS propagation."
+ "propagation-seconds-info": "Leave empty to use the plugins default value. Number of seconds to wait for DNS propagation.",
+ "obtaining-certificate-info": "Obtaining certificate... This might take a few minutes."
},
"proxy-hosts": {
"title": "Proxy Hosts",
diff --git a/utils/certbot-dns-plugins.js b/utils/certbot-dns-plugins.js
index 4af678e..ef533c1 100644
--- a/utils/certbot-dns-plugins.js
+++ b/utils/certbot-dns-plugins.js
@@ -1,5 +1,7 @@
/**
* This file contains info about available Certbot DNS plugins.
+ * This only works for plugins which use the standard argument structure, so:
+ * --authenticator ---credentials ---propagation-seconds
*
* File Structure:
*
@@ -102,13 +104,15 @@ dns_luadns_token = 0123456789abcdef0123456789abcdef`,
display_name: "netcup",
package_name: "certbot-dns-netcup",
package_version: "1.0.0",
- credentials: `certbot_dns_njalla:dns_njalla_token = 0123456789abcdef0123456789abcdef01234567`,
+ credentials: `dns_netcup_customer_id = 123456
+dns_netcup_api_key = 0123456789abcdef0123456789abcdef01234567
+dns_netcup_api_password = abcdef0123456789abcdef01234567abcdef0123`,
full_plugin_name: "certbot-dns-netcup:dns-netcup",
},
//####################################################//
njalla: {
display_name: "Njalla",
- package_name: "certbot-dns-nsone",
+ package_name: "certbot-dns-njalla",
package_version: "0.0.4",
credentials: `certbot_dns_njalla:dns_njalla_token = 0123456789abcdef0123456789abcdef01234567`,
full_plugin_name: "certbot-dns-njalla:dns-njalla",