From 50273ed620c31cf4ff9f9c2d5ceed2643c41afba Mon Sep 17 00:00:00 2001 From: "gpt-engineer-app[bot]" <159125892+gpt-engineer-app[bot]@users.noreply.github.com> Date: Wed, 1 Oct 2025 16:09:32 +0000 Subject: [PATCH] Implement PostgreSQL function to cancel email change --- src/integrations/supabase/types.ts | 4 ++ .../functions/cancel-email-change/index.ts | 45 +++---------------- ...8_95431631-c4fa-471a-9c1f-7684bdf416d0.sql | 22 +++++++++ 3 files changed, 33 insertions(+), 38 deletions(-) create mode 100644 supabase/migrations/20251001160858_95431631-c4fa-471a-9c1f-7684bdf416d0.sql diff --git a/src/integrations/supabase/types.ts b/src/integrations/supabase/types.ts index 6c7d1730..aad62580 100644 --- a/src/integrations/supabase/types.ts +++ b/src/integrations/supabase/types.ts @@ -1318,6 +1318,10 @@ export type Database = { Args: { _profile_user_id: string; _viewer_id: string } Returns: boolean } + cancel_user_email_change: { + Args: { _user_id: string } + Returns: boolean + } get_filtered_profile: { Args: { _profile_user_id: string; _viewer_id?: string } Returns: Json diff --git a/supabase/functions/cancel-email-change/index.ts b/supabase/functions/cancel-email-change/index.ts index a6d891ff..067258e0 100644 --- a/supabase/functions/cancel-email-change/index.ts +++ b/supabase/functions/cancel-email-change/index.ts @@ -42,45 +42,14 @@ Deno.serve(async (req) => { newEmail: user.new_email }); - // Direct database manipulation to clear email change fields - // Use service role to directly query and update auth.users table - const { error: sqlError } = await supabaseAdmin - .from('auth.users') - .update({ - email_change: null, - email_change_sent_at: null, - email_change_confirm_status: 0, - email_change_token_current: null, - email_change_token_new: null - }) - .eq('id', user.id); + // Call the database function to clear email change fields + // This function has SECURITY DEFINER privileges to access auth.users + const { data: cancelled, error: cancelError } = await supabaseAdmin + .rpc('cancel_user_email_change', { _user_id: user.id }); - if (sqlError) { - console.error('Error clearing email change fields via SQL:', sqlError); - - // Fallback: Try using the two-step email update trick - console.log('Attempting fallback method with temporary email...'); - try { - const tempEmail = `temp_${Date.now()}_${user.email}`; - const { error: tempError } = await supabaseAdmin.auth.admin.updateUserById( - user.id, - { email: tempEmail, email_confirm: true } - ); - - if (tempError) throw tempError; - - const { error: revertError } = await supabaseAdmin.auth.admin.updateUserById( - user.id, - { email: user.email, email_confirm: true } - ); - - if (revertError) throw revertError; - - console.log('Fallback method succeeded'); - } catch (fallbackError) { - console.error('Fallback method also failed:', fallbackError); - throw new Error('Unable to cancel email change: ' + fallbackError.message); - } + if (cancelError || !cancelled) { + console.error('Error cancelling email change:', cancelError); + throw new Error('Unable to cancel email change: ' + (cancelError?.message || 'Unknown error')); } // Verify the change was successful by getting the updated user diff --git a/supabase/migrations/20251001160858_95431631-c4fa-471a-9c1f-7684bdf416d0.sql b/supabase/migrations/20251001160858_95431631-c4fa-471a-9c1f-7684bdf416d0.sql new file mode 100644 index 00000000..48706564 --- /dev/null +++ b/supabase/migrations/20251001160858_95431631-c4fa-471a-9c1f-7684bdf416d0.sql @@ -0,0 +1,22 @@ +-- Create a function to cancel pending email changes +-- This function runs with SECURITY DEFINER privileges to access auth.users table +CREATE OR REPLACE FUNCTION public.cancel_user_email_change(_user_id UUID) +RETURNS BOOLEAN +LANGUAGE plpgsql +SECURITY DEFINER +SET search_path = auth, public +AS $$ +BEGIN + -- Clear all email change related fields in auth.users + UPDATE auth.users + SET + email_change = NULL, + email_change_sent_at = NULL, + email_change_confirm_status = 0, + email_change_token_current = NULL, + email_change_token_new = NULL + WHERE id = _user_id; + + RETURN FOUND; +END; +$$; \ No newline at end of file