Files
pwap/web/supabase/migrations/004_create_upsert_function.sql
T
Claude 24be8d4411 Reorganize repository into monorepo structure
Restructured the project to support multiple frontend applications:
- Move web app to web/ directory
- Create pezkuwi-sdk-ui/ for Polkadot SDK clone (planned)
- Create mobile/ directory for mobile app development
- Add shared/ directory with common utilities, types, and blockchain code
- Update README.md with comprehensive documentation
- Remove obsolete DKSweb/ directory

This monorepo structure enables better code sharing and organized
development across web, mobile, and SDK UI projects.
2025-11-14 00:46:35 +00:00

98 lines
2.9 KiB
PL/PgSQL

-- ========================================
-- Create Secure Upsert Function for Profiles
-- ========================================
-- Uses SECURITY DEFINER to bypass RLS for authenticated users
-- First, ensure username is nullable
ALTER TABLE public.profiles
ALTER COLUMN username DROP NOT NULL;
ALTER TABLE public.profiles
ALTER COLUMN username SET DEFAULT '';
-- Create secure upsert function
CREATE OR REPLACE FUNCTION public.upsert_user_profile(
p_username TEXT DEFAULT '',
p_full_name TEXT DEFAULT NULL,
p_bio TEXT DEFAULT NULL,
p_phone_number TEXT DEFAULT NULL,
p_location TEXT DEFAULT NULL,
p_website TEXT DEFAULT NULL,
p_language TEXT DEFAULT 'en',
p_theme TEXT DEFAULT 'dark',
p_notifications_email BOOLEAN DEFAULT true,
p_notifications_push BOOLEAN DEFAULT false,
p_notifications_sms BOOLEAN DEFAULT false
)
RETURNS public.profiles AS $$
DECLARE
result public.profiles;
BEGIN
-- Use auth.uid() to ensure user can only upsert their own profile
INSERT INTO public.profiles (
id,
username,
full_name,
bio,
phone_number,
location,
website,
language,
theme,
notifications_email,
notifications_push,
notifications_sms,
updated_at
)
VALUES (
auth.uid(),
p_username,
p_full_name,
p_bio,
p_phone_number,
p_location,
p_website,
p_language,
p_theme,
p_notifications_email,
p_notifications_push,
p_notifications_sms,
NOW()
)
ON CONFLICT (id)
DO UPDATE SET
username = COALESCE(NULLIF(EXCLUDED.username, ''), profiles.username, ''),
full_name = COALESCE(EXCLUDED.full_name, profiles.full_name),
bio = COALESCE(EXCLUDED.bio, profiles.bio),
phone_number = COALESCE(EXCLUDED.phone_number, profiles.phone_number),
location = COALESCE(EXCLUDED.location, profiles.location),
website = COALESCE(EXCLUDED.website, profiles.website),
language = COALESCE(EXCLUDED.language, profiles.language),
theme = COALESCE(EXCLUDED.theme, profiles.theme),
notifications_email = COALESCE(EXCLUDED.notifications_email, profiles.notifications_email),
notifications_push = COALESCE(EXCLUDED.notifications_push, profiles.notifications_push),
notifications_sms = COALESCE(EXCLUDED.notifications_sms, profiles.notifications_sms),
updated_at = NOW()
RETURNING *
INTO result;
RETURN result;
END;
$$ LANGUAGE plpgsql SECURITY DEFINER;
-- Grant execute permission to authenticated users only
GRANT EXECUTE ON FUNCTION public.upsert_user_profile TO authenticated;
-- Revoke from public for security
REVOKE EXECUTE ON FUNCTION public.upsert_user_profile FROM PUBLIC;
-- Success message
DO $$
BEGIN
RAISE NOTICE '========================================';
RAISE NOTICE 'Profile upsert function created successfully!';
RAISE NOTICE 'Function: upsert_user_profile()';
RAISE NOTICE 'This bypasses RLS using SECURITY DEFINER';
RAISE NOTICE '========================================';
END $$;