mirror of
https://github.com/pezkuwichain/pwap.git
synced 2026-04-22 21:47:56 +00:00
c48ded7ff2
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.
98 lines
2.9 KiB
PL/PgSQL
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 $$;
|