mirror of
https://github.com/tobychui/zoraxy.git
synced 2025-06-06 15:47:19 +02:00
629 lines
22 KiB
HTML
629 lines
22 KiB
HTML
<!DOCTYPE html>
|
|
<html>
|
|
<head>
|
|
<!-- Notes: This should be open in its original path-->
|
|
<link rel="stylesheet" href="../script/semantic/semantic.min.css">
|
|
<script src="../script/jquery-3.6.0.min.js"></script>
|
|
<script src="../script/semantic/semantic.min.js"></script>
|
|
<style>
|
|
.disabled.table{
|
|
opacity: 0.5;
|
|
pointer-events: none;
|
|
|
|
}
|
|
|
|
.expiredDomain{
|
|
color: rgb(238, 31, 31);
|
|
}
|
|
|
|
.validDomain{
|
|
color: rgb(49, 192, 113);
|
|
}
|
|
</style>
|
|
</head>
|
|
<body>
|
|
<br>
|
|
<div class="ui container">
|
|
<div class="ui header">
|
|
<div class="content">
|
|
Certificates Auto Renew Settings
|
|
<div class="sub header">Fetch and renew your certificates with Automated Certificate Management Environment (ACME) protocol</div>
|
|
</div>
|
|
</div>
|
|
<div class="ui basic segment">
|
|
<p style="float: right; color: #21ba45; display:none;" id="enableToggleSucc"><i class="green checkmark icon"></i> Setting Updated</p>
|
|
<div class="ui toggle checkbox">
|
|
<input type="checkbox" id="enableCertAutoRenew">
|
|
<label>Enable Certificate Auto Renew</label>
|
|
</div>
|
|
<br>
|
|
<h3>ACME Email</h3>
|
|
<p>Email is required by many CAs for renewing via ACME protocol</p>
|
|
<div class="ui fluid action input">
|
|
<input id="caRegisterEmail" type="text" placeholder="webmaster@example.com">
|
|
<button class="ui icon basic button" onclick="saveEmailToConfig(this);">
|
|
<i class="blue save icon"></i>
|
|
</button>
|
|
</div>
|
|
<small>If you don't want to share your private email address, you can also fill in an email address that point to a mailbox not exists on your domain.</small>
|
|
</div>
|
|
<div class="ui basic segment" style="background-color: #f7f7f7; border-radius: 1em;">
|
|
<div class="ui accordion advanceSettings">
|
|
<div class="title">
|
|
<i class="dropdown icon"></i>
|
|
Advance Renew Policy
|
|
</div>
|
|
<div class="content">
|
|
<p>Renew all certificates with ACME supported CAs</p>
|
|
<div class="ui toggle checkbox">
|
|
<input type="checkbox" id="renewAllSupported" onchange="setAutoRenewIfCASupportMode(this.checked);">
|
|
<label>Renew All Certs</label>
|
|
</div><br>
|
|
<button id="renewNowBtn" onclick="renewNow();" class="ui basic right floated button" style="margin-top: -2em;"><i class="yellow refresh icon"></i> Renew Now</button>
|
|
<div class="ui horizontal divider"> OR </div>
|
|
<p>Select the certificates to automatic renew in the list below</p>
|
|
<table id="domainCertFileTable" class="ui very compact unstackable basic disabled table">
|
|
<thead>
|
|
<tr>
|
|
<th>Domain Name</th>
|
|
<th>Match Rule</th>
|
|
<th>Auto-Renew</th>
|
|
</tr>
|
|
</thead>
|
|
<tbody id="domainTableBody"></tbody>
|
|
</table>
|
|
<small><i class="ui red info circle icon"></i> Domain in red are expired</small><br>
|
|
<div class="ui yellow message">
|
|
Certificate Renew only works on the certification authority (CA) supported by Zoraxy. Check Zoraxy wiki for more information on supported list of CAs.
|
|
</div>
|
|
<button class="ui basic right floated button" onclick="saveAutoRenewPolicy();"><i class="blue save icon"></i> Save Changes</button>
|
|
<button id="renewSelectedButton" onclick="renewNow();" class="ui basic right floated disabled button"><i class="yellow refresh icon"></i> Renew Selected</button>
|
|
<br><br>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
<div class="ui divider"></div>
|
|
<h3>Generate New Certificate</h3>
|
|
<p>Enter a new / existing domain(s) to request new certificate(s)</p>
|
|
<div class="ui form">
|
|
<div class="field">
|
|
<label>Domain(s)</label>
|
|
<input id="domainsInput" type="text" placeholder="example.com" onkeyup="checkIfInputDomainIsMultiple();">
|
|
<small>If you have more than one domain in a single certificate, enter the domains separated by commas (e.g. s1.dev.example.com,s2.dev.example.com)</small>
|
|
</div>
|
|
<div class="field multiDomainOnly" style="display:none;">
|
|
<label>Matching Rule</label>
|
|
<input id="filenameInput" type="text" placeholder="Enter filename (no file extension)">
|
|
<small>Matching rule to let Zoraxy pick which certificate to use (Also be used as filename). Usually is the longest common suffix of the entered addresses. (e.g. dev.example.com)</small>
|
|
</div>
|
|
<div class="field multiDomainOnly" style="display:none;">
|
|
<button class="ui basic fluid button" onclick="autoDetectMatchingRules();">Auto Detect Matching Rule</button>
|
|
</div>
|
|
<div class="field">
|
|
<label>Certificate Authority (CA)</label>
|
|
<div class="ui selection dropdown" id="ca">
|
|
<input type="hidden" name="ca">
|
|
<i class="dropdown icon"></i>
|
|
<div class="default text">Let's Encrypt</div>
|
|
<div class="menu">
|
|
<div class="item" data-value="Let's Encrypt">Let's Encrypt</div>
|
|
<div class="item" data-value="Buypass">Buypass</div>
|
|
<div class="item" data-value="ZeroSSL">ZeroSSL</div>
|
|
<div class="item" data-value="Custom ACME Server">Custom ACME Server</div>
|
|
<!-- <div class="item" data-value="Google">Google</div> -->
|
|
</div>
|
|
</div>
|
|
</div>
|
|
<div class="field">
|
|
<div class="ui checkbox">
|
|
<input type="checkbox" id="useDnsChallenge" onchange="toggleDnsChallenge()">
|
|
<label>Use a DNS Challenge<br>
|
|
</div>
|
|
</div>
|
|
<div class="field dnsChallengeOnly" style="display:none;">
|
|
<label>DNS Provider</label>
|
|
<div class="ui selection dropdown" id="dnsProvider">
|
|
<input type="hidden" name="dnsProvider">
|
|
<i class="dropdown icon"></i>
|
|
<div class="default text">Please Choose...</div>
|
|
<div class="menu">
|
|
<div class="item" data-value="Dynu">Dynu</div>
|
|
<!-- <div class="item" data-value="Other DNS Providers">Other DNS Providers</div> -->
|
|
</div>
|
|
</div>
|
|
</div>
|
|
<div class="field dnsChallengeOnly" style="display:none;">
|
|
<label>Credentials File Content</label>
|
|
<textarea id="dnsCredentials" placeholder=""></textarea>
|
|
<small>Some text explaining how this works</small>
|
|
</div>
|
|
<div class="field" id="caInput" style="display:none;">
|
|
<label>ACME Server URL</label>
|
|
<input id="caURL" type="text" placeholder="https://example.com/acme/dictionary">
|
|
</div>
|
|
<div class="field" id="kidInput" style="display:none;">
|
|
<label>EAB Credentials (KID) for current provider</label>
|
|
<input id="eab_kid" type="text" placeholder="Leave this field blank to keep the current configuration">
|
|
</div>
|
|
<div class="field" id="hmacInput" style="display:none;">
|
|
<label>EAB HMAC Key for current provider</label>
|
|
<input id="eab_hmac" type="text" placeholder="Leave this field blank to keep the current configuration">
|
|
</div>
|
|
<div class="field" id="skipTLS" style="display:none;">
|
|
<div class="ui checkbox">
|
|
<input type="checkbox" id="skipTLSCheckbox">
|
|
<label>Ignore TLS/SSL Verification Error<br><small>E.g. self-signed, expired certificate (Not Recommended)</small></label>
|
|
</div>
|
|
</div>
|
|
<button id="obtainButton" class="ui basic button" type="submit"><i class="yellow refresh icon"></i> Get Certificate</button>
|
|
</div>
|
|
<div class="ui divider"></div>
|
|
<small>First time setting up HTTPS?<br>Try out our <a href="../tools/https.html" target="_blank">wizard</a></small>
|
|
<button class="ui basic button" style="float: right;" onclick="parent.hideSideWrapper();"><i class="remove icon"></i> Cancel</button>
|
|
<br><br><br><br>
|
|
</div>
|
|
|
|
<script>
|
|
let expiredDomains = [];
|
|
let enableTrigerOnChangeEvent = true;
|
|
$(".accordion").accordion();
|
|
$(".dropdown").dropdown();
|
|
$(".checkbox").checkbox();
|
|
|
|
function setAutoRenewIfCASupportMode(useAutoMode = true){
|
|
if (useAutoMode){
|
|
$("#domainCertFileTable").addClass("disabled");
|
|
$("#renewNowBtn").removeClass("disabled");
|
|
$("#renewSelectedButton").addClass("disabled");
|
|
}else{
|
|
$("#domainCertFileTable").removeClass("disabled");
|
|
$("#renewNowBtn").addClass("disabled");
|
|
$("#renewSelectedButton").removeClass("disabled");
|
|
}
|
|
}
|
|
|
|
function initRenewerConfigFromFile(){
|
|
//Set the renew switch state
|
|
$.get("/api/acme/autoRenew/enable", function(data){
|
|
if (data == true){
|
|
$("#enableCertAutoRenew").parent().checkbox("set checked");
|
|
}
|
|
|
|
$("#enableCertAutoRenew").on("change", function(){
|
|
if (!enableTrigerOnChangeEvent){
|
|
return;
|
|
}
|
|
toggleAutoRenew();
|
|
})
|
|
});
|
|
|
|
//Load the email from server side
|
|
$.get("/api/acme/autoRenew/email", function(data){
|
|
if (data != "" && data != undefined && data != null){
|
|
$("#caRegisterEmail").val(data);
|
|
}
|
|
});
|
|
|
|
//Load the domain selection options
|
|
$.get("/api/acme/autoRenew/renewPolicy", function(data){
|
|
if (data == true){
|
|
$("#renewAllSupported").parent().checkbox("set checked");
|
|
}else{
|
|
$("#renewAllSupported").parent().checkbox("set unchecked");
|
|
}
|
|
});
|
|
}
|
|
initRenewerConfigFromFile();
|
|
|
|
function saveEmailToConfig(btn){
|
|
$.ajax({
|
|
url: "/api/acme/autoRenew/email",
|
|
data: {set: $("#caRegisterEmail").val()},
|
|
success: function(data){
|
|
if (data.error != undefined){
|
|
parent.msgbox(data.error, false, 5000);
|
|
|
|
}else{
|
|
parent.msgbox("Email updated");
|
|
$(btn).html(`<i class="green check icon"></i>`);
|
|
$(btn).addClass("disabled");
|
|
setTimeout(function(){
|
|
$(btn).html(`<i class="blue save icon"></i>`);
|
|
$(btn).removeClass("disabled");
|
|
}, 3000);
|
|
}
|
|
}
|
|
});
|
|
}
|
|
|
|
function toggleAutoRenew(){
|
|
var enabled = $("#enableCertAutoRenew").parent().checkbox("is checked");
|
|
$.post("/api/acme/autoRenew/enable?enable=" + enabled, function(data){
|
|
if (data.error){
|
|
parent.msgbox(data.error, false, 5000);
|
|
if (enabled){
|
|
enableTrigerOnChangeEvent = false;
|
|
$("#enableCertAutoRenew").parent().checkbox("set unchecked");
|
|
enableTrigerOnChangeEvent = true;
|
|
}
|
|
if (parent && parent.setACMEEnableStates){
|
|
parent.setACMEEnableStates(!enabled);
|
|
}
|
|
}else{
|
|
$("#enableToggleSucc").stop().finish().fadeIn("fast").delay(3000).fadeOut("fast");
|
|
if (parent && parent.setACMEEnableStates){
|
|
parent.setACMEEnableStates(enabled);
|
|
}
|
|
}
|
|
});
|
|
|
|
|
|
|
|
}
|
|
|
|
//Render the domains table that exists in this zoraxy host
|
|
function renderDomainTable(domainFileList) {
|
|
// Get the table body element
|
|
var tableBody = $('#domainTableBody');
|
|
|
|
// Clear the table body
|
|
tableBody.empty();
|
|
|
|
// Iterate over the domain names
|
|
var counter = 0;
|
|
for (const [srcfile, domains] of Object.entries(domainFileList)) {
|
|
|
|
// Create a table row
|
|
var row = $('<tr>');
|
|
|
|
// Create the domain name cell
|
|
var domainClass = "validDomain";
|
|
for (var i = 0; i < domains.length; i++){
|
|
let thisDomain = domains[i];
|
|
if (expiredDomains.includes(thisDomain)){
|
|
domainClass = "expiredDomain";
|
|
}
|
|
}
|
|
|
|
var domainCell = $('<td class="' + domainClass +'">').html(domains.join("<br>"));
|
|
row.append(domainCell);
|
|
|
|
var srcFileCell = $('<td>').text(srcfile);
|
|
row.append(srcFileCell);
|
|
|
|
// Create the auto-renew checkbox cell
|
|
let domainsEncoded = encodeURIComponent(JSON.stringify(domains));
|
|
var checkboxCell = $(`<td domain="${domainsEncoded}" srcfile="${srcfile}">`);
|
|
var checkbox = $(`<input name="${srcfile}">`).attr('type', 'checkbox');
|
|
checkboxCell.append(checkbox);
|
|
row.append(checkboxCell);
|
|
|
|
// Add the row to the table body
|
|
tableBody.append(row);
|
|
|
|
counter++;
|
|
}
|
|
|
|
if (Object.keys(domainFileList).length == 0){
|
|
//No certificate in this system
|
|
tableBody.append(`<tr>
|
|
<td colspan="3"><i class="ui green circle check icon"></i> No certificate in use</td>
|
|
</tr>`);
|
|
}
|
|
}
|
|
|
|
//Initiate domain table. If you needs to update the expired domain as well
|
|
//call from initDomainFileList() instead
|
|
function initDomainTable(){
|
|
$.get("/api/cert/listdomains?compact=true", function(data){
|
|
if (data.error != undefined){
|
|
parent.msgbox(data.error, false);
|
|
}else{
|
|
renderDomainTable(data);
|
|
}
|
|
initAutoRenewPolicy();
|
|
})
|
|
}
|
|
|
|
function initDomainFileList() {
|
|
$.ajax({
|
|
url: "/api/acme/listExpiredDomains",
|
|
method: "GET",
|
|
success: function(response) {
|
|
// Render domain table
|
|
expiredDomains = response.domain;
|
|
initDomainTable();
|
|
//renderDomainTable(response.domain);
|
|
},
|
|
error: function(error) {
|
|
console.log("Failed to fetch expired domains:", error);
|
|
}
|
|
});
|
|
}
|
|
initDomainFileList();
|
|
|
|
// Button click event handler for obtaining certificate
|
|
$("#obtainButton").click(function() {
|
|
$("#obtainButton").addClass("loading").addClass("disabled");
|
|
updateCertificateEAB();
|
|
obtainCertificate();
|
|
});
|
|
|
|
$("input[name=ca]").on('change', function() {
|
|
if(this.value == "Custom ACME Server") {
|
|
$("#caInput").show();
|
|
$("#kidInput").show();
|
|
$("#hmacInput").show();
|
|
$("#skipTLS").show();
|
|
} else if (this.value == "ZeroSSL") {
|
|
$("#kidInput").show();
|
|
$("#hmacInput").show();
|
|
} else if (this.value == "Buypass") {
|
|
$("#kidInput").show();
|
|
$("#hmacInput").show();
|
|
}else {
|
|
$("#caInput").hide();
|
|
$("#skipTLS").hide();
|
|
$("#kidInput").hide();
|
|
$("#hmacInput").hide();
|
|
}
|
|
})
|
|
|
|
|
|
// Obtain certificate from API
|
|
function updateCertificateEAB() {
|
|
var ca = $("#ca").dropdown("get value");
|
|
var caURL = "";
|
|
if (ca == "Custom ACME Server") {
|
|
ca = "custom";
|
|
caURL = $("#caURL").val();
|
|
}else if(ca == "Buypass") {
|
|
caURL = "https://api.buypass.com/acme/directory";
|
|
}else if(ca == "ZeroSSL") {
|
|
caURL = "https://acme.zerossl.com/v2/DV90";
|
|
}
|
|
|
|
if(caURL == "") {
|
|
return;
|
|
}
|
|
|
|
var kid = $("#eab_kid").val();
|
|
var hmac = $("#eab_hmac").val();
|
|
|
|
if(kid == "" || hmac == "") {
|
|
return;
|
|
}
|
|
|
|
console.log(caURL + " " + kid + " " + hmac);
|
|
|
|
$.ajax({
|
|
url: "/api/acme/autoRenew/setEAB",
|
|
method: "GET",
|
|
data: {
|
|
acmeDirectoryURL: caURL,
|
|
kid: kid,
|
|
hmacEncoded: hmac,
|
|
},
|
|
success: function(response) {
|
|
//$("#obtainButton").removeClass("loading").removeClass("disabled");
|
|
if (response.error) {
|
|
console.log("Error:", response.error);
|
|
// Show error message
|
|
parent.msgbox(response.error, false, 12000);
|
|
} else {
|
|
console.log("Certificate EAB updated successfully");
|
|
// Show success message
|
|
parent.msgbox("Certificate EAB updated successfully");
|
|
|
|
// Renew the parent certificate list
|
|
parent.initManagedDomainCertificateList();
|
|
}
|
|
},
|
|
error: function(error) {
|
|
//$("#obtainButton").removeClass("loading").removeClass("disabled");
|
|
console.log("Failed to update EAB configuration:", error);
|
|
parent.msgbox("Failed to update EAB configuration");
|
|
}
|
|
});
|
|
}
|
|
|
|
// Obtain certificate from API
|
|
function obtainCertificate() {
|
|
var domains = $("#domainsInput").val();
|
|
var filename = $("#filenameInput").val();
|
|
var email = $("#caRegisterEmail").val();
|
|
if (email == ""){
|
|
parent.msgbox("ACME renew email is not set", false)
|
|
$("#obtainButton").removeClass("loading").removeClass("disabled");
|
|
return;
|
|
}
|
|
if (filename.trim() == "" && !domains.includes(",")){
|
|
//Zoraxy filename are the matching name for domains.
|
|
//Use the same as domains
|
|
filename = domains;
|
|
}else if (filename != "" && !domains.includes(",")){
|
|
//Invalid settings. Force the filename to be same as domain
|
|
//if there are only 1 domain
|
|
filename = domains;
|
|
}else if (filename == "" && domains.includes(",")){
|
|
parent.msgbox("Filename cannot be empty for certs containing multiple domains.", false, 5000);
|
|
$("#obtainButton").removeClass("loading").removeClass("disabled");
|
|
return;
|
|
}
|
|
|
|
var ca = $("#ca").dropdown("get value");
|
|
var caURL = "";
|
|
if (ca == "Custom ACME Server") {
|
|
ca = "custom";
|
|
caURL = $("#caURL").val();
|
|
}
|
|
|
|
var skipTLSValue = $("#skipTLSCheckbox")[0].checked;
|
|
|
|
$.ajax({
|
|
url: "/api/acme/obtainCert",
|
|
method: "GET",
|
|
data: {
|
|
domains: domains,
|
|
filename: filename,
|
|
email: email,
|
|
ca: ca,
|
|
caURL: caURL,
|
|
skipTLS: skipTLSValue,
|
|
},
|
|
success: function(response) {
|
|
$("#obtainButton").removeClass("loading").removeClass("disabled");
|
|
if (response.error) {
|
|
console.log("Error:", response.error);
|
|
// Show error message
|
|
parent.msgbox(response.error, false, 12000);
|
|
} else {
|
|
console.log("Certificate renewed successfully");
|
|
// Show success message
|
|
parent.msgbox("Certificate renewed successfully");
|
|
|
|
// Renew the parent certificate list
|
|
parent.initManagedDomainCertificateList();
|
|
}
|
|
},
|
|
error: function(error) {
|
|
$("#obtainButton").removeClass("loading").removeClass("disabled");
|
|
console.log("Failed to renewed certificate:", error);
|
|
}
|
|
});
|
|
}
|
|
|
|
function checkIfInputDomainIsMultiple(){
|
|
var inputDomains = $("#domainsInput").val();
|
|
if (inputDomains.includes(",")){
|
|
$(".multiDomainOnly").show();
|
|
}else{
|
|
$(".multiDomainOnly").hide();
|
|
}
|
|
}
|
|
|
|
function toggleDnsChallenge(){
|
|
if ( $("#useDnsChallenge")[0].checked){
|
|
$(".dnsChallengeOnly").show();
|
|
}else{
|
|
$(".dnsChallengeOnly").hide();
|
|
}
|
|
}
|
|
|
|
//Grab the longest common suffix of all domains
|
|
//not that smart technically
|
|
function autoDetectMatchingRules(){
|
|
var domainsString = $("#domainsInput").val();
|
|
if (!domainsString.includes(",")){
|
|
return domainsString;
|
|
}
|
|
|
|
let domains = domainsString.split(",");
|
|
|
|
//Clean out any spacing between commas
|
|
for (var i = 0; i < domains.length; i++){
|
|
domains[i] = domains[i].trim();
|
|
}
|
|
|
|
function getLongestCommonSuffix(strings) {
|
|
if (strings.length === 0) {
|
|
return ''; // Return an empty string if the array is empty
|
|
}
|
|
|
|
var sortedStrings = strings.slice().sort(); // Create a sorted copy of the array
|
|
|
|
var firstString = sortedStrings[0];
|
|
var lastString = sortedStrings[sortedStrings.length - 1];
|
|
|
|
var suffix = '';
|
|
var minLength = Math.min(firstString.length, lastString.length);
|
|
|
|
for (var i = 0; i < minLength; i++) {
|
|
if (firstString[firstString.length - 1 - i] !== lastString[lastString.length - 1 - i]) {
|
|
break; // Stop iterating if characters don't match
|
|
}
|
|
suffix = firstString[firstString.length - 1 - i] + suffix;
|
|
}
|
|
|
|
return suffix;
|
|
}
|
|
|
|
let longestSuffix = getLongestCommonSuffix(domains);
|
|
|
|
//Check if the suffix is a valid domain
|
|
if (longestSuffix.substr(0,1) == "."){
|
|
//Trim off the first dot
|
|
longestSuffix = longestSuffix.substr(1);
|
|
}
|
|
|
|
if (!longestSuffix.includes(".")){
|
|
parent.msgbox("Auto Detect failed: Multiple Domains", false, 5000);
|
|
return;
|
|
}
|
|
$("#filenameInput").val(longestSuffix);
|
|
}
|
|
|
|
//Handle the renew now btn click
|
|
function renewNow(){
|
|
$.get("/api/acme/autoRenew/renewNow", function(data){
|
|
if (data.error != undefined){
|
|
parent.msgbox(data.error, false, 6000);
|
|
}else{
|
|
parent.msgbox(data)
|
|
}
|
|
})
|
|
}
|
|
|
|
function initAutoRenewPolicy(){
|
|
$.get("/api/acme/autoRenew/listDomains", function(data){
|
|
if (data.error != undefined){
|
|
parent.msgbox(data.error, false)
|
|
}else{
|
|
if (data[0] == "*"){
|
|
//Auto select and renew is enabled
|
|
$("#renewAllSupported").parent().checkbox("set checked");
|
|
}else{
|
|
//This is a list of domain files
|
|
data.forEach(function(name) {
|
|
$('#domainTableBody input[type="checkbox"][name="' + name + '"]').prop('checked', true);
|
|
});
|
|
$("#domainCertFileTable").removeClass("disabled");
|
|
$("#renewNowBtn").addClass("disabled");
|
|
$("#renewSelectedButton").removeClass("disabled");
|
|
}
|
|
}
|
|
})
|
|
}
|
|
|
|
function saveAutoRenewPolicy(){
|
|
let autoRenewAll = $("#renewAllSupported").parent().checkbox("is checked");
|
|
if (autoRenewAll == true){
|
|
$.ajax({
|
|
url: "/api/acme/autoRenew/setDomains",
|
|
data: {opr: "setAuto"},
|
|
success: function(data){
|
|
parent.msgbox("Renew policy rule updated")
|
|
}
|
|
});
|
|
}else{
|
|
let checkedNames = [];
|
|
$('#domainTableBody input[type="checkbox"]:checked').each(function() {
|
|
checkedNames.push($(this).attr('name'));
|
|
});
|
|
|
|
$.ajax({
|
|
url: "/api/acme/autoRenew/setDomains",
|
|
data: {opr: "setSelected", domains: JSON.stringify(checkedNames)},
|
|
success: function(data){
|
|
parent.msgbox("Renew policy rule updated")
|
|
}
|
|
});
|
|
}
|
|
}
|
|
|
|
//Clear up the input field when page load
|
|
$("#filenameInput").val("");
|
|
</script>
|
|
</body>
|
|
</html>
|