j49_c commited on
Commit
092273c
·
1 Parent(s): a39ccf4

fix icons, ban, and add delete server functionality

Browse files
Files changed (4) hide show
  1. admin.html +6 -0
  2. app.py +17 -2
  3. index.html +9 -0
  4. 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"></div>
 
 
 
 
 
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