initial commit
This commit is contained in:
1
.gitignore
vendored
Normal file
1
.gitignore
vendored
Normal file
@@ -0,0 +1 @@
|
|||||||
|
node_modules/*
|
||||||
92
index.js
Normal file
92
index.js
Normal file
@@ -0,0 +1,92 @@
|
|||||||
|
import fs from "fs";
|
||||||
|
import path from "path";
|
||||||
|
import crypto from "crypto";
|
||||||
|
import express from "express";
|
||||||
|
import multer from "multer";
|
||||||
|
|
||||||
|
const {
|
||||||
|
FILE_LOCATION,
|
||||||
|
ID_LENGTH = 12,
|
||||||
|
TOKEN_FILE,
|
||||||
|
PORT = 3000
|
||||||
|
} = process.env;
|
||||||
|
|
||||||
|
if (!FILE_LOCATION || !TOKEN_FILE) {
|
||||||
|
throw new Error("Missing FILE_LOCATION or TOKEN_FILE");
|
||||||
|
}
|
||||||
|
|
||||||
|
const TOKENS = new Set(
|
||||||
|
fs.readFileSync(TOKEN_FILE, "utf8")
|
||||||
|
.split("\n")
|
||||||
|
.map(t => t.trim())
|
||||||
|
.filter(Boolean)
|
||||||
|
);
|
||||||
|
|
||||||
|
function randomId(len) {
|
||||||
|
const chars = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789";
|
||||||
|
let out = "";
|
||||||
|
for (let i = 0; i < len; i++) {
|
||||||
|
out += chars[Math.floor(Math.random() * chars.length)];
|
||||||
|
}
|
||||||
|
return out;
|
||||||
|
}
|
||||||
|
|
||||||
|
function auth(req, res, next) {
|
||||||
|
const header = req.headers.authorization;
|
||||||
|
if (!header || !header.startsWith("Bearer ")) {
|
||||||
|
return res.status(401).json({ error: "Missing auth" });
|
||||||
|
}
|
||||||
|
|
||||||
|
const token = header.slice(7);
|
||||||
|
if (!TOKENS.has(token)) {
|
||||||
|
return res.status(403).json({ error: "Invalid token" });
|
||||||
|
}
|
||||||
|
|
||||||
|
next();
|
||||||
|
}
|
||||||
|
|
||||||
|
const upload = multer({
|
||||||
|
storage: multer.diskStorage({
|
||||||
|
destination: FILE_LOCATION,
|
||||||
|
filename: (req, file, cb) => {
|
||||||
|
const id = randomId(Number(ID_LENGTH));
|
||||||
|
const ext = path.extname(file.originalname);
|
||||||
|
cb(null, id + ext);
|
||||||
|
}
|
||||||
|
}),
|
||||||
|
limits: {
|
||||||
|
fileSize: 25 * 1024 * 1024
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
const app = express();
|
||||||
|
|
||||||
|
app.post("/upload", auth, upload.single("file"), (req, res) => {
|
||||||
|
if (!req.file) {
|
||||||
|
return res.status(400).json({ error: "No file" });
|
||||||
|
}
|
||||||
|
|
||||||
|
res.json({
|
||||||
|
id: path.parse(req.file.filename).name,
|
||||||
|
filename: req.file.filename,
|
||||||
|
url: `/${req.file.filename}`
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
app.get("/:name", (req, res) => {
|
||||||
|
const filePath = path.join(FILE_LOCATION, req.params.name);
|
||||||
|
|
||||||
|
if (!filePath.startsWith(FILE_LOCATION)) {
|
||||||
|
return res.status(400).end();
|
||||||
|
}
|
||||||
|
|
||||||
|
fs.access(filePath, fs.constants.R_OK, err => {
|
||||||
|
if (err) return res.status(404).end();
|
||||||
|
res.sendFile(filePath);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
app.listen(PORT, () => {
|
||||||
|
console.log(`Listening on :${PORT}`);
|
||||||
|
});
|
||||||
|
|
||||||
1029
package-lock.json
generated
Normal file
1029
package-lock.json
generated
Normal file
File diff suppressed because it is too large
Load Diff
16
package.json
Normal file
16
package.json
Normal file
@@ -0,0 +1,16 @@
|
|||||||
|
{
|
||||||
|
"name": "imgshare",
|
||||||
|
"version": "1.0.0",
|
||||||
|
"description": "",
|
||||||
|
"license": "ISC",
|
||||||
|
"author": "",
|
||||||
|
"type": "commonjs",
|
||||||
|
"main": "index.js",
|
||||||
|
"scripts": {
|
||||||
|
"test": "echo \"Error: no test specified\" && exit 1"
|
||||||
|
},
|
||||||
|
"dependencies": {
|
||||||
|
"express": "^5.2.1",
|
||||||
|
"multer": "^2.0.2"
|
||||||
|
}
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user