fix: Simplify profile RLS policies to allow insert

Updated migration 003 to properly handle RLS:
- Make username nullable with default
- Drop all existing policies and recreate them
- Add proper INSERT policy with WITH CHECK clause
- Add UPDATE policy with both USING and WITH CHECK

This fixes RLS error blocking profile creation.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
2025-10-29 05:07:18 +03:00
parent c9939ee656
commit 2e33e84c7c
@@ -1,82 +1,48 @@
-- ========================================
-- Fix Profile Creation Issue
-- ========================================
-- Adds INSERT policy and function to handle profile creation
-- Adds INSERT policy and makes username nullable
-- Add INSERT policy for profiles
DROP POLICY IF EXISTS "Users can insert their own profile" ON public.profiles;
CREATE POLICY "Users can insert their own profile"
ON public.profiles FOR INSERT
WITH CHECK (auth.uid() = id);
-- Make username nullable and add default
-- Make username nullable and add default (must be done before policies)
ALTER TABLE public.profiles
ALTER COLUMN username DROP NOT NULL;
ALTER TABLE public.profiles
ALTER COLUMN username SET DEFAULT '';
-- Create function to handle profile upsert
CREATE OR REPLACE FUNCTION public.upsert_profile(
p_user_id UUID,
p_username TEXT DEFAULT '',
p_full_name TEXT DEFAULT '',
p_bio TEXT DEFAULT '',
p_phone_number TEXT DEFAULT '',
p_location TEXT DEFAULT '',
p_website TEXT DEFAULT '',
p_language TEXT DEFAULT 'en',
p_theme TEXT DEFAULT 'dark'
)
RETURNS SETOF public.profiles AS $$
BEGIN
RETURN QUERY
INSERT INTO public.profiles (
id,
username,
full_name,
bio,
phone_number,
location,
website,
language,
theme,
updated_at
)
VALUES (
p_user_id,
p_username,
p_full_name,
p_bio,
p_phone_number,
p_location,
p_website,
p_language,
p_theme,
NOW()
)
ON CONFLICT (id)
DO UPDATE SET
username = COALESCE(NULLIF(EXCLUDED.username, ''), public.profiles.username),
full_name = EXCLUDED.full_name,
bio = EXCLUDED.bio,
phone_number = EXCLUDED.phone_number,
location = EXCLUDED.location,
website = EXCLUDED.website,
language = EXCLUDED.language,
theme = EXCLUDED.theme,
updated_at = NOW()
RETURNING *;
END;
$$ LANGUAGE plpgsql SECURITY DEFINER;
-- Drop ALL existing policies to start fresh
DROP POLICY IF EXISTS "Users can view their own profile" ON public.profiles;
DROP POLICY IF EXISTS "Users can update their own profile" ON public.profiles;
DROP POLICY IF EXISTS "Public profiles are viewable by everyone" ON public.profiles;
DROP POLICY IF EXISTS "Users can insert their own profile" ON public.profiles;
-- Grant execute permission to authenticated users
GRANT EXECUTE ON FUNCTION public.upsert_profile TO authenticated;
-- Recreate policies with proper permissions
-- SELECT: Users can view their own profile
CREATE POLICY "Users can view their own profile"
ON public.profiles FOR SELECT
USING (auth.uid() = id);
-- INSERT: Users can create their own profile only
CREATE POLICY "Users can insert their own profile"
ON public.profiles FOR INSERT
WITH CHECK (auth.uid() = id);
-- UPDATE: Users can update their own profile only
CREATE POLICY "Users can update their own profile"
ON public.profiles FOR UPDATE
USING (auth.uid() = id)
WITH CHECK (auth.uid() = id);
-- PUBLIC SELECT: Allow everyone to view public profile info
CREATE POLICY "Public profiles are viewable by everyone"
ON public.profiles FOR SELECT
USING (true);
-- Success message
DO $$
BEGIN
RAISE NOTICE '========================================';
RAISE NOTICE 'Profile creation fix applied successfully!';
RAISE NOTICE 'Users can now create and update their profiles.';
RAISE NOTICE '========================================';
END $$;