Skip to content

Commit

Permalink
feat: add support for native apple authentication (#78)
Browse files Browse the repository at this point in the history
* feat: add support for native apple authentication

* chore: u
  • Loading branch information
jonas-jonas committed Oct 19, 2023
1 parent 235cfee commit df56e2b
Show file tree
Hide file tree
Showing 9 changed files with 799 additions and 343 deletions.
3 changes: 2 additions & 1 deletion app.json
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,8 @@
"assetBundlePatterns": ["src/assets/*", "src/assets/**/*", "assets/*"],
"ios": {
"supportsTablet": true,
"bundleIdentifier": "com.ory.kratos-selfservice-ui-react-native"
"bundleIdentifier": "com.ory.kratos-selfservice-ui-react-native",
"usesAppleSignIn": true
},
"android": {
"package": "com.ory.kratos_self_service_ui_react_native",
Expand Down
332 changes: 228 additions & 104 deletions contrib/sdk/api.json

Large diffs are not rendered by default.

455 changes: 333 additions & 122 deletions contrib/sdk/generated/api.ts

Large diffs are not rendered by default.

60 changes: 37 additions & 23 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@
"@types/node": "18.17.5",
"axios": "0.21.4",
"expo": "49.0.10",
"expo-apple-authentication": "6.1.0",
"expo-application": "5.3.0",
"expo-auth-session": "5.0.2",
"expo-constants": "14.4.2",
Expand Down
75 changes: 47 additions & 28 deletions src/components/Routes/Login.tsx
Original file line number Diff line number Diff line change
@@ -1,13 +1,18 @@
// This file renders the login screen.
import { LoginFlow, UpdateLoginFlowBody } from "@ory/client"
import {
LoginFlow,
SuccessfulNativeLogin,
UpdateLoginFlowBody,
} from "@ory/client"
import { useFocusEffect } from "@react-navigation/native"
import { StackScreenProps } from "@react-navigation/stack"
import axios, { AxiosResponse } from "axios"
import React, { useContext, useState } from "react"

import { Platform } from "react-native"
import { SessionContext } from "../../helpers/auth"
import { logSDKError } from "../../helpers/axios"
import { handleFormSubmitError } from "../../helpers/form"
import { newOrySdk } from "../../helpers/sdk"
import { signInWithApple } from "../../helpers/oidc/apple"
import { AuthContext } from "../AuthProvider"
import AuthLayout from "../Layout/AuthLayout"
import ProjectPicker from "../Layout/ProjectPicker"
Expand All @@ -22,12 +27,12 @@ import * as AuthSession from "expo-auth-session"
type Props = StackScreenProps<RootStackParamList, "Login">

const Login = ({ navigation, route }: Props) => {
const { project } = useContext(ProjectContext)
const { sdk } = useContext(ProjectContext)
const { setSession, sessionToken } = useContext(AuthContext)
const [flow, setFlow] = useState<LoginFlow | undefined>(undefined)

const initializeFlow = () =>
newOrySdk(project)
sdk
.createNativeLoginFlow({
aal: route.params.aal,
refresh: route.params.refresh,
Expand All @@ -47,7 +52,7 @@ const Login = ({ navigation, route }: Props) => {
.catch(logSDKError)

const refetchFlow = () =>
newOrySdk(project)
sdk
.getLoginFlow({ id: flow!.id })
.then(({ data: f }) => setFlow({ ...flow, ...f })) // merging ensures we don't lose the code
.catch(logSDKError)
Expand All @@ -60,7 +65,7 @@ const Login = ({ navigation, route }: Props) => {
return () => {
setFlow(undefined)
}
}, [project]),
}, [sdk]),
)

const setSessionAndRedirect = (session: SessionContext) => {
Expand All @@ -71,27 +76,41 @@ const Login = ({ navigation, route }: Props) => {
}

// This will update the login flow with the user provided input:
const onSubmit = (payload: UpdateLoginFlowBody) =>
flow
? newOrySdk(project)
.updateLoginFlow({
flow: flow.id,
updateLoginFlowBody: payload,
xSessionToken: sessionToken,
})
.then(({ data }) => Promise.resolve(data as SessionContext))
// Looks like everything worked and we have a session!
.then(setSessionAndRedirect)
.catch(
handleFormSubmitError(
flow,
setFlow,
initializeFlow,
setSessionAndRedirect,
refetchFlow,
),
)
: Promise.resolve()
const onSubmit = async (payload: UpdateLoginFlowBody) => {
if (!flow) {
return
}

let res: AxiosResponse<SuccessfulNativeLogin, any>
try {
if (
Platform.OS === "ios" &&
"provider" in payload &&
payload.provider === "apple"
) {
res = await signInWithApple(sdk, flow.id)
} else {
res = await sdk.updateLoginFlow({
flow: flow.id,
updateLoginFlowBody: payload,
})
}

setSessionAndRedirect(res.data as SessionContext)
} catch (e) {
if (!axios.isAxiosError(e)) {
throw e
}

handleFormSubmitError(
flow,
setFlow,
initializeFlow,
setSessionAndRedirect,
refetchFlow,
)(e)
}
}

return (
<AuthLayout>
Expand Down
Loading

0 comments on commit df56e2b

Please sign in to comment.