|
@@ -5,6 +5,21 @@
|
|
|
<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;
|
|
|
+ user-select: none;
|
|
|
+ }
|
|
|
+
|
|
|
+ .expiredDomain{
|
|
|
+ color: rgb(238, 31, 31);
|
|
|
+ }
|
|
|
+
|
|
|
+ .validDomain{
|
|
|
+ color: rgb(49, 192, 113);
|
|
|
+ }
|
|
|
+ </style>
|
|
|
</head>
|
|
|
<body>
|
|
|
<br>
|
|
@@ -12,131 +27,197 @@
|
|
|
<div class="ui header">
|
|
|
<div class="content">
|
|
|
Certificates Auto Renew Settings
|
|
|
- <div class="sub header">Fetch and renew your certificates with ACME</div>
|
|
|
+ <div class="sub header">Fetch and renew your certificates with Automated Certificate Management Environment (ACME) protocol</div>
|
|
|
</div>
|
|
|
- </div>
|
|
|
- <div class="ui message">
|
|
|
-
|
|
|
</div>
|
|
|
<div class="ui basic segment">
|
|
|
<div class="ui toggle checkbox">
|
|
|
- <input type="checkbox" name="public">
|
|
|
- <label>Enable Domain Auto Renew</label>
|
|
|
+ <input type="checkbox" id="enableCertAutoRenew" checked>
|
|
|
+ <label>Enable Certificate Auto Renew</label>
|
|
|
</div>
|
|
|
</div>
|
|
|
- <div class="ui segment">
|
|
|
- <p>This is an example of using ACME.</p>
|
|
|
- <button id="fetchButton" class="ui primary button">Fetch Expired Domains</button>
|
|
|
+ <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>
|
|
|
-
|
|
|
- <div id="domainTable" class="ui segment hidden">
|
|
|
- <h2 class="ui header">Expired Domains</h2>
|
|
|
- <table id="domainList" class="ui celled table">
|
|
|
- <thead>
|
|
|
- <tr>
|
|
|
- <th>Domain</th>
|
|
|
- </tr>
|
|
|
- </thead>
|
|
|
- <tbody></tbody>
|
|
|
- </table>
|
|
|
- <div class="ui segment">
|
|
|
- <h2 class="ui header">Obtain Certificate</h2>
|
|
|
- <div class="ui form">
|
|
|
- <div class="field">
|
|
|
- <label>Domains</label>
|
|
|
- <input id="domainsInput" type="text" placeholder="Enter domains separated by commas (e.g. r5desktop.alanyeung.co,alanyeung.co)">
|
|
|
+ <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="field">
|
|
|
- <label>Filename</label>
|
|
|
- <input id="filenameInput" type="text" placeholder="Enter filename">
|
|
|
+ <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);" checked>
|
|
|
+ <label>Auto renew if CA is supported</label>
|
|
|
+ </div>
|
|
|
+ <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>Filename</th>
|
|
|
+ <th>Auto-Renew</th>
|
|
|
+ </tr>
|
|
|
+ </thead>
|
|
|
+ <tbody id="domainTableBody"></tbody>
|
|
|
+ </table>
|
|
|
+ <button class="ui basic right floated button"><i class="blue save icon"></i> Save Changes</button>
|
|
|
+ <button class="ui basic right floated button"><i class="yellow refresh icon"></i> Renew All</button>
|
|
|
+ <br><br>
|
|
|
</div>
|
|
|
- <button id="obtainButton" class="ui button" type="submit">Obtain Certificate</button>
|
|
|
+ </div>
|
|
|
+ </div>
|
|
|
+ <div class="ui divider"></div>
|
|
|
+ <h3>Manual Renew</h3>
|
|
|
+ <p>Pick a certificate below to force renew</p>
|
|
|
+ <div class="ui form">
|
|
|
+ <div class="field">
|
|
|
+ <label>Domains</label>
|
|
|
+ <input id="domainsInput" type="text" placeholder="example.com">
|
|
|
+ <small>If you have more than one domain in a single certificate, enter the domains separated by commas (e.g. test.example.com,example.com)</small>
|
|
|
+ </div>
|
|
|
+ <div class="field">
|
|
|
+ <label>Filename</label>
|
|
|
+ <input id="filenameInput" type="text" placeholder="Enter filename">
|
|
|
+ </div>
|
|
|
+ <div class="field">
|
|
|
+ <label>Certificate Authority (CA)</label>
|
|
|
+ <div class="ui selection dropdown">
|
|
|
+ <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="Google">Google</div>
|
|
|
</div>
|
|
|
</div>
|
|
|
</div>
|
|
|
+ <button id="obtainButton" class="ui basic button" type="submit"><i class="yellow refresh icon"></i> Renew Certificate</button>
|
|
|
+ </div>
|
|
|
+
|
|
|
+ <button class="ui basic button" style="float: right;" onclick="parent.hideSideWrapper();"><i class="remove icon"></i> Cancel</button>
|
|
|
+ <br><br><br><br>
|
|
|
</div>
|
|
|
|
|
|
- <script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.6.0/jquery.min.js"></script>
|
|
|
- <script src="https://cdnjs.cloudflare.com/ajax/libs/semantic-ui/2.4.1/semantic.min.js"></script>
|
|
|
<script>
|
|
|
- $(document).ready(function() {
|
|
|
- // Button click event handler
|
|
|
- $("#fetchButton").click(function() {
|
|
|
- fetchExpiredDomains();
|
|
|
- });
|
|
|
+ let expiredDomains = [];
|
|
|
+ $(".accordion").accordion();
|
|
|
+ $(".dropdown").dropdown();
|
|
|
|
|
|
- // Fetch expired domains from API
|
|
|
- function fetchExpiredDomains() {
|
|
|
- $.ajax({
|
|
|
- url: "/api/acme/listExpiredDomains",
|
|
|
- method: "GET",
|
|
|
- success: function(response) {
|
|
|
- // Render domain table
|
|
|
- renderDomainTable(response.domain);
|
|
|
- },
|
|
|
- error: function(error) {
|
|
|
- console.log("Failed to fetch expired domains:", error);
|
|
|
- }
|
|
|
- });
|
|
|
+ function setAutoRenewIfCASupportMode(useAutoMode = true){
|
|
|
+ if (useAutoMode){
|
|
|
+ $("#domainCertFileTable").addClass("disabled");
|
|
|
+ }else{
|
|
|
+ $("#domainCertFileTable").removeClass("disabled");
|
|
|
}
|
|
|
+ }
|
|
|
+
|
|
|
+ //Render the domains table that exists in this zoraxy host
|
|
|
+ function renderDomainTable(domains) {
|
|
|
+ // Get the table body element
|
|
|
+ var tableBody = $('#domainTableBody');
|
|
|
+
|
|
|
+ // Clear the table body
|
|
|
+ tableBody.empty();
|
|
|
+
|
|
|
+ // Iterate over the domain names
|
|
|
+ var counter = 0;
|
|
|
+ for (const [domain, srcfile] of Object.entries(domains)) {
|
|
|
|
|
|
- // Render domain table with data
|
|
|
- function renderDomainTable(domains) {
|
|
|
- var tableBody = $("#domainList tbody");
|
|
|
- tableBody.empty();
|
|
|
+ // Create a table row
|
|
|
+ var row = $('<tr>');
|
|
|
+
|
|
|
+ // Create the domain name cell
|
|
|
+ var domainClass = "validDomain";
|
|
|
+ if (expiredDomains.includes(domain)){
|
|
|
+ domainClass = "expiredDomain";
|
|
|
+ }
|
|
|
+ var domainCell = $('<td class="' + domainClass +'">').text(domain);
|
|
|
+ row.append(domainCell);
|
|
|
|
|
|
- $.each(domains, function(index, domain) {
|
|
|
- var row = $("<tr>").appendTo(tableBody);
|
|
|
- $("<td>").text(domain).appendTo(row);
|
|
|
- });
|
|
|
+ var srcFileCell = $('<td>').text(srcfile);
|
|
|
+ row.append(srcFileCell);
|
|
|
+
|
|
|
+ // Create the auto-renew checkbox cell
|
|
|
+ var checkboxCell = $(`<td domain="${domain}" srcfile="${srcfile}">`);
|
|
|
+ var checkbox = $('<input>').attr('type', 'checkbox');
|
|
|
+ checkboxCell.append(checkbox);
|
|
|
+ row.append(checkboxCell);
|
|
|
+
|
|
|
+ // Add the row to the table body
|
|
|
+ tableBody.append(row);
|
|
|
|
|
|
- // Show the domain table
|
|
|
- $("#domainTable").removeClass("hidden");
|
|
|
+ counter++;
|
|
|
}
|
|
|
+ }
|
|
|
+
|
|
|
+ //Initiate domain table. If you needs to update the expired domain as well
|
|
|
+ //call from initDomainFileList() instead
|
|
|
+ function initDomainTable(){
|
|
|
+ $.get("/api/cert/listdomains", function(data){
|
|
|
+ if (data.error != undefined){
|
|
|
+ parent.msgbox(data.error, false);
|
|
|
+ }else{
|
|
|
+ renderDomainTable(data);
|
|
|
+ }
|
|
|
+ })
|
|
|
+ }
|
|
|
|
|
|
- // Button click event handler for obtaining certificate
|
|
|
- $("#obtainButton").click(function() {
|
|
|
- obtainCertificate();
|
|
|
+ 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() {
|
|
|
+ obtainCertificate();
|
|
|
+ });
|
|
|
|
|
|
- // Obtain certificate from API
|
|
|
- function obtainCertificate() {
|
|
|
- var domains = $("#domainsInput").val();
|
|
|
- var filename = $("#filenameInput").val();
|
|
|
+ // Obtain certificate from API
|
|
|
+ function obtainCertificate() {
|
|
|
+ var domains = $("#domainsInput").val();
|
|
|
+ var filename = $("#filenameInput").val();
|
|
|
|
|
|
- $.ajax({
|
|
|
- url: "/api/acme/obtainCert",
|
|
|
- method: "GET",
|
|
|
- data: {
|
|
|
- domains: domains,
|
|
|
- filename: filename
|
|
|
- },
|
|
|
- success: function(response) {
|
|
|
- if (response.error) {
|
|
|
- console.log("Error:", response.error);
|
|
|
- // Show error message
|
|
|
- showMessage(response.error);
|
|
|
- } else {
|
|
|
- console.log("Certificate obtained successfully");
|
|
|
- // Show success message
|
|
|
- showMessage("Certificate obtained successfully");
|
|
|
- }
|
|
|
- },
|
|
|
- error: function(error) {
|
|
|
- console.log("Failed to obtain certificate:", error);
|
|
|
+ $.ajax({
|
|
|
+ url: "/api/acme/obtainCert",
|
|
|
+ method: "GET",
|
|
|
+ data: {
|
|
|
+ domains: domains,
|
|
|
+ filename: filename
|
|
|
+ },
|
|
|
+ success: function(response) {
|
|
|
+ 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");
|
|
|
}
|
|
|
- });
|
|
|
- }
|
|
|
+ },
|
|
|
+ error: function(error) {
|
|
|
+ console.log("Failed to renewed certificate:", error);
|
|
|
+ }
|
|
|
+ });
|
|
|
+ }
|
|
|
|
|
|
- // Show message in a popup
|
|
|
- function showMessage(message) {
|
|
|
- $("<div>").addClass("ui message").text(message).appendTo("body").modal({
|
|
|
- onHide: function() {
|
|
|
- $(this).remove();
|
|
|
- }
|
|
|
- }).modal("show");
|
|
|
- }
|
|
|
- });
|
|
|
</script>
|
|
|
</body>
|
|
|
</html>
|