Fix unapproved hack viewing permissions

This commit is contained in:
Jared Schoeny 2026-01-16 13:42:35 -10:00
parent 456832aad3
commit f0875bc929
2 changed files with 11 additions and 12 deletions

View File

@ -134,20 +134,21 @@ export default async function HackDetail({ params }: HackDetailProps) {
canEdit: canUploadPatch, canEdit: canUploadPatch,
} = await checkPatchEditPermission(hack, user?.id as string, supabase); } = await checkPatchEditPermission(hack, user?.id as string, supabase);
// isAdmin always needs to be checked for archive hacks
let isAdmin = false; let isAdmin = false;
if (!hack.approved || isArchive) { if (!hack.approved || isArchive) {
const { data: admin } = await supabase.rpc("is_admin"); const { data: admin } = await supabase.rpc("is_admin");
if (admin) { if (admin) {
isAdmin = true; isAdmin = true;
} else if (!isArchive) { } else if (!hack.approved) {
return notFound(); if (isArchive && !canEditAsArchiver) {
return notFound();
} else if (!canEdit) {
return notFound();
}
} }
} }
if (isArchive && !isAdmin && !canEditAsArchiver) {
return notFound();
}
// Extract patch info from cached metadata // Extract patch info from cached metadata
const patchFilename = patch?.filename || null; const patchFilename = patch?.filename || null;
const patchVersion = isArchive ? "Archive" : (patch?.version || ""); const patchVersion = isArchive ? "Archive" : (patch?.version || "");

View File

@ -2,7 +2,7 @@ import { createClient } from "@/utils/supabase/server";
import { notFound, redirect } from "next/navigation"; import { notFound, redirect } from "next/navigation";
import HackStatsClient from "@/components/Hack/Stats/HackStatsClient"; import HackStatsClient from "@/components/Hack/Stats/HackStatsClient";
import { getDownloadsSeriesAll, getHackInsights } from "@/app/dashboard/actions"; import { getDownloadsSeriesAll, getHackInsights } from "@/app/dashboard/actions";
import { isArchiveHack, canEditAsArchiver } from "@/utils/hack"; import { checkEditPermission } from "@/utils/hack";
export default async function HackStatsPage({ params: { slug } }: { params: { slug: string } }) { export default async function HackStatsPage({ params: { slug } }: { params: { slug: string } }) {
const supa = await createClient(); const supa = await createClient();
@ -17,11 +17,9 @@ export default async function HackStatsPage({ params: { slug } }: { params: { sl
.maybeSingle(); .maybeSingle();
if (!hack) notFound(); if (!hack) notFound();
let isOwner = hack.created_by === user.id; const permission = await checkEditPermission(hack, user.id, supa);
if (!isOwner) { if (!permission.canEdit) {
const isArchive = isArchiveHack(hack); redirect(`/hack/${slug}`);
const isEditableByArchiver = await canEditAsArchiver(hack, user.id, supa);
if (!isOwner && !isArchive && !isEditableByArchiver) notFound();
} }
const allSeries = await getDownloadsSeriesAll({ days: 30 }); const allSeries = await getDownloadsSeriesAll({ days: 30 });