mirror of
https://github.com/tobychui/zoraxy.git
synced 2025-08-06 21:28:30 +02:00
Added Zoraxy experimental
This commit is contained in:
279
src/web/components/cert.html
Normal file
279
src/web/components/cert.html
Normal file
@@ -0,0 +1,279 @@
|
||||
|
||||
<h3><i class="ui lock icon"></i> TLS / SSL Certificates</h3>
|
||||
<p>Setup TLS cert for different domains of your reverse proxy server names</p>
|
||||
<div class="ui divider"></div>
|
||||
<h4>Default Certificates</h4>
|
||||
<small>When there are no matching certificate for the requested server name, reverse proxy router will always fallback to this one.<br>Note that you need both of them uploaded for it to fallback properly</small></p>
|
||||
<table class="ui very basic celled table">
|
||||
<thead>
|
||||
<tr><th>Key Type</th>
|
||||
<th>Exists</th>
|
||||
</tr></thead>
|
||||
<tbody>
|
||||
<tr>
|
||||
<td><i class="globe icon"></i> Default Public Key</td>
|
||||
<td id="pubkeyExists"></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><i class="lock icon"></i> Default Private Key</td>
|
||||
<td id="prikeyExists"></td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
<button class="ui button" onclick="uploadPublicKey();"><i class="globe icon"></i> Upload Public Key</button>
|
||||
<button class="ui black button" onclick="uploadPrivateKey();"><i class="lock icon"></i> Upload Private Key</button>
|
||||
<div class="ui divider"></div>
|
||||
<h4>Sub-domain Certificates</h4>
|
||||
<p>Provide certificates for multiple domains reverse proxy</p>
|
||||
<div class="ui fluid form">
|
||||
<div class="three fields">
|
||||
<div class="field">
|
||||
<label>Server Name (Domain)</label>
|
||||
<input type="text" id="certdomain" placeholder="example.com / blog.example.com">
|
||||
</div>
|
||||
<div class="field">
|
||||
<label>Public Key</label>
|
||||
<input type="file" id="pubkeySelector" onchange="handleFileSelect(event, 'pub')">
|
||||
</div>
|
||||
<div class="field">
|
||||
<label>Private Key</label>
|
||||
<input type="file" id="prikeySelector" onchange="handleFileSelect(event, 'pri')">
|
||||
</div>
|
||||
</div>
|
||||
<button class="ui teal button" onclick="handleDomainUploadByKeypress();"><i class="ui upload icon"></i> Upload</button>
|
||||
</div>
|
||||
<div id="certUploadSuccMsg" class="ui green message" style="display:none;">
|
||||
<i class="ui checkmark icon"></i> Certificate for domain <span id="certUploadingDomain"></span> uploaded.
|
||||
</div>
|
||||
<br>
|
||||
<div>
|
||||
<table class="ui sortable unstackable celled table">
|
||||
<thead>
|
||||
<tr><th>Domain</th>
|
||||
<th>Last Update</th>
|
||||
<th class="no-sort">Remove</th>
|
||||
</tr></thead>
|
||||
<tbody id="certifiedDomainList">
|
||||
|
||||
</tbody>
|
||||
</table>
|
||||
<button class="ui green basic button" onclick="initManagedDomainCertificateList();"><i class="refresh icon"></i> Refresh List</button>
|
||||
</div>
|
||||
<div class="ui message">
|
||||
<h4><i class="info circle icon"></i> Sub-domain Certificates</h4>
|
||||
If you have 3rd or even 4th level subdomains like <code>blog.example.com</code> or <code>en.blog.example.com</code> ,
|
||||
depending on your certificates coverage, you might need to setup them one by one (i.e. having two seperate certificate for <code>a.example.com</code> and <code>b.example.com</code>).<br>
|
||||
If you have a wildcard certificate that covers <code>*.example.com</code>, you can just enter <code>example.com</code> as server name in the form below to add a certificate.
|
||||
</div>
|
||||
<script>
|
||||
var uploadPendingPublicKey = undefined;
|
||||
var uploadPendingPrivateKey = undefined;
|
||||
|
||||
//Delete the certificate by its domain
|
||||
function deleteCertificate(domain){
|
||||
if (confirm("Confirm delete certificate for " + domain + " ?")){
|
||||
$.ajax({
|
||||
url: "/api/cert/delete",
|
||||
method: "POST",
|
||||
data: {domain: domain},
|
||||
success: function(data){
|
||||
if (data.error != undefined){
|
||||
alert(data.error);
|
||||
}else{
|
||||
initManagedDomainCertificateList();
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
//List the stored certificates
|
||||
function initManagedDomainCertificateList(){
|
||||
$("#certifiedDomainList").html("");
|
||||
$.get("/api/cert/list?date=true", function(data){
|
||||
if (data.error != undefined){
|
||||
alert(data.error);
|
||||
}else{
|
||||
data.forEach(entry => {
|
||||
$("#certifiedDomainList").append(`<tr>
|
||||
<td>${entry.Domain}</td>
|
||||
<td>${entry.LastModifiedDate}</td>
|
||||
<td><button title="Delete key-pair" class="ui mini basic red icon button" onclick="deleteCertificate('${entry.Domain}');"><i class="ui red trash icon"></i></button></td>
|
||||
</tr>`);
|
||||
})
|
||||
}
|
||||
})
|
||||
}
|
||||
initManagedDomainCertificateList();
|
||||
|
||||
function handleDomainUploadByKeypress(){
|
||||
handleDomainKeysUpload(function(){
|
||||
$("#certUploadingDomain").text($("#certdomain").val().trim());
|
||||
//After uploaded, reset the file selector
|
||||
document.getElementById('pubkeySelector').value = '';
|
||||
document.getElementById('prikeySelector').value = '';
|
||||
document.getElementById('certdomain').value = '';
|
||||
|
||||
uploadPendingPublicKey = undefined;
|
||||
uploadPendingPrivateKey = undefined;
|
||||
|
||||
//Show succ
|
||||
$("#certUploadSuccMsg").stop().finish().slideDown("fast").delay(3000).slideUp("fast");
|
||||
initManagedDomainCertificateList();
|
||||
});
|
||||
}
|
||||
//Handle domain keys upload
|
||||
function handleDomainKeysUpload(callback=undefined){
|
||||
let domain = $("#certdomain").val();
|
||||
if (domain.trim() == ""){
|
||||
alert("Missing domain.");
|
||||
return;
|
||||
}
|
||||
if (uploadPendingPublicKey && uploadPendingPrivateKey && typeof uploadPendingPublicKey === 'object' && typeof uploadPendingPrivateKey === 'object') {
|
||||
const publicKeyForm = new FormData();
|
||||
publicKeyForm.append('file', uploadPendingPublicKey, 'publicKey');
|
||||
|
||||
const privateKeyForm = new FormData();
|
||||
privateKeyForm.append('file', uploadPendingPrivateKey, 'privateKey');
|
||||
|
||||
const publicKeyRequest = new XMLHttpRequest();
|
||||
publicKeyRequest.open('POST', '/api/cert/upload?ktype=pub&domain=' + domain);
|
||||
publicKeyRequest.onreadystatechange = function() {
|
||||
if (publicKeyRequest.readyState === XMLHttpRequest.DONE) {
|
||||
if (publicKeyRequest.status !== 200) {
|
||||
alert('Error uploading public key: ' + publicKeyRequest.statusText);
|
||||
}
|
||||
|
||||
if (callback != undefined){
|
||||
callback();
|
||||
}
|
||||
|
||||
}
|
||||
};
|
||||
publicKeyRequest.send(publicKeyForm);
|
||||
|
||||
const privateKeyRequest = new XMLHttpRequest();
|
||||
privateKeyRequest.open('POST', '/api/cert/upload?ktype=pri&domain=' + domain);
|
||||
privateKeyRequest.onreadystatechange = function() {
|
||||
if (privateKeyRequest.readyState === XMLHttpRequest.DONE) {
|
||||
if (privateKeyRequest.status !== 200) {
|
||||
alert('Error uploading private key: ' + privateKeyRequest.statusText);
|
||||
}
|
||||
if (callback != undefined){
|
||||
callback();
|
||||
}
|
||||
}
|
||||
};
|
||||
privateKeyRequest.send(privateKeyForm);
|
||||
} else {
|
||||
alert('One or both of the files is missing or not a file object');
|
||||
}
|
||||
}
|
||||
|
||||
//Handlers for selecting domain based key pairs
|
||||
//ktype = {"pub" / "pri"}
|
||||
function handleFileSelect(event, ktype="pub") {
|
||||
const file = event.target.files[0];
|
||||
//const fileNameInput = document.getElementById('selected-file-name');
|
||||
if (ktype == "pub"){
|
||||
uploadPendingPublicKey = file;
|
||||
}else if (ktype == "pri"){
|
||||
uploadPendingPrivateKey = file;
|
||||
}
|
||||
|
||||
|
||||
//fileNameInput.value = file.name;
|
||||
}
|
||||
|
||||
//Check if the default keypairs exists
|
||||
function initDefaultKeypairCheck(){
|
||||
$.get("/api/cert/checkDefault", function(data){
|
||||
let tick = `<i class="ui green checkmark icon"></i>`;
|
||||
let cross = `<i class="ui red times icon"></i>`;
|
||||
$("#pubkeyExists").html(data.DefaultPubExists?tick:cross);
|
||||
$("#prikeyExists").html(data.DefaultPriExists?tick:cross);
|
||||
});
|
||||
}
|
||||
initDefaultKeypairCheck();
|
||||
|
||||
function uploadPrivateKey(){
|
||||
// create file input element
|
||||
const input = document.createElement('input');
|
||||
input.type = 'file';
|
||||
|
||||
// add change listener to file input
|
||||
input.addEventListener('change', () => {
|
||||
// create form data object
|
||||
const formData = new FormData();
|
||||
|
||||
// add selected file to form data
|
||||
formData.append('file', input.files[0]);
|
||||
|
||||
// send form data to server
|
||||
fetch('/api/cert/upload?ktype=pri', {
|
||||
method: 'POST',
|
||||
body: formData
|
||||
})
|
||||
.then(response => {
|
||||
initDefaultKeypairCheck();
|
||||
if (response.ok) {
|
||||
alert('File upload successful!');
|
||||
} else {
|
||||
response.text().then(text => {
|
||||
alert(text);
|
||||
});
|
||||
//console.log(response.text());
|
||||
//alert('File upload failed!');
|
||||
}
|
||||
})
|
||||
.catch(error => {
|
||||
alert('An error occurred while uploading the file.');
|
||||
console.error(error);
|
||||
});
|
||||
});
|
||||
|
||||
// click file input to open file selector
|
||||
input.click();
|
||||
}
|
||||
|
||||
function uploadPublicKey() {
|
||||
// create file input element
|
||||
const input = document.createElement('input');
|
||||
input.type = 'file';
|
||||
|
||||
// add change listener to file input
|
||||
input.addEventListener('change', () => {
|
||||
// create form data object
|
||||
const formData = new FormData();
|
||||
|
||||
// add selected file to form data
|
||||
formData.append('file', input.files[0]);
|
||||
|
||||
// send form data to server
|
||||
fetch('/api/cert/upload?ktype=pub', {
|
||||
method: 'POST',
|
||||
body: formData
|
||||
})
|
||||
.then(response => {
|
||||
if (response.ok) {
|
||||
alert('File upload successful!');
|
||||
initDefaultKeypairCheck();
|
||||
} else {
|
||||
response.text().then(text => {
|
||||
alert(text);
|
||||
});
|
||||
//console.log(response.text());
|
||||
//alert('File upload failed!');
|
||||
}
|
||||
})
|
||||
.catch(error => {
|
||||
alert('An error occurred while uploading the file.');
|
||||
console.error(error);
|
||||
});
|
||||
});
|
||||
|
||||
// click file input to open file selector
|
||||
input.click();
|
||||
}
|
||||
</script>
|
Reference in New Issue
Block a user