110 lines
3.6 KiB
JavaScript
110 lines
3.6 KiB
JavaScript
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");
|
|
const { likeDataForPosts } = require("./post_graph");
|
|
|
|
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 AND active = true",
|
|
[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);
|
|
fields.push("edited_last = NOW()");
|
|
values.push(id, req.user.id);
|
|
|
|
let updated;
|
|
try {
|
|
updated = await pool.query(
|
|
`WITH updated AS (UPDATE posts SET ${fields.join(", ")} WHERE id = $${values.length - 1} AND author_id = $${values.length} RETURNING id, title, text, author_id, image_link, created_at, edited_last) SELECT updated.*, people.username AS author_username FROM updated LEFT JOIN people ON people.id = updated.author_id`,
|
|
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 });
|
|
});
|
|
}
|
|
const likeData = (await likeDataForPosts(req.user.id, [updated.rows[0].id])).get(
|
|
Number(updated.rows[0].id),
|
|
) ?? { like_count: 0, liked_by_me: false };
|
|
return res.status(200).json({
|
|
...updated.rows[0],
|
|
like_count: likeData.like_count,
|
|
liked_by_me: likeData.liked_by_me,
|
|
});
|
|
} 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;
|