Harden web/download pipeline and split handler modules
Replace shell-based downloader execution with validated arguments, enforce request hardening and safer defaults, and refactor handlers/router/state so job control is safer and easier to maintain.
This commit is contained in:
@@ -4,7 +4,7 @@
|
||||
<meta charset="UTF-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<title>Simple Downloader</title>
|
||||
<style>
|
||||
<style nonce="{{.Nonce}}">
|
||||
body {
|
||||
font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Helvetica, Arial, sans-serif;
|
||||
background-color: #1e1e1e;
|
||||
@@ -203,7 +203,7 @@
|
||||
</head>
|
||||
<body>
|
||||
<h1>Simple Downloader</h1>
|
||||
<form action="/upload" method="post" enctype="multipart/form-data">
|
||||
<form action="{{if .AuthToken}}/upload?token={{.AuthToken}}{{else}}/upload{{end}}" method="post" enctype="multipart/form-data">
|
||||
<input type="file" name="files" accept=".drmd" multiple>
|
||||
<input type="submit" value="Upload and Process">
|
||||
</form>
|
||||
@@ -212,11 +212,12 @@
|
||||
{{range $filename, $info := .Jobs}}
|
||||
<li>
|
||||
<div class="job-title">
|
||||
<a href="/progress?filename={{$filename}}">{{$filename}}</a>
|
||||
<a href="{{if $.AuthToken}}/progress?filename={{$filename}}&token={{$.AuthToken}}{{else}}/progress?filename={{$filename}}{{end}}">{{$filename}}</a>
|
||||
</div>
|
||||
<div class="job-info">
|
||||
Progress: <span class="progress-text">{{printf "%5.1f%%" $info.Percentage}}</span>
|
||||
Current file: {{$info.CurrentFile}}
|
||||
Status: {{$info.Status}}
|
||||
{{if $info.Paused}}
|
||||
<span class="paused">(Paused)</span>
|
||||
{{end}}
|
||||
@@ -226,7 +227,7 @@
|
||||
<li>No active jobs</li>
|
||||
{{end}}
|
||||
</ul>
|
||||
<button id="clear-completed" onclick="clearCompleted()">Clear Completed Jobs</button>
|
||||
<button id="clear-completed">Clear Completed Jobs</button>
|
||||
|
||||
<div class="settings-section">
|
||||
<h2>Settings</h2>
|
||||
@@ -239,14 +240,26 @@
|
||||
<option value="MBps" selected>MBps</option>
|
||||
<option value="KBps">KBps</option>
|
||||
</select>
|
||||
<button type="button" onclick="updateSpeedLimit(event)">Set Limit</button>
|
||||
<button id="set-speed-limit" type="button">Set Limit</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<script>
|
||||
<script nonce="{{.Nonce}}">
|
||||
const authToken = "{{.AuthToken}}";
|
||||
const currentSpeedLimitRaw = "{{if .GlobalSpeedLimit}}{{.GlobalSpeedLimit}}{{else}}0{{end}}";
|
||||
|
||||
function withToken(path) {
|
||||
if (!authToken) {
|
||||
return path;
|
||||
}
|
||||
|
||||
const separator = path.includes('?') ? '&' : '?';
|
||||
return `${path}${separator}token=${authToken}`;
|
||||
}
|
||||
|
||||
function clearCompleted() {
|
||||
fetch('/clear-completed', { method: 'POST' })
|
||||
fetch(withToken('/clear-completed'), { method: 'POST' })
|
||||
.then(response => response.json())
|
||||
.then(data => {
|
||||
if (data.success) {
|
||||
@@ -269,7 +282,7 @@
|
||||
return;
|
||||
}
|
||||
|
||||
fetch('/set-speed-limit', {
|
||||
fetch(withToken('/set-speed-limit'), {
|
||||
method: 'POST',
|
||||
headers: {
|
||||
'Content-Type': 'application/json',
|
||||
@@ -278,7 +291,6 @@
|
||||
}).then(response => {
|
||||
if (response.ok) {
|
||||
alert('Speed limit updated successfully');
|
||||
document.getElementById('currentSpeedLimit').textContent = speedLimit;
|
||||
} else {
|
||||
alert('Failed to update speed limit');
|
||||
}
|
||||
@@ -291,18 +303,20 @@
|
||||
}
|
||||
|
||||
document.addEventListener('DOMContentLoaded', function() {
|
||||
const currentSpeedLimit = "{{if .GlobalSpeedLimit}}{{.GlobalSpeedLimit}}{{else}}0{{end}}";
|
||||
const speedLimitValueInput = document.getElementById('speedLimitValue');
|
||||
const speedLimitUnitSelect = document.getElementById('speedLimitUnit');
|
||||
|
||||
const match = currentSpeedLimit.match(/(\d+(\.\d+)?)([A-Za-z]+)/);
|
||||
const match = currentSpeedLimitRaw.match(/(\d+(\.\d+)?)([A-Za-z]+)/);
|
||||
if (match) {
|
||||
speedLimitValueInput.value = match[1];
|
||||
speedLimitUnitSelect.value = match[3];
|
||||
} else {
|
||||
speedLimitValueInput.value = "0";
|
||||
speedLimitValueInput.value = "0";
|
||||
speedLimitUnitSelect.value = "MBps";
|
||||
}
|
||||
|
||||
document.getElementById('clear-completed').addEventListener('click', clearCompleted);
|
||||
document.getElementById('set-speed-limit').addEventListener('click', updateSpeedLimit);
|
||||
});
|
||||
</script>
|
||||
</body>
|
||||
|
||||
Reference in New Issue
Block a user