2024-06-09 13:25:46 +02:00
|
|
|
const express = require("express");
|
|
|
|
const rateLimit = require("express-rate-limit");
|
|
|
|
const slowDown = require("express-slow-down");
|
2024-06-04 18:45:19 +02:00
|
|
|
const initializeLocalStorage = require("../engines/local.engine");
|
|
|
|
const initializeS3Storage = require("../engines/s3.engine");
|
|
|
|
|
2024-06-09 13:25:46 +02:00
|
|
|
const app = express();
|
|
|
|
|
2024-06-04 18:45:19 +02:00
|
|
|
const storageMode = process.env.STORAGE_MODE || "local";
|
|
|
|
const fileNameLength = parseInt(process.env.FILE_NAME_LENGTH, 10) || 10;
|
|
|
|
const multerOptions = {
|
|
|
|
limits: parseInt(process.env.FILE_MAX_SIZE_MB, 10) * 1024 * 1024,
|
|
|
|
};
|
|
|
|
const publicMulterOptions = {
|
|
|
|
limits: parseInt(process.env.PUBLIC_UPLOAD_SIZE_LIMIT, 10) * 1024 * 1024,
|
|
|
|
};
|
|
|
|
|
|
|
|
let storageEngine;
|
|
|
|
|
|
|
|
if (storageMode === "local") {
|
|
|
|
storageEngine = initializeLocalStorage(
|
|
|
|
multerOptions,
|
|
|
|
fileNameLength,
|
|
|
|
process.env.LOCAL_UPLOAD_PATH,
|
|
|
|
);
|
|
|
|
} else if (storageMode === "s3") {
|
|
|
|
const s3Config = {
|
|
|
|
accessKeyId: process.env.AWS_ACCESS_KEY_ID,
|
|
|
|
secretAccessKey: process.env.AWS_SECRET_ACCESS_KEY,
|
|
|
|
region: process.env.AWS_REGION,
|
|
|
|
bucketName: process.env.S3_BUCKET_NAME,
|
2024-06-09 13:22:57 +02:00
|
|
|
endpoint: process.env.S3_ENDPOINT,
|
2024-06-04 18:45:19 +02:00
|
|
|
};
|
|
|
|
storageEngine = initializeS3Storage(multerOptions, fileNameLength, s3Config);
|
|
|
|
} else {
|
|
|
|
throw new Error("Invalid STORAGE_MODE");
|
|
|
|
}
|
|
|
|
|
|
|
|
const uploadFile = (req, res) => {
|
|
|
|
storageEngine.writeFile(req, res, () => {
|
|
|
|
const fileHostDomain =
|
|
|
|
process.env.FILEHOST_DOMAIN || `${req.protocol}://${req.get("host")}`;
|
|
|
|
res.status(200).json({
|
|
|
|
message: "File uploaded successfully",
|
|
|
|
url: `${fileHostDomain}/u/${req.filePath}`,
|
|
|
|
});
|
|
|
|
});
|
|
|
|
};
|
|
|
|
|
|
|
|
const getFile = (req, res) => {
|
|
|
|
const filename = req.params.filename;
|
|
|
|
storageEngine.findFile(filename, res);
|
|
|
|
};
|
|
|
|
|
2024-06-09 13:25:46 +02:00
|
|
|
// Rate limiting middleware
|
|
|
|
const limiter = rateLimit({
|
|
|
|
windowMs: 15 * 60 * 1000, // 15 minutes
|
|
|
|
max: 100, // Limit each IP to 100 requests per windowMs
|
|
|
|
message: "Too many requests from this IP, please try again after 15 minutes",
|
|
|
|
});
|
|
|
|
|
|
|
|
// Slow down middleware
|
|
|
|
const speedLimiter = slowDown({
|
|
|
|
windowMs: 15 * 60 * 1000, // 15 minutes
|
2024-06-09 13:28:44 +02:00
|
|
|
delayAfter: 75, // Allow 75 fast requests per 15 minutes.
|
|
|
|
delayMs: (hits) => hits * 100, // Increase delay by 100ms for each request after 5 requests
|
2024-06-09 13:25:46 +02:00
|
|
|
});
|
|
|
|
|
|
|
|
app.use("/u/:filename", limiter, speedLimiter, getFile);
|
|
|
|
|
2024-06-04 18:45:19 +02:00
|
|
|
module.exports = { uploadFile, getFile };
|