From 5e0671f79ef984c6469db7a99025530beb8bc4d7 Mon Sep 17 00:00:00 2001 From: "gpt-engineer-app[bot]" <159125892+gpt-engineer-app[bot]@users.noreply.github.com> Date: Sat, 11 Oct 2025 23:58:18 +0000 Subject: [PATCH] Refactor: Update auth callback logic --- src/components/auth/AuthModal.tsx | 6 +- src/integrations/supabase/types.ts | 3 + ...6_c25362a6-eed4-4d9d-8edb-f95c80d173b9.sql | 107 ++++++++++++++++++ 3 files changed, 115 insertions(+), 1 deletion(-) create mode 100644 supabase/migrations/20251011235746_c25362a6-eed4-4d9d-8edb-f95c80d173b9.sql diff --git a/src/components/auth/AuthModal.tsx b/src/components/auth/AuthModal.tsx index d7d631db..72d2ef20 100644 --- a/src/components/auth/AuthModal.tsx +++ b/src/components/auth/AuthModal.tsx @@ -225,7 +225,11 @@ export function AuthModal({ open, onOpenChange, defaultTab = 'signin' }: AuthMod const { error } = await supabase.auth.signInWithOAuth({ provider, options: { - redirectTo: `${window.location.origin}/` + redirectTo: `${window.location.origin}/auth/callback`, + // Request additional scopes for avatar access + scopes: provider === 'google' + ? 'email profile' + : 'identify email' } }); if (error) throw error; diff --git a/src/integrations/supabase/types.ts b/src/integrations/supabase/types.ts index d02999c9..d112510c 100644 --- a/src/integrations/supabase/types.ts +++ b/src/integrations/supabase/types.ts @@ -1352,6 +1352,7 @@ export type Database = { home_park_id: string | null id: string location_id: string | null + oauth_provider: string | null park_count: number | null personal_location: string | null preferred_language: string | null @@ -1379,6 +1380,7 @@ export type Database = { home_park_id?: string | null id?: string location_id?: string | null + oauth_provider?: string | null park_count?: number | null personal_location?: string | null preferred_language?: string | null @@ -1406,6 +1408,7 @@ export type Database = { home_park_id?: string | null id?: string location_id?: string | null + oauth_provider?: string | null park_count?: number | null personal_location?: string | null preferred_language?: string | null diff --git a/supabase/migrations/20251011235746_c25362a6-eed4-4d9d-8edb-f95c80d173b9.sql b/supabase/migrations/20251011235746_c25362a6-eed4-4d9d-8edb-f95c80d173b9.sql new file mode 100644 index 00000000..6af31a53 --- /dev/null +++ b/supabase/migrations/20251011235746_c25362a6-eed4-4d9d-8edb-f95c80d173b9.sql @@ -0,0 +1,107 @@ +-- Add oauth_provider column to profiles for tracking +ALTER TABLE public.profiles +ADD COLUMN IF NOT EXISTS oauth_provider TEXT; + +-- Add index for faster lookups +CREATE INDEX IF NOT EXISTS idx_profiles_oauth_provider +ON public.profiles(oauth_provider); + +-- Update handle_new_user function with enhanced OAuth profile creation +CREATE OR REPLACE FUNCTION public.handle_new_user() +RETURNS trigger +LANGUAGE plpgsql +SECURITY DEFINER +SET search_path = public +AS $$ +DECLARE + v_username TEXT; + v_display_name TEXT; + v_email TEXT; + v_provider TEXT; + v_username_attempt INTEGER := 0; + v_max_attempts INTEGER := 10; + v_unique_username TEXT; +BEGIN + -- Extract email and provider + v_email := NEW.email; + v_provider := NEW.raw_app_metadata->>'provider'; + + -- Smart username generation based on provider + IF v_provider = 'google' THEN + -- For Google: try email prefix, then name-based, then UUID fallback + v_username := COALESCE( + -- Email prefix (before @), sanitized + LOWER(REGEXP_REPLACE(split_part(v_email, '@', 1), '[^a-z0-9_]', '_', 'g')), + -- Name-based, sanitized + LOWER(REGEXP_REPLACE(NEW.raw_user_meta_data->>'name', '[^a-z0-9_]', '_', 'g')), + -- UUID fallback + 'user_' || substring(NEW.id::text, 1, 8) + ); + v_display_name := NEW.raw_user_meta_data->>'name'; + + ELSIF v_provider = 'discord' THEN + -- For Discord: use username, then global_name, then UUID fallback + v_username := COALESCE( + LOWER(REGEXP_REPLACE(NEW.raw_user_meta_data->>'username', '[^a-z0-9_]', '_', 'g')), + LOWER(REGEXP_REPLACE(NEW.raw_user_meta_data->>'global_name', '[^a-z0-9_]', '_', 'g')), + 'user_' || substring(NEW.id::text, 1, 8) + ); + v_display_name := COALESCE( + NEW.raw_user_meta_data->>'global_name', + NEW.raw_user_meta_data->>'username' + ); + + ELSE + -- Manual signup or other providers + v_username := COALESCE( + NEW.raw_user_meta_data->>'username', + 'user_' || substring(NEW.id::text, 1, 8) + ); + v_display_name := COALESCE( + NEW.raw_user_meta_data->>'display_name', + NEW.raw_user_meta_data->>'name' + ); + END IF; + + -- Ensure username uniqueness by appending counter if needed + v_unique_username := v_username; + WHILE v_username_attempt < v_max_attempts LOOP + BEGIN + -- Try to insert with current username + INSERT INTO public.profiles ( + user_id, + username, + display_name, + oauth_provider + ) + VALUES ( + NEW.id, + v_unique_username, + v_display_name, + v_provider + ); + + -- If successful, exit loop + EXIT; + + EXCEPTION WHEN unique_violation THEN + -- Username taken, try next variant + v_username_attempt := v_username_attempt + 1; + + IF v_username_attempt < v_max_attempts THEN + v_unique_username := v_username || '_' || v_username_attempt; + ELSE + -- Final fallback to UUID if all attempts fail + v_unique_username := 'user_' || substring(NEW.id::text, 1, 8); + END IF; + END; + END LOOP; + + -- Log the final username for debugging + RAISE NOTICE 'Created profile for user % with username %', NEW.id, v_unique_username; + + RETURN NEW; +END; +$$; + +COMMENT ON FUNCTION public.handle_new_user IS 'Creates user profile on signup with smart username generation for OAuth providers. Avatar processing is handled by frontend.'; \ No newline at end of file