Initial euclide.org release
This commit is contained in:
7
web/bootstrap.min.css
vendored
Normal file
7
web/bootstrap.min.css
vendored
Normal file
File diff suppressed because one or more lines are too long
1
web/bootstrap.min.css.map
Normal file
1
web/bootstrap.min.css.map
Normal file
File diff suppressed because one or more lines are too long
7
web/bootstrap.min.js
vendored
Normal file
7
web/bootstrap.min.js
vendored
Normal file
File diff suppressed because one or more lines are too long
83
web/common.css
Normal file
83
web/common.css
Normal file
@@ -0,0 +1,83 @@
|
||||
body {
|
||||
padding-top: 2rem;
|
||||
padding-bottom: 2rem;
|
||||
padding-left: 5em;
|
||||
padding-right: 5em;
|
||||
}
|
||||
|
||||
#zone {
|
||||
}
|
||||
|
||||
.hidden {
|
||||
display:none;
|
||||
}
|
||||
|
||||
.center {
|
||||
margin-left: 45%;
|
||||
}
|
||||
|
||||
.row {
|
||||
margin-bottom: 0.3rem;
|
||||
}
|
||||
.row .row {
|
||||
margin-top: 1rem;
|
||||
margin-bottom: 0;
|
||||
}
|
||||
[class*="col-"] {
|
||||
padding-top: 1rem;
|
||||
padding-bottom: 1rem;
|
||||
background-color: rgba(86, 61, 124, .15);
|
||||
border: 1px solid rgba(86, 61, 124, .2);
|
||||
}
|
||||
|
||||
hr {
|
||||
margin-top: 2rem;
|
||||
margin-bottom: 2rem;
|
||||
}
|
||||
|
||||
th {
|
||||
padding: 3px 5px 3px 5px;
|
||||
border-style: solid solid none none;
|
||||
border-width: 1px;
|
||||
text-align: left;
|
||||
font-weight:bold;
|
||||
font-size: 11pt;
|
||||
vertical-align: middle;
|
||||
}
|
||||
|
||||
td {
|
||||
padding: 3px 5px 3px 5px;
|
||||
border-style: solid solid none none;
|
||||
border-width: 1px;
|
||||
vertical-align: middle;
|
||||
font-size: 11pt;
|
||||
white-space: nowrap;
|
||||
}
|
||||
|
||||
td.empty {
|
||||
background-color: rgba(66, 51, 104, .15);
|
||||
}
|
||||
|
||||
table {
|
||||
border-width: 1px;
|
||||
border-spacing:0;
|
||||
margin: 1em;
|
||||
width: 100%;
|
||||
border-collapse:collapse;
|
||||
}
|
||||
|
||||
tbody {
|
||||
overflow-y: auto;
|
||||
height:700px;
|
||||
display:block;
|
||||
border-style: solid none solid solid;
|
||||
border-width: 1px;
|
||||
border-spacing:0;
|
||||
}
|
||||
|
||||
thead {
|
||||
display:table;
|
||||
border-style: solid none solid solid;
|
||||
border-width: 1px;
|
||||
border-spacing:0;
|
||||
}
|
||||
259
web/index.html
Normal file
259
web/index.html
Normal file
@@ -0,0 +1,259 @@
|
||||
<!doctype html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<title>DNS Editor</title>
|
||||
<meta http-equiv="content-type" content="text/html; charset=utf-8" />
|
||||
<link rel="stylesheet" href="bootstrap.min.css">
|
||||
<link rel="stylesheet" href="common.css">
|
||||
<script language="javascript" type="text/javascript" src="jquery.min.js"></script>
|
||||
<script type="text/javascript">
|
||||
$(function() {
|
||||
ajax([{"method":"list"}]);
|
||||
});
|
||||
|
||||
function ajax(action){
|
||||
$.ajax({
|
||||
type: 'post',
|
||||
url: '/jsonrpc',
|
||||
data: JSON.stringify(action),
|
||||
error:function(msg){
|
||||
data = jQuery.parseJSON(msg.responseText);
|
||||
if ('error' in data) {
|
||||
alert(data.error.message);
|
||||
}
|
||||
console.log( 'Error !: (' + msg.responseText + ')' );
|
||||
|
||||
},
|
||||
success:function(data){
|
||||
if (data.length == 0) {
|
||||
console.log(data);
|
||||
return;
|
||||
}
|
||||
if ('error' in data[0]) {
|
||||
alert(data[0].error.message);
|
||||
return;
|
||||
}
|
||||
if (action[data.length-1]["method"] == "list") {
|
||||
refreshList(data[data.length - 1]);
|
||||
$("#validNewZone").hide();
|
||||
$("#newZone").val($("#newZone").attr("value"));
|
||||
|
||||
return
|
||||
}
|
||||
refreshZone(data[data.length - 1]);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
function newZoneSet() {
|
||||
if($("#newZone").val() != "" && isChange("newZone")) {
|
||||
$("#validNewZone").show();
|
||||
} else {
|
||||
$("#validNewZone").hide();
|
||||
}
|
||||
}
|
||||
|
||||
function newSet() {
|
||||
if($("#newValue").val() != "" && isChange("newName")) {
|
||||
$("#ok-new").show();
|
||||
} else {
|
||||
$("#ok-new").hide();
|
||||
}
|
||||
}
|
||||
|
||||
function isChange(id) {
|
||||
if($("#"+id).val() != $("#"+id).attr('value')) {
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
function newZone() {
|
||||
zone = $("#newZone").val();
|
||||
ajax([
|
||||
{"id":1, "method":"newzone", "params":{"name":zone}},
|
||||
{"id":2, "method":"list"}
|
||||
]);
|
||||
}
|
||||
|
||||
function newEntry(zone) {
|
||||
method = $("#newType").val();
|
||||
entry = $("#newName").val() + "." + zone;
|
||||
if($("#newName").val() == "") {
|
||||
entry = zone;
|
||||
}
|
||||
newTTL = $("#newTTL").val();
|
||||
newValue = $("#newValue").val();
|
||||
newComment = "";
|
||||
if (isChange("newComment")) {
|
||||
newComment = $("#newComment").val();
|
||||
}
|
||||
ajax([{"id":1, "method":method,
|
||||
"params":{"name":entry, "value":newValue,
|
||||
"comment": comment, "append":true, "ttl":parseInt(newTTL, 10)}},
|
||||
{"id":2, "method":"dump", "params":{"name":zone}}]);
|
||||
return
|
||||
}
|
||||
|
||||
function editSet(line, sub) {
|
||||
$("#ok-" + line + "-" + sub).show();
|
||||
}
|
||||
|
||||
function entryedit(entry, method, zone, line, sub, nbvalues) {
|
||||
origValue = $("#value-" + line + "-" + sub).attr('value');
|
||||
origTTL = $("#ttl-" + line).attr('value')
|
||||
newTTL = $("#ttl-" + line).val();
|
||||
newValue = $("#value-" + line + "-" + sub).val();
|
||||
comment ="";
|
||||
if (isChange("comment-"+line)) {
|
||||
comment = $("#comment-"+line).val();
|
||||
}
|
||||
if(origValue == newValue && origTTL != newTTL) {
|
||||
ajax([{"id":1, "method":"ttl", "params":{"name":entry, "comment": comment, "ttl":parseInt(newTTL, 10)}},
|
||||
{"id":2, "method":"dump", "params":{"name":zone}}]);
|
||||
return
|
||||
}
|
||||
if (nbvalues == 1) {
|
||||
ajax([{"id":1, "method":method.toLowerCase(), "params":{"name":entry, "value":newValue, "comment": comment, "ttl":parseInt(newTTL, 10)}},
|
||||
{"id":2, "method":"dump", "params":{"name":zone}}]);
|
||||
return
|
||||
}
|
||||
ajax([
|
||||
{"id":1, "method":"delete", "params":{"name":entry, "value":origValue}},
|
||||
{"id":2, "method":method.toLowerCase(), "params":{"name":entry, "value":newValue, "comment": comment, "ttl":parseInt(newTTL, 10), "append":true}},
|
||||
{"id":3, "method":"dump", "params":{"name":zone}}]);
|
||||
return
|
||||
}
|
||||
|
||||
function entrydelete(entry, value, zone) {
|
||||
if (confirm("Do you want to delete " + entry + " ?")) {
|
||||
ajax([{"id":1, "method":"delete", "params":{"name":entry, "value":value}},
|
||||
{"id":2, "method":"dump", "params":{"name":zone}}]);
|
||||
}
|
||||
}
|
||||
|
||||
function dump() {
|
||||
$("#zonelist option[value='']").remove();
|
||||
zone=$("#zonelist").val();
|
||||
ajax([{"method":"dump", "params":{"name":zone}}]);
|
||||
}
|
||||
|
||||
function erase(input) {
|
||||
if (input != "newName" && $("#"+input).val()=="") {
|
||||
$("#"+input).val($("#" + input).attr('value'));
|
||||
return
|
||||
}
|
||||
if ($("#"+input).val()==$("#" + input).attr('value')) {
|
||||
$("#"+input).val("");
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
function refreshZone(data) {
|
||||
domain = data["result"][0].raw[0].domain;
|
||||
types = ["A", "AAAA", "CNAME", "MX", "SRV","TXT"];
|
||||
if(domain.endsWith(".arpa.")) {
|
||||
types = ["PTR"];
|
||||
}
|
||||
result = "<table>";
|
||||
result += "<thead>";
|
||||
result += "<tr><td>";
|
||||
result += "<input onfocus=\"erase('newName')\" id=\"newName\" value=\"new entry\">." + domain + "</b>";
|
||||
result += "</td>";
|
||||
result += "<td><select id=\"newType\">";
|
||||
types.forEach(function(type, index, e) {
|
||||
result += "<option value=\""+type.toLowerCase()+"\">"+type+"</option>";
|
||||
});
|
||||
result += "</select></td>";
|
||||
result += "<td><input oninput=\"newSet()\" id=\"newTTL\" size=\"5\" value=\"86400\"></td>";
|
||||
result += "<td><input oninput=\"newSet()\" id=\"newValue\" value=\"Add a target\" onfocus=\"erase('newValue')\" onfocusout=\"erase('newValue')\" id=\"newValue\"></td>";
|
||||
result += "<td><input id=\"newComment\" size=\"15\" value=\"Add a comment\" onfocusout=\"erase('newComment')\" onfocus=\"erase('newComment')\"></td>";
|
||||
result += "<td>";
|
||||
result += "<img onclick=\"newEntry('" + domain + "')\" class=\"hidden\" id=\"ok-new\" src=\"ok.png\">";
|
||||
result += "</td>";
|
||||
result += "</tr>";
|
||||
result += "<tr><td class=\"empty\" colspan=\"6\"> </td></tr>";
|
||||
result += "</thead>";
|
||||
result += "<tbody>";
|
||||
result += "<tr><th>Name</th><th>Type</th><th>TTL</th><th>Value</th><th>Comment</th><th>Action</th></tr>";
|
||||
num = 0;
|
||||
data["result"][0].raw[0].rrsets.forEach(function(entry, index, e) {
|
||||
comment="Add a comment";
|
||||
commentBy="";
|
||||
i = entry.comments.length;
|
||||
if (i > 0) {
|
||||
comment = entry.comments[i-1].content;
|
||||
commentBy = entry.comments[i-1].account;
|
||||
}
|
||||
name = entry["name"]
|
||||
num++;
|
||||
if (entry["type"] == "NS" && name == domain) {
|
||||
return;
|
||||
}
|
||||
if (entry["type"] == "SOA") {
|
||||
return;
|
||||
}
|
||||
size = entry["records"].length;
|
||||
if (name == domain) {
|
||||
name = "";
|
||||
} else {
|
||||
name = name.replace(domain, "");
|
||||
}
|
||||
result += "<tr><td rowspan=\""+size+"\">" + name + "<b>" + domain + "</b></td>";
|
||||
result += "<td rowspan=\""+size+"\">" + entry["type"] + "</td>";
|
||||
result += "<td rowspan=\""+size+"\"><input id=\"ttl-"+num.toString()+"\" size=\"5\" value=\"" + entry["ttl"] + "\" oninput=\"editSet(" + num.toString() + ", " + 0 +")\"></td>";
|
||||
result += "<td><input size=\"30\" id=\"value-"+num.toString()+"-0\" value=\"" + entry["records"][0]["content"].replace(/"/g, '') + "\" oninput=\"editSet(" + num.toString() + ", " + 0 +")\"></td>";
|
||||
result += "<td rowspan=\""+size+"\"><input id=\"comment-"+num.toString()+"\" size=\"15\" value=\"" + comment + "\" onfocusout=\"erase('comment-"+num.toString()+"')\" onfocus=\"erase('comment-"+num.toString()+"')\">"+commentBy+"</td>";
|
||||
result += "<td>";
|
||||
result += "<img onclick=\"entryedit('" + entry["name"] + "', '" + entry["type"] + "', '" + domain + "', " + num.toString() + ", " + 0 +", " + size + ")\" class=\"hidden\" id=\"ok-"+num.toString()+"-"+0+"\" src=\"ok.png\">";
|
||||
result += "<img onclick=\"entrydelete('" + entry["name"] + "', '" + entry["records"][0]["content"].replace(/"/g, '') + "', '" + domain + "')\" src=\"trash.png\">";
|
||||
result += "</td>";
|
||||
result += "</tr>";
|
||||
for(i=1;i<size;i++) {
|
||||
result += "<tr>";
|
||||
result += "<td><input size=\"30\" id=\"value-"+num.toString()+"-"+i+"\" value=\"" + entry["records"][i]["content"] + "\" oninput=\"editSet(" + num.toString() + ", " + i +")\"></td>";
|
||||
result += "<td>";
|
||||
result += "<img onclick=\"entryedit('" + entry["name"] + "', '" + entry["type"] + "', '" + domain + "', " + num.toString() + ", " + i +", " + size + ")\" class=\"hidden\" id=\"ok-"+num.toString()+"-"+i+"\" src=\"ok.png\">";
|
||||
result += "<img onclick=\"entrydelete('" + entry["name"] + "', '" + entry["records"][i]["content"].replace(/"/g, '') + "', '" + domain + "')\" src=\"trash.png\">";
|
||||
result += "</td>";
|
||||
result += "</tr>";
|
||||
}
|
||||
});
|
||||
result += "</tbody>";
|
||||
result += "</table>";
|
||||
$("#zone").html(result);
|
||||
}
|
||||
|
||||
function refreshList(data) {
|
||||
result = '<option value="">Select a zone</option>';
|
||||
data["result"][0].raw.forEach(function(domain, index, e) {
|
||||
result += "<option value=\"" + domain + "\">" + domain + "</option>";
|
||||
});
|
||||
$("#zone").html("<divv class=\"center\">Please select a zone<div>");
|
||||
$("#zonelist").html(result);
|
||||
}
|
||||
</script>
|
||||
</head>
|
||||
<body>
|
||||
<div>
|
||||
<h2 class="center">
|
||||
DNS editor
|
||||
</h2>
|
||||
<div class="row">
|
||||
<div class="col-6 col-sm-6 col-lg-6">
|
||||
<select onchange="dump()" id="zonelist"></select>
|
||||
</div>
|
||||
<div class="col-6 col-sm-6 col-lg-6">
|
||||
<input id="newZone" onfocusout="erase('newZone')" onfocus="erase('newZone')" oninput="newZoneSet()" value="create a new zone" />
|
||||
<img class="hidden" onclick="newZone()" id="validNewZone" src="ok.png" />
|
||||
</div>
|
||||
</div>
|
||||
<div class="row">
|
||||
<div class="col-12 col-sm-12 col-lg-12" id="zone">You must use your personnal SSL Certificate to authenticate</div>
|
||||
</div>
|
||||
</div>
|
||||
<script language="javascript" type="text/javascript" src="popper.min.js" ></script>
|
||||
<script language="javascript" type="text/javascript" src="bootstrap.min.js"></script>
|
||||
</body>
|
||||
</html>
|
||||
4
web/jquery.min.js
vendored
Normal file
4
web/jquery.min.js
vendored
Normal file
File diff suppressed because one or more lines are too long
BIN
web/ok.png
Normal file
BIN
web/ok.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 2.6 KiB |
5
web/popper.min.js
vendored
Normal file
5
web/popper.min.js
vendored
Normal file
File diff suppressed because one or more lines are too long
BIN
web/stop.png
Normal file
BIN
web/stop.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 2.1 KiB |
BIN
web/trash.png
Normal file
BIN
web/trash.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 2.1 KiB |
Reference in New Issue
Block a user