From d06ba7944e3b14c8a70db1f3e9316b221c24439f Mon Sep 17 00:00:00 2001 From: Camillalalala Date: Thu, 14 May 2026 22:26:17 -0700 Subject: [PATCH 1/3] Implement user role checking and notFound function --- .../manage/[storeId]/[storeItemId]/page.tsx | 25 +++++++++++++++++++ app/(main)/manage/[storeId]/add/page.tsx | 20 +++++++++++++++ app/(main)/manage/[storeId]/page.tsx | 25 +++++++++++++++++++ 3 files changed, 70 insertions(+) diff --git a/app/(main)/manage/[storeId]/[storeItemId]/page.tsx b/app/(main)/manage/[storeId]/[storeItemId]/page.tsx index 6c6374a8..4beb3e51 100644 --- a/app/(main)/manage/[storeId]/[storeItemId]/page.tsx +++ b/app/(main)/manage/[storeId]/[storeItemId]/page.tsx @@ -1,4 +1,5 @@ import Image from 'next/image'; +import { notFound } from 'next/navigation'; import Breadcrumbs from '@/app/(main)/components/Breadcrumbs'; import DeleteStoreItemButton from '@/app/(main)/manage/[storeId]/[storeItemId]/components/DeleteStoreItemButton'; import StoreItemForm from '@/app/(main)/manage/[storeId]/[storeItemId]/components/StoreItemForm'; @@ -16,6 +17,30 @@ export default async function ManageStoreItemPage({ const { storeId, storeItemId } = await params; const supabase = await createClient(); + + const { + data: { user }, + } = await supabase.auth.getUser(); + + if (!user) { + return notFound(); + } + + // Check if user can manage the store + const { data: canManage, error: canManageError } = await supabase.rpc( + 'can_manage_store', + { store_to_manage_id: storeId }, + ); + + if (canManageError) { + console.error('Error checking store access:', canManageError); + return notFound(); + } + + if (!canManage) { + return notFound(); + } + const [{ data: store }, { data: itemData, error: itemError }] = await Promise.all([ supabase.from('stores').select('name').eq('store_id', storeId).single(), diff --git a/app/(main)/manage/[storeId]/add/page.tsx b/app/(main)/manage/[storeId]/add/page.tsx index 0468d003..c8f15b50 100644 --- a/app/(main)/manage/[storeId]/add/page.tsx +++ b/app/(main)/manage/[storeId]/add/page.tsx @@ -19,6 +19,26 @@ export default async function AddStoreItemsPage({ const { data: { user }, } = await supabase.auth.getUser(); + + if (!user) { + return notFound(); + } + + // Check if user can manage the store + const { data: canManage, error: canManageError } = await supabase.rpc( + 'can_manage_store', + { store_to_manage_id: storeId }, + ); + + if (canManageError) { + console.error('Error checking store access:', canManageError); + return notFound(); + } + + if (!canManage) { + return notFound(); + } + // extract user id const userId = user?.id; // fetch user's entry from users table diff --git a/app/(main)/manage/[storeId]/page.tsx b/app/(main)/manage/[storeId]/page.tsx index ae586aa3..589ec4b1 100644 --- a/app/(main)/manage/[storeId]/page.tsx +++ b/app/(main)/manage/[storeId]/page.tsx @@ -1,4 +1,5 @@ import { createClient } from '@/app/lib/supabase/server-client'; +import { notFound } from 'next/navigation'; import ItemCard from '@/app/(main)/components/ItemCard'; import ItemSearch from '@/app/(main)/components/ItemSearch'; import Link from 'next/link'; @@ -24,6 +25,30 @@ export default async function ManageStorePage({ const supabase = await createClient(); + // Get the current user + const { + data: { user }, + } = await supabase.auth.getUser(); + + if (!user) { + return notFound(); + } + + // Check if user can manage the store + const { data: canManage, error: canManageError } = await supabase.rpc( + 'can_manage_store', + { store_to_manage_id: storeId }, + ); + + if (canManageError) { + console.error('Error checking store access:', canManageError); + return notFound(); + } + + if (!canManage) { + return notFound(); + } + const { data: categories } = await supabase .from('categories') .select('category_id, name') From db5ec5feb1ca5c3f7e212d4bd63861a90c319164 Mon Sep 17 00:00:00 2001 From: Camillalalala Date: Thu, 14 May 2026 22:36:23 -0700 Subject: [PATCH 2/3] Implement safeguards for individual ticket details access --- .../outgoing-tickets/[ticketId]/page.tsx | 21 +++++++++++++++++++ 1 file changed, 21 insertions(+) diff --git a/app/(main)/outgoing-tickets/[ticketId]/page.tsx b/app/(main)/outgoing-tickets/[ticketId]/page.tsx index 4c146e07..6eb47fd7 100644 --- a/app/(main)/outgoing-tickets/[ticketId]/page.tsx +++ b/app/(main)/outgoing-tickets/[ticketId]/page.tsx @@ -1,5 +1,7 @@ import TicketDetails from '@/app/(main)/components/TicketDetails'; import Breadcrumbs from '@/app/(main)/components/Breadcrumbs'; +import { createClient } from '@/app/lib/supabase/server-client'; +import { notFound } from 'next/navigation'; export default async function OutgoingTicketDetailsPage({ params, @@ -7,6 +9,25 @@ export default async function OutgoingTicketDetailsPage({ params: Promise<{ ticketId: string }>; }) { const { ticketId } = await params; + const supabase = await createClient(); + + const { + data: { user }, + } = await supabase.auth.getUser(); + + if (!user) { + return notFound(); + } + + const { data: ticket, error } = await supabase + .from('tickets') + .select('requestor_user_id') + .eq('ticket_id', ticketId) + .single(); + + if (error || !ticket || ticket.requestor_user_id !== user.id) { + return notFound(); + } return (
From 0f85a6a96daf1c2455e633eea7c7ccc76c4c6162 Mon Sep 17 00:00:00 2001 From: Camillalalala Date: Thu, 14 May 2026 22:38:21 -0700 Subject: [PATCH 3/3] Implement safeguards for stores and its corresponding incoming tickets --- .../[storeId]/[ticketId]/page.tsx | 22 +++++++++++++++++++ 1 file changed, 22 insertions(+) diff --git a/app/(main)/incoming-tickets/[storeId]/[ticketId]/page.tsx b/app/(main)/incoming-tickets/[storeId]/[ticketId]/page.tsx index e8a016c9..c40bb7e0 100644 --- a/app/(main)/incoming-tickets/[storeId]/[ticketId]/page.tsx +++ b/app/(main)/incoming-tickets/[storeId]/[ticketId]/page.tsx @@ -1,4 +1,5 @@ import { createClient } from '@/app/lib/supabase/server-client'; +import { notFound } from 'next/navigation'; import TicketDetails from '@/app/(main)/components/TicketDetails'; import Breadcrumbs from '@/app/(main)/components/Breadcrumbs'; @@ -10,6 +11,27 @@ export default async function IncomingTicketDetailsPage({ const { storeId, ticketId } = await params; const supabase = await createClient(); + const { + data: { user }, + } = await supabase.auth.getUser(); + + if (!user) { + return notFound(); + } + + // Check if user can manage the store + const { data: canManage, error: canManageError } = await supabase.rpc( + 'can_manage_store', + { store_to_manage_id: storeId }, + ); + + if (canManageError || !canManage) { + if (canManageError) { + console.error('Error checking store access:', canManageError); + } + return notFound(); + } + const { data: store, error: storeError } = await supabase .from('stores') .select('name')