Skip to content

Commit

Permalink
docs review
Browse files Browse the repository at this point in the history
  • Loading branch information
alexisintech committed Jan 30, 2025
1 parent d4c8941 commit 0a5b335
Show file tree
Hide file tree
Showing 9 changed files with 186 additions and 129 deletions.
58 changes: 0 additions & 58 deletions docs/_partials/expo/deprecated-oauth-custom-flow.mdx

This file was deleted.

28 changes: 19 additions & 9 deletions docs/_partials/expo/enterprise-sso-custom-flow.mdx
Original file line number Diff line number Diff line change
@@ -1,11 +1,12 @@
The following example demonstrates how to create a custom SSO flow with [SAML](docs/authentication/enterprise-connections/overview#saml).
Expo supports SAML Enterprise SSO, but does not support EASIE or OIDC.

The following example demonstrates how to create a custom SSO flow with [SAML](docs/authentication/enterprise-connections/overview#saml). In the following example, when the user selects the "Sign in with SAML" button, they will be redirected to the provider's authentication page. Once they authenticate, they will be redirected back to your app. If there are missing requirements, like they need to complete MFA, then the `createdSessionId` will remain `null`, and you'll need to add logic to handle the missing requirements. If there are no missing requirements, then the user will be signed in.

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

export const useWarmUpBrowser = () => {
useEffect(() => {
Expand All @@ -25,22 +26,25 @@ WebBrowser.maybeCompleteAuthSession()
export default function Page() {
useWarmUpBrowser()

const [email, setEmail] = useState('')

const { startSSOFlow } = useSSO()

const onPress = useCallback(async () => {
try {
const { createdSessionId, setActive, signIn, signUp } = await startSSOFlow({
strategy: 'enterprise_sso',
// This identifier would likely be derived from a text input
identifier: '[email protected]',
identifier: email,
})

// If sign in was successful, set the active session
if (createdSessionId) {
setActive!({ session: createdSessionId })
} else {
// Use `signIn` or `signUp` returned from `startSSOFlow`
// for next steps, such as MFA
// If there is no `createdSessionId`,
// there are missing requirements, such as MFA
// Use the `signIn` or `signUp` returned from `startSSOFlow`
// to handle next steps
}
} catch (err) {
// See https://clerk.com/docs/custom-flows/error-handling
Expand All @@ -51,7 +55,13 @@ export default function Page() {

return (
<View>
<Button title="Sign in with SSO" onPress={onPress} />
<TextInput
value={email}
onChangeText={setEmail}
placeholder="Enter email"
placeholderTextColor="#666666"
/>
<Button title="Sign in with SAML" onPress={onPress} />
</View>
)
}
Expand Down
11 changes: 7 additions & 4 deletions docs/_partials/expo/oauth-custom-flow.mdx
Original file line number Diff line number Diff line change
@@ -1,9 +1,8 @@
The following example demonstrates how to create a custom SSO flow for [Google OAuth](/docs/authentication/social-connections/google).
The following example demonstrates how to create a custom SSO flow for [Google OAuth](/docs/authentication/social-connections/google). In the following example, when the user selects the "Sign in with Google" button, they will be redirected to the Google authentication page. Once they authenticate, they will be redirected back to your app. If there are missing requirements, like they need to complete MFA, then the `createdSessionId` will remain `null`, and you'll need to add logic to handle the missing requirements. If there are no missing requirements, then the user will be signed in.

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

Expand All @@ -25,10 +24,12 @@ WebBrowser.maybeCompleteAuthSession()
export default function Page() {
useWarmUpBrowser()

// Use the `useSSO()` hook to access the `startSSOFlow()` method
const { startSSOFlow } = useSSO()

const onPress = useCallback(async () => {
try {
// Start the OAuth process by calling `startSSOFlow()`
const { createdSessionId, setActive, signIn, signUp } = await startSSOFlow({
strategy: 'oauth_google',
})
Expand All @@ -37,8 +38,10 @@ export default function Page() {
if (createdSessionId) {
setActive!({ session: createdSessionId })
} else {
// Use `signIn` or `signUp` returned from `startSSOFlow`
// for next steps, such as MFA
// If there is no `createdSessionId`,
// there are missing requirements, such as MFA
// Use the `signIn` or `signUp` returned from `startSSOFlow`
// to handle next steps
}
} catch (err) {
// See https://clerk.com/docs/custom-flows/error-handling
Expand Down
36 changes: 22 additions & 14 deletions docs/custom-flows/enterprise-connections.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -11,8 +11,9 @@ You must configure your application instance through the Clerk Dashboard for the

## Create the sign-up and sign-in flow

When using Enterprise SSO, the sign-in and sign-up flows are equivalent. A successful Enterprise SSO flow consists of the following steps:
When using Enterprise SSO, **the sign-up and sign-in flows are equivalent.** A successful Enterprise SSO authentication flow consists of the following steps:

1. Access the [`SignIn`](/docs/references/javascript/sign-in/sign-in) or [`SignUp`](/docs/references/javascript/sign-up/sign-up) object using the [`useSignIn()`](/docs/references/react/use-sign-in) or [`useSignUp()`](/docs/references/react/use-sign-up) hook, respectively.
1. Start the Enterprise SSO flow by calling [`SignIn.authenticateWithRedirect(params)`][sign-in-redirect] or [`SignUp.authenticateWithRedirect(params)`][sign-up-redirect]. Both of these methods require a `redirectUrl` param, which is the URL that the browser will be redirected to once the user authenticates with the identity provider.
1. Create a route at the URL that the `redirectUrl` param points to. The following example names this route `/sso-callback`. This route should either call the [`Clerk.handleRedirectCallback()`](/docs/references/javascript/clerk/handle-navigation#handle-redirect-callback) method or render the prebuilt [`<AuthenticateWithRedirectCallback/>`](/docs/components/control/authenticate-with-callback) component.

Expand All @@ -21,52 +22,53 @@ The following example shows two files:
1. The sign-in page where the user can start the Enterprise SSO flow.
1. The SSO callback page where the flow is completed.

<Tabs items={["Next.js"]}>
<Tabs items={["Next.js", "Expo"]}>
<Tab>
<CodeBlockTabs options={["Sign in page", "SSO callback page"]}>
```tsx {{ filename: 'app/sign-in/page.tsx' }}
'use client'

import * as React from 'react'
import { useSignIn, useSignUp } from '@clerk/nextjs'
import { useSignIn } from '@clerk/nextjs'

export default function Page() {
const { signIn } = useSignIn()
const { signUp } = useSignUp()

if (!signIn || !signUp) return null
const { signIn, isLoaded } = useSignIn()

const signInWithEnterpriseSSO = (e: React.FormEvent) => {
const signInWithEnterpriseSSO = async (e: React.FormEvent) => {
e.preventDefault()

if (!isLoaded) return null

const email = (e.target as HTMLFormElement).email.value

signIn
await signIn
.authenticateWithRedirect({
identifier: email,
strategy: 'enterprise_sso',
redirectUrl: '/sign-up/sso-callback',
redirectUrl: '/sign-in/sso-callback',
redirectUrlComplete: '/',
})
.then((res) => {
console.log(res)
})
.catch((err: any) => {
// See https://clerk.com/docs/custom-flows/error-handling
// for more info on error handling
console.log(err.errors)
console.error(err, null, 2)
})
}

return (
<form onSubmit={(e) => signInWithEnterpriseSSO(e)}>
<input type="email" name="email" placeholder="Enter email address" />
<input id="email" type="email" name="email" placeholder="Enter email address" />
<button>Sign in with Enterprise SSO</button>
</form>
)
}
```

```jsx {{ filename: 'app/sign-up/sso-callback/page.tsx' }}
```jsx {{ filename: 'app/sign-in/sso-callback/page.tsx' }}
import { AuthenticateWithRedirectCallback } from '@clerk/nextjs'

export default function Page() {
Expand All @@ -78,10 +80,16 @@ The following example shows two files:
```
</CodeBlockTabs>
</Tab>

<Tab>
<Include src="_partials/expo/enterprise-sso-custom-flow" />
</Tab>
</Tabs>

## Enterprise account transfer flows

{/* TODO(Laura): I believe this is built in with Expo's `useSSO()` hook, so I don't think we need to add Expo example here. Is this correct? */}

It is common for users who are authenticating with an enterprise account to use a sign-in button when they mean to sign-up, and vice versa. For those cases, the `SignIn` and `SignUp` objects have a `transferable` status that indicates whether the user can be transferred to the other flow.

**If you would like to keep your sign-in and sign-up flows completely separate, then you can skip this section.**
Expand All @@ -90,7 +98,7 @@ The following example demonstrates how to handle these cases in your sign-in flo

<Tabs items={["Next.js"]}>
<Tab>
```tsx {{ filename: 'app/sign-in/[[...sign-in]]/page.tsx', collapsible: true }}
```tsx {{ filename: 'app/sign-in/page.tsx', collapsible: true }}
'use client'

import * as React from 'react'
Expand All @@ -111,7 +119,7 @@ The following example demonstrates how to handle these cases in your sign-in flo
.authenticateWithRedirect({
identifier: email,
strategy: 'enterprise_sso',
redirectUrl: '/sign-up/sso-callback',
redirectUrl: '/sign-in/sso-callback',
redirectUrlComplete: '/',
})
.then((res) => {
Expand Down
40 changes: 15 additions & 25 deletions docs/custom-flows/oauth-connections.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -39,11 +39,21 @@ When using OAuth, the sign-up and sign-in flows are equivalent.
if (!signIn) return null

const signInWith = (strategy: OAuthStrategy) => {
return signIn.authenticateWithRedirect({
strategy,
redirectUrl: '/sign-up/sso-callback',
redirectUrlComplete: '/',
})
return signIn
.authenticateWithRedirect({
strategy,
redirectUrl: '/sign-up/sso-callback',
redirectUrlComplete: '/',
})
.then((res) => {
console.log(res)
})
.catch((err: any) => {
// See https://clerk.com/docs/custom-flows/error-handling
// for more info on error handling
console.log(err.errors)
console.error(err, null, 2)
})
}

// Render a button for each supported OAuth provider
Expand All @@ -70,26 +80,6 @@ When using OAuth, the sign-up and sign-in flows are equivalent.
</Tab>

<Tab>
### Before you start

Install `expo-linking` to handle linking.

<CodeBlockTabs options={["npm", "yarn", "pnpm"]}>
```bash {{ filename: 'terminal' }}
npm install expo-linking
```

```bash {{ filename: 'terminal' }}
yarn add expo-linking
```

```bash {{ filename: 'terminal' }}
pnpm add expo-linking
```
</CodeBlockTabs>

### Build the flow

<Include src="_partials/expo/oauth-custom-flow" />
</Tab>

Expand Down
17 changes: 10 additions & 7 deletions docs/references/expo/overview.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -11,20 +11,23 @@ The Expo SDK gives you access to the following resources:

### Clerk hooks {{ id: 'hooks' }}

The following hooks are available for both **native** and **web** apps:
The Expo SDK provides the following hooks:

- All React hooks are available. See [the React docs](/docs/references/react/overview){{ target: '_blank' }} for more information.
- [`useSSO()`](/docs/references/expo/use-sso)
- [`useLocalCredentials()`](/docs/references/expo/use-local-credentials)

Because the Expo SDK is built on top of the Clerk React SDK, you can use the hooks that the React SDK provides. These hooks include access to the [`Clerk`](/docs/references/javascript/clerk/clerk) object, [`User` object](/docs/references/javascript/user/user), [`Organization` object](/docs/references/javascript/organization/organization), and a set of useful helper methods for signing in and signing up.

<Include src="_partials/hooks/hook-list" />

### Clerk components {{ id: 'components' }}

- **Native** apps:
- [`<ClerkLoaded>`](/docs/components/control/clerk-loaded){{ target: '_blank' }}
- [`<ClerkLoading>`](/docs/components/control/clerk-loading){{ target: '_blank' }}
- [`<SignedIn>`](/docs/components/control/signed-in){{ target: '_blank' }}
- [`<SignedOut>`](/docs/components/control/signed-out){{ target: '_blank' }}
- [`<Protect>`](/docs/components/protect){{ target: '_blank' }}
- [`<ClerkLoaded>`](/docs/components/control/clerk-loaded)
- [`<ClerkLoading>`](/docs/components/control/clerk-loading)
- [`<SignedIn>`](/docs/components/control/signed-in)
- [`<SignedOut>`](/docs/components/control/signed-out)
- [`<Protect>`](/docs/components/protect)
- **Web** apps:
- All Clerk components are available. See [the component docs](/docs/components/overview) for more information.

Expand Down
Loading

0 comments on commit 0a5b335

Please sign in to comment.