Fix paths

This commit is contained in:
2026-03-20 14:23:11 +01:00
parent e70015692e
commit d45448a662
14 changed files with 2 additions and 2 deletions

View File

@@ -1,35 +0,0 @@
Terms of Service (TOS) Send.it
Effective Date: March 2026
Welcome to Send.it. By using our service, you agree to the following terms:
1. No Ownership of Uploaded Files
You retain full ownership and responsibility for any files you upload.
We do not claim ownership of your content.
2. Access to Files
While we may technically have the ability to view the files you upload,
we will not access them without a valid reason. Your privacy is important,
but absolute confidentiality cannot be guaranteed.
3. User Responsibility
You are fully responsible for the content you upload. Send.it is not
responsible for any consequences arising from your uploaded files,
including legal or personal liability.
4. File Availability and Deletion
Files may be deleted automatically based on the settings you choose
(expiration time or “burn after read”). Send.it does not guarantee
permanent storage of files.
5. Prohibited Content
You may not upload content that is illegal, harmful, or violates the rights
of others. Send.it reserves the right to remove files that violate
applicable laws or these Terms.
6. Disclaimer of Liability
Send.it provides the service “as-is.” We make no warranties regarding file
availability, security, or content. We are not liable for any damages,
loss, or issues arising from your use of the service.
By uploading files, you acknowledge that you have read and agree to these Terms.

Binary file not shown.

Before

Width:  |  Height:  |  Size: 361 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 261 KiB

View File

