import { db } from "../db/index.ts"; import type { SessionUser } from "../middleware/session.ts"; /** * Authorise an edit on an issue or patch comment. * * Returns a Response if the request must be denied, or null if it may proceed. * * Verifies, in one query, that: * 1. the comment exists, and * 2. its parent issue/patch belongs to the requested repo (prevents * cross-repo bypasses where the URL repo and the comment's repo differ), * 3. the user is the comment author or an admin, * 4. the parent issue/patch is open (admins may edit on closed parents). */ export async function authorizeCommentEdit( kind: "issue" | "patch", commentId: number, repoId: number, user: SessionUser | null, ): Promise { if (!user) return new Response("Unauthorized", { status: 401 }); const row = kind === "issue" ? await db .selectFrom("issue_comments") .innerJoin("issues", "issues.id", "issue_comments.issue_id") .select(["issue_comments.author_id", "issues.status"]) .where("issue_comments.id", "=", commentId) .where("issues.repo_id", "=", repoId) .executeTakeFirst() : await db .selectFrom("patch_comments") .innerJoin("patches", "patches.id", "patch_comments.patch_id") .select(["patch_comments.author_id", "patches.status"]) .where("patch_comments.id", "=", commentId) .where("patches.repo_id", "=", repoId) .executeTakeFirst(); if (!row) return new Response("Not found", { status: 404 }); if (row.author_id !== user.id && !user.isAdmin) return new Response("Forbidden", { status: 403 }); if (row.status !== "open" && !user.isAdmin) return new Response("Forbidden", { status: 403 }); return null; }