Enforce RLS when user opted in to MFA. (#188)

* Allow Super Admin to view tables using RLS
* Replace previous usages of the Admin client using the authed client using the new RLS
* Enforce MFA for Super Admin users
* Enforce RLS when user opted in to MFA.
* Add Super Admin Access Policies and Update Database Types
* Consolidate super admin logic into a single function that uses the RPC is_super_admin
* Added Super Admin E2E tests
* Fixes and improvements
* Bump version to 2.5.0
This commit is contained in:
Giancarlo Buomprisco
2025-03-02 10:21:01 +07:00
committed by GitHub
parent 9cf7bf0aac
commit 131b1061e6
61 changed files with 2193 additions and 302 deletions

View File

@@ -2,7 +2,7 @@ import 'server-only';
import { cache } from 'react';
import { getSupabaseServerAdminClient } from '@kit/supabase/server-admin-client';
import { getSupabaseServerClient } from '@kit/supabase/server-client';
import { createAdminDashboardService } from '../services/admin-dashboard.service';
@@ -14,7 +14,7 @@ import { createAdminDashboardService } from '../services/admin-dashboard.service
export const loadAdminDashboard = cache(adminDashboardLoader);
function adminDashboardLoader() {
const client = getSupabaseServerAdminClient();
const client = getSupabaseServerClient();
const service = createAdminDashboardService(client);
return service.getDashboardData();

View File

@@ -137,6 +137,17 @@ class AdminAuthUserService {
`You cannot perform a destructive action on your own account as a Super Admin`,
);
}
const targetUser =
await this.adminClient.auth.admin.getUserById(targetUserId);
const targetUserRole = targetUser.data.user?.app_metadata?.role;
if (targetUserRole === 'super-admin') {
throw new Error(
`You cannot perform a destructive action on a Super Admin account`,
);
}
}
private async setBanDuration(userId: string, banDuration: string) {

View File

@@ -1,6 +1,5 @@
import { SupabaseClient } from '@supabase/supabase-js';
import { checkRequiresMultiFactorAuthentication } from '@kit/supabase/check-requires-mfa';
import { Database } from '@kit/supabase/database';
/**
@@ -9,25 +8,15 @@ import { Database } from '@kit/supabase/database';
* @param client
*/
export async function isSuperAdmin(client: SupabaseClient<Database>) {
const { data, error } = await client.auth.getUser();
try {
const { data, error } = await client.rpc('is_super_admin');
if (error) {
throw error;
}
if (error) {
throw error;
}
if (!data.user) {
return data;
} catch {
return false;
}
const requiresMultiFactorAuthentication =
await checkRequiresMultiFactorAuthentication(client);
// If user requires multi-factor authentication, deny access.
if (requiresMultiFactorAuthentication) {
return false;
}
const appMetadata = data.user.app_metadata;
return appMetadata?.role === 'super-admin';
}