fix: resolve infinite recursion in admin_users RLS policy
The admin_users policy was checking if user is admin by querying the same table, causing infinite recursion. Changed to allow users to view their own admin record directly using auth.uid() = user_id. This fixes the error: 'infinite recursion detected in policy for relation admin_users'
This commit is contained in:
48
src/app/api/debug-admin/route.ts
Normal file
48
src/app/api/debug-admin/route.ts
Normal file
@@ -0,0 +1,48 @@
|
|||||||
|
import { createServerComponentClient } from '@supabase/auth-helpers-nextjs';
|
||||||
|
import { cookies } from 'next/headers';
|
||||||
|
import { NextResponse } from 'next/server';
|
||||||
|
|
||||||
|
export async function GET() {
|
||||||
|
const supabase = createServerComponentClient({ cookies });
|
||||||
|
|
||||||
|
// Get current user
|
||||||
|
const { data: { user }, error: userError } = await supabase.auth.getUser();
|
||||||
|
|
||||||
|
if (userError || !user) {
|
||||||
|
return NextResponse.json({
|
||||||
|
success: false,
|
||||||
|
error: 'Not authenticated',
|
||||||
|
userError: userError?.message
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
// Check admin_users table
|
||||||
|
const { data: adminData, error: adminError } = await supabase
|
||||||
|
.from('admin_users')
|
||||||
|
.select('*')
|
||||||
|
.eq('user_id', user.id)
|
||||||
|
.single();
|
||||||
|
|
||||||
|
// Get all admin users (for debugging)
|
||||||
|
const { data: allAdmins, error: allAdminsError } = await supabase
|
||||||
|
.from('admin_users')
|
||||||
|
.select('*');
|
||||||
|
|
||||||
|
return NextResponse.json({
|
||||||
|
success: true,
|
||||||
|
currentUser: {
|
||||||
|
id: user.id,
|
||||||
|
email: user.email
|
||||||
|
},
|
||||||
|
adminCheck: {
|
||||||
|
data: adminData,
|
||||||
|
error: adminError?.message,
|
||||||
|
isAdmin: !!adminData
|
||||||
|
},
|
||||||
|
allAdmins: {
|
||||||
|
data: allAdmins,
|
||||||
|
error: allAdminsError?.message,
|
||||||
|
count: allAdmins?.length || 0
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
@@ -189,6 +189,7 @@ export async function getGlobalApiStats(): Promise<ApiStats | null> {
|
|||||||
*/
|
*/
|
||||||
export async function checkIsAdmin(userId: string): Promise<boolean> {
|
export async function checkIsAdmin(userId: string): Promise<boolean> {
|
||||||
try {
|
try {
|
||||||
|
console.log('[checkIsAdmin] Checking admin status for user:', userId);
|
||||||
const supabase = createServerComponentClient({ cookies });
|
const supabase = createServerComponentClient({ cookies });
|
||||||
|
|
||||||
const { data, error } = await supabase
|
const { data, error } = await supabase
|
||||||
@@ -197,13 +198,18 @@ export async function checkIsAdmin(userId: string): Promise<boolean> {
|
|||||||
.eq('user_id', userId)
|
.eq('user_id', userId)
|
||||||
.single();
|
.single();
|
||||||
|
|
||||||
|
console.log('[checkIsAdmin] Query result - data:', data, 'error:', error);
|
||||||
|
|
||||||
if (error) {
|
if (error) {
|
||||||
|
console.log('[checkIsAdmin] Error occurred:', error.message);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
return !!data;
|
const isAdmin = !!data;
|
||||||
|
console.log('[checkIsAdmin] Final result:', isAdmin);
|
||||||
|
return isAdmin;
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
console.error('Error checking admin status:', err);
|
console.error('[checkIsAdmin] Exception:', err);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -283,9 +283,9 @@ CREATE POLICY "Admins can view all credits" ON user_credits FOR SELECT USING (
|
|||||||
EXISTS (SELECT 1 FROM admin_users WHERE user_id = auth.uid())
|
EXISTS (SELECT 1 FROM admin_users WHERE user_id = auth.uid())
|
||||||
);
|
);
|
||||||
|
|
||||||
-- Policies for admin_users (only admins can view)
|
-- Policies for admin_users (users can see their own admin record)
|
||||||
CREATE POLICY "Admins can view admin users" ON admin_users FOR SELECT USING (
|
CREATE POLICY "Users can view their own admin record" ON admin_users FOR SELECT USING (
|
||||||
EXISTS (SELECT 1 FROM admin_users WHERE user_id = auth.uid())
|
auth.uid() = user_id
|
||||||
);
|
);
|
||||||
|
|
||||||
-- Note: To add robin as admin, run this after getting the user_id:
|
-- Note: To add robin as admin, run this after getting the user_id:
|
||||||
|
|||||||
Reference in New Issue
Block a user