const express = require("express"); const router = express.Router(); const pool = require("../../db"); const { strictInput } = require("../../middleware/strict_input"); const { authenticateToken } = require("../../middleware/authenticate_token"); const { handlePostUpload, imageLinkForFile, removeImageLink, removeUploadedFile, } = require("../../middleware/post_upload"); async function editPost(req, res) { const id = req.query.id; const { title, text, remove_image: removeImageValue } = req.body; const removeImage = removeImageValue === "true"; if (removeImageValue !== undefined && !["true", "false"].includes(removeImageValue)) { await removeUploadedFile(req.file); return res.status(400).send("remove_image must be true or false"); } if (req.file && removeImage) { await removeUploadedFile(req.file); return res.status(400).send("Choose either an image or remove_image=true"); } if (title === "" || text === "") { await removeUploadedFile(req.file); return res.status(400).send("title and text cannot be empty"); } if (title === undefined && text === undefined && !req.file && !removeImage) { return res.status(400).send("At least one post field must be changed"); } try { const existing = await pool.query( "SELECT id, image_link FROM posts WHERE id = $1 AND author_id = $2", [id, req.user.id], ); if (existing.rowCount === 0) { await removeUploadedFile(req.file); return res.status(404).send("Post not found or does not belong to you"); } const oldImageLink = existing.rows[0].image_link; const fields = []; const values = []; const addField = (field, value) => { fields.push(`${field} = $${values.length + 1}`); values.push(value); }; if (title !== undefined) addField("title", title); if (text !== undefined) addField("text", text); if (req.file) addField("image_link", imageLinkForFile(req.file)); if (removeImage) addField("image_link", null); values.push(id, req.user.id); let updated; try { updated = await pool.query( `UPDATE posts SET ${fields.join(", ")} WHERE id = $${values.length - 1} AND author_id = $${values.length} RETURNING id, title, text, author_id, image_link`, values, ); } catch (err) { await removeUploadedFile(req.file); throw err; } if (req.file || removeImage) { await removeImageLink(oldImageLink).catch((err) => { console.error("old post image could not be removed", { message: err.message }); }); } return res.status(200).json(updated.rows[0]); } catch (err) { await removeUploadedFile(req.file); console.error("database query failed", { message: err.message, code: err.code, detail: err.detail, hint: err.hint, stack: err.stack, }); return res.status(500).send("Post was not updated, request failed"); } } router.put( "/", authenticateToken, handlePostUpload, strictInput({ query: ["id"], body: ["title", "text", "remove_image"], cleanupUploadedFile: true, }), editPost, ); module.exports = router;