浏览代码

Merge branch 'develop'

chaptergy 4 年之前
父节点
当前提交
ab026e5e18

+ 1 - 1
backend/internal/certificate.js

@@ -869,7 +869,7 @@ const internalCertificate = {
 
 		const credentialsLocation = '/etc/letsencrypt/credentials/credentials-' + certificate.id;
 		const credentialsCmd      = 'mkdir -p /etc/letsencrypt/credentials 2> /dev/null; echo \'' + certificate.meta.dns_provider_credentials.replace('\'', '\\\'') + '\' > \'' + credentialsLocation + '\' && chmod 600 \'' + credentialsLocation + '\'';
-		const prepareCmd          = 'pip install ' + dns_plugin.package_name + '==' + dns_plugin.package_version + ' ' + dns_plugin.dependencies;
+		const prepareCmd          = 'pip install ' + dns_plugin.package_name + (dns_plugin.version_requirement || '') + ' ' + dns_plugin.dependencies;
 
 		// Whether the plugin has a --<name>-credentials argument
 		const hasConfigArg = certificate.meta.dns_provider !== 'route53';

+ 1 - 1
backend/package.json

@@ -25,7 +25,7 @@
 		"mysql": "^2.18.1",
 		"node-rsa": "^1.0.8",
 		"nodemon": "^2.0.2",
-		"objection": "^2.1.3",
+		"objection": "^2.2.16",
 		"path": "^0.12.7",
 		"pg": "^7.12.1",
 		"restler": "^3.4.0",

+ 1 - 1
backend/setup.js

@@ -178,7 +178,7 @@ const setupCertbotPlugins = () => {
 				certificates.map(function (certificate) {
 					if (certificate.meta && certificate.meta.dns_challenge === true) {
 						const dns_plugin          = dns_plugins[certificate.meta.dns_provider];
-						const packages_to_install = `${dns_plugin.package_name}==${dns_plugin.package_version} ${dns_plugin.dependencies}`;
+						const packages_to_install = `${dns_plugin.package_name}${dns_plugin.version_requirement || ''} ${dns_plugin.dependencies}`;
 
 						if (plugins.indexOf(packages_to_install) === -1) plugins.push(packages_to_install);
 

+ 9 - 9
backend/yarn.lock

@@ -77,10 +77,10 @@ acorn@^7.1.1:
   resolved "https://registry.yarnpkg.com/acorn/-/acorn-7.4.0.tgz#e1ad486e6c54501634c6c397c5c121daa383607c"
   integrity sha512-+G7P8jJmCHr+S+cLfQxygbWhXy+8YTVGzAkpEbcLo2mLoL7tij/VG41QSHACSf5QgYRhMZYHuNc6drJaO0Da+w==
 
-ajv@^6.10.0, ajv@^6.10.2, ajv@^6.12.0:
-  version "6.12.3"
-  resolved "https://registry.yarnpkg.com/ajv/-/ajv-6.12.3.tgz#18c5af38a111ddeb4f2697bd78d68abc1cabd706"
-  integrity sha512-4K0cK3L1hsqk9xIb2z9vs/XU+PGJZ9PNpJRDS9YLzmNdX6jmVPfamLvTJr0aDAusnHyCHO6MjzlkAsgtqp9teA==
+ajv@^6.10.0, ajv@^6.10.2, ajv@^6.12.0, ajv@^6.12.6:
+  version "6.12.6"
+  resolved "https://registry.yarnpkg.com/ajv/-/ajv-6.12.6.tgz#baf5a62e802b07d977034586f8c3baf5adf26df4"
+  integrity sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==
   dependencies:
     fast-deep-equal "^3.1.1"
     fast-json-stable-stringify "^2.0.0"
@@ -2572,12 +2572,12 @@ object.pick@^1.2.0, object.pick@^1.3.0:
   dependencies:
     isobject "^3.0.1"
 
-objection@^2.1.3:
-  version "2.2.2"
-  resolved "https://registry.yarnpkg.com/objection/-/objection-2.2.2.tgz#1a3c9010270e3677940d2bc91aeaeb3c0f103800"
-  integrity sha512-+1Ap7u9NQRochzDW5/BggUlKi94JfZGTJwQJuNXo8DwmAb8czEirvxcWBcX91/MmQq0BQUJjM4RPSiZhnkkWQw==
+objection@^2.2.16:
+  version "2.2.16"
+  resolved "https://registry.yarnpkg.com/objection/-/objection-2.2.16.tgz#552ec6d625a7f80d6e204fc63732cbd3fc56f31c"
+  integrity sha512-sq8erZdxW5ruPUK6tVvwDxyO16U49XAn/BmOm2zaNhNA2phOPCe2/7+R70nDEF1SFrgJOrwDu/PtoxybuJxnjQ==
   dependencies:
-    ajv "^6.12.0"
+    ajv "^6.12.6"
     db-errors "^0.2.3"
 
 on-finished@~2.3.0:

+ 3 - 3
docs/yarn.lock

@@ -1624,9 +1624,9 @@ ansi-regex@^4.1.0:
   integrity sha512-1apePfXM1UOSqw0o9IiFAovVz9M5S1Dg+4TrDwfMewQ6p/rmMueb7tWZjQ1rx4Loy1ArBggoqGpfqqdI4rondg==
 
 ansi-regex@^5.0.0:
-  version "5.0.0"
-  resolved "https://registry.yarnpkg.com/ansi-regex/-/ansi-regex-5.0.0.tgz#388539f55179bf39339c81af30a654d69f87cb75"
-  integrity sha512-bY6fj56OUQ0hU1KjFNDQuJFezqKdrAyFdIevADiqrWHwSlbmBNMHp5ak2f40Pm8JTFyM2mqxkG6ngkHO11f/lg==
+  version "5.0.1"
+  resolved "https://registry.yarnpkg.com/ansi-regex/-/ansi-regex-5.0.1.tgz#082cb2c89c9fe8659a311a53bd6a4dc5301db304"
+  integrity sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==
 
 ansi-styles@^2.2.1:
   version "2.2.1"

+ 3 - 0
frontend/js/app/ui/header/main.ejs

@@ -1,5 +1,8 @@
 <div class="container">
     <div class="d-flex">
+        <button class="navbar-toggler d-lg-none mr-2" type="button" data-toggle="collapse" data-target="#menu">
+            <span class="navbar-toggler-icon"></span>
+        </button>
         <a class="navbar-brand" href="/">
             <img src="/images/favicons/favicon-32x32.png" border="0"> &nbsp; <%- i18n('main', 'app') %>
         </a>

+ 7 - 5
frontend/js/app/ui/main.ejs

@@ -1,9 +1,11 @@
 <div class="page-main">
-    <div class="header" id="header">
-        <!-- Header View -->
-    </div>
-    <div id="menu">
-        <!-- Menu View -->
+    <div class="navbar-light">
+        <div class="header" id="header">
+            <!-- Header View -->
+        </div>
+        <div id="menu">
+            <!-- Menu View -->
+        </div>
     </div>
     <div class="my-3 my-md-5">
         <div id="app-content" class="container">

+ 2 - 2
frontend/package.json

@@ -28,10 +28,10 @@
     "messageformat-loader": "^0.8.1",
     "mini-css-extract-plugin": "^0.9.0",
     "moment": "^2.24.0",
-    "node-sass": "^4.13.1",
+    "node-sass": "^6.0.1",
     "nodemon": "^2.0.2",
     "numeral": "^2.0.6",
-    "sass-loader": "^8.0.2",
+    "sass-loader": "10.2.0",
     "style-loader": "^1.1.3",
     "tabler-ui": "git+https://github.com/tabler/tabler.git#00f78ad823311bc3ad974ac3e5b0126198f0a813",
     "underscore": "^1.12.1",

文件差异内容过多而无法显示
+ 286 - 250
frontend/yarn.lock


+ 223 - 209
global/certbot-dns-plugins.js

@@ -9,7 +9,7 @@
  *    cloudflare: {
  *      display_name: "Name displayed to the user",
  *      package_name: "Package name in PyPi repo",
- *      package_version: "Package version in PyPi repo",
+ *      version_requirement: "Optional package version requirements (e.g. ==1.3 or >=1.2,<2.0, see https://www.python.org/dev/peps/pep-0440/#version-specifiers)",
  *      dependencies: "Additional dependencies, space separated (as you would pass it to pip install)",
  *      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'",
@@ -22,30 +22,30 @@
 module.exports = {
 	//####################################################//
 	acmedns: {
-		display_name:    'ACME-DNS',
-		package_name:    'certbot-dns-acmedns',
-		package_version: '0.1.0',
-		dependencies:    '',
-		credentials:     `certbot_dns_acmedns:dns_acmedns_api_url = http://acmedns-server/
+		display_name:        'ACME-DNS',
+		package_name:        'certbot-dns-acmedns',
+		version_requirement: '~=0.1.0',
+		dependencies:        '',
+		credentials:         `certbot_dns_acmedns:dns_acmedns_api_url = http://acmedns-server/
 certbot_dns_acmedns:dns_acmedns_registration_file = /data/acme-registration.json`,
 		full_plugin_name: 'certbot-dns-acmedns:dns-acmedns',
 	},
 	aliyun: {
-		display_name:    'Aliyun',
-		package_name:    'certbot-dns-aliyun',
-		package_version: '0.38.1',
-		dependencies:    '',
-		credentials:     `certbot_dns_aliyun:dns_aliyun_access_key = 12345678
+		display_name:        'Aliyun',
+		package_name:        'certbot-dns-aliyun',
+		version_requirement: '~=0.38.1',
+		dependencies:        '',
+		credentials:         `certbot_dns_aliyun:dns_aliyun_access_key = 12345678
 certbot_dns_aliyun:dns_aliyun_access_key_secret = 1234567890abcdef1234567890abcdef`,
 		full_plugin_name: 'certbot-dns-aliyun:dns-aliyun',
 	},
 	//####################################################//
 	azure: {
-		display_name:    'Azure',
-		package_name:    'certbot-dns-azure',
-		package_version: '1.2.0',
-		dependencies:    '',
-		credentials:     `# This plugin supported API authentication using either Service Principals or utilizing a Managed Identity assigned to the virtual machine.
+		display_name:        'Azure',
+		package_name:        'certbot-dns-azure',
+		version_requirement: '~=1.2.0',
+		dependencies:        '',
+		credentials:         `# This plugin supported API authentication using either Service Principals or utilizing a Managed Identity assigned to the virtual machine.
 # Regardless which authentication method used, the identity will need the “DNS Zone Contributor” role assigned to it.
 # As multiple Azure DNS Zones in multiple resource groups can exist, the config file needs a mapping of zone to resource group ID. Multiple zones -> ID mappings can be listed by using the key dns_azure_zoneX where X is a unique number. At least 1 zone mapping is required.
 
@@ -67,165 +67,175 @@ dns_azure_zone2 = example.org:/subscriptions/99800903-fb14-4992-9aff-12eaf274462
 	},
 	//####################################################//
 	cloudflare: {
-		display_name:    'Cloudflare',
-		package_name:    'certbot-dns-cloudflare',
-		package_version: '1.8.0',
-		dependencies:    'cloudflare',
-		credentials:     `# Cloudflare API token
+		display_name: 'Cloudflare',
+		package_name: 'certbot-dns-cloudflare',
+		// version_requirement: '', // Official plugin, no version requirement
+		dependencies: 'cloudflare',
+		credentials:  `# Cloudflare API token
 dns_cloudflare_api_token = 0123456789abcdef0123456789abcdef01234567`,
 		full_plugin_name: 'dns-cloudflare',
 	},
 	//####################################################//
 	cloudns: {
-		display_name:    'ClouDNS',
-		package_name:    'certbot-dns-cloudns',
-		package_version: '0.4.0',
-		dependencies:    '',
-		credentials:     `# Target user ID (see https://www.cloudns.net/api-settings/)
+		display_name:        'ClouDNS',
+		package_name:        'certbot-dns-cloudns',
+		version_requirement: '~=0.4.0',
+		dependencies:        '',
+		credentials:         `# Target user ID (see https://www.cloudns.net/api-settings/)
 	dns_cloudns_auth_id=1234
 	# Alternatively, one of the following two options can be set:
 	# dns_cloudns_sub_auth_id=1234
-	# dns_cloudns_sub_auth_user=foobar 
-	
+	# dns_cloudns_sub_auth_user=foobar
+
 	# API password
 	dns_cloudns_auth_password=password1`,
 		full_plugin_name: 'dns-cloudns',
 	},
 	//####################################################//
 	cloudxns: {
-		display_name:    'CloudXNS',
-		package_name:    'certbot-dns-cloudxns',
-		package_version: '1.8.0',
-		dependencies:    '',
-		credentials:     `dns_cloudxns_api_key = 1234567890abcdef1234567890abcdef
+		display_name: 'CloudXNS',
+		package_name: 'certbot-dns-cloudxns',
+		// version_requirement: '', // Official plugin, no version requirement
+		dependencies: '',
+		credentials:  `dns_cloudxns_api_key = 1234567890abcdef1234567890abcdef
 dns_cloudxns_secret_key = 1122334455667788`,
 		full_plugin_name: 'dns-cloudxns',
 	},
 	//####################################################//
 	corenetworks: {
-		display_name:    'Core Networks',
-		package_name:    'certbot-dns-corenetworks',
-		package_version: '0.1.4',
-		dependencies:    '',
-		credentials:     `certbot_dns_corenetworks:dns_corenetworks_username = asaHB12r
+		display_name:        'Core Networks',
+		package_name:        'certbot-dns-corenetworks',
+		version_requirement: '~=0.1.4',
+		dependencies:        '',
+		credentials:         `certbot_dns_corenetworks:dns_corenetworks_username = asaHB12r
 certbot_dns_corenetworks:dns_corenetworks_password = secure_password`,
 		full_plugin_name: 'certbot-dns-corenetworks:dns-corenetworks',
 	},
 	//####################################################//
 	cpanel: {
-		display_name:    'cPanel',
-		package_name:    'certbot-dns-cpanel',
-		package_version: '0.2.2',
-		dependencies:    '',
-		credentials:     `certbot_dns_cpanel:cpanel_url = https://cpanel.example.com:2083
+		display_name:        'cPanel',
+		package_name:        'certbot-dns-cpanel',
+		version_requirement: '~=0.2.2',
+		dependencies:        '',
+		credentials:         `certbot_dns_cpanel:cpanel_url = https://cpanel.example.com:2083
 certbot_dns_cpanel:cpanel_username = user
 certbot_dns_cpanel:cpanel_password = hunter2`,
 		full_plugin_name: 'certbot-dns-cpanel:cpanel',
 	},
 	//####################################################//
+	desec: {
+		display_name:        'deSEC',
+		package_name:        'certbot-dns-desec',
+		version_requirement: '~=0.3.0',
+		dependencies:        '',
+		credentials:         `certbot_dns_desec:dns_desec_token = YOUR_DESEC_API_TOKEN
+certbot_dns_desec:dns_desec_endpoint = https://desec.io/api/v1/`,
+		full_plugin_name: 'certbot-dns-desec:dns-desec',
+	},
+	//####################################################//
 	duckdns: {
-		display_name:     'DuckDNS',
-		package_name:     'certbot-dns-duckdns',
-		package_version:  '0.6',
-		dependencies:     '',
-		credentials:      'dns_duckdns_token=your-duckdns-token',
-		full_plugin_name: 'dns-duckdns',
+		display_name:        'DuckDNS',
+		package_name:        'certbot-dns-duckdns',
+		version_requirement: '~=0.6',
+		dependencies:        '',
+		credentials:         'dns_duckdns_token=your-duckdns-token',
+		full_plugin_name:    'dns-duckdns',
 	},
 	//####################################################//
 	digitalocean: {
 		display_name:     'DigitalOcean',
 		package_name:     'certbot-dns-digitalocean',
-		package_version:  '1.8.0',
+		// version_requirement: '', // Official plugin, no version requirement
 		dependencies:     '',
 		credentials:      'dns_digitalocean_token = 0000111122223333444455556666777788889999aaaabbbbccccddddeeeeffff',
 		full_plugin_name: 'dns-digitalocean',
 	},
 	//####################################################//
 	directadmin: {
-		display_name:    'DirectAdmin',
-		package_name:    'certbot-dns-directadmin',
-		package_version: '0.0.20',
-		dependencies:    '',
-		credentials:     `directadmin_url = https://my.directadminserver.com:2222
+		display_name:        'DirectAdmin',
+		package_name:        'certbot-dns-directadmin',
+		version_requirement: '~=0.0.23',
+		dependencies:        '',
+		credentials:         `directadmin_url = https://my.directadminserver.com:2222
 directadmin_username = username
 directadmin_password = aSuperStrongPassword`,
-		full_plugin_name: 'certbot-dns-directadmin:directadmin',
+		full_plugin_name: 'directadmin',
 	},
 	//####################################################//
 	dnsimple: {
 		display_name:     'DNSimple',
 		package_name:     'certbot-dns-dnsimple',
-		package_version:  '1.8.0',
+		// version_requirement: '', // Official plugin, no version requirement
 		dependencies:     '',
 		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',
-		dependencies:    '',
-		credentials:     `dns_dnsmadeeasy_api_key = 1c1a3c91-4770-4ce7-96f4-54c0eb0e457a
+		display_name: 'DNS Made Easy',
+		package_name: 'certbot-dns-dnsmadeeasy',
+		// version_requirement: '', // Official plugin, no version requirement
+		dependencies: '',
+		credentials:  `dns_dnsmadeeasy_api_key = 1c1a3c91-4770-4ce7-96f4-54c0eb0e457a
 dns_dnsmadeeasy_secret_key = c9b5625f-9834-4ff8-baba-4ed5f32cae55`,
 		full_plugin_name: 'dns-dnsmadeeasy',
 	},
 	//####################################################//
 	dnspod: {
-		display_name:    'DNSPod',
-		package_name:    'certbot-dns-dnspod',
-		package_version: '0.1.0',
-		dependencies:    '',
-		credentials:     `certbot_dns_dnspod:dns_dnspod_email = "DNSPOD-API-REQUIRES-A-VALID-EMAIL"
+		display_name:        'DNSPod',
+		package_name:        'certbot-dns-dnspod',
+		version_requirement: '~=0.1.0',
+		dependencies:        '',
+		credentials:         `certbot_dns_dnspod:dns_dnspod_email = "DNSPOD-API-REQUIRES-A-VALID-EMAIL"
 certbot_dns_dnspod:dns_dnspod_api_token = "DNSPOD-API-TOKEN"`,
 		full_plugin_name: 'certbot-dns-dnspod:dns-dnspod',
 	},
 	//####################################################//
 	dynu: {
-		display_name:     'Dynu',
-		package_name:     'certbot-dns-dynu',
-		package_version:  '0.0.1',
-		dependencies:     '',
-		credentials:      'certbot_dns_dynu:dns_dynu_auth_token = YOUR_DYNU_AUTH_TOKEN',
-		full_plugin_name: 'certbot-dns-dynu:dns-dynu',
+		display_name:        'Dynu',
+		package_name:        'certbot-dns-dynu',
+		version_requirement: '~=0.0.1',
+		dependencies:        '',
+		credentials:         'certbot_dns_dynu:dns_dynu_auth_token = YOUR_DYNU_AUTH_TOKEN',
+		full_plugin_name:    'certbot-dns-dynu:dns-dynu',
 	},
 	//####################################################//
 	eurodns: {
-		display_name:    'EuroDNS',
-		package_name:    'certbot-dns-eurodns',
-		package_version: '0.0.4',
-		dependencies:    '',
-		credentials:     `dns_eurodns_applicationId = myuser
+		display_name:        'EuroDNS',
+		package_name:        'certbot-dns-eurodns',
+		version_requirement: '~=0.0.4',
+		dependencies:        '',
+		credentials:         `dns_eurodns_applicationId = myuser
 dns_eurodns_apiKey = mysecretpassword
 dns_eurodns_endpoint = https://rest-api.eurodns.com/user-api-gateway/proxy`,
 		full_plugin_name: 'certbot-dns-eurodns:dns-eurodns',
 	},
 	//####################################################//
 	gandi: {
-		display_name:     'Gandi Live DNS',
-		package_name:     'certbot_plugin_gandi',
-		package_version:  '1.2.5',
-		dependencies:     '',
-		credentials:      'certbot_plugin_gandi:dns_api_key = APIKEY',
-		full_plugin_name: 'certbot-plugin-gandi:dns',
+		display_name:        'Gandi Live DNS',
+		package_name:        'certbot_plugin_gandi',
+		version_requirement: '~=1.2.5',
+		dependencies:        '',
+		credentials:         'certbot_plugin_gandi:dns_api_key = APIKEY',
+		full_plugin_name:    'certbot-plugin-gandi:dns',
 	},
 	//####################################################//
 	godaddy: {
-		display_name:    'GoDaddy',
-		package_name:    'certbot-dns-godaddy',
-		package_version: '0.2.0',
-		dependencies:    '',
-		credentials:     `dns_godaddy_secret = 0123456789abcdef0123456789abcdef01234567
+		display_name:        'GoDaddy',
+		package_name:        'certbot-dns-godaddy',
+		version_requirement: '~=0.2.0',
+		dependencies:        '',
+		credentials:         `dns_godaddy_secret = 0123456789abcdef0123456789abcdef01234567
 dns_godaddy_key = abcdef0123456789abcdef01234567abcdef0123`,
 		full_plugin_name: 'dns-godaddy',
 	},
 	//####################################################//
 	google: {
-		display_name:    'Google',
-		package_name:    'certbot-dns-google',
-		package_version: '1.8.0',
-		dependencies:    '',
-		credentials:     `{
+		display_name: 'Google',
+		package_name: 'certbot-dns-google',
+		// version_requirement: '', // Official plugin, no version requirement
+		dependencies: '',
+		credentials:  `{
 "type": "service_account",
 ...
 }`,
@@ -233,29 +243,29 @@ dns_godaddy_key = abcdef0123456789abcdef01234567abcdef0123`,
 	},
 	//####################################################//
 	hetzner: {
-		display_name:     'Hetzner',
-		package_name:     'certbot-dns-hetzner',
-		package_version:  '1.0.4',
-		dependencies:     '',
-		credentials:      'certbot_dns_hetzner:dns_hetzner_api_token = 0123456789abcdef0123456789abcdef',
-		full_plugin_name: 'certbot-dns-hetzner:dns-hetzner',
+		display_name:        'Hetzner',
+		package_name:        'certbot-dns-hetzner',
+		version_requirement: '~=1.0.4',
+		dependencies:        '',
+		credentials:         'certbot_dns_hetzner:dns_hetzner_api_token = 0123456789abcdef0123456789abcdef',
+		full_plugin_name:    'certbot-dns-hetzner:dns-hetzner',
 	},
 	//####################################################//
 	infomaniak: {
-		display_name:     'Infomaniak',
-		package_name:     'certbot-dns-infomaniak',
-		package_version:  '0.1.12',
-		dependencies:     '',
-		credentials:      'certbot_dns_infomaniak:dns_infomaniak_token = XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX',
-		full_plugin_name: 'certbot-dns-infomaniak:dns-infomaniak',
+		display_name:        'Infomaniak',
+		package_name:        'certbot-dns-infomaniak',
+		version_requirement: '~=0.1.12',
+		dependencies:        '',
+		credentials:         'certbot_dns_infomaniak:dns_infomaniak_token = XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX',
+		full_plugin_name:    'certbot-dns-infomaniak:dns-infomaniak',
 	},
 	//####################################################//
 	inwx: {
-		display_name:    'INWX',
-		package_name:    'certbot-dns-inwx',
-		package_version: '2.1.2',
-		dependencies:    '',
-		credentials:     `certbot_dns_inwx:dns_inwx_url = https://api.domrobot.com/xmlrpc/
+		display_name:        'INWX',
+		package_name:        'certbot-dns-inwx',
+		version_requirement: '~=2.1.2',
+		dependencies:        '',
+		credentials:         `certbot_dns_inwx:dns_inwx_url = https://api.domrobot.com/xmlrpc/
 certbot_dns_inwx:dns_inwx_username = your_username
 certbot_dns_inwx:dns_inwx_password = your_password
 certbot_dns_inwx:dns_inwx_shared_secret = your_shared_secret optional`,
@@ -263,112 +273,126 @@ certbot_dns_inwx:dns_inwx_shared_secret = your_shared_secret optional`,
 	},
 	//####################################################//
 	ionos: {
-		display_name:    'IONOS',
-		package_name:    'certbot-dns-ionos',
-		package_version: '0.0.7',
-		dependencies:    '',
-		credentials:     `certbot_dns_ionos:dns_ionos_prefix = myapikeyprefix
+		display_name:        'IONOS',
+		package_name:        'certbot-dns-ionos',
+		version_requirement: '~=0.0.7',
+		dependencies:        '',
+		credentials:         `certbot_dns_ionos:dns_ionos_prefix = myapikeyprefix
 certbot_dns_ionos:dns_ionos_secret = verysecureapikeysecret
 certbot_dns_ionos:dns_ionos_endpoint = https://api.hosting.ionos.com`,
 		full_plugin_name: 'certbot-dns-ionos:dns-ionos',
 	},
 	//####################################################//
 	ispconfig: {
-		display_name:    'ISPConfig',
-		package_name:    'certbot-dns-ispconfig',
-		package_version: '0.2.0',
-		dependencies:    '',
-		credentials:     `certbot_dns_ispconfig:dns_ispconfig_username = myremoteuser
+		display_name:        'ISPConfig',
+		package_name:        'certbot-dns-ispconfig',
+		version_requirement: '~=0.2.0',
+		dependencies:        '',
+		credentials:         `certbot_dns_ispconfig:dns_ispconfig_username = myremoteuser
 certbot_dns_ispconfig:dns_ispconfig_password = verysecureremoteuserpassword
 certbot_dns_ispconfig:dns_ispconfig_endpoint = https://localhost:8080`,
 		full_plugin_name: 'certbot-dns-ispconfig:dns-ispconfig',
 	},
 	//####################################################//
 	isset: {
-		display_name:    'Isset',
-		package_name:    'certbot-dns-isset',
-		package_version: '0.0.3',
-		dependencies:    '',
-		credentials:     `certbot_dns_isset:dns_isset_endpoint="https://customer.isset.net/api"
+		display_name:        'Isset',
+		package_name:        'certbot-dns-isset',
+		version_requirement: '~=0.0.3',
+		dependencies:        '',
+		credentials:         `certbot_dns_isset:dns_isset_endpoint="https://customer.isset.net/api"
 certbot_dns_isset:dns_isset_token="<token>"`,
 		full_plugin_name: 'certbot-dns-isset:dns-isset',
 	},
 	joker: {
-		display_name:    'Joker',
-		package_name:    'certbot-dns-joker',
-		package_version: '1.1.0',
-		dependencies:    '',
-		credentials:     `certbot_dns_joker:dns_joker_username = <Dynamic DNS Authentication Username>
+		display_name:        'Joker',
+		package_name:        'certbot-dns-joker',
+		version_requirement: '~=1.1.0',
+		dependencies:        '',
+		credentials:         `certbot_dns_joker:dns_joker_username = <Dynamic DNS Authentication Username>
 certbot_dns_joker:dns_joker_password = <Dynamic DNS Authentication Password>
 certbot_dns_joker:dns_joker_domain = <Dynamic DNS Domain>`,
 		full_plugin_name: 'certbot-dns-joker:dns-joker',
 	},
 	//####################################################//
 	linode: {
-		display_name:    'Linode',
-		package_name:    'certbot-dns-linode',
-		package_version: '1.8.0',
-		dependencies:    '',
-		credentials:     `dns_linode_key = 0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ64
+		display_name: 'Linode',
+		package_name: 'certbot-dns-linode',
+		// version_requirement: '', // Official plugin, no version requirement
+		dependencies: '',
+		credentials:  `dns_linode_key = 0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ64
 dns_linode_version = [<blank>|3|4]`,
 		full_plugin_name: 'dns-linode',
 	},
 	//####################################################//
 	loopia: {
-		display_name:    'Loopia',
-		package_name:    'certbot-dns-loopia',
-		package_version: '1.0.0',
-		dependencies:    '',
-		credentials:     `dns_loopia_user = user@loopiaapi
+		display_name:        'Loopia',
+		package_name:        'certbot-dns-loopia',
+		version_requirement: '~=1.0.0',
+		dependencies:        '',
+		credentials:         `dns_loopia_user = user@loopiaapi
 dns_loopia_password = abcdef0123456789abcdef01234567abcdef0123`,
 		full_plugin_name: 'dns-loopia',
 	},
 	//####################################################//
 	luadns: {
-		display_name:    'LuaDNS',
-		package_name:    'certbot-dns-luadns',
-		package_version: '1.8.0',
-		dependencies:    '',
-		credentials:     `dns_luadns_email = [email protected]
+		display_name: 'LuaDNS',
+		package_name: 'certbot-dns-luadns',
+		// version_requirement: '', // Official plugin, no version requirement
+		dependencies: '',
+		credentials:  `dns_luadns_email = [email protected]
 dns_luadns_token = 0123456789abcdef0123456789abcdef`,
 		full_plugin_name: 'dns-luadns',
 	},
 	//####################################################//
 	netcup: {
-		display_name:    'netcup',
-		package_name:    'certbot-dns-netcup',
-		package_version: '1.0.0',
-		dependencies:    '',
-		credentials:     `certbot_dns_netcup:dns_netcup_customer_id  = 123456
+		display_name:        'netcup',
+		package_name:        'certbot-dns-netcup',
+		version_requirement: '~=1.0.0',
+		dependencies:        '',
+		credentials:         `certbot_dns_netcup:dns_netcup_customer_id  = 123456
 certbot_dns_netcup:dns_netcup_api_key      = 0123456789abcdef0123456789abcdef01234567
 certbot_dns_netcup:dns_netcup_api_password = abcdef0123456789abcdef01234567abcdef0123`,
 		full_plugin_name: 'certbot-dns-netcup:dns-netcup',
 	},
 	//####################################################//
 	njalla: {
-		display_name:     'Njalla',
-		package_name:     'certbot-dns-njalla',
-		package_version:  '1.0.0',
-		dependencies:     '',
-		credentials:      'certbot_dns_njalla:dns_njalla_token = 0123456789abcdef0123456789abcdef01234567',
-		full_plugin_name: 'certbot-dns-njalla:dns-njalla',
+		display_name:        'Njalla',
+		package_name:        'certbot-dns-njalla',
+		version_requirement: '~=1.0.0',
+		dependencies:        '',
+		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',
+		// version_requirement: '', // Official plugin, no version requirement
 		dependencies:     '',
 		credentials:      'dns_nsone_api_key = MDAwMDAwMDAwMDAwMDAw',
 		full_plugin_name: 'dns-nsone',
 	},
 	//####################################################//
+	oci: {
+		display_name:    'Oracle Cloud Infrastructure DNS',
+		package_name:    'certbot-dns-oci',
+		package_version: '0.3.6',
+		dependencies:    'oci',
+		credentials:     `[DEFAULT]
+user = ocid1.user.oc1...
+fingerprint = xx:xx:xx:xx:xx:xx:xx:xx:xx:xx:xx:xx:xx
+tenancy = ocid1.tenancy.oc1...
+region = us-ashburn-1
+key_file = ~/.oci/oci_api_key.pem`,
+		full_plugin_name: 'dns-oci',
+	},
+	//####################################################//
 	ovh: {
-		display_name:    'OVH',
-		package_name:    'certbot-dns-ovh',
-		package_version: '1.8.0',
-		dependencies:    '',
-		credentials:     `dns_ovh_endpoint = ovh-eu
+		display_name: 'OVH',
+		package_name: 'certbot-dns-ovh',
+		// version_requirement: '', // Official plugin, no version requirement
+		dependencies: '',
+		credentials:  `dns_ovh_endpoint = ovh-eu
 dns_ovh_application_key = MDAwMDAwMDAwMDAw
 dns_ovh_application_secret = MDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAw
 dns_ovh_consumer_key = MDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAw`,
@@ -376,41 +400,41 @@ dns_ovh_consumer_key = MDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAw`,
 	},
 	//####################################################//
 	porkbun: {
-		display_name:    'Porkbun',
-		package_name:    'certbot-dns-porkbun',
-		package_version: '0.2',
-		dependencies:    '',
-		credentials:     `dns_porkbun_key=your-porkbun-api-key
+		display_name:        'Porkbun',
+		package_name:        'certbot-dns-porkbun',
+		version_requirement: '~=0.2',
+		dependencies:        '',
+		credentials:         `dns_porkbun_key=your-porkbun-api-key
 dns_porkbun_secret=your-porkbun-api-secret`,
 		full_plugin_name: 'dns-porkbun',
 	},
 	//####################################################//
 	powerdns: {
-		display_name:    'PowerDNS',
-		package_name:    'certbot-dns-powerdns',
-		package_version: '0.2.0',
-		dependencies:    '',
-		credentials:     `certbot_dns_powerdns:dns_powerdns_api_url = https://api.mypowerdns.example.org
+		display_name:        'PowerDNS',
+		package_name:        'certbot-dns-powerdns',
+		version_requirement: '~=0.2.0',
+		dependencies:        '',
+		credentials:         `certbot_dns_powerdns:dns_powerdns_api_url = https://api.mypowerdns.example.org
 certbot_dns_powerdns:dns_powerdns_api_key = AbCbASsd!@34`,
 		full_plugin_name: 'certbot-dns-powerdns:dns-powerdns',
 	},
 	//####################################################//
 	regru: {
-		display_name:    'reg.ru',
-		package_name:    'certbot-regru',
-		package_version: '1.0.2',
-		dependencies:    '',
-		credentials:     `certbot_regru:dns_username=username
+		display_name:        'reg.ru',
+		package_name:        'certbot-regru',
+		version_requirement: '~=1.0.2',
+		dependencies:        '',
+		credentials:         `certbot_regru:dns_username=username
 certbot_regru:dns_password=password`,
 		full_plugin_name: 'certbot-regru:dns',
 	},
 	//####################################################//
 	rfc2136: {
-		display_name:    'RFC 2136',
-		package_name:    'certbot-dns-rfc2136',
-		package_version: '1.8.0',
-		dependencies:    '',
-		credentials:     `# Target DNS server
+		display_name: 'RFC 2136',
+		package_name: 'certbot-dns-rfc2136',
+		// version_requirement: '', // Official plugin, no version requirement
+		dependencies: '',
+		credentials:  `# Target DNS server
 dns_rfc2136_server = 192.0.2.1
 # Target DNS port
 dns_rfc2136_port = 53
@@ -424,42 +448,32 @@ dns_rfc2136_algorithm = HMAC-SHA512`,
 	},
 	//####################################################//
 	route53: {
-		display_name:    'Route 53 (Amazon)',
-		package_name:    'certbot-dns-route53',
-		package_version: '1.8.0',
-		dependencies:    '',
-		credentials:     `[default]
+		display_name: 'Route 53 (Amazon)',
+		package_name: 'certbot-dns-route53',
+		// version_requirement: '', // Official plugin, no version requirement
+		dependencies: '',
+		credentials:  `[default]
 aws_access_key_id=AKIAIOSFODNN7EXAMPLE
 aws_secret_access_key=wJalrXUtnFEMI/K7MDENG/bPxRfiCYEXAMPLEKEY`,
 		full_plugin_name: 'dns-route53',
 	},
 	//####################################################//
 	transip: {
-		display_name:    'TransIP',
-		package_name:    'certbot-dns-transip',
-		package_version: '0.3.3',
-		dependencies:    '',
-		credentials:     `certbot_dns_transip:dns_transip_username = my_username
+		display_name:        'TransIP',
+		package_name:        'certbot-dns-transip',
+		version_requirement: '~=0.3.3',
+		dependencies:        '',
+		credentials:         `certbot_dns_transip:dns_transip_username = my_username
 certbot_dns_transip:dns_transip_key_file = /etc/letsencrypt/transip-rsa.key`,
 		full_plugin_name: 'certbot-dns-transip:dns-transip',
 	},
 	//####################################################//
 	vultr: {
-		display_name:     'Vultr',
-		package_name:     'certbot-dns-vultr',
-		package_version:  '1.0.3',
-		dependencies:     '',
-		credentials:      'certbot_dns_vultr:dns_vultr_key = YOUR_VULTR_API_KEY',
-		full_plugin_name: 'certbot-dns-vultr:dns-vultr',
-	},
-	//####################################################//
-	desec: {
-		display_name:    'deSEC',
-		package_name:    'certbot-dns-desec',
-		package_version: '0.3.0',
-		dependencies:    '',
-		credentials:     `certbot_dns_desec:dns_desec_token = YOUR_DESEC_API_TOKEN
-certbot_dns_desec:dns_desec_endpoint = https://desec.io/api/v1/`,
-		full_plugin_name: 'certbot-dns-desec:dns-desec',
+		display_name:        'Vultr',
+		package_name:        'certbot-dns-vultr',
+		version_requirement: '~=1.0.3',
+		dependencies:        '',
+		credentials:         'certbot_dns_vultr:dns_vultr_key = YOUR_VULTR_API_KEY',
+		full_plugin_name:    'certbot-dns-vultr:dns-vultr',
 	},
 };

部分文件因为文件数量过多而无法显示