Add Sign in with Apple sorta

This commit is contained in:
Gabriel Brown 2025-03-05 12:58:41 -06:00
parent c62926b8f2
commit 708c0553f5
4 changed files with 29 additions and 37 deletions

View File

@ -27,7 +27,7 @@ const AppleSignIn: React.FC<AppleSignInProps> = ({
const handleAppleSignIn = async () => {
try {
onSignInStart?.();
// Get credentials from Apple
const credential = await AppleAuthentication.signInAsync({
requestedScopes: [
@ -35,36 +35,36 @@ const AppleSignIn: React.FC<AppleSignInProps> = ({
AppleAuthentication.AppleAuthenticationScope.EMAIL,
],
});
if (!credential.email) {
throw new Error('Email is required for Apple Sign In');
}
// Extract user information
const { email, fullName, user: appleUserId } = credential;
// Create a name from the fullName object if available
let name = null;
if (fullName?.givenName || fullName?.familyName) {
name = `${fullName?.givenName || ''} ${fullName?.familyName || ''}`.trim();
}
// Create a deterministic password based on the Apple user ID
// This way the user can sign in again with the same password
const password = `Apple-${appleUserId.substring(0, 16)}`;
// First try to sign in (in case the user already exists)
const { data: signInData, error: signInError } = await supabase.auth.signInWithPassword({
email,
password,
});
if (!signInError && signInData?.user) {
// User exists and signed in successfully
onSignInComplete?.();
return;
}
// If sign-in failed, create a new user
const { data: signUpData, error: signUpError } = await supabase.auth.signUp({
email,
@ -72,26 +72,25 @@ const AppleSignIn: React.FC<AppleSignInProps> = ({
options: {
data: {
full_name: name,
}
}
},
},
});
if (signUpError) {
throw signUpError;
}
// User created successfully
onSignInComplete?.();
} catch (error) {
console.error('Apple sign in error:', error);
if (error.code === 'ERR_REQUEST_CANCELED') {
console.log('Sign in was canceled');
} else {
Alert.alert(
'Sign in error',
'An error occurred while signing in with Apple. Please try again.'
'An error occurred while signing in with Apple. Please try again.',
);
onSignInError?.(error);
}

View File

@ -22,7 +22,7 @@ const LoginPage = () => {
const [email, setEmail] = useState('');
const [password, setPassword] = useState('');
const [loading, setLoading] = useState(false);
// Set up auto-refreshing for web
useEffect(() => {
if (Platform.OS === 'web') {
@ -32,7 +32,7 @@ const LoginPage = () => {
};
}
}, []);
const signInWithEmail = async () => {
setLoading(true);
const { error } = await supabase.auth.signInWithPassword({
@ -42,7 +42,7 @@ const LoginPage = () => {
if (error) Alert.alert(error.message);
setLoading(false);
};
const signUpWithEmail = async () => {
setLoading(true);
const {
@ -56,7 +56,7 @@ const LoginPage = () => {
else if (!session) Alert.alert('Please check your inbox for email verification!');
setLoading(false);
};
return (
<ThemedView style={styles.container}>
<ThemedView style={styles.titleContainer}>
@ -65,7 +65,7 @@ const LoginPage = () => {
Tech Tracker
</ThemedText>
</ThemedView>
<ThemedView style={[styles.verticallySpaced]}>
<ThemedTextInput
fontSize={24}
@ -74,7 +74,7 @@ const LoginPage = () => {
placeholder='email@address.com'
/>
</ThemedView>
<ThemedView style={styles.verticallySpaced}>
<ThemedTextInput
fontSize={24}
@ -84,7 +84,7 @@ const LoginPage = () => {
placeholder='Password'
/>
</ThemedView>
<ThemedView style={[styles.verticallySpaced, styles.mt20]}>
<ThemedTextButton
text='Sign in'
@ -93,7 +93,7 @@ const LoginPage = () => {
fontSize={24}
/>
</ThemedView>
<ThemedView style={styles.verticallySpaced}>
<ThemedTextButton
text='Sign up'
@ -102,10 +102,10 @@ const LoginPage = () => {
fontSize={24}
/>
</ThemedView>
{/* Apple Sign In - Only shows on iOS */}
<ThemedView style={[styles.verticallySpaced, styles.mt20]}>
<AppleSignIn
<AppleSignIn
onSignInStart={() => setLoading(true)}
onSignInComplete={() => setLoading(false)}
onSignInError={() => setLoading(false)}

View File

@ -31,8 +31,9 @@ const ThemedTextInput: React.FC<ThemedTextInputProps> = ({
{
width,
height,
borderColor: Colors[scheme].accent },
containerStyle,
borderColor: Colors[scheme].accent,
},
containerStyle,
]}
>
<TextInput

View File

@ -28,18 +28,10 @@ const config = {
teamId: process.env.APPLE_TEAM_ID || '',
clientId: process.env.AUTH_APPLE_ID || '',
keyId: process.env.APPLE_KEY_ID || '',
privateKeyPath: path.resolve(
__dirname,
process.env.APPLE_PRIVATE_KEY_PATH || '',
),
privateKeyPath: path.resolve(__dirname, process.env.APPLE_PRIVATE_KEY_PATH || ''),
};
if (
!config.teamId ||
!config.clientId ||
!config.keyId ||
!config.privateKeyPath
) {
if (!config.teamId || !config.clientId || !config.keyId || !config.privateKeyPath) {
console.error('Missing necessary Apple configuration');
process.exit(1);
}