|
1 | 1 | // /api/comments.js |
2 | | -export default async function handler(req, res) { |
3 | | - const fs = require('fs'); |
4 | | - const path = require('path'); |
5 | 2 |
|
6 | | - // Ensure the request body is parsed |
| 3 | +import fs from "fs"; |
| 4 | +import path from "path"; |
| 5 | +import { kv } from "@vercel/kv"; |
| 6 | +import sanitizeHtml from "sanitize-html"; |
| 7 | + |
| 8 | +const USE_KV = process.env.USE_KV === "true"; |
| 9 | + |
| 10 | +function filePath() { return path.join(process.cwd(), "comments.json"); } |
| 11 | + |
| 12 | +async function readComments(slug) { |
| 13 | + if (USE_KV) return (await kv.get(`comments:${slug}`)) || []; |
| 14 | + if (!fs.existsSync(filePath())) fs.writeFileSync(filePath(), "{}"); |
| 15 | + const data = JSON.parse(fs.readFileSync(filePath(), "utf8")); |
| 16 | + return data[slug] || []; |
| 17 | +} |
| 18 | + |
| 19 | +async function writeComments(slug, arr) { |
| 20 | + if (USE_KV) return kv.set(`comments:${slug}`, arr); |
| 21 | + const data = fs.existsSync(filePath()) |
| 22 | + ? JSON.parse(fs.readFileSync(filePath(), "utf8")) |
| 23 | + : {}; |
| 24 | + data[slug] = arr; |
| 25 | + fs.writeFileSync(filePath(), JSON.stringify(data, null, 2)); |
| 26 | +} |
| 27 | + |
| 28 | +export default async function handler(req, res) { |
7 | 29 | if (req.method === 'POST' && !req.body) { |
8 | 30 | return res.status(400).json({ error: "Invalid or missing request body" }); |
9 | 31 | } |
10 | | - |
11 | | - const filePath = path.join(process.cwd(), 'comments.json'); |
12 | | - |
13 | | - // Ensure file exists |
14 | | - if (!fs.existsSync(filePath)) { |
15 | | - fs.writeFileSync(filePath, '{}'); |
16 | | - } |
17 | | - |
18 | | - const data = JSON.parse(fs.readFileSync(filePath, 'utf8')); |
19 | 32 |
|
20 | 33 | if (req.method === 'GET') { |
21 | 34 | const { slug } = req.query; |
22 | 35 | if (!slug) { |
23 | 36 | return res.status(400).json({ error: "Missing slug" }); |
24 | 37 | } |
25 | | - return res.status(200).json(data[slug] || []); |
| 38 | + const comments = await readComments(slug); |
| 39 | + return res.status(200).json(comments); |
26 | 40 | } |
27 | 41 |
|
28 | 42 | if (req.method === 'POST') { |
29 | 43 | const { slug, text } = req.body; |
30 | 44 | if (!slug || !text) { |
31 | 45 | return res.status(400).json({ error: "Missing slug or text" }); |
32 | 46 | } |
33 | | - if (!data[slug]) { |
34 | | - data[slug] = []; |
35 | | - } |
36 | | - const timestamp = Date.now(); |
37 | | - data[slug].push({ |
38 | | - text, |
39 | | - timestamp, |
| 47 | + |
| 48 | + const sanitizedText = sanitizeHtml(text, { |
| 49 | + allowedTags: [], |
| 50 | + allowedAttributes: {}, |
40 | 51 | }); |
41 | 52 |
|
42 | | - fs.writeFileSync(filePath, JSON.stringify(data, null, 2)); |
43 | | - return res.status(201).json({ text, timestamp }); |
| 53 | + const timestamp = Date.now(); |
| 54 | + const comments = await readComments(slug); |
| 55 | + comments.push({ text: sanitizedText, timestamp }); |
| 56 | + await writeComments(slug, comments); |
| 57 | + return res.status(201).json({ text: sanitizedText, timestamp }); |
44 | 58 | } |
45 | 59 |
|
46 | 60 | res.setHeader('Allow', ['GET', 'POST']); |
|
0 commit comments