This repository has been archived on 2026-10-08. You can view files and clone it, but cannot push or open issues or pull requests.

84 lines
2.0 KiB
JavaScript

import express from "express";
import multer from "multer";
import {
uploadPatchImage,
getImageFileStream,
isS3UploadConfigured,
} from "../services/images.js";
const upload = multer({
storage: multer.memoryStorage(),
limits: { fileSize: 8 * 1024 * 1024 },
fileFilter: (_req, file, cb) => {
const ok = /^image\/(jpeg|png|webp|gif)$/i.test(file.mimetype);
cb(ok ? null : new Error("Invalid file type"), ok);
},
});
function requireUser(req, res, next) {
if (!req.session?.user?.sub) {
res.status(401).json({ status: "error", error: "Unauthorized" });
return;
}
next();
}
export function createImagesRouter() {
const router = express.Router();
router.post(
"/upload",
requireUser,
(req, res, next) => {
upload.single("file")(req, res, (err) => {
if (err) {
res
.status(400)
.json({ status: "error", error: err.message || "Upload error" });
return;
}
next();
});
},
async (req, res) => {
try {
if (!isS3UploadConfigured()) {
res.status(503).json({
status: "error",
error: "Image upload not configured",
});
return;
}
const file = req.file;
if (!file?.buffer) {
res.status(400).json({ status: "error", error: "file required" });
return;
}
const { id, blurHash } = await uploadPatchImage(
file.buffer,
file.mimetype,
);
res.json({ status: "ok", id, blurHash });
} catch (e) {
res.status(400).json({
status: "error",
error: e.message || "Upload failed",
});
}
},
);
router.get("/:id", requireUser, async (req, res) => {
const result = await getImageFileStream(req.params.id);
if (!result) {
res.status(404).end();
return;
}
res.setHeader("Content-Type", result.contentType);
res.setHeader("Cache-Control", "private, max-age=3600");
result.stream.pipe(res);
});
return router;
}