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')