mirror of
https://github.com/OHTU-German-learning-website/OHTU-German-learning-website.git
synced 2026-10-12 19:13:51 +03:00
85 lines
2.6 KiB
JavaScript
85 lines
2.6 KiB
JavaScript
import { DB } from "@/backend/db";
|
|
import { withAuth } from "@/backend/middleware/withAuth";
|
|
import DOMPurify from "dompurify";
|
|
import { JSDOM } from "jsdom";
|
|
|
|
function sanitizeHtml(html) {
|
|
const window = new JSDOM("").window;
|
|
const purify = DOMPurify(window);
|
|
return purify.sanitize(String(html || ""), { ADD_ATTR: ["target"] });
|
|
}
|
|
|
|
export const POST = withAuth(
|
|
async (request) => {
|
|
const json = await request.json();
|
|
const { title, targetCategory, targetWords, allWords, sourceHtml } = json;
|
|
const sanitizedSourceHtml = sanitizeHtml(sourceHtml || "");
|
|
|
|
if (!title || !targetCategory || !targetWords || !allWords) {
|
|
return Response.json(
|
|
{ error: "Alle Felder sind erforderlich." },
|
|
{ status: 400 }
|
|
);
|
|
}
|
|
if (title.length < 3 || title.length > 50) {
|
|
return Response.json(
|
|
{ error: "Der Titel muss zwischen 3 und 50 Zeichen lang sein." },
|
|
{ status: 422 }
|
|
);
|
|
}
|
|
if (targetCategory.length < 3 || targetCategory.length > 30) {
|
|
return Response.json(
|
|
{ error: "Die Kategorie muss zwischen 3 und 30 Zeichen lang sein." },
|
|
{ status: 422 }
|
|
);
|
|
}
|
|
if (targetWords.length < 1 || targetWords.length > 1000) {
|
|
return Response.json(
|
|
{ error: "Es müssen zwischen 1 und 1000 Zielwörter vorhanden sein." },
|
|
{ status: 422 }
|
|
);
|
|
}
|
|
if (allWords.length < 1 || allWords.length > 1000) {
|
|
return Response.json(
|
|
{ error: "Es müssen zwischen 1 und 1000 Wörter vorhanden sein." },
|
|
{ status: 422 }
|
|
);
|
|
}
|
|
const existingExercise = await DB.pool(
|
|
`SELECT ce.id
|
|
FROM click_exercises ce
|
|
JOIN click_to_exercises cte ON cte.click_id = ce.id
|
|
WHERE LOWER(TRIM(ce.title)) = LOWER(TRIM($1))
|
|
LIMIT 1`,
|
|
[title]
|
|
);
|
|
if (existingExercise.rows.length > 0) {
|
|
return Response.json(
|
|
{ error: "Eine Übung mit diesem Titel existiert bereits." },
|
|
{ status: 409 }
|
|
);
|
|
}
|
|
const id = await DB.pool(
|
|
`INSERT INTO click_exercises (title, category, target_words, all_words, source_html)
|
|
VALUES ($1, $2, $3, $4, $5) returning id`,
|
|
[title, targetCategory, targetWords, allWords, sanitizedSourceHtml]
|
|
);
|
|
|
|
await DB.pool(
|
|
`UPDATE exercises e
|
|
SET created_by = $1,
|
|
updated_by = $1
|
|
FROM click_to_exercises cte
|
|
WHERE cte.exercise_id = e.id
|
|
AND cte.click_id = $2`,
|
|
[request.user?.id ?? null, id.rows[0].id]
|
|
);
|
|
|
|
return Response.json({ id: id.rows[0].id }, { status: 201 });
|
|
},
|
|
{
|
|
requireAdmin: true,
|
|
requireAuth: true,
|
|
}
|
|
);
|