@@ -1,219 +0,0 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Admin Console</title>
<script src="https://cdn.tailwindcss.com"></script>
<link rel="icon" type="image/x-icon" href="/static/favicon.ico">
<style>
* { border-radius: 0 !important; }
body { font-family: ui-monospace, 'Cascadia Code', 'Source Code Pro', monospace; background: #fff; color: #000; padding: 20px; }
.box { border: 3px solid #000; background: #fff; }
table { width: 100%; border-collapse: collapse; }
th { background: #000; color: #fff; text-align: left; padding: 10px; font-size: 12px; text-transform: uppercase; border: 1px solid #000; }
td { border: 1px solid #000; padding: 10px; font-size: 13px; font-weight: 500; }
tr:hover { background: #ffff00; }
/* Harsh Status Tags */
.status-tag { font-weight: 900; font-size: 11px; padding: 3px 6px; border: 2px solid #000; display: inline-block; text-transform: uppercase; }
.status-deleted { background: #000; color: #ff0000; }
.status-no { background: #eee; color: #666; }
.status-active { background: #00ff00; color: #000; }
.status-yes { background: #ff00ff; color: #fff; }
/* Chunky Buttons */
.btn-group { display: flex; gap: 5px; }
button, .button {
border: 2px solid #000;
background: #fff;
padding: 4px 10px;
cursor: pointer;
font-size: 11px;
font-weight: 900;
text-decoration: none;
text-transform: uppercase;
box-shadow: 3px 3px 0px #000;
}
button:hover, .button:hover { background: #000; color: #fff; box-shadow: none; transform: translate(2px, 2px); }
button:active { background: #ff0000; color: #fff; }
.nav-link { font-weight: 900; text-decoration: underline; text-transform: uppercase; font-size: 12px; }
.nav-link:hover { background: #000; color: #fff; }
/* --- CUSTOM MODAL STYLES --- */
#modal-overlay {
display: none;
position: fixed;
top: 0; left: 0; width: 100%; height: 100%;
background: rgba(255, 255, 255, 0.9);
backdrop-filter: blur(4px);
z-index: 1000;
align-items: center;
justify-content: center;
}
.modal-box {
border: 8px solid #000;
background: #fff;
padding: 30px;
max-width: 480px;
width: 90%;
box-shadow: 20px 20px 0px #000;
}
#modal-confirm-btn:hover {
background: #ff0000;
color: white;
animation: pulse 0.4s infinite;
}
@keyframes pulse {
0% { transform: scale(1); }
50% { transform: scale(1.03); }
100% { transform: scale(1); }
}
</style>
</head>
<body>
<div id="modal-overlay">
<div class="modal-box">
<h2 id="modal-title" class="text-4xl font-black uppercase tracking-tighter mb-4">CONFIRM_WIPE</h2>
<div id="modal-message" class="text-sm font-bold mb-8 border-l-8 border-black pl-4 py-2 italic bg-gray-50">
Awaiting system confirmation for permanent data erasure.
</div>
<div class="flex gap-4">
<button id="modal-confirm-btn" class="flex-1 py-4 text-xl border-4 border-black font-black uppercase bg-yellow-400">EXECUTE</button>
<button onclick="closeModal()" class="flex-1 py-4 text-xl border-4 border-black font-black uppercase hover:bg-black hover:text-white">ABORT</button>
</div>
</div>
</div>
<div class="max-w-7xl mx-auto">
<header class="mb-6 border-b-8 border-black pb-4 flex justify-between items-start">
<div>
<h1 class="text-4xl font-black uppercase tracking-tighter leading-none">System_Admin</h1>
</div>
<div class="flex flex-col items-end gap-2">
<a href="/" class="nav-link">← BACK_TO_UPLOADER</a>
<a href="/logout" class="nav-link text-red-600">LOGOUT_SESSION</a>
</div>
</header>
<div class="box overflow-x-auto">
<table>
<thead>
<tr>
<th>File_Identifier</th>
<th>Size</th>
<th>Timeline (In/Out)</th>
<th>Hits</th>
<th>Burn</th>
<th>Status</th>
<th>System_Actions</th>
</tr>
</thead>
<tbody>
{{if not .Files}}
<tr><td colspan="7" class="text-center py-10 font-bold uppercase italic">Zero files in buffer</td></tr>
{{end}}
{{range .Files}}
<tr>
<td class="font-bold">
<a href="/api/files/admin/download/{{.ID}}" target="_blank" class="underline hover:bg-black hover:text-white">{{.Filename}}</a>
</td>
<td class="whitespace-nowrap italic text-gray-600">{{humanSize .Size}}</td>
<td class="text-[11px] leading-tight">
<span class="block"><strong>CRT:</strong> {{.CreatedAt.Format "02/01/06 15:04"}}</span>
<span class="block text-red-600"><strong>EXP:</strong> {{.ExpiresAt.Format "02/01/06 15:04"}}</span>
</td>
<td class="text-center font-black text-lg">{{.DownloadCount}}</td>
<td>
{{if .DeleteAfterDownload}}
<span class="status-tag status-yes">YES</span>
{{else}}
<span class="status-tag status-no">NO</span>
{{end}}
</td>
<td>
{{if .Deleted}}
<span class="status-tag status-deleted">REMOVED</span>
{{else}}
<span class="status-tag status-active">LIVE</span>
{{end}}
</td>
<td>
<div class="btn-group">
{{if not .Deleted}}
<form action="/api/files/admin/delete/{{.ID}}" method="GET" onsubmit="return openConfirm(event, 'TERMINATE', 'Kill this file? It will be removed from active storage.')">
<button type="submit" style="background: #ffcccc;">Terminate</button>
</form>
{{end}}
<form action="/api/files/admin/delete/fr/{{.ID}}" method="GET" onsubmit="return openConfirm(event, 'FULL_WIPE', 'Wiping file and purging record? This is a permanent database scrub.')">
<button type="submit">Full_Wipe</button>
</form>
</div>
</td>
</tr>
{{end}}
</tbody>
</table>
</div>
<div class="mt-6 flex justify-between items-center border-t-8 border-black pt-4">
<div class="flex gap-4">
{{if gt .Page 1}}
<a href="?page={{sub .Page 1}}" class="button">Prev_Page</a>
{{end}}
{{if lt .Page .TotalPages}}
<a href="?page={{add .Page 1}}" class="button">Next_Page</a>
{{end}}
</div>
<footer class="text-right">
<div class="text-[12px] font-black uppercase">
Data_Density: {{len .Files}} records | Page: {{.Page}}/{{.TotalPages}}
</div>
</footer>
</div>
</div>
<script>
let currentForm = null;
function openConfirm(e, title, msg) {
e.preventDefault(); // Stop form from submitting immediately
currentForm = e.target;
document.getElementById('modal-title').innerText = title;
document.getElementById('modal-message').innerText = msg;
document.getElementById('modal-overlay').style.display = 'flex';
return false;
}
function closeModal() {
document.getElementById('modal-overlay').style.display = 'none';
currentForm = null;
}
document.getElementById('modal-confirm-btn').addEventListener('click', () => {
if (currentForm) {
currentForm.submit();
}
});
// Close if clicking outside the box
window.onclick = function(event) {
const overlay = document.getElementById('modal-overlay');
if (event.target == overlay) closeModal();
}
</script>
</body>
</html>

View File

@@ -1,94 +0,0 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>File Deleted sucessfull</title>
<script src="https://cdn.tailwindcss.com"></script>
<link rel="icon" type="image/x-icon" href="/static/favicon.ico">
<style>
* { border-radius: 0 !important; transition: none !important; }
body { font-family: sans-serif; background: #fff; color: #000; }
.box {
border: 3px solid #000;
padding: 20px;
background: #fff;
width: 100%;
}
.title {
font-size: 28px;
font-weight: 900;
border-bottom: 3px solid #000;
padding-bottom: 6px;
margin-bottom: 12px;
text-transform: uppercase;
}
.subtitle {
font-size: 12px;
font-weight: bold;
text-transform: uppercase;
margin-bottom: 16px;
}
.button {
border: 2px solid #000;
background: #eee;
padding: 6px 12px;
font-weight: bold;
text-decoration: none;
display: inline-block;
}
.button:hover {
background: #000;
color: #fff;
}
.ascii {
font-family: monospace;
font-size: 11px;
border: 2px dashed #000;
padding: 10px;
margin: 10px 0;
text-align: left;
white-space: pre;
}
</style>
</head>
<body class="min-h-screen flex items-center justify-center p-4">
<div class="w-full max-w-[520px]">
<div class="box text-center">
<div class="title">
FILE DELETED SUCESSFULL
</div>
<div class="subtitle">
The file has been absolutely obliterated.
</div>
<!-- <div class="ascii">-->
<!-- [ OK ] locating file...-->
<!-- [ OK ] emotionally detaching...-->
<!-- [ OK ] pressing the big red button...-->
<!-- [ OK ] file screaming detected...-->
<!-- [ OK ] scream ignored...-->
<!-- [ OK ] file is now gone forever™-->
<!-- (there is no undo)-->
<!-- </div>-->
<!-- <div class="text-xs font-bold uppercase mb-4">-->
<!-- Congratulations. The electrons have been freed.-->
<!-- </div>-->
<div class="flex flex-col gap-2">
<a href="/" class="button w-full">Pretend Nothing Happened</a>
</div>
</div>
</div>
</body>
</html>

View File

@@ -1,99 +0,0 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Nothing to see here</title>
<script src="https://cdn.tailwindcss.com"></script>
<link rel="icon" type="image/x-icon" href="/static/favicon.ico">
<style>
* {
border-radius: 0 !important;
transition: none !important;
}
body {
font-family: sans-serif;
background: #fff;
color: #000;
}
.box {
border: 2px solid #000;
padding: 20px;
background: #fff;
width: 100%;
}
.button {
border: 2px solid #000;
background: #eee;
padding: 4px 12px;
font-weight: bold;
cursor: pointer;
text-decoration: none;
display: inline-block;
}
.button:hover {
background: #ccc;
}
.button:active {
background: #000;
color: #fff;
}
.title {
font-size: 28px;
font-weight: 900;
border-bottom: 2px solid #000;
margin-bottom: 10px;
padding-bottom: 4px;
}
.subtitle {
font-size: 12px;
font-weight: bold;
text-transform: uppercase;
margin-bottom: 16px;
}
.text {
font-size: 12px;
text-transform: uppercase;
margin-bottom: 20px;
}
</style>
</head>
<body class="min-h-screen flex items-center justify-center p-4">
<div class="w-full max-w-[493px] flex flex-col items-center">
<div class="box text-center">
<div class="title">
NOTHING TO SEE HERE
</div>
<div class="subtitle">
MOVE ALONG
</div>
<div class="text">
This page is empty,<br>
unavailable, private,<br>
or intentionally left blank.
</div>
<div class="flex flex-col gap-2">
<a href="/" class="button w-full">GO BACK</a>
</div>
</div>
</div>
</body>
</html>

View File

@@ -1,89 +0,0 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>404 — File Not Found</title>
<link rel="icon" type="image/x-icon" href="/static/favicon.ico">
<script src="https://cdn.tailwindcss.com"></script>
<style>
* {
border-radius: 0 !important;
transition: none !important;
}
body {
font-family: sans-serif;
background: #fff;
color: #000;
}
.box {
border: 2px solid #000;
padding: 20px;
background: #fff;
width: 100%;
}
button, .button {
border: 2px solid #000;
background: #eee;
padding: 4px 12px;
font-weight: bold;
cursor: pointer;
text-decoration: none;
display: inline-block;
}
button:hover, .button:hover {
background: #ccc;
}
button:active, .button:active {
background: #000;
color: #fff;
}
.error-code {
font-size: 64px;
font-weight: 900;
border-bottom: 2px solid #000;
margin-bottom: 10px;
}
.error-text {
font-size: 14px;
font-weight: bold;
text-transform: uppercase;
}
</style>
</head>
<body class="min-h-screen flex items-center justify-center p-4">
<div class="w-full max-w-[493px] flex flex-col items-center">
<div class="box text-center">
<div class="error-code">404</div>
<div class="error-text mb-4">
FILE NOT FOUND 💀
</div>
<div class="text-xs mb-6 uppercase">
The requested file does not exist,<br>
has expired, or was obliterated,<br>or my db is fucked.
We'll never know :D
</div>
<div class="flex flex-col gap-2">
<a href="/" class="button w-full">RETURN TO UPLOADER</a>
</div>
</div>
</div>
</body>
</html>

View File

@@ -1,343 +0,0 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Send.it</title>
<script src="https://cdn.tailwindcss.com"></script>
<link rel="icon" type="image/x-icon" href="/static/favicon.ico">
<style>
/* The "No-Design" Design */
* {
border-radius: 0 !important;
transition: none !important;
}
body {
font-family: sans-serif;
background: #fff;
color: #000;
}
.box {
border: 2px solid #000;
padding: 20px;
background: #fff;
width: 100%;
}
.input-text {
border: 1px solid #000;
padding: 4px 8px;
background: #fff;
width: 100%;
}
button {
border: 2px solid #000;
background: #eee;
padding: 4px 12px;
font-weight: bold;
cursor: pointer;
}
button:hover {
background: #ccc;
}
button:active {
background: #000;
color: #fff;
}
button:disabled {
background: #f0f0f0;
color: #999;
border-color: #ccc;
cursor: not-allowed;
}
.btn-cancel {
background: #fff;
color: #cc0000;
border-color: #cc0000;
margin-top: 8px;
width: 100%;
font-size: 10px;
}
.btn-cancel:hover {
background: #fee2e2;
}
.drop-zone {
border: 2px dashed #000;
padding: 80px;
text-align: center;
background: #f9f9f9;
cursor: pointer;
}
.drop-zone.active {
background: #eee;
border-style: solid;
}
.burn-option {
color: #cc0000;
font-weight: bold;
font-size: 12px;
}
</style>
</head>
<body class="min-h-screen flex items-center justify-center p-4">
<!--<div class="w-full max-w-[493px] flex flex-col items-end">-->
<div class="w-full max-w-[493px] flex flex-col items-center">
<img src="/static/logo.png" alt="Send.it logo" style="width:50%;" class="mb-2 border-black">
<div class="box">
<header class="mb-6 border-b-2 border-black pb-2 text-center">
<h1 class="text-xl font-bold uppercase">Send it</h1>
</header>
<div id="upload-ui">
<div id="drop-zone" class="drop-zone mb-4">
<input type="file" id="fileInput" class="hidden">
<div id="dz-content">
<span id="dz-text" class="text-sm">Click to select or drop file</span>
</div>
<div id="progress-container" class="hidden mt-3 border border-black h-4">
<div id="progress-bar" class="h-full bg-black" style="width:0%"></div>
</div>
<div class="flex justify-between items-center mt-1">
<div id="progress-text" class="text-[10px] font-bold hidden">0%</div>
<div id="stats-text" class="text-[10px] font-bold hidden uppercase">
<span id="speed-text">0 KB/S</span>
<span class="mx-1 opacity-30">|</span>
<span id="eta-text">--:--</span>
</div>
</div>
</div>
<div class="space-y-4">
<div class="flex items-center justify-between border-b border-black pb-2">
<label class="text-xs font-bold uppercase">Expire In:</label>
<select id="duration" class="border border-black text-xs p-1">
<option value="1">1 Hour</option>
<option value="24">24 Hours</option>
<option value="168">7 Days</option>
<option value="730" selected>1 Month</option>
</select>
</div>
<div class="flex items-center gap-2">
<input type="checkbox" id="once" class="w-4 h-4 border-black">
<label for="once" class="burn-option uppercase">Burn after</label>
</div>
<button id="uploadBtn" class="w-full" disabled>UPLOAD</button>
<button id="cancelBtn" class="btn-cancel hidden">CANCEL UPLOAD</button>
</div>
</div>
<div id="success-ui" class="hidden space-y-4">
<div class="bg-black text-white p-2 text-xs font-bold">
UPLOAD COMPLETE
</div>
<div>
<label class="text-[10px] font-bold block">DOWNLOAD LINK</label>
<div class="flex">
<input id="res-url" readonly class="input-text text-sm">
<button onclick="copy('res-url')" class="border-l-0">COPY</button>
</div>
</div>
<div>
<label class="text-[10px] font-bold block">DELETION LINK (PRIVATE)</label>
<div class="flex">
<input id="res-del" readonly class="input-text text-sm text-red-600">
<button onclick="copy('res-del')" class="border-l-0">COPY</button>
</div>
</div>
<div class="pt-4 flex justify-between">
<button onclick="location.reload()" class="text-xs">NEW UPLOAD</button>
</div>
</div>
</div>
<p class="mt-1 text-[10px] uppercase font-bold text-gray-400">A service by Brammie15</p>
</div>
<script>
const zone = document.getElementById('drop-zone');
const input = document.getElementById('fileInput');
const uploadBtn = document.getElementById('uploadBtn');
const cancelBtn = document.getElementById('cancelBtn');
const progressText = document.getElementById("progress-text");
const statsText = document.getElementById("stats-text");
const speedText = document.getElementById("speed-text");
const etaText = document.getElementById("eta-text");
const progressBar = document.getElementById("progress-bar");
const progressContainer = document.getElementById("progress-container");
let currentXhr = null;
// Helper: Human Readable Size
function formatBytes(bytes, decimals = 2) {
if (bytes === 0) return '0 Bytes';
const k = 1024;
const dm = decimals < 0 ? 0 : decimals;
const sizes = ['Bytes', 'KB', 'MB', 'GB', 'TB'];
const i = Math.floor(Math.log(bytes) / Math.log(k));
return parseFloat((bytes / Math.pow(k, i)).toFixed(dm)) + ' ' + sizes[i];
}
// Helper: Human Readable Time
function formatTime(seconds) {
if (!isFinite(seconds) || seconds < 0) return "--:--";
const h = Math.floor(seconds / 3600);
const m = Math.floor((seconds % 3600) / 60);
const s = Math.floor(seconds % 60);
return [
h > 0 ? h : null,
(h > 0 ? m.toString().padStart(2, '0') : m),
s.toString().padStart(2, '0')
].filter(x => x !== null).join(':');
}
zone.onclick = () => input.click();
zone.ondragover = (e) => {
e.preventDefault();
zone.classList.add('active');
};
zone.ondragleave = () => zone.classList.remove('active');
zone.ondrop = (e) => {
e.preventDefault();
zone.classList.remove('active');
if (e.dataTransfer.files.length) {
input.files = e.dataTransfer.files;
input.dispatchEvent(new Event('change'));
}
};
input.onchange = () => {
if (input.files.length) {
showFile(input.files[0]);
uploadBtn.disabled = false;
} else {
uploadBtn.disabled = true;
}
};
function showFile(file) {
document.getElementById('dz-text').innerText =
`${file.name} (${formatBytes(file.size)})`;
}
uploadBtn.onclick = () => {
if (input.files.length) handleUpload(input.files[0]);
};
cancelBtn.onclick = (e) => {
e.stopPropagation();
if (currentXhr) {
currentXhr.abort();
alert("Upload cancelled.");
location.reload();
}
};
function handleUpload(file) {
uploadBtn.disabled = true;
uploadBtn.innerText = "UPLOADING...";
cancelBtn.classList.remove('hidden');
progressContainer.classList.remove("hidden");
progressText.classList.remove("hidden");
statsText.classList.remove("hidden");
const fd = new FormData();
fd.append("file", file);
fd.append("once", document.getElementById("once").checked ? "true" : "false");
const hours = parseInt(document.getElementById("duration").value, 10);
fd.append("duration", hours);
const xhr = new XMLHttpRequest();
currentXhr = xhr;
let startTime = Date.now();
xhr.upload.onprogress = (e) => {
if (e.lengthComputable) {
const percent = Math.round((e.loaded / e.total) * 100);
progressBar.style.width = percent + "%";
progressText.innerText = percent + "%";
const elapsedSeconds = (Date.now() - startTime) / 1000;
if (elapsedSeconds > 0) {
const bytesPerSecond = e.loaded / elapsedSeconds;
const remainingBytes = e.total - e.loaded;
const secondsRemaining = remainingBytes / bytesPerSecond;
speedText.innerText = formatBytes(bytesPerSecond) + "/S";
etaText.innerText = formatTime(secondsRemaining);
}
}
};
xhr.onload = () => {
if (xhr.status >= 200 && xhr.status < 300) {
try {
const data = JSON.parse(xhr.responseText);
if (data.error) throw new Error(data.error);
document.getElementById('upload-ui').classList.add('hidden');
document.getElementById('success-ui').classList.remove('hidden');
const dlUrl = window.location.origin + "/api/files/download/" + data.id;
const delUrl = window.location.origin + "/api/files/delete/" + data.deletion_id;
document.getElementById('res-url').value = dlUrl;
document.getElementById('res-del').value = delUrl;
} catch (err) {
console.error("JSON Parse Error. Server sent:", xhr.responseText);
alert("Server returned an invalid response");
}
} else {
console.error("Server Error:", xhr.status, xhr.responseText);
alert(`Upload failed with status ${xhr.status}. Check console.`);
}
};
xhr.onerror = () => {
if (xhr.statusText !== "abort") {
alert("Upload failed");
location.reload();
}
};
xhr.open("POST", "/api/files/upload");
xhr.send(fd);
}
function copy(id) {
const el = document.getElementById(id);
el.select();
document.execCommand('copy');
}
</script>
<a href="/admin" class="fixed bottom-1 right-1 text-[10px] underline">SUDO</a>
<a href="/static/TOS.txt" class="fixed bottom-1 left-1 text-[10px] underline">TOS</a>
</body>
</html>

View File

@@ -1,169 +0,0 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Login</title>
<script src="https://cdn.tailwindcss.com"></script>
<link rel="icon" type="image/x-icon" href="/static/favicon.ico">
<style>
* { border-radius: 0 !important; }
body {
font-family: sans-serif;
background: #fff;
color: #000;
padding: 20px;
}
.box {
border: 2px solid #000;
background: #fff;
}
input {
border: 1px solid #000;
padding: 6px;
font-size: 13px;
width: 100%;
background: #fff;
}
input:focus {
outline: none;
background: #f9f9f9;
}
button {
border: 1px solid #000;
background: #eee;
padding: 4px 10px;
cursor: pointer;
font-size: 12px;
font-weight: bold;
}
button:hover {
background: #000;
color: #fff;
}
.nav-link {
font-weight: bold;
text-decoration: underline;
font-size: 11px;
}
.label {
font-size: 10px;
font-weight: bold;
text-transform: uppercase;
margin-bottom: 2px;
}
.error {
border: 1px solid #000;
background: #ffcccc;
font-size: 11px;
padding: 4px;
margin-bottom: 10px;
font-weight: bold;
}
</style>
</head>
<body>
<div class="max-w-md mx-auto">
<header class="mb-8 border-b-4 border-black pb-2 flex justify-between items-end">
<h1 class="text-3xl font-black uppercase tracking-tighter">
System Access
</h1>
<a href="/" class="nav-link">
← BACK
</a>
</header>
<div class="box p-4">
{{if .Error}}
<div class="error">
ACCESS DENIED
</div>
{{end}}
<form id="login-form" class="space-y-3">
<div>
<div class="label">Username</div>
<input id="username" required autocomplete="username">
</div>
<div>
<div class="label">Password</div>
<input id="password" type="password" required autocomplete="current-password">
</div>
<div class="pt-2">
<button type="submit">
AUTHENTICATE
</button>
</div>
</form>
</div>
</div>
<script>
const form = document.getElementById("login-form");
form.addEventListener("submit", async (e) => {
e.preventDefault();
const username = document.getElementById("username").value;
const password = document.getElementById("password").value;
try {
const res = await fetch("/api/auth/login", {
method: "POST",
headers: {
"Content-Type": "application/json"
},
body: JSON.stringify({
username: username,
password: password
})
});
const data = await res.json();
if (!res.ok) {
showError();
return;
}
// Redirect to admin
window.location.href = "/admin";
} catch (err) {
showError();
}
});
function showError() {
let err = document.getElementById("error-box");
if (!err) {
err = document.createElement("div");
err.id = "error-box";
err.className = "error";
err.innerText = "ACCESS DENIED";
form.prepend(err);
}
}
</script>
</body>
</html>

View File

@@ -1,118 +0,0 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Admin</title>
<script src="https://cdn.tailwindcss.com"></script>
<style>
* { border-radius: 0 !important; }
body { font-family: sans-serif; background: #fff; color: #000; padding: 20px; }
.box { border: 2px solid #000; background: #fff; }
table { width: 100%; border-collapse: collapse; }
th { background: #000; color: #fff; text-align: left; padding: 8px; font-size: 12px; text-transform: uppercase; }
td { border-bottom: 1px solid #000; padding: 8px; font-size: 13px; }
tr:hover { background: #f9f9f9; }
.status-tag { font-weight: bold; font-size: 10px; padding: 2px 4px; border: 1px solid #000; }
.status-deleted { background: #ffcccc; text-decoration: line-through; }
.status-no{ background: #ffcccc; }
.status-active { background: #ccffcc; }
button, .button { border: 1px solid #000; background: #eee; padding: 2px 8px; cursor: pointer; font-size: 11px; font-weight: bold; text-decoration: none; }
button:hover, .button:hover { background: #000; color: #fff; }
.nav-link { font-weight: bold; text-decoration: underline; margin-bottom: 20px; display: inline-block; }
.pagination a { margin: 0 2px; }
</style>
</head>
<body>
<div class="max-w-6xl mx-auto">
<header class="mb-8 border-b-4 border-black pb-2 flex justify-between items-end">
<h1 class="text-3xl font-black uppercase tracking-tighter">System Console</h1>
<div>
<a href="/" class="nav-link text-xs">← BACK TO UPLOADER</a>
<a href="/logout" class="nav-link text-xs">LOGOUT</a>
</div>
</header>
<div class="box overflow-x-auto">
<table>
<thead>
<tr>
<th>Filename</th>
<th>Size</th>
<th>Created</th>
<th>Expires</th>
<th>Hits</th>
<th>Burn after</th>
<th>Status</th>
<th>Actions</th>
</tr>
</thead>
<tbody>
{{if not .Files}}
<tr><td colspan="8">No files found</td></tr>
{{end}}
{{range .Files}}
<tr>
<td class="font-mono">
<a href="/api/files/admin/download/{{.ID}}" target="_blank">{{.Filename}}</a>
</td>
<td>{{humanSize .Size}}</td>
<td>{{.CreatedAt.Format "Jan 02, 2006 15:04"}}</td>
<td>{{.ExpiresAt.Format "Jan 02, 2006 15:04"}}</td>
<td>{{.DownloadCount}}</td>
<td>
{{if .DeleteAfterDownload}}
<span class="status-tag status-active">YES</span>
{{else}}
<span class="status-tag status-no">NO</span>
{{end}}
</td>
<td>
{{if .Deleted}}
<span class="status-tag status-deleted">REMOVED</span>
{{else}}
<span class="status-tag status-active">LIVE</span>
{{end}}
</td>
<td>
{{if not .Deleted}}
<form action="/api/files/admin/delete/{{.ID}}" method="GET" onsubmit="return confirm('Kill this file?')">
<button type="submit">TERMINATE</button>
</form>
{{end}}
<form action="/api/files/admin/delete/fr/{{.ID}}" method="GET" onsubmit="return confirm('Kill this file and the record?')">
<button type="submit">TERMINATE RECORD</button>
</form>
</td>
</tr>
{{end}}
</tbody>
</table>
</div>
<div class="mt-4 flex justify-between items-center">
<div class="space-x-2">
{{if gt .Page 1}}
<a href="?page={{sub .Page 1}}" class="button">← Prev</a>
{{end}}
{{if lt .Page .TotalPages}}
<a href="?page={{add .Page 1}}" class="button">Next →</a>
{{end}}
</div>
</div>
<footer class="mt-4 text-[10px] text-gray-500 uppercase font-bold">
Showing {{len .Files}} records — Page {{.Page}} of {{.TotalPages}} — Total Pages: {{.TotalPages}}
</footer>
</div>
</body>
</html>

View File

@@ -1,342 +0,0 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Send.it</title>
<script src="https://cdn.tailwindcss.com"></script>
<style>
/* The "No-Design" Design */
* {
border-radius: 0 !important;
transition: none !important;
}
body {
font-family: sans-serif;
background: #fff;
color: #000;
}
.box {
border: 2px solid #000;
padding: 20px;
background: #fff;
width: 100%;
}
.input-text {
border: 1px solid #000;
padding: 4px 8px;
background: #fff;
width: 100%;
}
button {
border: 2px solid #000;
background: #eee;
padding: 4px 12px;
font-weight: bold;
cursor: pointer;
}
button:hover {
background: #ccc;
}
button:active {
background: #000;
color: #fff;
}
button:disabled {
background: #f0f0f0;
color: #999;
border-color: #ccc;
cursor: not-allowed;
}
.btn-cancel {
background: #fff;
color: #cc0000;
border-color: #cc0000;
margin-top: 8px;
width: 100%;
font-size: 10px;
}
.btn-cancel:hover {
background: #fee2e2;
}
.drop-zone {
border: 2px dashed #000;
padding: 80px;
text-align: center;
background: #f9f9f9;
cursor: pointer;
}
.drop-zone.active {
background: #eee;
border-style: solid;
}
.burn-option {
color: #cc0000;
font-weight: bold;
font-size: 12px;
}
</style>
</head>
<body class="min-h-screen flex items-center justify-center p-4">
<!--<div class="w-full max-w-[493px] flex flex-col items-end">-->
<div class="w-full max-w-[493px] flex flex-col items-center">
<img src="/static/logo.png" alt="Send.it logo" style="width:50%;" class="mb-2 border-black">
<div class="box">
<header class="mb-6 border-b-2 border-black pb-2 text-center">
<h1 class="text-xl font-bold uppercase">Send it</h1>
</header>
<div id="upload-ui">
<div id="drop-zone" class="drop-zone mb-4">
<input type="file" id="fileInput" class="hidden">
<div id="dz-content">
<span id="dz-text" class="text-sm">Click to select or drop file</span>
</div>
<div id="progress-container" class="hidden mt-3 border border-black h-4">
<div id="progress-bar" class="h-full bg-black" style="width:0%"></div>
</div>
<div class="flex justify-between items-center mt-1">
<div id="progress-text" class="text-[10px] font-bold hidden">0%</div>
<div id="stats-text" class="text-[10px] font-bold hidden uppercase">
<span id="speed-text">0 KB/S</span>
<span class="mx-1 opacity-30">|</span>
<span id="eta-text">--:--</span>
</div>
</div>
</div>
<div class="space-y-4">
<div class="flex items-center justify-between border-b border-black pb-2">
<label class="text-xs font-bold uppercase">Expire In:</label>
<select id="duration" class="border border-black text-xs p-1">
<option value="1">1 Hour</option>
<option value="24">24 Hours</option>
<option value="168">7 Days</option>
<option value="730" selected>1 Month</option>
</select>
</div>
<div class="flex items-center gap-2">
<input type="checkbox" id="once" class="w-4 h-4 border-black">
<label for="once" class="burn-option uppercase">Burn after</label>
</div>
<button id="uploadBtn" class="w-full" disabled>UPLOAD</button>
<button id="cancelBtn" class="btn-cancel hidden">CANCEL UPLOAD</button>
</div>
</div>
<div id="success-ui" class="hidden space-y-4">
<div class="bg-black text-white p-2 text-xs font-bold">
UPLOAD COMPLETE
</div>
<div>
<label class="text-[10px] font-bold block">DOWNLOAD LINK</label>
<div class="flex">
<input id="res-url" readonly class="input-text text-sm">
<button onclick="copy('res-url')" class="border-l-0">COPY</button>
</div>
</div>
<div>
<label class="text-[10px] font-bold block">DELETION LINK (PRIVATE)</label>
<div class="flex">
<input id="res-del" readonly class="input-text text-sm text-red-600">
<button onclick="copy('res-del')" class="border-l-0">COPY</button>
</div>
</div>
<div class="pt-4 flex justify-between">
<button onclick="location.reload()" class="text-xs">NEW UPLOAD</button>
</div>
</div>
</div>
<p class="mt-1 text-[10px] uppercase font-bold text-gray-400">A service by Brammie15</p>
</div>
<script>
const zone = document.getElementById('drop-zone');
const input = document.getElementById('fileInput');
const uploadBtn = document.getElementById('uploadBtn');
const cancelBtn = document.getElementById('cancelBtn');
const progressText = document.getElementById("progress-text");
const statsText = document.getElementById("stats-text");
const speedText = document.getElementById("speed-text");
const etaText = document.getElementById("eta-text");
const progressBar = document.getElementById("progress-bar");
const progressContainer = document.getElementById("progress-container");
let currentXhr = null;
// Helper: Human Readable Size
function formatBytes(bytes, decimals = 2) {
if (bytes === 0) return '0 Bytes';
const k = 1024;
const dm = decimals < 0 ? 0 : decimals;
const sizes = ['Bytes', 'KB', 'MB', 'GB', 'TB'];
const i = Math.floor(Math.log(bytes) / Math.log(k));
return parseFloat((bytes / Math.pow(k, i)).toFixed(dm)) + ' ' + sizes[i];
}
// Helper: Human Readable Time
function formatTime(seconds) {
if (!isFinite(seconds) || seconds < 0) return "--:--";
const h = Math.floor(seconds / 3600);
const m = Math.floor((seconds % 3600) / 60);
const s = Math.floor(seconds % 60);
return [
h > 0 ? h : null,
(h > 0 ? m.toString().padStart(2, '0') : m),
s.toString().padStart(2, '0')
].filter(x => x !== null).join(':');
}
zone.onclick = () => input.click();
zone.ondragover = (e) => {
e.preventDefault();
zone.classList.add('active');
};
zone.ondragleave = () => zone.classList.remove('active');
zone.ondrop = (e) => {
e.preventDefault();
zone.classList.remove('active');
if (e.dataTransfer.files.length) {
input.files = e.dataTransfer.files;
input.dispatchEvent(new Event('change'));
}
};
input.onchange = () => {
if (input.files.length) {
showFile(input.files[0]);
uploadBtn.disabled = false;
} else {
uploadBtn.disabled = true;
}
};
function showFile(file) {
document.getElementById('dz-text').innerText =
`${file.name} (${formatBytes(file.size)})`;
}
uploadBtn.onclick = () => {
if (input.files.length) handleUpload(input.files[0]);
};
cancelBtn.onclick = (e) => {
e.stopPropagation();
if (currentXhr) {
currentXhr.abort();
alert("Upload cancelled.");
location.reload();
}
};
function handleUpload(file) {
uploadBtn.disabled = true;
uploadBtn.innerText = "UPLOADING...";
cancelBtn.classList.remove('hidden');
progressContainer.classList.remove("hidden");
progressText.classList.remove("hidden");
statsText.classList.remove("hidden");
const fd = new FormData();
fd.append("file", file);
fd.append("once", document.getElementById("once").checked ? "true" : "false");
const hours = parseInt(document.getElementById("duration").value, 10);
fd.append("duration", hours);
const xhr = new XMLHttpRequest();
currentXhr = xhr;
let startTime = Date.now();
xhr.upload.onprogress = (e) => {
if (e.lengthComputable) {
const percent = Math.round((e.loaded / e.total) * 100);
progressBar.style.width = percent + "%";
progressText.innerText = percent + "%";
const elapsedSeconds = (Date.now() - startTime) / 1000;
if (elapsedSeconds > 0) {
const bytesPerSecond = e.loaded / elapsedSeconds;
const remainingBytes = e.total - e.loaded;
const secondsRemaining = remainingBytes / bytesPerSecond;
speedText.innerText = formatBytes(bytesPerSecond) + "/S";
etaText.innerText = formatTime(secondsRemaining);
}
}
};
xhr.onload = () => {
if (xhr.status >= 200 && xhr.status < 300) {
try {
const data = JSON.parse(xhr.responseText);
if (data.error) throw new Error(data.error);
document.getElementById('upload-ui').classList.add('hidden');
document.getElementById('success-ui').classList.remove('hidden');
const dlUrl = window.location.origin + "/api/files/download/" + data.id;
const delUrl = window.location.origin + "/api/files/delete/" + data.deletion_id;
document.getElementById('res-url').value = dlUrl;
document.getElementById('res-del').value = delUrl;
} catch (err) {
console.error("JSON Parse Error. Server sent:", xhr.responseText);
alert("Server returned an invalid response");
}
} else {
console.error("Server Error:", xhr.status, xhr.responseText);
alert(`Upload failed with status ${xhr.status}. Check console.`);
}
};
xhr.onerror = () => {
if (xhr.statusText !== "abort") {
alert("Upload failed");
location.reload();
}
};
xhr.open("POST", "/api/files/upload");
xhr.send(fd);
}
function copy(id) {
const el = document.getElementById(id);
el.select();
document.execCommand('copy');
}
</script>
<a href="/admin" class="fixed bottom-1 right-1 text-[10px] underline">SUDO</a>
<a href="/static/TOS.txt" class="fixed bottom-1 left-1 text-[10px] underline">TOS</a>
</body>
</html>

View File

@@ -1,202 +0,0 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Login // System_Access</title>
<script src="https://cdn.tailwindcss.com"></script>
<style>
* { border-radius: 0 !important; transition: none !important; }
body {
font-family: ui-monospace, 'Cascadia Code', monospace;
background: #fff;
color: #000;
padding: 40px 20px;
}
.box {
border: 3px solid #000;
background: #fff;
box-shadow: 6px 6px 0px #000;
}
input {
border: 2px solid #000;
padding: 8px;
font-size: 14px;
width: 100%;
background: #fff;
font-weight: bold;
}
input:focus {
outline: none;
background: #ffff00; /* Yellow highlight on focus */
}
button {
border: 2px solid #000;
background: #fff;
padding: 8px 16px;
cursor: pointer;
font-size: 13px;
font-weight: 900;
text-transform: uppercase;
box-shadow: 4px 4px 0px #000;
}
button:hover {
background: #00ff00; /* Neon green hover */
transform: translate(-1px, -1px);
box-shadow: 5px 5px 0px #000;
}
button:active {
background: #000;
color: #fff;
transform: translate(2px, 2px);
box-shadow: none;
}
.nav-link {
font-weight: 900;
text-decoration: underline;
font-size: 11px;
text-transform: uppercase;
}
.nav-link:hover {
background: #000;
color: #fff;
}
.label {
font-size: 11px;
font-weight: 900;
text-transform: uppercase;
margin-bottom: 4px;
letter-spacing: -0.5px;
}
.error {
border: 3px solid #000;
background: #ff0000;
color: #fff;
font-size: 12px;
padding: 8px;
margin-bottom: 15px;
font-weight: 900;
text-align: center;
text-transform: uppercase;
}
</style>
</head>
<body class="min-h-screen flex flex-col items-center justify-center">
<div class="w-full max-w-[400px]">
<header class="mb-6 border-b-8 border-black pb-2 flex justify-between items-end">
<h1 class="text-3xl font-black uppercase tracking-tighter italic">
Access
</h1>
<a href="/" class="nav-link mb-1">
← RETREAT
</a>
</header>
<div class="box p-6">
<div id="error-container">
{{if .Error}}
<div class="error">
CRITICAL_AUTH_FAILURE
</div>
{{end}}
</div>
<form id="login-form" class="space-y-5">
<div>
<div class="label">User_Identity</div>
<input id="username" required autocomplete="username" placeholder="ID_01">
</div>
<div>
<div class="label">Secure_Passphrase</div>
<input id="password" type="password" required autocomplete="current-password" placeholder="********">
</div>
<div class="pt-2">
<button type="submit" class="w-full">
INITIALIZE_AUTHENTICATION
</button>
</div>
</form>
</div>
<p class="mt-6 text-[10px] uppercase font-black text-gray-400 text-center tracking-widest">
Session_Log: 0.0.0.0 // Node: Auth_Main
</p>
</div>
<script>
const form = document.getElementById("login-form");
const errorContainer = document.getElementById("error-container");
form.addEventListener("submit", async (e) => {
e.preventDefault();
const username = document.getElementById("username").value;
const password = document.getElementById("password").value;
// Visual feedback
const btn = form.querySelector('button');
btn.innerText = "VERIFYING...";
btn.disabled = true;
try {
const res = await fetch("/api/auth/login", {
method: "POST",
headers: {
"Content-Type": "application/json"
},
body: JSON.stringify({
username: username,
password: password
})
});
if (!res.ok) {
showError();
btn.innerText = "AUTHENTICATE";
btn.disabled = false;
return;
}
window.location.href = "/admin";
} catch (err) {
showError();
btn.innerText = "AUTHENTICATE";
btn.disabled = false;
}
});
function showError() {
errorContainer.innerHTML = `<div class="error">ACCESS_DENIED_BY_SYSTEM</div>`;
// Shake the box for UX effect
const box = document.querySelector('.box');
box.style.transform = "translateX(5px)";
setTimeout(() => box.style.transform = "translateX(-5px)", 50);
setTimeout(() => box.style.transform = "translateX(0)", 100);
}
</script>
</body>
</html>

View File

@@ -1,15 +0,0 @@
<!DOCTYPE html>
<html>
<head>
<title>Upload</title>
</head>
<body>
<h1>Upload File</h1>
<form action="/api/files/upload" method="post" enctype="multipart/form-data">
<input type="file" name="file" />
<button type="submit">Upload</button>
</form>
</body>
</html>