diff --git a/supabase/migrations/20250907000001_update_keycloak_user_creation.sql b/supabase/migrations/20250907000001_update_keycloak_user_creation.sql new file mode 100644 index 0000000..ccc7834 --- /dev/null +++ b/supabase/migrations/20250907000001_update_keycloak_user_creation.sql @@ -0,0 +1,94 @@ +-- Update the user creation trigger to properly handle Keycloak user metadata +CREATE OR REPLACE FUNCTION kit.setup_new_user() +RETURNS trigger +LANGUAGE plpgsql +SECURITY DEFINER +SET search_path TO '' +AS $$ +DECLARE + user_name text; + picture_url text; + personal_code text; + full_name text; + given_name text; + family_name text; + preferred_username text; +BEGIN + -- Extract data from Keycloak user metadata + -- Check raw_user_meta_data first (this is where Keycloak data is stored) + IF new.raw_user_meta_data IS NOT NULL THEN + -- Try full_name first, then name field + full_name := new.raw_user_meta_data ->> 'full_name'; + IF full_name IS NULL THEN + full_name := new.raw_user_meta_data ->> 'name'; + END IF; + + -- Extract individual name components + given_name := new.raw_user_meta_data -> 'custom_claims' ->> 'given_name'; + family_name := new.raw_user_meta_data -> 'custom_claims' ->> 'family_name'; + preferred_username := new.raw_user_meta_data -> 'custom_claims' ->> 'preferred_username'; + + -- Use given_name (first name) for the name field + IF given_name IS NOT NULL THEN + user_name := given_name; + ELSIF full_name IS NOT NULL THEN + user_name := full_name; + ELSIF preferred_username IS NOT NULL THEN + user_name := preferred_username; + END IF; + + -- Extract personal code from preferred_username (Keycloak provides Estonian personal codes here) + IF preferred_username IS NOT NULL THEN + personal_code := preferred_username; + END IF; + + -- Also try personalCode field as fallback + IF personal_code IS NULL THEN + personal_code := new.raw_user_meta_data ->> 'personalCode'; + END IF; + END IF; + + -- Fall back to email if no name found + IF user_name IS NULL AND new.email IS NOT NULL THEN + user_name := split_part(new.email, '@', 1); + END IF; + + -- Default empty string if still no name + IF user_name IS NULL THEN + user_name := ''; + END IF; + + -- Extract picture URL + IF new.raw_user_meta_data ->> 'avatar_url' IS NOT NULL THEN + picture_url := new.raw_user_meta_data ->> 'avatar_url'; + ELSE + picture_url := null; + END IF; + + -- Insert into medreport.accounts + INSERT INTO medreport.accounts ( + id, + primary_owner_user_id, + name, + last_name, + is_personal_account, + picture_url, + email, + personal_code, + application_role + ) + VALUES ( + new.id, + new.id, + user_name, + family_name, + true, + picture_url, + NULL, -- Keycloak email !== customer personal email, they will set this later + personal_code, + 'user' -- Default role for new users + ); + + RETURN new; +END; +$$;