Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

update expo docs #1666

Merged
merged 29 commits into from
Dec 6, 2024
Merged
Show file tree
Hide file tree
Changes from 24 commits
Commits
Show all changes
29 commits
Select commit Hold shift + click to select a range
2810fe2
wip
alexisintech Oct 28, 2024
2608da3
update QS; update email/password custom flow
alexisintech Oct 30, 2024
3774645
update read-session-data
alexisintech Oct 30, 2024
b9f1244
update email pass mfa
alexisintech Oct 30, 2024
8468e58
wip
alexisintech Oct 30, 2024
4e0d5a1
Update docs/custom-flows/oauth-connections.mdx
alexisintech Oct 30, 2024
55ed7a2
Apply suggestions from code review
alexisintech Oct 30, 2024
6f3f8c8
update sidenav; update overview
alexisintech Nov 5, 2024
606d6ab
update styling for mobile
alexisintech Nov 7, 2024
937aa58
add install types step to quickstrt
alexisintech Nov 7, 2024
313fc22
wip
alexisintech Nov 7, 2024
2cad807
finishhh
alexisintech Nov 7, 2024
98eefa6
fix links
alexisintech Nov 7, 2024
45c6925
add signout custom flow example
alexisintech Nov 21, 2024
6b9618b
wip oauth hook
alexisintech Nov 21, 2024
2dfbbb4
add metadata types (#1733)
alexisintech Nov 21, 2024
227e6d5
Merge branch 'main' into aa/DOCS-9323
alexisintech Nov 21, 2024
3255e99
Merge branch 'aa/DOCS-9323' of https://github.com/clerk/clerk-docs in…
alexisintech Nov 21, 2024
48cd09c
finish documenting oauth hook
alexisintech Nov 21, 2024
608a1b6
Update docs/references/expo/overview.mdx
alexisintech Nov 21, 2024
0e62f46
Merge branch 'main' into aa/DOCS-9323
alexisintech Dec 6, 2024
a6bda5d
Update docs/_partials/expo/oauth-custom-flow.mdx
victoriaxyz Dec 6, 2024
9094979
Merge branch 'main' into aa/DOCS-9323
victoriaxyz Dec 6, 2024
0b07323
add clerkprovider partial
victoriaxyz Dec 6, 2024
2a7c482
Update docs/custom-flows/email-password-mfa.mdx
victoriaxyz Dec 6, 2024
7d6cbb2
Apply suggestions from code review
victoriaxyz Dec 6, 2024
c49ab5a
Merge branch 'main' into aa/DOCS-9323
alexisintech Dec 6, 2024
1e618a7
formatting
alexisintech Dec 6, 2024
66176f5
update file path
alexisintech Dec 6, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
58 changes: 58 additions & 0 deletions docs/_partials/expo/oauth-custom-flow.mdx
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
The following example demonstrates how to create a custom OAuth sign-in flow for [Google accounts](/docs/authentication/social-connections/google).

```tsx {{ filename: 'app/(auth)/sign-in.tsx', collapsible: true }}
import React from 'react'
import * as WebBrowser from 'expo-web-browser'
import { Text, View, Button } from 'react-native'
import { Link } from 'expo-router'
import { useOAuth } from '@clerk/clerk-expo'
import * as Linking from 'expo-linking'

export const useWarmUpBrowser = () => {
React.useEffect(() => {
// Warm up the android browser to improve UX
// https://docs.expo.dev/guides/authentication/#improving-user-experience
void WebBrowser.warmUpAsync()
return () => {
void WebBrowser.coolDownAsync()
}
}, [])
}

WebBrowser.maybeCompleteAuthSession()

export default function Page() {
useWarmUpBrowser()

const { startOAuthFlow } = useOAuth({ strategy: 'oauth_google' })

const onPress = React.useCallback(async () => {
try {
const { createdSessionId, signIn, signUp, setActive } = await startOAuthFlow({
redirectUrl: Linking.createURL('/dashboard', { scheme: 'myapp' }),
})

// If sign in was successful, set the active session
if (createdSessionId) {
setActive!({ session: createdSessionId })
} else {
// Use signIn or signUp returned from startOAuthFlow
// for next steps, such as MFA
}
} catch (err) {
// See https://clerk.com/docs/custom-flows/error-handling
// for more info on error handling
console.error(JSON.stringify(err, null, 2))
}
}, [])

return (
<View>
<Link href="/">
<Text>Home</Text>
</Link>
<Button title="Sign in with Google" onPress={onPress} />
</View>
)
}
```
68 changes: 44 additions & 24 deletions docs/custom-flows/email-password-mfa.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ This guide will walk you through how to build a custom email/password sign-in fl

1. In the Clerk Dashboard, navigate to the [**Multi-factor**](https://dashboard.clerk.com/last-active?path=user-authentication/multi-factor) page.
1. For the purpose of this guide, toggle on both the **Authenticator application** and **Backup codes** strategies.
1. Select **Save**.

### Sign-in flow

Expand Down Expand Up @@ -309,19 +310,34 @@ This guide will walk you through how to build a custom email/password sign-in fl

### Build the flow

Create a component that handles the sign-in with multi-factor authentication flow.
1. Create the `(auth)` route group. This will group your sign-up and sign-in pages.
victoriaxyz marked this conversation as resolved.
Show resolved Hide resolved
1. In the `(auth)` group, create a `_layout.tsx` file with the following code. The [`useAuth()`](/docs/references/react/use-auth) hook is used to access the user's authentication state. If the user is already signed in, they will be redirected to the home page.
victoriaxyz marked this conversation as resolved.
Show resolved Hide resolved

> [!NOTE]
> You can render this component in a custom sign-in or sign-up flow, which you can find examples of in [the Expo quickstart](/docs/quickstarts/expo).
```tsx {{ filename: 'app/(auth)/_layout.tsx' }}
import { Redirect, Stack } from 'expo-router'
import { useAuth } from '@clerk/clerk-expo'

```tsx {{ filename: 'SignInMFAForm.tsx', collapsible: true }}
export default function AuthenticatedLayout() {
const { isSignedIn } = useAuth()

if (isSignedIn) {
return <Redirect href={'/'} />
}

return <Stack />
}
```

In the `(auth)` group, create a `sign-in.tsx` file with the following code. The [`useSignIn()`](/docs/references/react/use-sign-in) hook is used to create a sign-in flow. The user can sign in using their email and password and will be prompted to verify their account with a code from their authenticator app or with a backup code.

```tsx {{ filename: 'app/(auth)/sign-in.tsx', collapsible: true }}
import React from 'react'
import { useSignIn } from '@clerk/clerk-expo'
import { useRouter } from 'expo-router'
import { Text, TextInput, TouchableOpacity, View } from 'react-native'
import { Text, TextInput, Button, View } from 'react-native'
import Checkbox from 'expo-checkbox'

export default function SignInMFAForm() {
export default function Page() {
const { signIn, setActive, isLoaded } = useSignIn()

const [email, setEmail] = React.useState('')
Expand All @@ -335,18 +351,24 @@ This guide will walk you through how to build a custom email/password sign-in fl
const handleFirstStage = async () => {
if (!isLoaded) return

// Attempt to sign in using the email and password provided
try {
const attemptFirstFactor = await signIn.create({
identifier: email,
password,
})

// If the sign in was successful, set the session to active
victoriaxyz marked this conversation as resolved.
Show resolved Hide resolved
// and redirect the user
if (attemptFirstFactor.status === 'complete') {
await setActive({ session: attemptFirstFactor.createdSessionId })
router.replace('/dashboard')
router.replace('/')
} else if (attemptFirstFactor.status === 'needs_second_factor') {
// If the sign in requires a second factor, display the TOTP form
victoriaxyz marked this conversation as resolved.
Show resolved Hide resolved
setDisplayTOTP(true)
} else {
// If the sign in failed, check why. User may need to
victoriaxyz marked this conversation as resolved.
Show resolved Hide resolved
// complete further steps.
console.error(JSON.stringify(attemptFirstFactor, null, 2))
}
} catch (err) {
Expand All @@ -356,6 +378,7 @@ This guide will walk you through how to build a custom email/password sign-in fl
}
}

// Handle the submission of the TOTP or backup code
const onPressTOTP = React.useCallback(async () => {
if (!isLoaded) return

Expand All @@ -371,13 +394,13 @@ This guide will walk you through how to build a custom email/password sign-in fl
if (attemptSecondFactor.status === 'complete') {
await setActive({ session: attemptSecondFactor.createdSessionId })

router.replace('/dashboard')
router.replace('/')
} else {
// If the status is not complete, check why. User may need to
// complete further steps.
console.error(JSON.stringify(attemptSecondFactor, null, 2))
}
} catch (err: any) {
} catch (err) {
// See https://clerk.com/docs/custom-flows/error-handling
// for more info on error handling
console.error(JSON.stringify(err, null, 2))
Expand All @@ -390,48 +413,45 @@ This guide will walk you through how to build a custom email/password sign-in fl
<Text>Verify your account</Text>

<View>
<Text>Code</Text>
<TextInput
value={code}
placeholder="OTP or Backup Code"
placeholder="Enter the code"
placeholderTextColor="#666666"
onChangeText={(c) => setCode(c)}
/>
</View>
<View>
<Text>This code is a backup code</Text>
<View style={{ flexDirection: 'row', alignItems: 'center', gap: 5 }}>
<Text>Check if this code is a backup code</Text>
<Checkbox value={useBackupCode} onValueChange={() => setUseBackupCode((prev) => !prev)} />
</View>
<TouchableOpacity onPress={onPressTOTP}>
<Text>Verify</Text>
</TouchableOpacity>
<Button title="Verify" onPress={onPressTOTP} />
</View>
)
}

return (
<View>
<Text>Sign In</Text>
<Text>Sign in</Text>
<View>
<TextInput
value={email}
placeholder="Email..."
placeholderTextColor="#000"
placeholder="Enter email"
placeholderTextColor="#666666"
onChangeText={(email) => setEmail(email)}
/>
</View>

<View>
<TextInput
value={password}
placeholder="Password..."
placeholderTextColor="#000"
placeholder="Enter password"
placeholderTextColor="#666666"
secureTextEntry={true}
onChangeText={(password) => setPassword(password)}
/>
</View>

<TouchableOpacity onPress={handleFirstStage}>
<Text>Sign In</Text>
</TouchableOpacity>
<Button title="Continue" onPress={handleFirstStage} />
</View>
)
}
Expand Down
Loading
Loading