diff --git a/assets/fonts/SpaceMono-Regular.ttf b/assets/fonts/SpaceMono-Regular.ttf old mode 100644 new mode 100755 diff --git a/components/auth/AppleSignIniOS.tsx b/components/auth/AppleSignIniOS.tsx index 55688c8..7dbe563 100644 --- a/components/auth/AppleSignIniOS.tsx +++ b/components/auth/AppleSignIniOS.tsx @@ -30,6 +30,7 @@ const AppleSignInButton = () => { credential.fullName && credential.fullName.givenName && credential.fullName.familyName ? `${credential.fullName.givenName} ${credential.fullName.familyName}` : null; + const { error, data: { user, session }, @@ -41,26 +42,25 @@ const AppleSignInButton = () => { if (!error && session) { if (email) { const data: updateUser = { + id: session?.user.id, + updated_at: new Date(), email, full_name: full_name ?? '', + provider: 'apple', }; - const { error: authUpdateError } = await supabase.auth.updateUser({ - data, - }); - if (authUpdateError) - Alert.alert('Error updating auth info:', authUpdateError.message); - const { error: updateError } = await supabase + const { error: updateError } = await supabase.auth.updateUser({ data }); + if (updateError) Alert.alert('Error updating auth info:', updateError.message); + const { error: updateProfileError } = await supabase .from('profiles') .upsert({ - id: session.user.id, - full_name, - email, - provider: 'apple', + id: session?.user.id ?? '', updated_at: new Date(), - }); - if (updateError) { - console.error('Error updating user metadata:', updateError); - } + email: email ?? '', + full_name: full_name ?? '', + provider: 'apple', + }); + if (updateProfileError) + Alert.alert('Error updating profile:', updateProfileError.message); } } } else { diff --git a/components/auth/Auth.tsx b/components/auth/Auth.tsx index 5708325..b1f5d75 100644 --- a/components/auth/Auth.tsx +++ b/components/auth/Auth.tsx @@ -58,24 +58,15 @@ const Auth = () => { } = await supabase.auth.signUp({ email, password, + options: { + data: { + full_name, + provider: 'email', + } + } }); if (error) Alert.alert(error.message); else if (!session) Alert.alert('Please check your inbox for email verification!'); - else { - const { error: updateProfileError } = await supabase - .from('profiles') - .upsert({ - id: session.user.id, - full_name, - email, - provider: 'email', - updated_at: new Date(), - }); - if (updateProfileError) { - Alert.alert('Error updating profile:', updateProfileError.message); - console.error('Error updating profile:', updateProfileError.message); - } - } setLoading(false); }; diff --git a/components/auth/AzureSignIn.tsx b/components/auth/AzureSignIn.tsx index e1d8d19..c245a67 100644 --- a/components/auth/AzureSignIn.tsx +++ b/components/auth/AzureSignIn.tsx @@ -28,7 +28,7 @@ const AzureSignIn = () => { const signInWithAzure = async () => { try { setLoading(true); - + // Create the MSAL auth request const request = new AuthSession.AuthRequest({ clientId: clientId!, @@ -38,17 +38,12 @@ const AzureSignIn = () => { responseType: AuthSession.ResponseType.Code, }); - // Generate the auth URL with PKCE + // Generate the auth URL with PKCE & open in browser const authUrl = await request.makeAuthUrlAsync(discovery); - console.log('Generated auth URL:', authUrl); - - // Open the auth URL in a browser const result = await WebBrowser.openAuthSessionAsync(authUrl, redirectUri, { showInRecents: true, }); - console.log('Auth session result type:', result.type); - if (result.type === 'success' && result.url) { // Parse the URL to get the authorization code const { params, errorCode } = QueryParams.getQueryParams(result.url); @@ -57,13 +52,10 @@ const AzureSignIn = () => { const errorMessage = params.error_description || params.error || errorCode; throw new Error(`Error during authentication: ${errorMessage}`); } - if (!params.code) { throw new Error('No authorization code received'); } - console.log('Authorization code received'); - // Exchange the code for tokens const tokenResult = await AuthSession.exchangeCodeAsync( { @@ -76,9 +68,6 @@ const AzureSignIn = () => { }, discovery, ); - - console.log('Token exchange successful'); - if (!tokenResult.idToken) { throw new Error('No ID token received'); } @@ -88,40 +77,38 @@ const AzureSignIn = () => { provider: 'azure', token: tokenResult.idToken, }); + console.log(JSON.stringify({ data, error }, null, 2)); - // Check if profies table already has info (User is signing in, not signing up) - const { data: profileData, error: profileError } = await supabase + const { data: profile, error: profileError } = await supabase .from('profiles') .select('*') .eq('id', data.user?.id) .single(); - if (profileData.email === '' || !profileData.email && data.session?.user.email) { - const updateData: updateUser = { - email: data.session?.user.email ?? '', - }; - const { error: updateAuthError } = await supabase.auth.updateUser({ - data: updateData, - }); - if (updateAuthError) - Alert.alert('Error updating auth info:', updateAuthError.message); + if (profileError) { + console.error('Supabase profile error:', profileError); + throw profileError; + } + console.log(JSON.stringify({ profile, error: profileError }, null, 2)); + + if (profile?.provider !== 'azure') { const { error: updateProfileError } = await supabase - .from('profiles') - .upsert({ - id: data.session?.user.id ?? '', - email: data.session?.user.email ?? '', - provider: 'azure', - updated_at: new Date(), - }); - if (updateProfileError) + .from('profiles') + .upsert({ + id: data.session?.user.id ?? '', + provider: 'azure', + updated_at: new Date(), + }); + if (updateProfileError) { + console.error('Supabase profile error:', updateProfileError); Alert.alert('Error updating profile:', updateProfileError.message); + } } if (error) { console.error('Supabase sign-in error:', error); throw error; } - console.log('Successfully signed in with Azure via Supabase'); return data; } else { diff --git a/scripts/files_to_clipboard b/scripts/files_to_clipboard old mode 100644 new mode 100755 diff --git a/scripts/supabase_schema.sql b/scripts/supabase_schema.sql new file mode 100644 index 0000000..74ada70 --- /dev/null +++ b/scripts/supabase_schema.sql @@ -0,0 +1,59 @@ +-- Create a table for public profiles +create table profiles ( + id uuid references auth.users on delete cascade not null primary key, + updated_at timestamp with time zone, + email text, + full_name text, + avatar_url text, + provider text, + + constraint full_name_length check (char_length(full_name) >= 3 and char_length(full_name) <= 50), +); +-- Set up Row Level Security (RLS) +-- See https://supabase.com/docs/guides/auth/row-level-security for more details. +alter table profiles + enable row level security; + +create policy "Public profiles are viewable by everyone." on profiles + for select using (true); + +create policy "Users can insert their own profile." on profiles + for insert with check ((select auth.uid()) = id); + +create policy "Users can update own profile." on profiles + for update using ((select auth.uid()) = id); + +-- This trigger automatically creates a profile entry when a new user signs up via Supabase Auth. +-- See https://supabase.com/docs/guides/auth/managing-user-data#using-triggers for more details. +create function public.handle_new_user() +returns trigger +set search_path = '' +as $$ +begin + insert into public.profiles (id, email, full_name, avatar_url, provider, updated_at) + values ( + new.id, + new.email, + new.raw_user_meta_data->>'full_name', + new.raw_user_meta_data->>'avatar_url' + new.raw_user_meta_data->>'provider', + now() + ); + return new; +end; +$$ language plpgsql security definer; +create trigger on_auth_user_created + after insert on auth.users + for each row execute procedure public.handle_new_user(); + +-- Set up Storage! +insert into storage.buckets (id, name) + values ('avatars', 'avatars'); + +-- Set up access controls for storage. +-- See https://supabase.com/docs/guides/storage#policy-examples for more details. +create policy "Avatar images are publicly accessible." on storage.objects + for select using (bucket_id = 'avatars'); + +create policy "Anyone can upload an avatar." on storage.objects + for insert with check (bucket_id = 'avatars');