Initial commit — SETEC LABS Manager (Setec_CDM)
Flask-based VPS management panel with SSH remote command execution. Includes E2E encrypted SSH tunnel (AES-256-GCM + Go agent), setup wizard, security hardening tools, DNS management, firewall configs, monitoring, backup, and .sec patch update system. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
93
setec-web/templates/files.html
Normal file
93
setec-web/templates/files.html
Normal file
@@ -0,0 +1,93 @@
|
||||
{% extends "base.html" %}
|
||||
{% block title %}Files{% endblock %}
|
||||
{% block content %}
|
||||
<h1>[/] File Manager</h1>
|
||||
|
||||
<div class="toolbar">
|
||||
<input type="text" id="file-path" value="/var/www" style="width:400px">
|
||||
<button class="btn" onclick="listFiles()">List</button>
|
||||
<button class="btn" onclick="readFile()">Read File</button>
|
||||
<button class="btn" onclick="mkdirRemote()">mkdir</button>
|
||||
</div>
|
||||
|
||||
<div class="grid grid-2">
|
||||
<div class="card">
|
||||
<div class="card-title">Directory Listing</div>
|
||||
<div class="output" id="dir-output" style="max-height:600px;cursor:pointer" onclick="handleDirClick(event)">
|
||||
<span class="info">Enter a path and click List</span>
|
||||
</div>
|
||||
</div>
|
||||
<div>
|
||||
<div class="card">
|
||||
<div class="card-title">File Editor</div>
|
||||
<label>Path</label>
|
||||
<input type="text" id="edit-path" style="width:100%">
|
||||
<textarea id="edit-content" rows="20" style="width:100%;resize:vertical"></textarea>
|
||||
<br>
|
||||
<button class="btn" onclick="saveFile()">Save File</button>
|
||||
<button class="btn btn-danger" onclick="deleteFile()">Delete</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="card">
|
||||
<div class="card-title">Output</div>
|
||||
<div class="output" id="output"><span class="info">Ready.</span></div>
|
||||
</div>
|
||||
{% endblock %}
|
||||
|
||||
{% block scripts %}
|
||||
<script>
|
||||
async function listFiles() {
|
||||
const path = document.getElementById('file-path').value;
|
||||
const res = await apiGet('/api/files/list?path='+encodeURIComponent(path));
|
||||
showResult(res, 'dir-output');
|
||||
}
|
||||
|
||||
async function readFile() {
|
||||
const path = document.getElementById('file-path').value;
|
||||
const res = await apiGet('/api/files/read?path='+encodeURIComponent(path));
|
||||
if (res.ok) {
|
||||
document.getElementById('edit-path').value = path;
|
||||
document.getElementById('edit-content').value = res.data.stdout || '';
|
||||
}
|
||||
showResult(res);
|
||||
}
|
||||
|
||||
async function saveFile() {
|
||||
const path = document.getElementById('edit-path').value;
|
||||
const content = document.getElementById('edit-content').value;
|
||||
if (!path) { alert('Enter file path'); return; }
|
||||
if (!confirm('Save to '+path+'?')) return;
|
||||
const res = await apiPost('/api/files/write', {path, content});
|
||||
showResult(res);
|
||||
}
|
||||
|
||||
async function deleteFile() {
|
||||
const path = document.getElementById('edit-path').value || document.getElementById('file-path').value;
|
||||
if (!path) return;
|
||||
if (!confirm('DELETE '+path+'? This cannot be undone!')) return;
|
||||
const res = await apiDelete('/api/files/delete', {path});
|
||||
showResult(res);
|
||||
listFiles();
|
||||
}
|
||||
|
||||
async function mkdirRemote() {
|
||||
const path = document.getElementById('file-path').value;
|
||||
if (!path) return;
|
||||
const res = await apiPost('/api/files/mkdir', {path});
|
||||
showResult(res);
|
||||
}
|
||||
|
||||
function handleDirClick(event) {
|
||||
// Allow clicking on filenames in the listing
|
||||
const text = window.getSelection().toString().trim();
|
||||
if (text && !text.includes('\n')) {
|
||||
const base = document.getElementById('file-path').value.replace(/\/$/,'');
|
||||
document.getElementById('file-path').value = base + '/' + text;
|
||||
}
|
||||
}
|
||||
|
||||
listFiles();
|
||||
</script>
|
||||
{% endblock %}
|
||||
Reference in New Issue
Block a user