Fixed bugs caused by DNS challenge PR

- Fixed concurrency in EAB and DNS credential save
- Fixed missing CA name in ACME Obtain certificate handler
- Optimized acmedns code config
- Fixed a lot of front-end bugs in acme snippet
This commit is contained in:
Toby Chui 2024-05-14 16:21:47 +08:00
parent 3454a9b975
commit ce4f46cb50
8 changed files with 593 additions and 908 deletions

View File

@ -117,6 +117,11 @@ func (a *ACMEHandler) ObtainCert(domains []string, certificateName string, email
} }
} }
//Fallback to Let's Encrypt if it is not set
if caName == "" {
caName = "Let's Encrypt"
}
// setup the custom ACME url endpoint. // setup the custom ACME url endpoint.
if caUrl != "" { if caUrl != "" {
config.CADirURL = caUrl config.CADirURL = caUrl

View File

@ -7,20 +7,29 @@ import (
"strings" "strings"
"github.com/go-acme/lego/v4/challenge" "github.com/go-acme/lego/v4/challenge"
"github.com/go-acme/lego/v4/providers/dns" "imuslab.com/zoraxy/mod/acme/acmedns"
) )
func GetDnsChallengeProviderByName(dnsProvider string, dnsCredentials string) (challenge.Provider, error) { func GetDnsChallengeProviderByName(dnsProvider string, dnsCredentials string) (challenge.Provider, error) {
credentials, err := extractDnsCredentials(dnsCredentials)
//Original Implementation
/*credentials, err := extractDnsCredentials(dnsCredentials)
if err != nil { if err != nil {
return nil, err return nil, err
} }
setCredentialsIntoEnvironmentVariables(credentials) setCredentialsIntoEnvironmentVariables(credentials)
provider, err := dns.NewDNSChallengeProviderByName(dnsProvider) provider, err := dns.NewDNSChallengeProviderByName(dnsProvider)
return provider, err */
//New implementation using acmedns CICD pipeline generated datatype
return acmedns.GetDNSProviderByJsonConfig(dnsProvider, dnsCredentials)
} }
/*
Original implementation of DNS ACME using OS.Env as payload
*/
func setCredentialsIntoEnvironmentVariables(credentials map[string]string) { func setCredentialsIntoEnvironmentVariables(credentials map[string]string) {
for key, value := range credentials { for key, value := range credentials {
err := os.Setenv(key, value) err := os.Setenv(key, value)

File diff suppressed because it is too large Load Diff

View File

@ -133,7 +133,8 @@
</div> </div>
<div class="field dnsChallengeOnly" style="display:none;"> <div class="field dnsChallengeOnly" style="display:none;">
<div class="ui divider"></div> <div class="ui divider"></div>
<p>Required Configurations</p> <p>DNS Credentials (Leave all fields empty to use previous settings)<br>
<small><i class="yellow exclamation triangle icon"></i> Note that domain DNS credentials are stored separately. For each new subdomain, you will need to enter a new DNS credentials.</small></p>
<div id="dnsProviderAPIFields"> <div id="dnsProviderAPIFields">
</div> </div>
@ -355,9 +356,26 @@
// Button click event handler for obtaining certificate // Button click event handler for obtaining certificate
$("#obtainButton").click(function() { $("#obtainButton").click(function() {
$("#obtainButton").addClass("loading").addClass("disabled"); $("#obtainButton").addClass("loading").addClass("disabled");
updateCertificateEAB(); updateCertificateEAB(function(succ){
updateCertificateDNS(); if (succ){
obtainCertificate(); //Continue to next step
updateCertificateDNS(function(succ){
if (succ){
obtainCertificate(function(succ){
$("#obtainButton").removeClass("loading").removeClass("disabled");
});
}else{
$("#obtainButton").removeClass("loading").removeClass("disabled");
console.log("update Certificate DNS process halted");
}
});
}else{
console.log("Update Certificate EAB process halted");
$("#obtainButton").removeClass("loading").removeClass("disabled");
}
});
}); });
//On CA change in dropdown //On CA change in dropdown
@ -459,7 +477,7 @@
// Update EAB values for autorenewal // Update EAB values for autorenewal
function updateCertificateEAB() { function updateCertificateEAB(callback=undefined) {
var ca = $("#ca").dropdown("get value"); var ca = $("#ca").dropdown("get value");
var caURL = ""; var caURL = "";
if (ca == "Custom ACME Server") { if (ca == "Custom ACME Server") {
@ -472,6 +490,10 @@
} }
if(caURL == "") { if(caURL == "") {
//Skip update
if (callback != undefined){
callback(true);
}
return; return;
} }
@ -479,6 +501,10 @@
var hmac = $("#eab_hmac").val(); var hmac = $("#eab_hmac").val();
if(kid == "" || hmac == "") { if(kid == "" || hmac == "") {
//Skip update
if (callback != undefined){
callback(true);
}
return; return;
} }
@ -498,6 +524,9 @@
console.log("Error:", response.error); console.log("Error:", response.error);
// Show error message // Show error message
parent.msgbox(response.error, false, 12000); parent.msgbox(response.error, false, 12000);
if (callback != undefined){
callback(false);
}
} else { } else {
console.log("Certificate EAB updated successfully"); console.log("Certificate EAB updated successfully");
// Show success message // Show success message
@ -505,12 +534,18 @@
// Renew the parent certificate list // Renew the parent certificate list
parent.initManagedDomainCertificateList(); parent.initManagedDomainCertificateList();
if (callback != undefined){
callback(true);
}
} }
}, },
error: function(error) { error: function(error) {
//$("#obtainButton").removeClass("loading").removeClass("disabled"); //$("#obtainButton").removeClass("loading").removeClass("disabled");
console.log("Failed to update EAB configuration:", error); console.log("Failed to update EAB configuration:", error);
parent.msgbox("Failed to update EAB configuration"); parent.msgbox("Failed to update EAB configuration");
if (callback != undefined){
callback(false);
}
} }
}); });
} }
@ -519,30 +554,49 @@
// the old DNSCredential TextArea input // the old DNSCredential TextArea input
function readDnsCredentials(){ function readDnsCredentials(){
let dnsCredentials = ""; let dnsCredentials = {};
$(".dnsConfigField").each(function(){ $(".dnsConfigField").each(function(){
let thisKey = $(this).attr("key"); let thisKey = $(this).attr("key");
let value = "";
if ($(this).hasClass("checkbox")){ if ($(this).hasClass("checkbox")){
//Boolean option //Boolean option
let checked = $(this).find("input")[0].checked; let checked = $(this).find("input")[0].checked;
dnsCredentials += `${thisKey}=${checked?"true":"false"}\n` dnsCredentials[thisKey] = checked;
}else{ }else{
//String or int options //String or int options
let value = $(this).find("input").val().trim(); let value = $(this).find("input").val().trim();
dnsCredentials += `${thisKey}=${value}\n` dnsCredentials[thisKey] = value;
} }
}); });
dnsCredentials = dnsCredentials.trim();
return dnsCredentials; return dnsCredentials;
} }
// Update DNS values for autorenewal // Update DNS values for autorenewal
function updateCertificateDNS() { function updateCertificateDNS(callback=undefined) {
var dns = $("#useDnsChallenge")[0].checked; var dns = $("#useDnsChallenge")[0].checked;
var dnsProvider = ""; var dnsProvider = "";
var dnsCredentials = ""; var dnsCredentials = "";
if (!dns) { if (!dns) {
if (callback != undefined){
callback(true);
}
return;
}
//Check if all fields is empty. If yes, do not update the config
let allFieldsEmpty = true;
$(".dnsConfigField").each(function(){
if ($(this).find("input").val().trim() != ""){
allFieldsEmpty = false;
}
});
if (allFieldsEmpty){
//Do not update config on server side
if (callback != undefined){
callback(true);
}
return; return;
} }
@ -554,18 +608,18 @@
if(dnsProvider == "") { if(dnsProvider == "") {
parent.msgbox("DNS Provider cannot be empty", false, 5000); parent.msgbox("DNS Provider cannot be empty", false, 5000);
$("#obtainButton").removeClass("loading").removeClass("disabled"); $("#obtainButton").removeClass("loading").removeClass("disabled");
return; if (callback != undefined){
callback(false);
} }
if(dnsCredentials == "") {
parent.msgbox("DNS Credentials cannot be empty", false, 5000);
$("#obtainButton").removeClass("loading").removeClass("disabled");
return; return;
} }
var filename = getFilename(); var filename = getFilename();
if (filename == '') { if (filename == '') {
parent.msgbox("Domain to renew cannot be empty", false, 5000);
if (callback != undefined){
callback(false);
}
return; return;
} }
@ -575,7 +629,7 @@
data: { data: {
filename: filename, filename: filename,
dnsProvider: dnsProvider, dnsProvider: dnsProvider,
dnsCredentials: dnsCredentials, dnsCredentials: JSON.stringify(dnsCredentials),
}, },
success: function(response) { success: function(response) {
//$("#obtainButton").removeClass("loading").removeClass("disabled"); //$("#obtainButton").removeClass("loading").removeClass("disabled");
@ -583,31 +637,44 @@
console.log("Error:", response.error); console.log("Error:", response.error);
// Show error message // Show error message
parent.msgbox(response.error, false, 12000); parent.msgbox(response.error, false, 12000);
if (callback != undefined){
callback(false);
}
} else { } else {
console.log("Certificate DNS Credentials updated successfully"); console.log("Certificate DNS Credentials updated successfully");
// Show success message // Show success message
parent.msgbox("Certificate DNS Credentials updated successfully"); parent.msgbox("Certificate DNS Credentials updated successfully");
if (callback != undefined){
callback(true);
}
} }
}, },
error: function(error) { error: function(error) {
//$("#obtainButton").removeClass("loading").removeClass("disabled"); //$("#obtainButton").removeClass("loading").removeClass("disabled");
console.log("Failed to update DNS configuration:", error); console.log("Failed to update DNS configuration:", error);
parent.msgbox("Failed to update DNS configuration"); parent.msgbox("Failed to update DNS configuration");
if (callback != undefined){
callback(false);
}
} }
}); });
} }
// Obtain certificate from API // Obtain certificate from API
function obtainCertificate() { function obtainCertificate(callback=undefined) {
var domains = $("#domainsInput").val(); var domains = $("#domainsInput").val();
var filename = getFilename(); var filename = getFilename();
if (filename == '') { if (filename == '') {
if (callback != undefined){
parent.msgbox("Domain to obtain certificate cannot be empty", false)
callback(false);
}
return; return;
} }
var email = $("#caRegisterEmail").val(); var email = $("#caRegisterEmail").val();
if (email == ""){ if (email == ""){
parent.msgbox("ACME renew email is not set", false) parent.msgbox("ACME renew email is not set", false)
$("#obtainButton").removeClass("loading").removeClass("disabled"); if (callback != undefined){callback(false);}
return; return;
} }
@ -641,6 +708,7 @@
console.log("Error:", response.error); console.log("Error:", response.error);
// Show error message // Show error message
parent.msgbox(response.error, false, 12000); parent.msgbox(response.error, false, 12000);
if (callback != undefined){callback(false);}
} else { } else {
console.log("Certificate renewed successfully"); console.log("Certificate renewed successfully");
// Show success message // Show success message
@ -648,11 +716,14 @@
// Renew the parent certificate list // Renew the parent certificate list
parent.initManagedDomainCertificateList(); parent.initManagedDomainCertificateList();
if (callback != undefined){callback(true);}
} }
}, },
error: function(error) { error: function(error) {
$("#obtainButton").removeClass("loading").removeClass("disabled"); $("#obtainButton").removeClass("loading").removeClass("disabled");
console.log("Failed to renewed certificate:", error); console.log("Failed to renewed certificate:", error);
if (callback != undefined){callback(false);}
} }
}); });
} }

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -176,6 +176,8 @@ func main() {
Title: fields[0], Title: fields[0],
Datatype: fields[1], Datatype: fields[1],
}) })
} else if fields[0] == "TTL" {
//haveTTLField = true
} else { } else {
hiddenKeys = append(hiddenKeys, &Field{ hiddenKeys = append(hiddenKeys, &Field{
Title: fields[0], Title: fields[0],
@ -210,17 +212,15 @@ func main() {
HiddenFields: hiddenKeys, HiddenFields: hiddenKeys,
} }
//Generate the code for it
//Generate the code for converting incoming json into target config //Generate the code for converting incoming json into target config
codeSegment := ` codeSegment := `
case "` + providerName + `": case "` + providerName + `":
cfg := ` + providerName + `.Config{} cfg := ` + providerName + `.NewDefaultConfig()
err := json.Unmarshal([]byte(js), &cfg) err := json.Unmarshal([]byte(js), &cfg)
if err != nil { if err != nil {
return nil, err return nil, err
} }
return ` + providerName + `.NewDNSProviderConfig(&cfg)` return ` + providerName + `.NewDNSProviderConfig(cfg)`
generatedConvertcode += codeSegment generatedConvertcode += codeSegment
importList += ` "github.com/go-acme/lego/v4/providers/dns/` + providerName + "\"\n" importList += ` "github.com/go-acme/lego/v4/providers/dns/` + providerName + "\"\n"

View File

@ -22,5 +22,5 @@ go run ./extract.go
echo "Cleaning up lego" echo "Cleaning up lego"
# Comment the line below if you dont want to pull everytime update # Comment the line below if you dont want to pull everytime update
# This is to help go compiler to not load all the lego source file when compile # This is to help go compiler to not load all the lego source file when compile
rm -rf ./lego/ #rm -rf ./lego/
echo "Config generated" echo "Config generated"