Spaces:
Paused
Paused
j49_c commited on
Commit ·
092273c
1
Parent(s): a39ccf4
fix icons, ban, and add delete server functionality
Browse files- admin.html +6 -0
- app.py +17 -2
- index.html +9 -0
- login.html +6 -1
admin.html
CHANGED
|
@@ -422,6 +422,7 @@
|
|
| 422 |
${s.banned
|
| 423 |
? `<button class="btn" onclick="banServer('${s.key}', false)">Authorize</button>`
|
| 424 |
: `<button class="btn btn-danger" onclick="banServer('${s.key}', true)">Quarantine (Ban)</button>`}
|
|
|
|
| 425 |
</td>
|
| 426 |
</tr>`;
|
| 427 |
});
|
|
@@ -431,6 +432,11 @@
|
|
| 431 |
await fetch('/api/admin/server/ban', { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({ key, banned }) });
|
| 432 |
refreshAll();
|
| 433 |
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 434 |
|
| 435 |
async function refreshUsers() {
|
| 436 |
const r = await fetch('/api/admin/users');
|
|
|
|
| 422 |
${s.banned
|
| 423 |
? `<button class="btn" onclick="banServer('${s.key}', false)">Authorize</button>`
|
| 424 |
: `<button class="btn btn-danger" onclick="banServer('${s.key}', true)">Quarantine (Ban)</button>`}
|
| 425 |
+
<button class="btn btn-danger" style="border-style:dotted" onclick="deleteServerAdmin('${s.key}')">Purge (Delete)</button>
|
| 426 |
</td>
|
| 427 |
</tr>`;
|
| 428 |
});
|
|
|
|
| 432 |
await fetch('/api/admin/server/ban', { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({ key, banned }) });
|
| 433 |
refreshAll();
|
| 434 |
}
|
| 435 |
+
async function deleteServerAdmin(key) {
|
| 436 |
+
if (!confirm(`DANGER: Are you sure you want to completely PURGE this node?`)) return;
|
| 437 |
+
await fetch(`/server/delete/${encodeURIComponent(key)}`, { method: 'POST' });
|
| 438 |
+
refreshAll();
|
| 439 |
+
}
|
| 440 |
|
| 441 |
async function refreshUsers() {
|
| 442 |
const r = await fetch('/api/admin/users');
|
app.py
CHANGED
|
@@ -473,7 +473,8 @@ def list_all_servers_for_admin():
|
|
| 473 |
"key": key,
|
| 474 |
"subtitle": f"Owner: {owner}",
|
| 475 |
"startup_file": meta.get("startup_file", ""),
|
| 476 |
-
"status": st
|
|
|
|
| 477 |
})
|
| 478 |
return servers
|
| 479 |
|
|
@@ -497,7 +498,8 @@ def list_servers_for_user(username: str):
|
|
| 497 |
"key": key,
|
| 498 |
"subtitle": f"Owner: {username}",
|
| 499 |
"startup_file": meta.get("startup_file", ""),
|
| 500 |
-
"status": st
|
|
|
|
| 501 |
})
|
| 502 |
return servers
|
| 503 |
|
|
@@ -680,6 +682,19 @@ def set_startup(key):
|
|
| 680 |
return jsonify({"success": True})
|
| 681 |
|
| 682 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 683 |
@app.route("/files/list/<path:key>")
|
| 684 |
@login_required
|
| 685 |
def files_list(key):
|
|
|
|
| 473 |
"key": key,
|
| 474 |
"subtitle": f"Owner: {owner}",
|
| 475 |
"startup_file": meta.get("startup_file", ""),
|
| 476 |
+
"status": st,
|
| 477 |
+
"banned": banned
|
| 478 |
})
|
| 479 |
return servers
|
| 480 |
|
|
|
|
| 498 |
"key": key,
|
| 499 |
"subtitle": f"Owner: {username}",
|
| 500 |
"startup_file": meta.get("startup_file", ""),
|
| 501 |
+
"status": st,
|
| 502 |
+
"banned": banned
|
| 503 |
})
|
| 504 |
return servers
|
| 505 |
|
|
|
|
| 682 |
return jsonify({"success": True})
|
| 683 |
|
| 684 |
|
| 685 |
+
@app.route("/server/delete/<path:key>", methods=["POST"])
|
| 686 |
+
@login_required
|
| 687 |
+
def server_delete(key):
|
| 688 |
+
if not can_access_key(key):
|
| 689 |
+
return jsonify({"success": False, "message": "Forbidden"}), 403
|
| 690 |
+
stop_proc(key)
|
| 691 |
+
owner, folder = parse_server_key(key, allow_admin=True)
|
| 692 |
+
server_dir = get_server_dir(owner, folder)
|
| 693 |
+
if os.path.isdir(server_dir):
|
| 694 |
+
shutil.rmtree(server_dir)
|
| 695 |
+
return jsonify({"success": True})
|
| 696 |
+
|
| 697 |
+
|
| 698 |
@app.route("/files/list/<path:key>")
|
| 699 |
@login_required
|
| 700 |
def files_list(key):
|
index.html
CHANGED
|
@@ -736,6 +736,7 @@
|
|
| 736 |
<button id="adminBtn" class="btn" style="display:none" onclick="location.href='/admin'">HQ Interface</button>
|
| 737 |
<button id="homeBtn" class="btn" style="display:none" onclick="goHome()">Directory</button>
|
| 738 |
<button id="newBtn" class="btn btn-primary">+ Initialize Node</button>
|
|
|
|
| 739 |
<button class="btn btn-danger" onclick="location.href='/logout'">Disconnect</button>
|
| 740 |
</div>
|
| 741 |
</div>
|
|
@@ -941,6 +942,7 @@
|
|
| 941 |
document.getElementById('serverView').style.display = 'block';
|
| 942 |
document.getElementById('homeBtn').style.display = 'inline-block';
|
| 943 |
document.getElementById('newBtn').style.display = 'none';
|
|
|
|
| 944 |
|
| 945 |
document.getElementById('srvHeader').textContent = s.title;
|
| 946 |
document.getElementById('srvSub').textContent = s.subtitle || 'Container node verified';
|
|
@@ -952,6 +954,7 @@
|
|
| 952 |
document.getElementById('homeView').style.display = 'block';
|
| 953 |
document.getElementById('serverView').style.display = 'none';
|
| 954 |
document.getElementById('homeBtn').style.display = 'none';
|
|
|
|
| 955 |
document.getElementById('newBtn').style.display = 'inline-block';
|
| 956 |
clearInterval(poll); loadServers();
|
| 957 |
}
|
|
@@ -1127,6 +1130,12 @@
|
|
| 1127 |
});
|
| 1128 |
alert("Write success ✅");
|
| 1129 |
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1130 |
function closeEditor() { document.getElementById('editor-modal').style.display = 'none'; }
|
| 1131 |
|
| 1132 |
function openM(t, v, cb) {
|
|
|
|
| 736 |
<button id="adminBtn" class="btn" style="display:none" onclick="location.href='/admin'">HQ Interface</button>
|
| 737 |
<button id="homeBtn" class="btn" style="display:none" onclick="goHome()">Directory</button>
|
| 738 |
<button id="newBtn" class="btn btn-primary">+ Initialize Node</button>
|
| 739 |
+
<button id="delSrvBtn" class="btn btn-danger" style="display:none" onclick="deleteServer()">Purge Node</button>
|
| 740 |
<button class="btn btn-danger" onclick="location.href='/logout'">Disconnect</button>
|
| 741 |
</div>
|
| 742 |
</div>
|
|
|
|
| 942 |
document.getElementById('serverView').style.display = 'block';
|
| 943 |
document.getElementById('homeBtn').style.display = 'inline-block';
|
| 944 |
document.getElementById('newBtn').style.display = 'none';
|
| 945 |
+
document.getElementById('delSrvBtn').style.display = 'inline-block';
|
| 946 |
|
| 947 |
document.getElementById('srvHeader').textContent = s.title;
|
| 948 |
document.getElementById('srvSub').textContent = s.subtitle || 'Container node verified';
|
|
|
|
| 954 |
document.getElementById('homeView').style.display = 'block';
|
| 955 |
document.getElementById('serverView').style.display = 'none';
|
| 956 |
document.getElementById('homeBtn').style.display = 'none';
|
| 957 |
+
document.getElementById('delSrvBtn').style.display = 'none';
|
| 958 |
document.getElementById('newBtn').style.display = 'inline-block';
|
| 959 |
clearInterval(poll); loadServers();
|
| 960 |
}
|
|
|
|
| 1130 |
});
|
| 1131 |
alert("Write success ✅");
|
| 1132 |
}
|
| 1133 |
+
async function deleteServer() {
|
| 1134 |
+
if (!currentSrv || !confirm(`Verify purging protocol on '${currentSrv.title}'? All data will be destroyed.`)) return;
|
| 1135 |
+
const res = await fetch(`/server/delete/${encodeURIComponent(currentSrv.key)}`, { method: 'POST' });
|
| 1136 |
+
if (res.ok) { goHome(); } else { alert("Purge request failed."); }
|
| 1137 |
+
}
|
| 1138 |
+
|
| 1139 |
function closeEditor() { document.getElementById('editor-modal').style.display = 'none'; }
|
| 1140 |
|
| 1141 |
function openM(t, v, cb) {
|
login.html
CHANGED
|
@@ -188,7 +188,12 @@
|
|
| 188 |
<body>
|
| 189 |
<div class="container">
|
| 190 |
<div class="card">
|
| 191 |
-
<div class="logo">
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 192 |
<div class="title">الذئب الابيض</div>
|
| 193 |
<div class="sub">Central Intelligence Node<br>Authorized Personnel Only</div>
|
| 194 |
|
|
|
|
| 188 |
<body>
|
| 189 |
<div class="container">
|
| 190 |
<div class="card">
|
| 191 |
+
<div class="logo">
|
| 192 |
+
<svg width="40" height="40" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round"
|
| 193 |
+
stroke-linejoin="round">
|
| 194 |
+
<path d="M12 22s8-4 8-10V5l-8-3-8 3v7c0 6 8 10 8 10z" />
|
| 195 |
+
</svg>
|
| 196 |
+
</div>
|
| 197 |
<div class="title">الذئب الابيض</div>
|
| 198 |
<div class="sub">Central Intelligence Node<br>Authorized Personnel Only</div>
|
| 199 |
|