From 046e8d749c47ea439fbe25cb3f2d96c075927a8a Mon Sep 17 00:00:00 2001 From: gbuomprisco Date: Mon, 7 Oct 2024 17:31:10 +0200 Subject: [PATCH] Added RLS to delete a team account; converted --- .../20241007151024_delete-team-account.sql | 7 +++ ...counts.test.sql => team-accounts.test.sql} | 28 ++++++++++++ .../delete-team-account-server-actions.ts | 43 ++++++++++--------- 3 files changed, 57 insertions(+), 21 deletions(-) create mode 100644 apps/web/supabase/migrations/20241007151024_delete-team-account.sql rename apps/web/supabase/tests/database/{create-team-accounts.test.sql => team-accounts.test.sql} (77%) diff --git a/apps/web/supabase/migrations/20241007151024_delete-team-account.sql b/apps/web/supabase/migrations/20241007151024_delete-team-account.sql new file mode 100644 index 000000000..a510115fc --- /dev/null +++ b/apps/web/supabase/migrations/20241007151024_delete-team-account.sql @@ -0,0 +1,7 @@ +create policy delete_team_account + on public.accounts + for delete + to authenticated + using ( + auth.uid() = primary_owner_user_id + ); \ No newline at end of file diff --git a/apps/web/supabase/tests/database/create-team-accounts.test.sql b/apps/web/supabase/tests/database/team-accounts.test.sql similarity index 77% rename from apps/web/supabase/tests/database/create-team-accounts.test.sql rename to apps/web/supabase/tests/database/team-accounts.test.sql index 9f7d1cb12..16fba4456 100644 --- a/apps/web/supabase/tests/database/create-team-accounts.test.sql +++ b/apps/web/supabase/tests/database/team-accounts.test.sql @@ -118,6 +118,34 @@ select $$ select public.create_team_account('Test2') $$, 'User can only own 1 account'); +-- Test Delete Team Account +select + tests.authenticate_as('test2'); + +-- deletion don't throw an error +select lives_ok( + $$ delete from public.accounts where id = (select id from makerkit.get_account_by_slug('test')) $$, + 'permission denied for function delete_team_account' +); + +select tests.authenticate_as('test1'); + +select isnt_empty( + $$ select * from public.accounts where id = (select id from makerkit.get_account_by_slug('test')) $$, + 'The account should still exist' +); + +-- delete as primary owner +select lives_ok( + $$ delete from public.accounts where id = (select id from makerkit.get_account_by_slug('test')) $$, + 'The primary owner should be able to delete the team account' +); + +select is_empty( + $$ select * from public.accounts where id = (select id from makerkit.get_account_by_slug('test')) $$, + 'The account should be deleted' +); + select * from diff --git a/packages/features/team-accounts/src/server/actions/delete-team-account-server-actions.ts b/packages/features/team-accounts/src/server/actions/delete-team-account-server-actions.ts index 6165d4458..93d44f2d8 100644 --- a/packages/features/team-accounts/src/server/actions/delete-team-account-server-actions.ts +++ b/packages/features/team-accounts/src/server/actions/delete-team-account-server-actions.ts @@ -2,8 +2,10 @@ import { redirect } from 'next/navigation'; +import type { SupabaseClient } from '@supabase/supabase-js'; + import { enhanceAction } from '@kit/next/actions'; -import { getSupabaseServerAdminClient } from '@kit/supabase/server-admin-client'; +import type { Database } from '@kit/supabase/database'; import { getSupabaseServerClient } from '@kit/supabase/server-client'; import { DeleteTeamAccountSchema } from '../../schema/delete-team-account.schema'; @@ -15,25 +17,9 @@ export const deleteTeamAccountAction = enhanceAction( Object.fromEntries(formData.entries()), ); - const userId = user.id; - const accountId = params.accountId; - - // Check if the user has the necessary permissions to delete the team account - await assertUserPermissionsToDeleteTeamAccount({ - accountId, - userId, - }); - - // Get the Supabase client and create a new service instance. - const service = createDeleteTeamAccountService(); - - // Get the Supabase admin client. - const adminClient = getSupabaseServerAdminClient(); - - // Delete the team account and all associated data. - await service.deleteTeamAccount(adminClient, { - accountId, - userId, + await deleteTeamAccount({ + accountId: params.accountId, + userId: user.id, }); return redirect('/home'); @@ -41,12 +27,27 @@ export const deleteTeamAccountAction = enhanceAction( {}, ); -async function assertUserPermissionsToDeleteTeamAccount(params: { +async function deleteTeamAccount(params: { accountId: string; userId: string; }) { const client = getSupabaseServerClient(); + const service = createDeleteTeamAccountService(); + // verify that the user has the necessary permissions to delete the team account + await assertUserPermissionsToDeleteTeamAccount(client, params); + + // delete the team account + await service.deleteTeamAccount(client, params); +} + +async function assertUserPermissionsToDeleteTeamAccount( + client: SupabaseClient, + params: { + accountId: string; + userId: string; + }, +) { const { data, error } = await client .from('accounts') .select('id')