web: samplehub

This commit is contained in:
agatha 2024-10-25 19:16:56 -04:00
parent 6993d95ff1
commit ad2485a290
15 changed files with 135 additions and 0 deletions

Binary file not shown.

View File

@ -0,0 +1 @@
HERO{FAKE_FLAG}

View File

@ -0,0 +1,10 @@
FROM alpine:3.20.3
WORKDIR /usr/app
COPY ./src/ .
COPY ./.flag.txt /.flag.txt
RUN apk add --update --no-cache nodejs npm && \
npm install
USER guest
CMD ["/usr/bin/node", "/usr/app/app.js"]

View File

@ -0,0 +1,16 @@
version: '3.8'
services:
web:
build: .
ports:
- "3000:3000"
read_only: true
restart: unless-stopped
cap_drop:
- all
deploy:
resources:
limits:
cpus: "0.5"
memory: 1G

View File

@ -0,0 +1,28 @@
const express = require("express");
const path = require("path");
const app = express();
const PORT = 3000;
app.use(express.static(path.join(__dirname, "public")));
app.set("view engine", "ejs");
app.set("views", path.join(__dirname, "views"));
app.get("/", (req, res) => {
res.render("index");
});
process.chdir(path.join(__dirname, "samples"));
app.get("/download/:file", (req, res) => {
const file = path.basename(req.params.file);
res.download(file, req.query.filename || "sample.png", (err) => {
if (err) {
res.status(404).send(`File "${file}" not found`);
}
});
});
app.listen(PORT, () => {
console.log(`Server is running on http://localhost:${PORT}`);
});

View File

@ -0,0 +1,6 @@
{
"dependencies": {
"ejs": "^3.1.10",
"express": "^4.21.1"
}
}

View File

@ -0,0 +1,9 @@
[
{ "filename": "sample.png", "extension": ".png", "description": "A Portable Network Graphics file that supports lossless data compression. Commonly used for web images and graphics." },
{ "filename": "sample.jpg", "extension": ".jpg", "description": "A JPEG image file, widely used for digital photos and web graphics. It employs lossy compression to reduce file size." },
{ "filename": "sample.pdf", "extension": ".pdf", "description": "A Portable Document Format file used for sharing documents while preserving formatting. It is viewable on any platform using a PDF reader." },
{ "filename": "sample.doc", "extension": ".doc", "description": "A Microsoft Word document file format used for text documents. It supports rich formatting and can include images, tables, and other elements." },
{ "filename": "sample.xls", "extension": ".xls", "description": "A Microsoft Excel spreadsheet file format that supports data analysis and calculation. It allows for complex formulas and data visualization." },
{ "filename": "sample.mp3", "extension": ".mp3", "description": "An audio file format that uses lossy compression to reduce file size. It's commonly used for music and audio streaming." },
{ "filename": "sample.mp4", "extension": ".mp4", "description": "A digital multimedia format commonly used for video files. It supports a wide range of codecs and is ideal for streaming." }
]

Binary file not shown.

Binary file not shown.

After

Width:  |  Height:  |  Size: 542 KiB

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

After

Width:  |  Height:  |  Size: 501 KiB

Binary file not shown.

View File

@ -0,0 +1,65 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Samples</title>
<link href="https://cdn.jsdelivr.net/npm/tailwindcss@2.2.19/dist/tailwind.min.css" rel="stylesheet">
</head>
<body class="bg-gray-100">
<div class="container mx-auto p-5">
<h1 class="text-3xl font-bold mb-6 text-center">File Samples</h1>
<div class="mb-6">
<input
type="text"
id="search"
placeholder="Search for files..."
class="w-full p-3 border border-gray-300 rounded-lg shadow focus:outline-none focus:ring-2 focus:ring-blue-500"
>
</div>
<div id="file-list" class="space-y-4"></div>
</div>
<script>
const searchInput = document.getElementById("search");
const fileList = document.getElementById("file-list");
fetch("/samples.json")
.then(response => response.json())
.then(samples => {
const originalSamples = samples;
function populateList(samples) {
fileList.innerHTML = "";
if (samples.length === 0) return;
samples.forEach(sample => {
const div = document.createElement("div");
div.className = "flex items-center justify-between p-4 bg-white border border-gray-200 rounded-lg shadow";
div.innerHTML = `
<div>
<h2 class="font-semibold">${sample.extension}</h2>
<p class="text-gray-600">${sample.description}</p>
</div>
<a href="/download/${sample.filename}" class="bg-blue-500 text-white py-2 px-4 rounded hover:bg-blue-600 transition">Download</a>
`;
fileList.appendChild(div);
});
}
searchInput.addEventListener("input", function() {
const query = this.value.toLowerCase();
if (query) {
const filteredSamples = originalSamples.filter(sample =>
sample.extension.toLowerCase().includes(query)
);
populateList(filteredSamples);
} else {
fileList.innerHTML = "";
}
});
})
.catch(error => console.error("Error fetching samples:", error));
</script>
</body>
</html>