fix: resolve RLS infinite recursion in tastings and sessions
This commit is contained in:
@@ -89,9 +89,9 @@ export default function Home() {
|
|||||||
});
|
});
|
||||||
|
|
||||||
setBottles(processedBottles);
|
setBottles(processedBottles);
|
||||||
} catch (err) {
|
} catch (err: any) {
|
||||||
console.error('Detailed fetch error:', err);
|
console.error('Detailed fetch error:', err);
|
||||||
setFetchError('Die Sammlung konnte nicht geladen werden. Bitte versuche es später erneut.');
|
setFetchError(err.message || JSON.stringify(err));
|
||||||
} finally {
|
} finally {
|
||||||
setIsLoading(false);
|
setIsLoading(false);
|
||||||
}
|
}
|
||||||
@@ -153,12 +153,12 @@ export default function Home() {
|
|||||||
<div className="animate-spin rounded-full h-8 w-8 border-b-2 border-amber-600"></div>
|
<div className="animate-spin rounded-full h-8 w-8 border-b-2 border-amber-600"></div>
|
||||||
</div>
|
</div>
|
||||||
) : fetchError ? (
|
) : fetchError ? (
|
||||||
<div className="p-8 bg-red-50 dark:bg-red-900/10 border border-red-200 dark:border-red-900/30 rounded-3xl text-center">
|
<div className="p-8 bg-zinc-100 dark:bg-zinc-900/50 border border-zinc-200 dark:border-zinc-800 rounded-3xl text-center">
|
||||||
<p className="text-red-600 dark:text-red-400 font-bold mb-2">Hoppla!</p>
|
<p className="text-zinc-800 dark:text-zinc-200 font-bold mb-2">Sammlung konnte nicht geladen werden</p>
|
||||||
<p className="text-red-500/80 text-sm italic">{fetchError}</p>
|
<p className="text-zinc-500 text-sm italic mb-4">Möglicherweise müssen die Datenbank-Regeln aktualisiert werden.</p>
|
||||||
<button
|
<button
|
||||||
onClick={fetchCollection}
|
onClick={fetchCollection}
|
||||||
className="mt-4 px-6 py-2 bg-zinc-900 dark:bg-zinc-100 text-white dark:text-zinc-900 rounded-xl text-xs font-bold uppercase tracking-widest"
|
className="px-6 py-2 bg-amber-600 hover:bg-amber-700 text-white rounded-xl text-xs font-bold uppercase tracking-widest transition-all"
|
||||||
>
|
>
|
||||||
Erneut versuchen
|
Erneut versuchen
|
||||||
</button>
|
</button>
|
||||||
|
|||||||
@@ -99,9 +99,16 @@ export default function SessionDetailPage() {
|
|||||||
const handleAddParticipant = async (buddyId: string) => {
|
const handleAddParticipant = async (buddyId: string) => {
|
||||||
if (participants.some(p => p.buddy_id === buddyId)) return;
|
if (participants.some(p => p.buddy_id === buddyId)) return;
|
||||||
|
|
||||||
|
const { data: { user } } = await supabase.auth.getUser();
|
||||||
|
if (!user) return;
|
||||||
|
|
||||||
const { error } = await supabase
|
const { error } = await supabase
|
||||||
.from('session_participants')
|
.from('session_participants')
|
||||||
.insert([{ session_id: id, buddy_id: buddyId }]);
|
.insert([{
|
||||||
|
session_id: id,
|
||||||
|
buddy_id: buddyId,
|
||||||
|
user_id: user.id
|
||||||
|
}]);
|
||||||
|
|
||||||
if (!error) {
|
if (!error) {
|
||||||
fetchSessionData();
|
fetchSessionData();
|
||||||
|
|||||||
@@ -41,7 +41,8 @@ export async function saveTasting(data: {
|
|||||||
if (data.buddy_ids && data.buddy_ids.length > 0) {
|
if (data.buddy_ids && data.buddy_ids.length > 0) {
|
||||||
const tags = data.buddy_ids.map(buddyId => ({
|
const tags = data.buddy_ids.map(buddyId => ({
|
||||||
tasting_id: tasting.id,
|
tasting_id: tasting.id,
|
||||||
buddy_id: buddyId
|
buddy_id: buddyId,
|
||||||
|
user_id: session.user.id
|
||||||
}));
|
}));
|
||||||
const { error: tagError } = await supabase
|
const { error: tagError } = await supabase
|
||||||
.from('tasting_tags')
|
.from('tasting_tags')
|
||||||
|
|||||||
@@ -64,10 +64,11 @@ CREATE TABLE IF NOT EXISTS tasting_sessions (
|
|||||||
created_at TIMESTAMP WITH TIME ZONE DEFAULT timezone('Europe/Berlin'::text, now())
|
created_at TIMESTAMP WITH TIME ZONE DEFAULT timezone('Europe/Berlin'::text, now())
|
||||||
);
|
);
|
||||||
|
|
||||||
-- Session Participants junction
|
-- Session Participants junction (updated with user_id to avoid RLS recursion)
|
||||||
CREATE TABLE IF NOT EXISTS session_participants (
|
CREATE TABLE IF NOT EXISTS session_participants (
|
||||||
session_id UUID REFERENCES tasting_sessions(id) ON DELETE CASCADE NOT NULL,
|
session_id UUID REFERENCES tasting_sessions(id) ON DELETE CASCADE NOT NULL,
|
||||||
buddy_id UUID REFERENCES buddies(id) ON DELETE CASCADE NOT NULL,
|
buddy_id UUID REFERENCES buddies(id) ON DELETE CASCADE NOT NULL,
|
||||||
|
user_id UUID REFERENCES profiles(id) ON DELETE CASCADE NOT NULL, -- The owner of the session
|
||||||
PRIMARY KEY (session_id, buddy_id)
|
PRIMARY KEY (session_id, buddy_id)
|
||||||
);
|
);
|
||||||
|
|
||||||
@@ -85,10 +86,11 @@ CREATE TABLE IF NOT EXISTS tastings (
|
|||||||
created_at TIMESTAMP WITH TIME ZONE DEFAULT timezone('Europe/Berlin'::text, now())
|
created_at TIMESTAMP WITH TIME ZONE DEFAULT timezone('Europe/Berlin'::text, now())
|
||||||
);
|
);
|
||||||
|
|
||||||
-- Tasting Tagging (to tag buddies in a tasting)
|
-- Tasting Tagging (updated with user_id to avoid RLS recursion)
|
||||||
CREATE TABLE IF NOT EXISTS tasting_tags (
|
CREATE TABLE IF NOT EXISTS tasting_tags (
|
||||||
tasting_id UUID REFERENCES tastings(id) ON DELETE CASCADE NOT NULL,
|
tasting_id UUID REFERENCES tastings(id) ON DELETE CASCADE NOT NULL,
|
||||||
buddy_id UUID REFERENCES buddies(id) ON DELETE CASCADE NOT NULL,
|
buddy_id UUID REFERENCES buddies(id) ON DELETE CASCADE NOT NULL,
|
||||||
|
user_id UUID REFERENCES profiles(id) ON DELETE CASCADE NOT NULL, -- The owner of the tasting
|
||||||
PRIMARY KEY (tasting_id, buddy_id)
|
PRIMARY KEY (tasting_id, buddy_id)
|
||||||
);
|
);
|
||||||
|
|
||||||
@@ -160,10 +162,8 @@ CREATE POLICY "Users can see sessions they participate in" ON tasting_sessions
|
|||||||
|
|
||||||
-- Policies for Session Participants
|
-- Policies for Session Participants
|
||||||
ALTER TABLE session_participants ENABLE ROW LEVEL SECURITY;
|
ALTER TABLE session_participants ENABLE ROW LEVEL SECURITY;
|
||||||
CREATE POLICY "Users can manage participants of their sessions" ON session_participants
|
CREATE POLICY "Users can manage their own session participants" ON session_participants
|
||||||
FOR ALL USING (
|
FOR ALL USING (auth.uid() = user_id);
|
||||||
session_id IN (SELECT id FROM tasting_sessions WHERE user_id = auth.uid())
|
|
||||||
);
|
|
||||||
CREATE POLICY "Participants can see session membership" ON session_participants
|
CREATE POLICY "Participants can see session membership" ON session_participants
|
||||||
FOR SELECT USING (
|
FOR SELECT USING (
|
||||||
buddy_id IN (SELECT id FROM buddies WHERE buddy_profile_id = auth.uid())
|
buddy_id IN (SELECT id FROM buddies WHERE buddy_profile_id = auth.uid())
|
||||||
@@ -171,10 +171,8 @@ CREATE POLICY "Participants can see session membership" ON session_participants
|
|||||||
|
|
||||||
-- Policies for Tasting Tags
|
-- Policies for Tasting Tags
|
||||||
ALTER TABLE tasting_tags ENABLE ROW LEVEL SECURITY;
|
ALTER TABLE tasting_tags ENABLE ROW LEVEL SECURITY;
|
||||||
CREATE POLICY "Users can manage tags on their tastings" ON tasting_tags
|
CREATE POLICY "Users can manage their own tasting tags" ON tasting_tags
|
||||||
FOR ALL USING (
|
FOR ALL USING (auth.uid() = user_id);
|
||||||
tasting_id IN (SELECT id FROM tastings WHERE user_id = auth.uid())
|
|
||||||
);
|
|
||||||
CREATE POLICY "Tagged users can see the tags" ON tasting_tags
|
CREATE POLICY "Tagged users can see the tags" ON tasting_tags
|
||||||
FOR SELECT USING (
|
FOR SELECT USING (
|
||||||
buddy_id IN (SELECT id FROM buddies WHERE buddy_profile_id = auth.uid())
|
buddy_id IN (SELECT id FROM buddies WHERE buddy_profile_id = auth.uid())
|
||||||
|
|||||||
Reference in New Issue
Block a user