mirror of
				https://github.com/NginxProxyManager/nginx-proxy-manager.git
				synced 2025-10-31 15:53:33 +00:00 
			
		
		
		
	Implements dns challenge provider selection in frontend
This commit is contained in:
		| @@ -21,21 +21,92 @@ | |||||||
|                         </div> |                         </div> | ||||||
|                     </div> |                     </div> | ||||||
|  |  | ||||||
|                     <!-- CloudFlare --> |                     <!-- DNS challenge --> | ||||||
|                     <div class="col-sm-12 col-md-12"> |                     <div class="col-sm-12 col-md-12"> | ||||||
|                         <div class="form-group"> |                         <div class="form-group"> | ||||||
|                             <label class="custom-switch"> |                             <label class="custom-switch"> | ||||||
|                                 <input type="checkbox" class="custom-switch-input" name="meta[cloudflare_use]" value="1"> |                                 <input  | ||||||
|  |                                     type="checkbox"  | ||||||
|  |                                     class="custom-switch-input"  | ||||||
|  |                                     name="meta[dns_challenge]"  | ||||||
|  |                                     value="1"  | ||||||
|  |                                     <%- getUseDnsChallenge() ? 'checked' : '' %> | ||||||
|  |                                 > | ||||||
|                                 <span class="custom-switch-indicator"></span> |                                 <span class="custom-switch-indicator"></span> | ||||||
|                                 <span class="custom-switch-description"><%= i18n('ssl', 'use-cloudflare') %></span> |                                 <span class="custom-switch-description"><%= i18n('ssl', 'dns-challenge') %></span> | ||||||
|                             </label> |                             </label> | ||||||
|                         </div> |                         </div> | ||||||
|                     </div> |                     </div> | ||||||
|                     <div class="col-sm-12 col-md-12 cloudflare"> |                     <div class="col-sm-12 col-md-12"> | ||||||
|                         <div class="form-group"> |                         <fieldset class="form-fieldset dns-challenge"> | ||||||
|                             <label class="form-label">CloudFlare DNS API Token  <span class="form-required">*</span></label> |                             <div class="text-red mb-4"><i class="fe fe-alert-triangle"></i> <%= i18n('ssl', 'certbot-warning') %></div> | ||||||
|                             <input type="text" name="meta[cloudflare_token]" class="form-control" id="cloudflare_token"> |  | ||||||
|                         </div> |                             <!-- Certbot DNS plugin selection --> | ||||||
|  |                             <div class="row"> | ||||||
|  |                                 <div class="col-sm-12 col-md-12"> | ||||||
|  |                                     <div class="form-group"> | ||||||
|  |                                         <label class="form-label"><%- i18n('ssl', 'dns-provider') %> <span class="form-required">*</span></label> | ||||||
|  |                                         <select  | ||||||
|  |                                             name="meta[dns_provider]"  | ||||||
|  |                                             id="dns_provider" | ||||||
|  |                                             class="form-control custom-select" | ||||||
|  |                                         > | ||||||
|  |                                             <option  | ||||||
|  |                                                 value=""  | ||||||
|  |                                                 disabled  | ||||||
|  |                                                 hidden | ||||||
|  |                                                 <%- getDnsProvider() === null ? 'selected' : '' %> | ||||||
|  |                                             >Please Choose...</option> | ||||||
|  |                                             <% _.each(dns_plugins, function(plugin_info, plugin_name){ %> | ||||||
|  |                                             <option  | ||||||
|  |                                                 value="<%- plugin_name %>" | ||||||
|  |                                                 <%- getDnsProvider() === plugin_name ? 'selected' : '' %> | ||||||
|  |                                             ><%- plugin_info.display_name %></option> | ||||||
|  |                                             <% }); %> | ||||||
|  |                                         </select> | ||||||
|  |                                     </div> | ||||||
|  |                                 </div> | ||||||
|  |                             </div> | ||||||
|  |  | ||||||
|  |                             <!-- Certbot credentials file content --> | ||||||
|  |                             <div class="row credentials-file-content"> | ||||||
|  |                                 <div class="col-sm-12 col-md-12"> | ||||||
|  |                                     <div class="form-group"> | ||||||
|  |                                         <label class="form-label"><%- i18n('ssl', 'credentials-file-content') %> <span class="form-required">*</span></label> | ||||||
|  |                                         <textarea  | ||||||
|  |                                             name="meta[dns_provider_credentials]"  | ||||||
|  |                                             class="form-control text-monospace"  | ||||||
|  |                                             id="dns_provider_credentials"  | ||||||
|  |                                         ><%- getDnsProviderCredentials() %></textarea> | ||||||
|  |                                         <div class="text-secondary small"> | ||||||
|  |                                             <i class="fe fe-info"></i>  | ||||||
|  |                                             <%= i18n('ssl', 'credentials-file-content-info') %> | ||||||
|  |                                         </div> | ||||||
|  |                                     </div> | ||||||
|  |                                 </div> | ||||||
|  |                             </div> | ||||||
|  |  | ||||||
|  |                             <!-- DNS propagation delay --> | ||||||
|  |                             <div class="row"> | ||||||
|  |                                 <div class="col-sm-12 col-md-12"> | ||||||
|  |                                     <div class="form-group mb-0"> | ||||||
|  |                                         <label class="form-label"><%- i18n('ssl', 'propagation-seconds') %></label> | ||||||
|  |                                         <input  | ||||||
|  |                                             type="number" | ||||||
|  |                                             min="0" | ||||||
|  |                                             name="meta[propagation_seconds]"  | ||||||
|  |                                             class="form-control"  | ||||||
|  |                                             id="propagation_seconds"  | ||||||
|  |                                             value="<%- getPropagationSeconds() %>" | ||||||
|  |                                         > | ||||||
|  |                                         <div class="text-secondary small"> | ||||||
|  |                                             <i class="fe fe-info"></i>  | ||||||
|  |                                             <%= i18n('ssl', 'propagation-seconds-info') %> | ||||||
|  |                                         </div> | ||||||
|  |                                     </div> | ||||||
|  |                                 </div> | ||||||
|  |                             </div> | ||||||
|  |                         </fieldset> | ||||||
|                     </div> |                     </div> | ||||||
|  |  | ||||||
|                     <div class="col-sm-12 col-md-12"> |                     <div class="col-sm-12 col-md-12"> | ||||||
|   | |||||||
| @@ -3,6 +3,8 @@ const Mn               = require('backbone.marionette'); | |||||||
| const App              = require('../../main'); | const App              = require('../../main'); | ||||||
| const CertificateModel = require('../../../models/certificate'); | const CertificateModel = require('../../../models/certificate'); | ||||||
| const template         = require('./form.ejs'); | const template         = require('./form.ejs'); | ||||||
|  | const i18n             = require('../../i18n'); | ||||||
|  | const dns_providers    = require('../../../../../utils/certbot-dns-plugins'); | ||||||
|  |  | ||||||
| require('jquery-serializejson'); | require('jquery-serializejson'); | ||||||
| require('selectize'); | require('selectize'); | ||||||
| @@ -21,25 +23,46 @@ module.exports = Mn.View.extend({ | |||||||
|         other_certificate:                    '#other_certificate', |         other_certificate:                    '#other_certificate', | ||||||
|         other_certificate_label:              '#other_certificate_label', |         other_certificate_label:              '#other_certificate_label', | ||||||
|         other_certificate_key:                '#other_certificate_key', |         other_certificate_key:                '#other_certificate_key', | ||||||
|         cloudflare_switch:                    'input[name="meta[cloudflare_use]"]', |         dns_challenge_switch:                 'input[name="meta[dns_challenge]"]', | ||||||
|         cloudflare_token:                     'input[name="meta[cloudflare_token]"', |         dns_challenge_content:                '.dns-challenge', | ||||||
|         cloudflare:                           '.cloudflare', |         dns_provider:                         'select[name="meta[dns_provider]"]', | ||||||
|  |         credentials_file_content:             '.credentials-file-content', | ||||||
|  |         dns_provider_credentials:             'textarea[name="meta[dns_provider_credentials]"]', | ||||||
|  |         propagation_seconds:                  'input[name="meta[propagation_seconds]"]', | ||||||
|         other_certificate_key_label:          '#other_certificate_key_label', |         other_certificate_key_label:          '#other_certificate_key_label', | ||||||
|         other_intermediate_certificate:       '#other_intermediate_certificate', |         other_intermediate_certificate:       '#other_intermediate_certificate', | ||||||
|         other_intermediate_certificate_label: '#other_intermediate_certificate_label' |         other_intermediate_certificate_label: '#other_intermediate_certificate_label' | ||||||
|     }, |     }, | ||||||
|      |      | ||||||
|     events: { |     events: { | ||||||
|         'change @ui.cloudflare_switch': function() { |         'change @ui.dns_challenge_switch': function () { | ||||||
|             let checked = this.ui.cloudflare_switch.prop('checked'); |             const checked = this.ui.dns_challenge_switch.prop('checked'); | ||||||
|             if (checked) {                 |             if (checked) { | ||||||
|                 this.ui.cloudflare_token.prop('required', 'required'); |                 this.ui.dns_provider.prop('required', 'required'); | ||||||
|                 this.ui.cloudflare.show(); |                 const selected_provider = this.ui.dns_provider[0].options[this.ui.dns_provider[0].selectedIndex].value; | ||||||
|             } else {                 |                 if(selected_provider != '' && dns_providers[selected_provider].credentials !== false){ | ||||||
|                 this.ui.cloudflare_token.prop('required', false); |                     this.ui.dns_provider_credentials.prop('required', 'required'); | ||||||
|                 this.ui.cloudflare.hide();                 |                 } | ||||||
|  |                 this.ui.dns_challenge_content.show(); | ||||||
|  |             } else { | ||||||
|  |                 this.ui.dns_provider.prop('required', false); | ||||||
|  |                 this.ui.dns_provider_credentials.prop('required', false); | ||||||
|  |                 this.ui.dns_challenge_content.hide();                 | ||||||
|             } |             } | ||||||
|         }, |         }, | ||||||
|  |  | ||||||
|  |         'change @ui.dns_provider': function () { | ||||||
|  |             const selected_provider = this.ui.dns_provider[0].options[this.ui.dns_provider[0].selectedIndex].value; | ||||||
|  |             if (selected_provider != '' && dns_providers[selected_provider].credentials !== false) { | ||||||
|  |                 this.ui.dns_provider_credentials.prop('required', 'required'); | ||||||
|  |                 this.ui.dns_provider_credentials[0].value = dns_providers[selected_provider].credentials; | ||||||
|  |                 this.ui.credentials_file_content.show(); | ||||||
|  |             } else { | ||||||
|  |                 this.ui.dns_provider_credentials.prop('required', false); | ||||||
|  |                 this.ui.credentials_file_content.hide();                 | ||||||
|  |             } | ||||||
|  |         }, | ||||||
|  |          | ||||||
|         'click @ui.save': function (e) { |         'click @ui.save': function (e) { | ||||||
|             e.preventDefault(); |             e.preventDefault(); | ||||||
|  |  | ||||||
| @@ -56,7 +79,7 @@ module.exports = Mn.View.extend({ | |||||||
|  |  | ||||||
|  |  | ||||||
|             let domain_err = false; |             let domain_err = false; | ||||||
|             if (!data.meta.cloudflare_use) {                 |             if (!data.meta.dns_challenge) {                 | ||||||
|                 data.domain_names.split(',').map(function (name) { |                 data.domain_names.split(',').map(function (name) { | ||||||
|                     if (name.match(/\*/im)) { |                     if (name.match(/\*/im)) { | ||||||
|                         domain_err = true; |                         domain_err = true; | ||||||
| @@ -65,7 +88,7 @@ module.exports = Mn.View.extend({ | |||||||
|             } |             } | ||||||
|  |  | ||||||
|             if (domain_err) { |             if (domain_err) { | ||||||
|                 alert('Cannot request Let\'s Encrypt Certificate for wildcard domains when not using CloudFlare DNS'); |                 alert(i18n('ssl', 'no-wildcard-without-dns')); | ||||||
|                 return; |                 return; | ||||||
|             } |             } | ||||||
|  |  | ||||||
| @@ -73,8 +96,9 @@ module.exports = Mn.View.extend({ | |||||||
|             if (typeof data.meta !== 'undefined' && typeof data.meta.letsencrypt_agree !== 'undefined') { |             if (typeof data.meta !== 'undefined' && typeof data.meta.letsencrypt_agree !== 'undefined') { | ||||||
|                 data.meta.letsencrypt_agree = !!data.meta.letsencrypt_agree; |                 data.meta.letsencrypt_agree = !!data.meta.letsencrypt_agree; | ||||||
|             } |             } | ||||||
|             if (typeof data.meta !== 'undefined' && typeof data.meta.cloudflare_use !== 'undefined') { |  | ||||||
|                 data.meta.cloudflare_use = !!data.meta.cloudflare_use; |             if (typeof data.meta !== 'undefined' && typeof data.meta.dns_challenge !== 'undefined') { | ||||||
|  |                 data.meta.dns_challenge = !!data.meta.dns_challenge; | ||||||
|             } |             } | ||||||
|  |  | ||||||
|             if (typeof data.domain_names === 'string' && data.domain_names) { |             if (typeof data.domain_names === 'string' && data.domain_names) { | ||||||
| @@ -176,14 +200,22 @@ module.exports = Mn.View.extend({ | |||||||
|         getLetsencryptEmail: function () { |         getLetsencryptEmail: function () { | ||||||
|             return typeof this.meta.letsencrypt_email !== 'undefined' ? this.meta.letsencrypt_email : App.Cache.User.get('email'); |             return typeof this.meta.letsencrypt_email !== 'undefined' ? this.meta.letsencrypt_email : App.Cache.User.get('email'); | ||||||
|         }, |         }, | ||||||
|  |  | ||||||
|         getLetsencryptAgree: function () { |         getLetsencryptAgree: function () { | ||||||
|             return typeof this.meta.letsencrypt_agree !== 'undefined' ? this.meta.letsencrypt_agree : false; |             return typeof this.meta.letsencrypt_agree !== 'undefined' ? this.meta.letsencrypt_agree : false; | ||||||
|         }, |         }, | ||||||
|  |         getUseDnsChallenge: function () { | ||||||
|         getCloudflareUse: function () { |             return typeof this.meta.dns_challenge !== 'undefined' ? this.meta.dns_challenge : false; | ||||||
|             return typeof this.meta.cloudflare_use !== 'undefined' ? this.meta.cloudflare_use : false; |         }, | ||||||
|         } |         getDnsProvider: function () { | ||||||
|  |             return typeof this.meta.dns_provider !== 'undefined' && this.meta.dns_provider != '' ? this.meta.dns_provider : null; | ||||||
|  |         }, | ||||||
|  |         getDnsProviderCredentials: function () { | ||||||
|  |             return typeof this.meta.dns_provider_credentials !== 'undefined' ? this.meta.dns_provider_credentials : ''; | ||||||
|  |         }, | ||||||
|  |         getPropagationSeconds: function () { | ||||||
|  |             return typeof this.meta.propagation_seconds !== 'undefined' ? this.meta.propagation_seconds : ''; | ||||||
|  |         }, | ||||||
|  |         dns_plugins: dns_providers, | ||||||
|     }, |     }, | ||||||
|  |  | ||||||
|     onRender: function () { |     onRender: function () { | ||||||
| @@ -199,7 +231,8 @@ module.exports = Mn.View.extend({ | |||||||
|             }, |             }, | ||||||
|             createFilter: /^(?:[^.]+\.?)+[^.]$/ |             createFilter: /^(?:[^.]+\.?)+[^.]$/ | ||||||
|         }); |         }); | ||||||
|         this.ui.cloudflare.hide(); |         this.ui.dns_challenge_content.hide(); | ||||||
|  |         this.ui.credentials_file_content.hide();  | ||||||
|     }, |     }, | ||||||
|  |  | ||||||
|     initialize: function (options) { |     initialize: function (options) { | ||||||
|   | |||||||
| @@ -28,7 +28,7 @@ | |||||||
|     </div> |     </div> | ||||||
| </td> | </td> | ||||||
| <td> | <td> | ||||||
|     <%- i18n('ssl', provider) %><% if (meta.cloudflare_use) { %> - CloudFlare DNS<% } %> |     <%- i18n('ssl', provider) %><% if (meta.dns_provider) { %> - <% dns_providers[meta.dns_provider].display_name } %> | ||||||
| </td> | </td> | ||||||
| <td class="<%- isExpired() ? 'text-danger' : '' %>"> | <td class="<%- isExpired() ? 'text-danger' : '' %>"> | ||||||
|     <%- formatDbDate(expires_on, 'Do MMMM YYYY, h:mm a') %> |     <%- formatDbDate(expires_on, 'Do MMMM YYYY, h:mm a') %> | ||||||
|   | |||||||
| @@ -1,7 +1,8 @@ | |||||||
| const Mn       = require('backbone.marionette'); | const Mn            = require('backbone.marionette'); | ||||||
| const moment   = require('moment'); | const moment        = require('moment'); | ||||||
| const App      = require('../../../main'); | const App           = require('../../../main'); | ||||||
| const template = require('./item.ejs'); | const template      = require('./item.ejs'); | ||||||
|  | const dns_providers = require('../../../../../../utils/certbot-dns-plugins') | ||||||
|  |  | ||||||
| module.exports = Mn.View.extend({ | module.exports = Mn.View.extend({ | ||||||
|     template: template, |     template: template, | ||||||
| @@ -35,7 +36,8 @@ module.exports = Mn.View.extend({ | |||||||
|         canManage: App.Cache.User.canManage('certificates'), |         canManage: App.Cache.User.canManage('certificates'), | ||||||
|         isExpired: function () { |         isExpired: function () { | ||||||
|             return moment(this.expires_on).isBefore(moment()); |             return moment(this.expires_on).isBefore(moment()); | ||||||
|         } |         }, | ||||||
|  |         dns_providers: dns_providers | ||||||
|     }, |     }, | ||||||
|  |  | ||||||
|     initialize: function () { |     initialize: function () { | ||||||
|   | |||||||
| @@ -73,21 +73,92 @@ | |||||||
|                             </div> |                             </div> | ||||||
|                         </div> |                         </div> | ||||||
|  |  | ||||||
|                         <!-- CloudFlare --> |                         <!-- DNS challenge --> | ||||||
|                         <div class="col-sm-12 col-md-12 letsencrypt"> |                         <div class="col-sm-12 col-md-12 letsencrypt"> | ||||||
|                             <div class="form-group"> |                             <div class="form-group"> | ||||||
|                                 <label class="custom-switch"> |                                 <label class="custom-switch"> | ||||||
|                                     <input type="checkbox" class="custom-switch-input" name="meta[cloudflare_use]" value="1"> |                                     <input  | ||||||
|  |                                         type="checkbox"  | ||||||
|  |                                         class="custom-switch-input"  | ||||||
|  |                                         name="meta[dns_challenge]"  | ||||||
|  |                                         value="1"  | ||||||
|  |                                         <%- getUseDnsChallenge() ? 'checked' : '' %> | ||||||
|  |                                     > | ||||||
|                                     <span class="custom-switch-indicator"></span> |                                     <span class="custom-switch-indicator"></span> | ||||||
|                                     <span class="custom-switch-description"><%= i18n('ssl', 'use-cloudflare') %></span> |                                     <span class="custom-switch-description"><%= i18n('ssl', 'dns-challenge') %></span> | ||||||
|                                 </label> |                                 </label> | ||||||
|                             </div> |                             </div> | ||||||
|                         </div> |                         </div> | ||||||
|                         <div class="col-sm-12 col-md-12 cloudflare letsencrypt"> |                         <div class="col-sm-12 col-md-12 letsencrypt"> | ||||||
|                             <div class="form-group"> |                             <fieldset class="form-fieldset dns-challenge"> | ||||||
|                                 <label class="form-label">CloudFlare DNS API Token  <span class="form-required">*</span></label> |                                 <div class="text-red mb-4"><i class="fe fe-alert-triangle"></i> <%= i18n('ssl', 'certbot-warning') %></div> | ||||||
|                                 <input type="text" name="meta[cloudflare_token]" class="form-control" id="cloudflare_token"> |  | ||||||
|                             </div> |                                 <!-- Certbot DNS plugin selection --> | ||||||
|  |                                 <div class="row"> | ||||||
|  |                                     <div class="col-sm-12 col-md-12"> | ||||||
|  |                                         <div class="form-group"> | ||||||
|  |                                             <label class="form-label"><%- i18n('ssl', 'dns-provider') %> <span class="form-required">*</span></label> | ||||||
|  |                                             <select  | ||||||
|  |                                                 name="meta[dns_provider]"  | ||||||
|  |                                                 id="dns_provider" | ||||||
|  |                                                 class="form-control custom-select" | ||||||
|  |                                             > | ||||||
|  |                                                 <option  | ||||||
|  |                                                     value=""  | ||||||
|  |                                                     disabled  | ||||||
|  |                                                     hidden | ||||||
|  |                                                     <%- getDnsProvider() === null ? 'selected' : '' %> | ||||||
|  |                                                 >Please Choose...</option> | ||||||
|  |                                                 <% _.each(dns_plugins, function(plugin_info, plugin_name){ %> | ||||||
|  |                                                 <option  | ||||||
|  |                                                     value="<%- plugin_name %>" | ||||||
|  |                                                     <%- getDnsProvider() === plugin_name ? 'selected' : '' %> | ||||||
|  |                                                 ><%- plugin_info.display_name %></option> | ||||||
|  |                                                 <% }); %> | ||||||
|  |                                             </select> | ||||||
|  |                                         </div> | ||||||
|  |                                     </div> | ||||||
|  |                                 </div> | ||||||
|  |  | ||||||
|  |                                 <!-- Certbot credentials file content --> | ||||||
|  |                                 <div class="row credentials-file-content"> | ||||||
|  |                                     <div class="col-sm-12 col-md-12"> | ||||||
|  |                                         <div class="form-group"> | ||||||
|  |                                             <label class="form-label"><%- i18n('ssl', 'credentials-file-content') %> <span class="form-required">*</span></label> | ||||||
|  |                                             <textarea  | ||||||
|  |                                                 name="meta[dns_provider_credentials]"  | ||||||
|  |                                                 class="form-control text-monospace"  | ||||||
|  |                                                 id="dns_provider_credentials"  | ||||||
|  |                                             ><%- getDnsProviderCredentials() %></textarea> | ||||||
|  |                                             <div class="text-secondary small"> | ||||||
|  |                                                 <i class="fe fe-info"></i>  | ||||||
|  |                                                 <%= i18n('ssl', 'credentials-file-content-info') %> | ||||||
|  |                                             </div> | ||||||
|  |                                         </div> | ||||||
|  |                                     </div> | ||||||
|  |                                 </div> | ||||||
|  |  | ||||||
|  |                                 <!-- DNS propagation delay --> | ||||||
|  |                                 <div class="row"> | ||||||
|  |                                     <div class="col-sm-12 col-md-12"> | ||||||
|  |                                         <div class="form-group mb-0"> | ||||||
|  |                                             <label class="form-label"><%- i18n('ssl', 'propagation-seconds') %></label> | ||||||
|  |                                             <input  | ||||||
|  |                                                 type="number" | ||||||
|  |                                                 min="0" | ||||||
|  |                                                 name="meta[propagation_seconds]"  | ||||||
|  |                                                 class="form-control"  | ||||||
|  |                                                 id="propagation_seconds"  | ||||||
|  |                                                 value="<%- getPropagationSeconds() %>" | ||||||
|  |                                             > | ||||||
|  |                                             <div class="text-secondary small"> | ||||||
|  |                                                 <i class="fe fe-info"></i>  | ||||||
|  |                                                 <%= i18n('ssl', 'propagation-seconds-info') %> | ||||||
|  |                                             </div> | ||||||
|  |                                         </div> | ||||||
|  |                                     </div> | ||||||
|  |                                 </div> | ||||||
|  |                             </fieldset> | ||||||
|                         </div> |                         </div> | ||||||
|  |  | ||||||
|                         <!-- Lets encrypt --> |                         <!-- Lets encrypt --> | ||||||
|   | |||||||
| @@ -4,6 +4,8 @@ const DeadHostModel        = require('../../../models/dead-host'); | |||||||
| const template             = require('./form.ejs'); | const template             = require('./form.ejs'); | ||||||
| const certListItemTemplate = require('../certificates-list-item.ejs'); | const certListItemTemplate = require('../certificates-list-item.ejs'); | ||||||
| const Helpers              = require('../../../lib/helpers'); | const Helpers              = require('../../../lib/helpers'); | ||||||
|  | const i18n                 = require('../../i18n'); | ||||||
|  | const dns_providers        = require('../../../../../utils/certbot-dns-plugins'); | ||||||
|  |  | ||||||
| require('jquery-serializejson'); | require('jquery-serializejson'); | ||||||
| require('selectize'); | require('selectize'); | ||||||
| @@ -13,20 +15,23 @@ module.exports = Mn.View.extend({ | |||||||
|     className: 'modal-dialog', |     className: 'modal-dialog', | ||||||
|  |  | ||||||
|     ui: { |     ui: { | ||||||
|         form:               'form', |         form:                     'form', | ||||||
|         domain_names:       'input[name="domain_names"]', |         domain_names:             'input[name="domain_names"]', | ||||||
|         buttons:            '.modal-footer button', |         buttons:                  '.modal-footer button', | ||||||
|         cancel:             'button.cancel', |         cancel:                   'button.cancel', | ||||||
|         save:               'button.save', |         save:                     'button.save', | ||||||
|         certificate_select: 'select[name="certificate_id"]', |         certificate_select:       'select[name="certificate_id"]', | ||||||
|         ssl_forced:         'input[name="ssl_forced"]', |         ssl_forced:               'input[name="ssl_forced"]', | ||||||
|         hsts_enabled:       'input[name="hsts_enabled"]', |         hsts_enabled:             'input[name="hsts_enabled"]', | ||||||
|         hsts_subdomains:    'input[name="hsts_subdomains"]', |         hsts_subdomains:          'input[name="hsts_subdomains"]', | ||||||
|         http2_support:      'input[name="http2_support"]', |         http2_support:            'input[name="http2_support"]', | ||||||
|         cloudflare_switch:  'input[name="meta[cloudflare_use]"]', |         dns_challenge_switch:     'input[name="meta[dns_challenge]"]', | ||||||
|         cloudflare_token:   'input[name="meta[cloudflare_token]"', |         dns_challenge_content:    '.dns-challenge', | ||||||
|         cloudflare:         '.cloudflare', |         dns_provider:             'select[name="meta[dns_provider]"]', | ||||||
|         letsencrypt:        '.letsencrypt' |         credentials_file_content: '.credentials-file-content', | ||||||
|  |         dns_provider_credentials: 'textarea[name="meta[dns_provider_credentials]"]', | ||||||
|  |         propagation_seconds:      'input[name="meta[propagation_seconds]"]', | ||||||
|  |         letsencrypt:              '.letsencrypt' | ||||||
|     }, |     }, | ||||||
|  |  | ||||||
|     events: { |     events: { | ||||||
| @@ -34,7 +39,7 @@ module.exports = Mn.View.extend({ | |||||||
|             let id = this.ui.certificate_select.val(); |             let id = this.ui.certificate_select.val(); | ||||||
|             if (id === 'new') { |             if (id === 'new') { | ||||||
|                 this.ui.letsencrypt.show().find('input').prop('disabled', false); |                 this.ui.letsencrypt.show().find('input').prop('disabled', false); | ||||||
|                 this.ui.cloudflare.hide(); |                 this.ui.dns_challenge_content.hide(); | ||||||
|             } else { |             } else { | ||||||
|                 this.ui.letsencrypt.hide().find('input').prop('disabled', true); |                 this.ui.letsencrypt.hide().find('input').prop('disabled', true); | ||||||
|             } |             } | ||||||
| @@ -81,14 +86,31 @@ module.exports = Mn.View.extend({ | |||||||
|             } |             } | ||||||
|         }, |         }, | ||||||
|  |  | ||||||
|         'change @ui.cloudflare_switch': function() { |         'change @ui.dns_challenge_switch': function () { | ||||||
|             let checked = this.ui.cloudflare_switch.prop('checked'); |             const checked = this.ui.dns_challenge_switch.prop('checked'); | ||||||
|             if (checked) {                 |             if (checked) { | ||||||
|                 this.ui.cloudflare_token.prop('required', 'required'); |                 this.ui.dns_provider.prop('required', 'required'); | ||||||
|                 this.ui.cloudflare.show(); |                 const selected_provider = this.ui.dns_provider[0].options[this.ui.dns_provider[0].selectedIndex].value; | ||||||
|             } else {                 |                 if(selected_provider != '' && dns_providers[selected_provider].credentials !== false){ | ||||||
|                 this.ui.cloudflare_token.prop('required', false); |                     this.ui.dns_provider_credentials.prop('required', 'required'); | ||||||
|                 this.ui.cloudflare.hide();                 |                 } | ||||||
|  |                 this.ui.dns_challenge_content.show(); | ||||||
|  |             } else { | ||||||
|  |                 this.ui.dns_provider.prop('required', false); | ||||||
|  |                 this.ui.dns_provider_credentials.prop('required', false); | ||||||
|  |                 this.ui.dns_challenge_content.hide();                 | ||||||
|  |             } | ||||||
|  |         }, | ||||||
|  |  | ||||||
|  |         'change @ui.dns_provider': function () { | ||||||
|  |             const selected_provider = this.ui.dns_provider[0].options[this.ui.dns_provider[0].selectedIndex].value; | ||||||
|  |             if (selected_provider != '' && dns_providers[selected_provider].credentials !== false) { | ||||||
|  |                 this.ui.dns_provider_credentials.prop('required', 'required'); | ||||||
|  |                 this.ui.dns_provider_credentials[0].value = dns_providers[selected_provider].credentials; | ||||||
|  |                 this.ui.credentials_file_content.show(); | ||||||
|  |             } else { | ||||||
|  |                 this.ui.dns_provider_credentials.prop('required', false); | ||||||
|  |                 this.ui.credentials_file_content.hide();                 | ||||||
|             } |             } | ||||||
|         }, |         }, | ||||||
|  |  | ||||||
| @@ -104,10 +126,11 @@ module.exports = Mn.View.extend({ | |||||||
|             let data = this.ui.form.serializeJSON(); |             let data = this.ui.form.serializeJSON(); | ||||||
|  |  | ||||||
|             // Manipulate |             // Manipulate | ||||||
|             data.hsts_enabled    = !!data.hsts_enabled; |             data.hsts_enabled       = !!data.hsts_enabled; | ||||||
|             data.hsts_subdomains = !!data.hsts_subdomains; |             data.hsts_subdomains    = !!data.hsts_subdomains; | ||||||
|             data.http2_support   = !!data.http2_support; |             data.http2_support      = !!data.http2_support; | ||||||
|             data.ssl_forced      = !!data.ssl_forced; |             data.ssl_forced         = !!data.ssl_forced; | ||||||
|  |             data.meta.dns_challenge = !!data.meta.dns_challenge; | ||||||
|  |  | ||||||
|             if (typeof data.domain_names === 'string' && data.domain_names) { |             if (typeof data.domain_names === 'string' && data.domain_names) { | ||||||
|                 data.domain_names = data.domain_names.split(','); |                 data.domain_names = data.domain_names.split(','); | ||||||
| @@ -116,7 +139,7 @@ module.exports = Mn.View.extend({ | |||||||
|             // Check for any domain names containing wildcards, which are not allowed with letsencrypt |             // Check for any domain names containing wildcards, which are not allowed with letsencrypt | ||||||
|             if (data.certificate_id === 'new') {                 |             if (data.certificate_id === 'new') {                 | ||||||
|                 let domain_err = false; |                 let domain_err = false; | ||||||
|                 if (!data.meta.cloudflare_use) { |                 if (!data.meta.dns_challenge) { | ||||||
|                     data.domain_names.map(function (name) { |                     data.domain_names.map(function (name) { | ||||||
|                         if (name.match(/\*/im)) { |                         if (name.match(/\*/im)) { | ||||||
|                             domain_err = true; |                             domain_err = true; | ||||||
| @@ -125,11 +148,10 @@ module.exports = Mn.View.extend({ | |||||||
|                 } |                 } | ||||||
|  |  | ||||||
|                 if (domain_err) { |                 if (domain_err) { | ||||||
|                     alert('Cannot request Let\'s Encrypt Certificate for wildcard domains without CloudFlare DNS.'); |                     alert(i18n('ssl', 'no-wildcard-without-dns')); | ||||||
|                     return; |                     return; | ||||||
|                 } |                 } | ||||||
|  |  | ||||||
|                 data.meta.cloudflare_use = data.meta.cloudflare_use === '1'; |  | ||||||
|                 data.meta.letsencrypt_agree = data.meta.letsencrypt_agree === '1';                 |                 data.meta.letsencrypt_agree = data.meta.letsencrypt_agree === '1';                 | ||||||
|             } else { |             } else { | ||||||
|                 data.certificate_id = parseInt(data.certificate_id, 10); |                 data.certificate_id = parseInt(data.certificate_id, 10); | ||||||
| @@ -169,7 +191,20 @@ module.exports = Mn.View.extend({ | |||||||
|     templateContext: { |     templateContext: { | ||||||
|         getLetsencryptEmail: function () { |         getLetsencryptEmail: function () { | ||||||
|             return App.Cache.User.get('email'); |             return App.Cache.User.get('email'); | ||||||
|         } |         }, | ||||||
|  |         getUseDnsChallenge: function () { | ||||||
|  |             return typeof this.meta.dns_challenge !== 'undefined' ? this.meta.dns_challenge : false; | ||||||
|  |         }, | ||||||
|  |         getDnsProvider: function () { | ||||||
|  |             return typeof this.meta.dns_provider !== 'undefined' && this.meta.dns_provider != '' ? this.meta.dns_provider : null; | ||||||
|  |         }, | ||||||
|  |         getDnsProviderCredentials: function () { | ||||||
|  |             return typeof this.meta.dns_provider_credentials !== 'undefined' ? this.meta.dns_provider_credentials : ''; | ||||||
|  |         }, | ||||||
|  |         getPropagationSeconds: function () { | ||||||
|  |             return typeof this.meta.propagation_seconds !== 'undefined' ? this.meta.propagation_seconds : ''; | ||||||
|  |         }, | ||||||
|  |         dns_plugins: dns_providers, | ||||||
|     }, |     }, | ||||||
|  |  | ||||||
|     onRender: function () { |     onRender: function () { | ||||||
| @@ -190,6 +225,8 @@ module.exports = Mn.View.extend({ | |||||||
|         }); |         }); | ||||||
|  |  | ||||||
|         // Certificates |         // Certificates | ||||||
|  |         this.ui.dns_challenge_content.hide(); | ||||||
|  |         this.ui.credentials_file_content.hide(); | ||||||
|         this.ui.letsencrypt.hide(); |         this.ui.letsencrypt.hide(); | ||||||
|         this.ui.certificate_select.selectize({ |         this.ui.certificate_select.selectize({ | ||||||
|             valueField:       'id', |             valueField:       'id', | ||||||
|   | |||||||
| @@ -141,21 +141,92 @@ | |||||||
|                             </div> |                             </div> | ||||||
|                         </div> |                         </div> | ||||||
|  |  | ||||||
|                         <!-- CloudFlare --> |                         <!-- DNS challenge --> | ||||||
|                         <div class="col-sm-12 col-md-12 letsencrypt"> |                         <div class="col-sm-12 col-md-12 letsencrypt"> | ||||||
|                             <div class="form-group"> |                             <div class="form-group"> | ||||||
|                                 <label class="custom-switch"> |                                 <label class="custom-switch"> | ||||||
|                                     <input type="checkbox" class="custom-switch-input" name="meta[cloudflare_use]" value="1"> |                                     <input  | ||||||
|  |                                         type="checkbox"  | ||||||
|  |                                         class="custom-switch-input"  | ||||||
|  |                                         name="meta[dns_challenge]"  | ||||||
|  |                                         value="1"  | ||||||
|  |                                         <%- getUseDnsChallenge() ? 'checked' : '' %> | ||||||
|  |                                     > | ||||||
|                                     <span class="custom-switch-indicator"></span> |                                     <span class="custom-switch-indicator"></span> | ||||||
|                                     <span class="custom-switch-description"><%= i18n('ssl', 'use-cloudflare') %></span> |                                     <span class="custom-switch-description"><%= i18n('ssl', 'dns-challenge') %></span> | ||||||
|                                 </label> |                                 </label> | ||||||
|                             </div> |                             </div> | ||||||
|                         </div> |                         </div> | ||||||
|                         <div class="col-sm-12 col-md-12 cloudflare letsencrypt"> |                         <div class="col-sm-12 col-md-12 letsencrypt"> | ||||||
|                             <div class="form-group"> |                             <fieldset class="form-fieldset dns-challenge"> | ||||||
|                                 <label class="form-label">CloudFlare DNS API Token  <span class="form-required">*</span></label> |                                 <div class="text-red mb-4"><i class="fe fe-alert-triangle"></i> <%= i18n('ssl', 'certbot-warning') %></div> | ||||||
|                                 <input type="text" name="meta[cloudflare_token]" class="form-control" id="cloudflare_token"> |  | ||||||
|                             </div> |                                 <!-- Certbot DNS plugin selection --> | ||||||
|  |                                 <div class="row"> | ||||||
|  |                                     <div class="col-sm-12 col-md-12"> | ||||||
|  |                                         <div class="form-group"> | ||||||
|  |                                             <label class="form-label"><%- i18n('ssl', 'dns-provider') %> <span class="form-required">*</span></label> | ||||||
|  |                                             <select  | ||||||
|  |                                                 name="meta[dns_provider]"  | ||||||
|  |                                                 id="dns_provider" | ||||||
|  |                                                 class="form-control custom-select" | ||||||
|  |                                             > | ||||||
|  |                                                 <option  | ||||||
|  |                                                     value=""  | ||||||
|  |                                                     disabled  | ||||||
|  |                                                     hidden | ||||||
|  |                                                     <%- getDnsProvider() === null ? 'selected' : '' %> | ||||||
|  |                                                 >Please Choose...</option> | ||||||
|  |                                                 <% _.each(dns_plugins, function(plugin_info, plugin_name){ %> | ||||||
|  |                                                 <option  | ||||||
|  |                                                     value="<%- plugin_name %>" | ||||||
|  |                                                     <%- getDnsProvider() === plugin_name ? 'selected' : '' %> | ||||||
|  |                                                 ><%- plugin_info.display_name %></option> | ||||||
|  |                                                 <% }); %> | ||||||
|  |                                             </select> | ||||||
|  |                                         </div> | ||||||
|  |                                     </div> | ||||||
|  |                                 </div> | ||||||
|  |  | ||||||
|  |                                 <!-- Certbot credentials file content --> | ||||||
|  |                                 <div class="row credentials-file-content"> | ||||||
|  |                                     <div class="col-sm-12 col-md-12"> | ||||||
|  |                                         <div class="form-group"> | ||||||
|  |                                             <label class="form-label"><%- i18n('ssl', 'credentials-file-content') %> <span class="form-required">*</span></label> | ||||||
|  |                                             <textarea  | ||||||
|  |                                                 name="meta[dns_provider_credentials]"  | ||||||
|  |                                                 class="form-control text-monospace"  | ||||||
|  |                                                 id="dns_provider_credentials"  | ||||||
|  |                                             ><%- getDnsProviderCredentials() %></textarea> | ||||||
|  |                                             <div class="text-secondary small"> | ||||||
|  |                                                 <i class="fe fe-info"></i>  | ||||||
|  |                                                 <%= i18n('ssl', 'credentials-file-content-info') %> | ||||||
|  |                                             </div> | ||||||
|  |                                         </div> | ||||||
|  |                                     </div> | ||||||
|  |                                 </div> | ||||||
|  |  | ||||||
|  |                                 <!-- DNS propagation delay --> | ||||||
|  |                                 <div class="row"> | ||||||
|  |                                     <div class="col-sm-12 col-md-12"> | ||||||
|  |                                         <div class="form-group mb-0"> | ||||||
|  |                                             <label class="form-label"><%- i18n('ssl', 'propagation-seconds') %></label> | ||||||
|  |                                             <input  | ||||||
|  |                                                 type="number" | ||||||
|  |                                                 min="0" | ||||||
|  |                                                 name="meta[propagation_seconds]"  | ||||||
|  |                                                 class="form-control"  | ||||||
|  |                                                 id="propagation_seconds"  | ||||||
|  |                                                 value="<%- getPropagationSeconds() %>" | ||||||
|  |                                             > | ||||||
|  |                                             <div class="text-secondary small"> | ||||||
|  |                                                 <i class="fe fe-info"></i>  | ||||||
|  |                                                 <%= i18n('ssl', 'propagation-seconds-info') %> | ||||||
|  |                                             </div> | ||||||
|  |                                         </div> | ||||||
|  |                                     </div> | ||||||
|  |                                 </div> | ||||||
|  |                             </fieldset> | ||||||
|                         </div> |                         </div> | ||||||
|  |  | ||||||
|                         <!-- Lets encrypt --> |                         <!-- Lets encrypt --> | ||||||
|   | |||||||
| @@ -7,6 +7,8 @@ const certListItemTemplate   = require('../certificates-list-item.ejs'); | |||||||
| const accessListItemTemplate = require('./access-list-item.ejs'); | const accessListItemTemplate = require('./access-list-item.ejs'); | ||||||
| const CustomLocation         = require('./location'); | const CustomLocation         = require('./location'); | ||||||
| const Helpers                = require('../../../lib/helpers'); | const Helpers                = require('../../../lib/helpers'); | ||||||
|  | const i18n                   = require('../../i18n'); | ||||||
|  | const dns_providers          = require('../../../../../utils/certbot-dns-plugins'); | ||||||
|  |  | ||||||
|  |  | ||||||
| require('jquery-serializejson'); | require('jquery-serializejson'); | ||||||
| @@ -19,25 +21,28 @@ module.exports = Mn.View.extend({ | |||||||
|     locationsCollection: new ProxyLocationModel.Collection(), |     locationsCollection: new ProxyLocationModel.Collection(), | ||||||
|  |  | ||||||
|     ui: { |     ui: { | ||||||
|         form:               'form', |         form:                     'form', | ||||||
|         domain_names:       'input[name="domain_names"]', |         domain_names:             'input[name="domain_names"]', | ||||||
|         forward_host:       'input[name="forward_host"]', |         forward_host:             'input[name="forward_host"]', | ||||||
|         buttons:            '.modal-footer button', |         buttons:                  '.modal-footer button', | ||||||
|         cancel:             'button.cancel', |         cancel:                   'button.cancel', | ||||||
|         save:               'button.save', |         save:                     'button.save', | ||||||
|         add_location_btn:   'button.add_location', |         add_location_btn:         'button.add_location', | ||||||
|         locations_container:'.locations_container', |         locations_container:      '.locations_container', | ||||||
|         certificate_select: 'select[name="certificate_id"]', |         certificate_select:       'select[name="certificate_id"]', | ||||||
|         access_list_select: 'select[name="access_list_id"]', |         access_list_select:       'select[name="access_list_id"]', | ||||||
|         ssl_forced:         'input[name="ssl_forced"]', |         ssl_forced:               'input[name="ssl_forced"]', | ||||||
|         hsts_enabled:       'input[name="hsts_enabled"]', |         hsts_enabled:             'input[name="hsts_enabled"]', | ||||||
|         hsts_subdomains:    'input[name="hsts_subdomains"]', |         hsts_subdomains:          'input[name="hsts_subdomains"]', | ||||||
|         http2_support:      'input[name="http2_support"]', |         http2_support:            'input[name="http2_support"]', | ||||||
|         cloudflare_switch:  'input[name="meta[cloudflare_use]"]', |         dns_challenge_switch:     'input[name="meta[dns_challenge]"]', | ||||||
|         cloudflare_token:   'input[name="meta[cloudflare_token]"', |         dns_challenge_content:    '.dns-challenge', | ||||||
|         cloudflare:         '.cloudflare', |         dns_provider:             'select[name="meta[dns_provider]"]', | ||||||
|         forward_scheme:     'select[name="forward_scheme"]', |         credentials_file_content: '.credentials-file-content', | ||||||
|         letsencrypt:        '.letsencrypt' |         dns_provider_credentials: 'textarea[name="meta[dns_provider_credentials]"]', | ||||||
|  |         propagation_seconds:      'input[name="meta[propagation_seconds]"]', | ||||||
|  |         forward_scheme:           'select[name="forward_scheme"]', | ||||||
|  |         letsencrypt:              '.letsencrypt' | ||||||
|     }, |     }, | ||||||
|  |  | ||||||
|     regions: { |     regions: { | ||||||
| @@ -49,7 +54,7 @@ module.exports = Mn.View.extend({ | |||||||
|             let id = this.ui.certificate_select.val(); |             let id = this.ui.certificate_select.val(); | ||||||
|             if (id === 'new') { |             if (id === 'new') { | ||||||
|                 this.ui.letsencrypt.show().find('input').prop('disabled', false); |                 this.ui.letsencrypt.show().find('input').prop('disabled', false); | ||||||
|                 this.ui.cloudflare.hide(); |                 this.ui.dns_challenge_content.hide(); | ||||||
|             } else { |             } else { | ||||||
|                 this.ui.letsencrypt.hide().find('input').prop('disabled', true); |                 this.ui.letsencrypt.hide().find('input').prop('disabled', true); | ||||||
|             } |             } | ||||||
| @@ -95,14 +100,31 @@ module.exports = Mn.View.extend({ | |||||||
|             } |             } | ||||||
|         }, |         }, | ||||||
|  |  | ||||||
|         'change @ui.cloudflare_switch': function() { |         'change @ui.dns_challenge_switch': function () { | ||||||
|             let checked = this.ui.cloudflare_switch.prop('checked'); |             const checked = this.ui.dns_challenge_switch.prop('checked'); | ||||||
|             if (checked) {                 |             if (checked) { | ||||||
|                 this.ui.cloudflare_token.prop('required', 'required'); |                 this.ui.dns_provider.prop('required', 'required'); | ||||||
|                 this.ui.cloudflare.show(); |                 const selected_provider = this.ui.dns_provider[0].options[this.ui.dns_provider[0].selectedIndex].value; | ||||||
|             } else {                 |                 if(selected_provider != '' && dns_providers[selected_provider].credentials !== false){ | ||||||
|                 this.ui.cloudflare_token.prop('required', false); |                     this.ui.dns_provider_credentials.prop('required', 'required'); | ||||||
|                 this.ui.cloudflare.hide();                 |                 } | ||||||
|  |                 this.ui.dns_challenge_content.show(); | ||||||
|  |             } else { | ||||||
|  |                 this.ui.dns_provider.prop('required', false); | ||||||
|  |                 this.ui.dns_provider_credentials.prop('required', false); | ||||||
|  |                 this.ui.dns_challenge_content.hide();                 | ||||||
|  |             } | ||||||
|  |         }, | ||||||
|  |  | ||||||
|  |         'change @ui.dns_provider': function () { | ||||||
|  |             const selected_provider = this.ui.dns_provider[0].options[this.ui.dns_provider[0].selectedIndex].value; | ||||||
|  |             if (selected_provider != '' && dns_providers[selected_provider].credentials !== false) { | ||||||
|  |                 this.ui.dns_provider_credentials.prop('required', 'required'); | ||||||
|  |                 this.ui.dns_provider_credentials[0].value = dns_providers[selected_provider].credentials; | ||||||
|  |                 this.ui.credentials_file_content.show(); | ||||||
|  |             } else { | ||||||
|  |                 this.ui.dns_provider_credentials.prop('required', false); | ||||||
|  |                 this.ui.credentials_file_content.hide();                 | ||||||
|             } |             } | ||||||
|         }, |         }, | ||||||
|  |  | ||||||
| @@ -143,6 +165,7 @@ module.exports = Mn.View.extend({ | |||||||
|             data.hsts_enabled            = !!data.hsts_enabled; |             data.hsts_enabled            = !!data.hsts_enabled; | ||||||
|             data.hsts_subdomains         = !!data.hsts_subdomains; |             data.hsts_subdomains         = !!data.hsts_subdomains; | ||||||
|             data.ssl_forced              = !!data.ssl_forced; |             data.ssl_forced              = !!data.ssl_forced; | ||||||
|  |             data.meta.dns_challenge      = !!data.meta.dns_challenge; | ||||||
|  |  | ||||||
|             if (typeof data.domain_names === 'string' && data.domain_names) { |             if (typeof data.domain_names === 'string' && data.domain_names) { | ||||||
|                 data.domain_names = data.domain_names.split(','); |                 data.domain_names = data.domain_names.split(','); | ||||||
| @@ -151,7 +174,7 @@ module.exports = Mn.View.extend({ | |||||||
|             // Check for any domain names containing wildcards, which are not allowed with letsencrypt |             // Check for any domain names containing wildcards, which are not allowed with letsencrypt | ||||||
|             if (data.certificate_id === 'new') {                 |             if (data.certificate_id === 'new') {                 | ||||||
|                 let domain_err = false; |                 let domain_err = false; | ||||||
|                 if (!data.meta.cloudflare_use) { |                 if (!data.meta.dns_challenge) { | ||||||
|                     data.domain_names.map(function (name) { |                     data.domain_names.map(function (name) { | ||||||
|                         if (name.match(/\*/im)) { |                         if (name.match(/\*/im)) { | ||||||
|                             domain_err = true; |                             domain_err = true; | ||||||
| @@ -160,11 +183,10 @@ module.exports = Mn.View.extend({ | |||||||
|                 } |                 } | ||||||
|  |  | ||||||
|                 if (domain_err) { |                 if (domain_err) { | ||||||
|                     alert('Cannot request Let\'s Encrypt Certificate for wildcard domains without CloudFlare DNS.'); |                     alert(i18n('ssl', 'no-wildcard-without-dns')); | ||||||
|                     return; |                     return; | ||||||
|                 } |                 } | ||||||
|  |  | ||||||
|                 data.meta.cloudflare_use = data.meta.cloudflare_use === '1'; |  | ||||||
|                 data.meta.letsencrypt_agree = data.meta.letsencrypt_agree === '1';                 |                 data.meta.letsencrypt_agree = data.meta.letsencrypt_agree === '1';                 | ||||||
|             } else { |             } else { | ||||||
|                 data.certificate_id = parseInt(data.certificate_id, 10); |                 data.certificate_id = parseInt(data.certificate_id, 10); | ||||||
| @@ -204,7 +226,20 @@ module.exports = Mn.View.extend({ | |||||||
|     templateContext: { |     templateContext: { | ||||||
|         getLetsencryptEmail: function () { |         getLetsencryptEmail: function () { | ||||||
|             return App.Cache.User.get('email'); |             return App.Cache.User.get('email'); | ||||||
|         } |         }, | ||||||
|  |         getUseDnsChallenge: function () { | ||||||
|  |             return typeof this.meta.dns_challenge !== 'undefined' ? this.meta.dns_challenge : false; | ||||||
|  |         }, | ||||||
|  |         getDnsProvider: function () { | ||||||
|  |             return typeof this.meta.dns_provider !== 'undefined' && this.meta.dns_provider != '' ? this.meta.dns_provider : null; | ||||||
|  |         }, | ||||||
|  |         getDnsProviderCredentials: function () { | ||||||
|  |             return typeof this.meta.dns_provider_credentials !== 'undefined' ? this.meta.dns_provider_credentials : ''; | ||||||
|  |         }, | ||||||
|  |         getPropagationSeconds: function () { | ||||||
|  |             return typeof this.meta.propagation_seconds !== 'undefined' ? this.meta.propagation_seconds : ''; | ||||||
|  |         }, | ||||||
|  |         dns_plugins: dns_providers, | ||||||
|     }, |     }, | ||||||
|  |  | ||||||
|     onRender: function () { |     onRender: function () { | ||||||
| @@ -258,6 +293,8 @@ module.exports = Mn.View.extend({ | |||||||
|         }); |         }); | ||||||
|  |  | ||||||
|         // Certificates |         // Certificates | ||||||
|  |         this.ui.dns_challenge_content.hide(); | ||||||
|  |         this.ui.credentials_file_content.hide(); | ||||||
|         this.ui.letsencrypt.hide(); |         this.ui.letsencrypt.hide(); | ||||||
|         this.ui.certificate_select.selectize({ |         this.ui.certificate_select.selectize({ | ||||||
|             valueField:       'id', |             valueField:       'id', | ||||||
|   | |||||||
| @@ -97,21 +97,92 @@ | |||||||
|                             </div> |                             </div> | ||||||
|                         </div> |                         </div> | ||||||
|  |  | ||||||
|                         <!-- CloudFlare --> |                         <!-- DNS challenge --> | ||||||
|                         <div class="col-sm-12 col-md-12 letsencrypt"> |                         <div class="col-sm-12 col-md-12 letsencrypt"> | ||||||
|                             <div class="form-group"> |                             <div class="form-group"> | ||||||
|                                 <label class="custom-switch"> |                                 <label class="custom-switch"> | ||||||
|                                     <input type="checkbox" class="custom-switch-input" name="meta[cloudflare_use]" value="1"> |                                     <input  | ||||||
|  |                                         type="checkbox"  | ||||||
|  |                                         class="custom-switch-input"  | ||||||
|  |                                         name="meta[dns_challenge]"  | ||||||
|  |                                         value="1"  | ||||||
|  |                                         <%- getUseDnsChallenge() ? 'checked' : '' %> | ||||||
|  |                                     > | ||||||
|                                     <span class="custom-switch-indicator"></span> |                                     <span class="custom-switch-indicator"></span> | ||||||
|                                     <span class="custom-switch-description"><%= i18n('ssl', 'use-cloudflare') %></span> |                                     <span class="custom-switch-description"><%= i18n('ssl', 'dns-challenge') %></span> | ||||||
|                                 </label> |                                 </label> | ||||||
|                             </div> |                             </div> | ||||||
|                         </div> |                         </div> | ||||||
|                         <div class="col-sm-12 col-md-12 cloudflare letsencrypt"> |                         <div class="col-sm-12 col-md-12 letsencrypt"> | ||||||
|                             <div class="form-group"> |                             <fieldset class="form-fieldset dns-challenge"> | ||||||
|                                 <label class="form-label">CloudFlare DNS API Token  <span class="form-required">*</span></label> |                                 <div class="text-red mb-4"><i class="fe fe-alert-triangle"></i> <%= i18n('ssl', 'certbot-warning') %></div> | ||||||
|                                 <input type="text" name="meta[cloudflare_token]" class="form-control" id="cloudflare_token"> |  | ||||||
|                             </div> |                                 <!-- Certbot DNS plugin selection --> | ||||||
|  |                                 <div class="row"> | ||||||
|  |                                     <div class="col-sm-12 col-md-12"> | ||||||
|  |                                         <div class="form-group"> | ||||||
|  |                                             <label class="form-label"><%- i18n('ssl', 'dns-provider') %> <span class="form-required">*</span></label> | ||||||
|  |                                             <select  | ||||||
|  |                                                 name="meta[dns_provider]"  | ||||||
|  |                                                 id="dns_provider" | ||||||
|  |                                                 class="form-control custom-select" | ||||||
|  |                                             > | ||||||
|  |                                                 <option  | ||||||
|  |                                                     value=""  | ||||||
|  |                                                     disabled  | ||||||
|  |                                                     hidden | ||||||
|  |                                                     <%- getDnsProvider() === null ? 'selected' : '' %> | ||||||
|  |                                                 >Please Choose...</option> | ||||||
|  |                                                 <% _.each(dns_plugins, function(plugin_info, plugin_name){ %> | ||||||
|  |                                                 <option  | ||||||
|  |                                                     value="<%- plugin_name %>" | ||||||
|  |                                                     <%- getDnsProvider() === plugin_name ? 'selected' : '' %> | ||||||
|  |                                                 ><%- plugin_info.display_name %></option> | ||||||
|  |                                                 <% }); %> | ||||||
|  |                                             </select> | ||||||
|  |                                         </div> | ||||||
|  |                                     </div> | ||||||
|  |                                 </div> | ||||||
|  |  | ||||||
|  |                                 <!-- Certbot credentials file content --> | ||||||
|  |                                 <div class="row credentials-file-content"> | ||||||
|  |                                     <div class="col-sm-12 col-md-12"> | ||||||
|  |                                         <div class="form-group"> | ||||||
|  |                                             <label class="form-label"><%- i18n('ssl', 'credentials-file-content') %> <span class="form-required">*</span></label> | ||||||
|  |                                             <textarea  | ||||||
|  |                                                 name="meta[dns_provider_credentials]"  | ||||||
|  |                                                 class="form-control text-monospace"  | ||||||
|  |                                                 id="dns_provider_credentials"  | ||||||
|  |                                             ><%- getDnsProviderCredentials() %></textarea> | ||||||
|  |                                             <div class="text-secondary small"> | ||||||
|  |                                                 <i class="fe fe-info"></i>  | ||||||
|  |                                                 <%= i18n('ssl', 'credentials-file-content-info') %> | ||||||
|  |                                             </div> | ||||||
|  |                                         </div> | ||||||
|  |                                     </div> | ||||||
|  |                                 </div> | ||||||
|  |  | ||||||
|  |                                 <!-- DNS propagation delay --> | ||||||
|  |                                 <div class="row"> | ||||||
|  |                                     <div class="col-sm-12 col-md-12"> | ||||||
|  |                                         <div class="form-group mb-0"> | ||||||
|  |                                             <label class="form-label"><%- i18n('ssl', 'propagation-seconds') %></label> | ||||||
|  |                                             <input  | ||||||
|  |                                                 type="number" | ||||||
|  |                                                 min="0" | ||||||
|  |                                                 name="meta[propagation_seconds]"  | ||||||
|  |                                                 class="form-control"  | ||||||
|  |                                                 id="propagation_seconds"  | ||||||
|  |                                                 value="<%- getPropagationSeconds() %>" | ||||||
|  |                                             > | ||||||
|  |                                             <div class="text-secondary small"> | ||||||
|  |                                                 <i class="fe fe-info"></i>  | ||||||
|  |                                                 <%= i18n('ssl', 'propagation-seconds-info') %> | ||||||
|  |                                             </div> | ||||||
|  |                                         </div> | ||||||
|  |                                     </div> | ||||||
|  |                                 </div> | ||||||
|  |                             </fieldset> | ||||||
|                         </div> |                         </div> | ||||||
|  |  | ||||||
|                         <!-- Lets encrypt --> |                         <!-- Lets encrypt --> | ||||||
|   | |||||||
| @@ -4,6 +4,9 @@ const RedirectionHostModel = require('../../../models/redirection-host'); | |||||||
| const template             = require('./form.ejs'); | const template             = require('./form.ejs'); | ||||||
| const certListItemTemplate = require('../certificates-list-item.ejs'); | const certListItemTemplate = require('../certificates-list-item.ejs'); | ||||||
| const Helpers              = require('../../../lib/helpers'); | const Helpers              = require('../../../lib/helpers'); | ||||||
|  | const i18n                 = require('../../i18n'); | ||||||
|  | const dns_providers        = require('../../../../../utils/certbot-dns-plugins'); | ||||||
|  |  | ||||||
|  |  | ||||||
| require('jquery-serializejson'); | require('jquery-serializejson'); | ||||||
| require('selectize'); | require('selectize'); | ||||||
| @@ -13,20 +16,23 @@ module.exports = Mn.View.extend({ | |||||||
|     className: 'modal-dialog', |     className: 'modal-dialog', | ||||||
|  |  | ||||||
|     ui: { |     ui: { | ||||||
|         form:               'form', |         form:                     'form', | ||||||
|         domain_names:       'input[name="domain_names"]', |         domain_names:             'input[name="domain_names"]', | ||||||
|         buttons:            '.modal-footer button', |         buttons:                  '.modal-footer button', | ||||||
|         cancel:             'button.cancel', |         cancel:                   'button.cancel', | ||||||
|         save:               'button.save', |         save:                     'button.save', | ||||||
|         certificate_select: 'select[name="certificate_id"]', |         certificate_select:       'select[name="certificate_id"]', | ||||||
|         ssl_forced:         'input[name="ssl_forced"]', |         ssl_forced:               'input[name="ssl_forced"]', | ||||||
|         hsts_enabled:       'input[name="hsts_enabled"]', |         hsts_enabled:             'input[name="hsts_enabled"]', | ||||||
|         hsts_subdomains:    'input[name="hsts_subdomains"]', |         hsts_subdomains:          'input[name="hsts_subdomains"]', | ||||||
|         http2_support:      'input[name="http2_support"]', |         http2_support:            'input[name="http2_support"]', | ||||||
|         cloudflare_switch:  'input[name="meta[cloudflare_use]"]', |         dns_challenge_switch:     'input[name="meta[dns_challenge]"]', | ||||||
|         cloudflare_token:   'input[name="meta[cloudflare_token]"', |         dns_challenge_content:    '.dns-challenge', | ||||||
|         cloudflare:         '.cloudflare', |         dns_provider:             'select[name="meta[dns_provider]"]', | ||||||
|         letsencrypt:        '.letsencrypt' |         credentials_file_content: '.credentials-file-content', | ||||||
|  |         dns_provider_credentials: 'textarea[name="meta[dns_provider_credentials]"]', | ||||||
|  |         propagation_seconds:      'input[name="meta[propagation_seconds]"]', | ||||||
|  |         letsencrypt:              '.letsencrypt' | ||||||
|     }, |     }, | ||||||
|  |  | ||||||
|     events: { |     events: { | ||||||
| @@ -34,7 +40,7 @@ module.exports = Mn.View.extend({ | |||||||
|             let id = this.ui.certificate_select.val(); |             let id = this.ui.certificate_select.val(); | ||||||
|             if (id === 'new') { |             if (id === 'new') { | ||||||
|                 this.ui.letsencrypt.show().find('input').prop('disabled', false); |                 this.ui.letsencrypt.show().find('input').prop('disabled', false); | ||||||
|                 this.ui.cloudflare.hide(); |                 this.ui.dns_challenge_content.hide(); | ||||||
|             } else { |             } else { | ||||||
|                 this.ui.letsencrypt.hide().find('input').prop('disabled', true); |                 this.ui.letsencrypt.hide().find('input').prop('disabled', true); | ||||||
|             } |             } | ||||||
| @@ -80,14 +86,31 @@ module.exports = Mn.View.extend({ | |||||||
|             } |             } | ||||||
|         }, |         }, | ||||||
|  |  | ||||||
|         'change @ui.cloudflare_switch': function() { |         'change @ui.dns_challenge_switch': function () { | ||||||
|             let checked = this.ui.cloudflare_switch.prop('checked'); |             const checked = this.ui.dns_challenge_switch.prop('checked'); | ||||||
|             if (checked) {                 |             if (checked) { | ||||||
|                 this.ui.cloudflare_token.prop('required', 'required'); |                 this.ui.dns_provider.prop('required', 'required'); | ||||||
|                 this.ui.cloudflare.show(); |                 const selected_provider = this.ui.dns_provider[0].options[this.ui.dns_provider[0].selectedIndex].value; | ||||||
|             } else {                 |                 if(selected_provider != '' && dns_providers[selected_provider].credentials !== false){ | ||||||
|                 this.ui.cloudflare_token.prop('required', false); |                     this.ui.dns_provider_credentials.prop('required', 'required'); | ||||||
|                 this.ui.cloudflare.hide();                 |                 } | ||||||
|  |                 this.ui.dns_challenge_content.show(); | ||||||
|  |             } else { | ||||||
|  |                 this.ui.dns_provider.prop('required', false); | ||||||
|  |                 this.ui.dns_provider_credentials.prop('required', false); | ||||||
|  |                 this.ui.dns_challenge_content.hide();                 | ||||||
|  |             } | ||||||
|  |         }, | ||||||
|  |  | ||||||
|  |         'change @ui.dns_provider': function () { | ||||||
|  |             const selected_provider = this.ui.dns_provider[0].options[this.ui.dns_provider[0].selectedIndex].value; | ||||||
|  |             if (selected_provider != '' && dns_providers[selected_provider].credentials !== false) { | ||||||
|  |                 this.ui.dns_provider_credentials.prop('required', 'required'); | ||||||
|  |                 this.ui.dns_provider_credentials[0].value = dns_providers[selected_provider].credentials; | ||||||
|  |                 this.ui.credentials_file_content.show(); | ||||||
|  |             } else { | ||||||
|  |                 this.ui.dns_provider_credentials.prop('required', false); | ||||||
|  |                 this.ui.credentials_file_content.hide();                 | ||||||
|             } |             } | ||||||
|         }, |         }, | ||||||
|  |  | ||||||
| @@ -103,12 +126,13 @@ module.exports = Mn.View.extend({ | |||||||
|             let data = this.ui.form.serializeJSON(); |             let data = this.ui.form.serializeJSON(); | ||||||
|  |  | ||||||
|             // Manipulate |             // Manipulate | ||||||
|             data.block_exploits  = !!data.block_exploits; |             data.block_exploits     = !!data.block_exploits; | ||||||
|             data.preserve_path   = !!data.preserve_path; |             data.preserve_path      = !!data.preserve_path; | ||||||
|             data.http2_support   = !!data.http2_support; |             data.http2_support      = !!data.http2_support; | ||||||
|             data.hsts_enabled    = !!data.hsts_enabled; |             data.hsts_enabled       = !!data.hsts_enabled; | ||||||
|             data.hsts_subdomains = !!data.hsts_subdomains; |             data.hsts_subdomains    = !!data.hsts_subdomains; | ||||||
|             data.ssl_forced      = !!data.ssl_forced; |             data.ssl_forced         = !!data.ssl_forced; | ||||||
|  |             data.meta.dns_challenge = !!data.meta.dns_challenge; | ||||||
|  |  | ||||||
|             if (typeof data.domain_names === 'string' && data.domain_names) { |             if (typeof data.domain_names === 'string' && data.domain_names) { | ||||||
|                 data.domain_names = data.domain_names.split(','); |                 data.domain_names = data.domain_names.split(','); | ||||||
| @@ -117,7 +141,7 @@ module.exports = Mn.View.extend({ | |||||||
|             // Check for any domain names containing wildcards, which are not allowed with letsencrypt |             // Check for any domain names containing wildcards, which are not allowed with letsencrypt | ||||||
|             if (data.certificate_id === 'new') {                 |             if (data.certificate_id === 'new') {                 | ||||||
|                 let domain_err = false; |                 let domain_err = false; | ||||||
|                 if (!data.meta.cloudflare_use) { |                 if (!data.meta.dns_challenge) { | ||||||
|                     data.domain_names.map(function (name) { |                     data.domain_names.map(function (name) { | ||||||
|                         if (name.match(/\*/im)) { |                         if (name.match(/\*/im)) { | ||||||
|                             domain_err = true; |                             domain_err = true; | ||||||
| @@ -126,7 +150,7 @@ module.exports = Mn.View.extend({ | |||||||
|                 } |                 } | ||||||
|  |  | ||||||
|                 if (domain_err) { |                 if (domain_err) { | ||||||
|                     alert('Cannot request Let\'s Encrypt Certificate for wildcard domains without CloudFlare DNS.'); |                     alert(i18n('ssl', 'no-wildcard-without-dns')); | ||||||
|                     return; |                     return; | ||||||
|                 } |                 } | ||||||
|  |  | ||||||
| @@ -170,7 +194,20 @@ module.exports = Mn.View.extend({ | |||||||
|     templateContext: { |     templateContext: { | ||||||
|         getLetsencryptEmail: function () { |         getLetsencryptEmail: function () { | ||||||
|             return App.Cache.User.get('email'); |             return App.Cache.User.get('email'); | ||||||
|         } |         }, | ||||||
|  |         getUseDnsChallenge: function () { | ||||||
|  |             return typeof this.meta.dns_challenge !== 'undefined' ? this.meta.dns_challenge : false; | ||||||
|  |         }, | ||||||
|  |         getDnsProvider: function () { | ||||||
|  |             return typeof this.meta.dns_provider !== 'undefined' && this.meta.dns_provider != '' ? this.meta.dns_provider : null; | ||||||
|  |         }, | ||||||
|  |         getDnsProviderCredentials: function () { | ||||||
|  |             return typeof this.meta.dns_provider_credentials !== 'undefined' ? this.meta.dns_provider_credentials : ''; | ||||||
|  |         }, | ||||||
|  |         getPropagationSeconds: function () { | ||||||
|  |             return typeof this.meta.propagation_seconds !== 'undefined' ? this.meta.propagation_seconds : ''; | ||||||
|  |         }, | ||||||
|  |         dns_plugins: dns_providers, | ||||||
|     }, |     }, | ||||||
|  |  | ||||||
|     onRender: function () { |     onRender: function () { | ||||||
| @@ -191,6 +228,8 @@ module.exports = Mn.View.extend({ | |||||||
|         }); |         }); | ||||||
|  |  | ||||||
|         // Certificates |         // Certificates | ||||||
|  |         this.ui.dns_challenge_content.hide(); | ||||||
|  |         this.ui.credentials_file_content.hide(); | ||||||
|         this.ui.letsencrypt.hide(); |         this.ui.letsencrypt.hide(); | ||||||
|         this.ui.certificate_select.selectize({ |         this.ui.certificate_select.selectize({ | ||||||
|             valueField:       'id', |             valueField:       'id', | ||||||
|   | |||||||
| @@ -102,7 +102,15 @@ | |||||||
|       "letsencrypt-agree": "I Agree to the <a href=\"{url}\" target=\"_blank\">Let's Encrypt Terms of Service</a>", |       "letsencrypt-agree": "I Agree to the <a href=\"{url}\" target=\"_blank\">Let's Encrypt Terms of Service</a>", | ||||||
|       "delete-ssl": "The SSL certificates attached will NOT be removed, they will need to be removed manually.", |       "delete-ssl": "The SSL certificates attached will NOT be removed, they will need to be removed manually.", | ||||||
|       "hosts-warning": "These domains must be already configured to point to this installation", |       "hosts-warning": "These domains must be already configured to point to this installation", | ||||||
|       "use-cloudflare": "Use CloudFlare DNS verification"       |       "no-wildcard-without-dns": "Cannot request Let's Encrypt Certificate for wildcard domains when not using DNS challenge", | ||||||
|  |       "dns-challenge": "Use a DNS Challenge", | ||||||
|  |       "certbot-warning": "This section requires some knowledge about Certbot and its DNS plugins. Please consult the respective plugins documentation.", | ||||||
|  |       "dns-provider": "DNS Provider", | ||||||
|  |       "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", | ||||||
|  |       "propagation-seconds": "Propagation Seconds", | ||||||
|  |       "propagation-seconds-info": "Leave empty to use the plugins default value. Number of seconds to wait for DNS propagation." | ||||||
|     }, |     }, | ||||||
|     "proxy-hosts": { |     "proxy-hosts": { | ||||||
|       "title": "Proxy Hosts", |       "title": "Proxy Hosts", | ||||||
|   | |||||||
							
								
								
									
										160
									
								
								utils/certbot-dns-plugins.js
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										160
									
								
								utils/certbot-dns-plugins.js
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,160 @@ | |||||||
|  | /** | ||||||
|  |  * This file contains info about available Certbot DNS plugins. | ||||||
|  |  * | ||||||
|  |  * File Structure: | ||||||
|  |  * | ||||||
|  |  *  { | ||||||
|  |  *    cloudflare: { | ||||||
|  |  *      display_name: "Name displayed to the user", | ||||||
|  |  *      package_name: "Package name in PyPi repo", | ||||||
|  |  *      package_version: "Package version in PyPi repo", | ||||||
|  |  *      credentials: `Template of the credentials file`, | ||||||
|  |  *      full_plugin_name: "The full plugin name as used in the commandline with certbot, including prefixes, e.g. 'certbot-dns-njalla:dns-njalla'", | ||||||
|  |  *      credentials_file: Whether the plugin has a credentials file | ||||||
|  |  *    }, | ||||||
|  |  *    ... | ||||||
|  |  *  } | ||||||
|  |  * | ||||||
|  |  */ | ||||||
|  |  | ||||||
|  | module.exports = { | ||||||
|  |   cloudflare: { | ||||||
|  |     display_name: "Cloudflare", | ||||||
|  |     package_name: "certbot-dns-cloudflare", | ||||||
|  |     package_version: "1.8.0", | ||||||
|  |     credentials: `# Cloudflare API token | ||||||
|  | dns_cloudflare_api_token = 0123456789abcdef0123456789abcdef01234567`, | ||||||
|  |     full_plugin_name: "dns-cloudflare", | ||||||
|  |   }, | ||||||
|  |   //####################################################// | ||||||
|  |   cloudxns: { | ||||||
|  |     display_name: "CloudXNS", | ||||||
|  |     package_name: "certbot-dns-cloudxns", | ||||||
|  |     package_version: "1.8.0", | ||||||
|  |     credentials: `dns_cloudxns_api_key = 1234567890abcdef1234567890abcdef | ||||||
|  | dns_cloudxns_secret_key = 1122334455667788`, | ||||||
|  |     full_plugin_name: "dns-cloudxns", | ||||||
|  |   }, | ||||||
|  |   //####################################################// | ||||||
|  |   digitalocean: { | ||||||
|  |     display_name: "DigitalOcean", | ||||||
|  |     package_name: "certbot-dns-digitalocean", | ||||||
|  |     package_version: "1.8.0", | ||||||
|  |     credentials: `dns_digitalocean_token = 0000111122223333444455556666777788889999aaaabbbbccccddddeeeeffff`, | ||||||
|  |     full_plugin_name: "dns-digitalocean", | ||||||
|  |   }, | ||||||
|  |   //####################################################// | ||||||
|  |   dnsimple: { | ||||||
|  |     display_name: "DNSimple", | ||||||
|  |     package_name: "certbot-dns-dnsimple", | ||||||
|  |     package_version: "1.8.0", | ||||||
|  |     credentials: `dns_dnsimple_token = MDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAw`, | ||||||
|  |     full_plugin_name: "dns-dnsimple", | ||||||
|  |   }, | ||||||
|  |   //####################################################// | ||||||
|  |   dnsmadeeasy: { | ||||||
|  |     display_name: "DNS Made Easy", | ||||||
|  |     package_name: "certbot-dns-dnsmadeeasy", | ||||||
|  |     package_version: "1.8.0", | ||||||
|  |     credentials: `dns_dnsmadeeasy_api_key = 1c1a3c91-4770-4ce7-96f4-54c0eb0e457a | ||||||
|  | dns_dnsmadeeasy_secret_key = c9b5625f-9834-4ff8-baba-4ed5f32cae55`, | ||||||
|  |     full_plugin_name: "dns-dnsmadeeasy", | ||||||
|  |   }, | ||||||
|  |   //####################################################// | ||||||
|  |   google: { | ||||||
|  |     display_name: "Google", | ||||||
|  |     package_name: "certbot-dns-google", | ||||||
|  |     package_version: "1.8.0", | ||||||
|  |     credentials: `{ | ||||||
|  |   "type": "service_account", | ||||||
|  |   ... | ||||||
|  | }`, | ||||||
|  |     full_plugin_name: "dns-google", | ||||||
|  |   }, | ||||||
|  |   //####################################################// | ||||||
|  |   hetzner: { | ||||||
|  |     display_name: "Hetzner", | ||||||
|  |     package_name: "certbot-dns-hetzner", | ||||||
|  |     package_version: "1.0.4", | ||||||
|  |     credentials: `certbot_dns_hetzner:dns_hetzner_api_token = 0123456789abcdef0123456789abcdef`, | ||||||
|  |     full_plugin_name: "certbot-dns-hetzner:dns-hetzner", | ||||||
|  |   }, | ||||||
|  |   //####################################################// | ||||||
|  |   linode: { | ||||||
|  |     display_name: "Linode", | ||||||
|  |     package_name: "certbot-dns-linode", | ||||||
|  |     package_version: "1.8.0", | ||||||
|  |     credentials: `dns_linode_key = 0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ64 | ||||||
|  | dns_linode_version = [<blank>|3|4]`, | ||||||
|  |     full_plugin_name: "dns-linode", | ||||||
|  |   }, | ||||||
|  |   //####################################################// | ||||||
|  |   luadns: { | ||||||
|  |     display_name: "LuaDNS", | ||||||
|  |     package_name: "certbot-dns-luadns", | ||||||
|  |     package_version: "1.8.0", | ||||||
|  |     credentials: `dns_luadns_email = user@example.com | ||||||
|  | dns_luadns_token = 0123456789abcdef0123456789abcdef`, | ||||||
|  |     full_plugin_name: "dns-luadns", | ||||||
|  |   }, | ||||||
|  |   //####################################################// | ||||||
|  |   netcup: { | ||||||
|  |     display_name: "netcup", | ||||||
|  |     package_name: "certbot-dns-netcup", | ||||||
|  |     package_version: "1.0.0", | ||||||
|  |     credentials: `certbot_dns_njalla:dns_njalla_token = 0123456789abcdef0123456789abcdef01234567`, | ||||||
|  |     full_plugin_name: "certbot-dns-netcup:dns-netcup", | ||||||
|  |   }, | ||||||
|  |   //####################################################// | ||||||
|  |   njalla: { | ||||||
|  |     display_name: "Njalla", | ||||||
|  |     package_name: "certbot-dns-nsone", | ||||||
|  |     package_version: "0.0.4", | ||||||
|  |     credentials: `certbot_dns_njalla:dns_njalla_token = 0123456789abcdef0123456789abcdef01234567`, | ||||||
|  |     full_plugin_name: "certbot-dns-njalla:dns-njalla", | ||||||
|  |   }, | ||||||
|  |   //####################################################// | ||||||
|  |   nsone: { | ||||||
|  |     display_name: "NS1", | ||||||
|  |     package_name: "certbot-dns-nsone", | ||||||
|  |     package_version: "1.8.0", | ||||||
|  |     credentials: `dns_nsone_api_key = MDAwMDAwMDAwMDAwMDAw`, | ||||||
|  |     full_plugin_name: "dns-nsone", | ||||||
|  |   }, | ||||||
|  |   //####################################################// | ||||||
|  |   ovh: { | ||||||
|  |     display_name: "OVH", | ||||||
|  |     package_name: "certbot-dns-ovh", | ||||||
|  |     package_version: "1.8.0", | ||||||
|  |     credentials: `dns_ovh_endpoint = ovh-eu | ||||||
|  | dns_ovh_application_key = MDAwMDAwMDAwMDAw | ||||||
|  | dns_ovh_application_secret = MDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAw | ||||||
|  | dns_ovh_consumer_key = MDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAw`, | ||||||
|  |     full_plugin_name: "dns-ovh", | ||||||
|  |   }, | ||||||
|  |   //####################################################// | ||||||
|  |   rfc2136: { | ||||||
|  |     display_name: "RFC 2136", | ||||||
|  |     package_name: "certbot-dns-rfc2136", | ||||||
|  |     package_version: "1.8.0", | ||||||
|  |     credentials: `# Target DNS server | ||||||
|  | dns_rfc2136_server = 192.0.2.1 | ||||||
|  | # Target DNS port | ||||||
|  | dns_rfc2136_port = 53 | ||||||
|  | # TSIG key name | ||||||
|  | dns_rfc2136_name = keyname. | ||||||
|  | # TSIG key secret | ||||||
|  | dns_rfc2136_secret = 4q4wM/2I180UXoMyN4INVhJNi8V9BCV+jMw2mXgZw/CSuxUT8C7NKKFs AmKd7ak51vWKgSl12ib86oQRPkpDjg== | ||||||
|  | # TSIG key algorithm | ||||||
|  | dns_rfc2136_algorithm = HMAC-SHA512`, | ||||||
|  |     full_plugin_name: "dns-rfc2136", | ||||||
|  |   }, | ||||||
|  |   //####################################################// | ||||||
|  |   route53: { | ||||||
|  |     display_name: "Route 53 (Amazon)", | ||||||
|  |     package_name: "certbot-dns-route53", | ||||||
|  |     package_version: "1.8.0", | ||||||
|  |     credentials: false, | ||||||
|  |     full_plugin_name: "dns-route53", | ||||||
|  |   }, | ||||||
|  | }; | ||||||
		Reference in New Issue
	
	Block a user