diff --git a/v2/emailpassword/custom-ui/email-password-login.mdx b/v2/emailpassword/custom-ui/email-password-login.mdx index de9928743..5adccfd9f 100644 --- a/v2/emailpassword/custom-ui/email-password-login.mdx +++ b/v2/emailpassword/custom-ui/email-password-login.mdx @@ -261,7 +261,7 @@ curl --location --request GET '^{form_apiDomain}^{form_apiBasePath}/signup/email The response body from the API call has a `status` property in it: -- `status: "OK"`: The response will also contain a `doesExist` boolean which will be `true` if the input email already belongs to an email password user. +- `status: "OK"`: The response will also contain a `exists` boolean which will be `true` if the input email already belongs to an email password user. - `status: "GENERAL_ERROR"`: This is only possible if you have overriden the backend API to send back a custom error message which should be displayed on the frontend. diff --git a/v2/thirdparty/custom-ui/thirdparty-login.mdx b/v2/thirdparty/custom-ui/thirdparty-login.mdx index 54c95843b..c467c7501 100644 --- a/v2/thirdparty/custom-ui/thirdparty-login.mdx +++ b/v2/thirdparty/custom-ui/thirdparty-login.mdx @@ -323,6 +323,8 @@ Coming Soon +

Step 1) Fetching the authorisation token on the frontend

+ For iOS you use the normal sign in with apple flow and then use the id token to login with SuperTokens ```swift @@ -363,6 +365,8 @@ fileprivate class ViewController: UIViewController, ASAuthorizationControllerPre +

Step 1) Fetching the authorisation token on the frontend

+ For flutter we use the [sign_in_with_apple](https://pub.dev/packages/sign_in_with_apple) package, make sure to follow the prerequisites steps to get the package setup. After setup use the snippet below to trigger the apple sign in flow. ```dart @@ -370,12 +374,22 @@ import 'package:sign_in_with_apple/sign_in_with_apple.dart'; void loginWithApple() async { try { - var credential = await SignInWithApple.getAppleIDCredential(scopes: [ - AppleIDAuthorizationScopes.email, - AppleIDAuthorizationScopes.fullName, - ]); + var credential = await SignInWithApple.getAppleIDCredential( + scopes: [ + AppleIDAuthorizationScopes.email, + AppleIDAuthorizationScopes.fullName, + ], + // Required for Android only + webAuthenticationOptions: WebAuthenticationOptions( + clientId: "", + redirectUri: Uri.parse( + "//callback/apple", + ), + ), + ); String authorizationCode = credential.authorizationCode; + String? idToken = credential.identityToken; String? email = credential.email; String? firstname = credential.givenName; String? lastName = credential.familyName; @@ -387,6 +401,191 @@ void loginWithApple() async { } ``` +In the snippet above for Android we need to pass an additional `webAuthenticationOptions` property when signing in with Apple. This is because on Android the library uses the web login flow and we need to provide it with the client id and redirection uri. The `redirectUri` property here is the URL to which Apple will make a `POST` request after the user has logged in. The SuperTokens backend SDKs provide an API for this at `//callback/apple`. + +

Additional steps for Android

+ +For android we also need to provide a way for the web login flow to redirect back to the app. By default the API provided by the backend SDKs redirect to the website domain you provide when initialising the SDK, we can override the API to have it redirect to our app instead. For example if you were using the Node.js SDK: + + + + + +```tsx +import ^{recipeNameCapitalLetters} from "supertokens-node/recipe/^{codeImportRecipeName}"; + +^{recipeNameCapitalLetters}.init({ + ^{nodeSignInUpFeatureStart} + // highlight-start + override: { + apis: (original) => { + return { + ...original, + appleRedirectHandlerPOST: async (input) => { + if (original.appleRedirectHandlerPOST === undefined) { + throw Error("Should never come here"); + } + + // inut.formPostInfoFromProvider contains all the query params attached by Apple + const stateInBase64 = input.formPostInfoFromProvider.state; + + // The web SDKs add a default state + if (stateInBase64 === undefined) { + // Redirect to android app + // We create a dummy URL to create the query string + const dummyUrl = new URL("http://localhost:8080"); + for (const [key, value] of Object.entries(input.formPostInfoFromProvider)) { + dummyUrl.searchParams.set(key, `${value}`); + } + + const queryString = dummyUrl.searchParams.toString(); + // Refer to the README of sign_in_with_apple to understand what this url is + const redirectUrl = `intent://callback?${queryString}#Intent;package=YOUR.PACKAGE.IDENTIFIER;scheme=signinwithapple;end`; + + input.options.res.setHeader("Location", redirectUrl, false); + input.options.res.setStatusCode(303); + input.options.res.sendHTMLResponse(""); + } else { + // For the web flow we can use the original implementation + original.appleRedirectHandlerPOST(input); + } + }, + }; + }, + }, + // highlight-end + providers: [ + // ... + ], + ^{nodeSignInUpFeatureEnd} +}) +``` + + + + + +```go +import ( + "net/http" + "strings" + + "github.com/supertokens/supertokens-golang/recipe/^{codeImportRecipeName}" + ^{goTPModelsImport} + "github.com/supertokens/supertokens-golang/recipe/^{codeImportRecipeName}/^{goModelName}" +) + +func main() { + ^{codeImportRecipeName}.Init(^{goModelNameForInit}.TypeInput{ + Override: &^{goModelName}.OverrideStruct{ + // highlight-start + APIs: func(originalImplementation ^{goModelName}.APIInterface) ^{goModelName}.APIInterface { + originalAppleRedirectPost := *originalImplementation.AppleRedirectHandlerPOST + + *originalImplementation.AppleRedirectHandlerPOST = func(formPostInfoFromProvider map[string]interface{}, options tpmodels.APIOptions, userContext *map[string]interface{}) error { + // formPostInfoFromProvider contains all the query params attached by Apple + state, stateOk := formPostInfoFromProvider["state"].(string) + + queryParams := []string{} + if (!stateOk) || state == "" { + // Redirect to android app + for key, value := range formPostInfoFromProvider { + queryParams = append(queryParams, key+"="+value.(string)) + } + + queryString := "" + if len(queryParams) > 0 { + queryString = strings.Join(queryParams, "&") + } + + // Refer to the README of sign_in_with_apple to understand what this url is + redirectUri := "intent://callback?" + queryString + "#Intent;package=YOUR.PACKAGE.IDENTIFIER;scheme=signinwithapple;end" + + options.Res.Header().Set("Location", redirectUri) + options.Res.WriteHeader(http.StatusSeeOther) + return nil + } else { + return originalAppleRedirectPost(formPostInfoFromProvider, options, userContext) + } + } + + return originalImplementation + }, + }, + // highlight-end + ^{goSignInUpFeatureStart} + Providers: []tpmodels.ProviderInput{ + // ... + }, + ^{goSignInUpFeatureEnd} + }) +} +``` + + + + + +```python +from supertokens_python.recipe import ^{codeImportRecipeName} +from supertokens_python.recipe.^{codeImportRecipeName}.interfaces import APIInterface, APIOptions +from typing import Union, Dict, Any +from supertokens_python.recipe.thirdparty.provider import Provider, RedirectUriInfo + +# highlight-start +def override_thirdparty_apis(original_implementation: APIInterface): + original_apple_redirect_post = original_implementation.apple_redirect_handler_post + + async def apple_redirect_handler_post( + form_post_info: Dict[str, Any], + api_options: APIOptions, + user_context: Dict[str, Any] + ): + # form_post_info contains all the query params attached by Apple + state = form_post_info["state"] + + # The web SDKs add a default state + if state is None: + query_items = [] + + for key, value in form_post_info.items(): + query_items.append(f"{key}={value}") + + query_string = "&".join(query_items) + + # Refer to the README of sign_in_with_apple to understand what this url is + redirect_url = f"intent://callback?${query_string}#Intent;package=YOUR.PACKAGE.IDENTIFIER;scheme=signinwithapple;end" + + api_options.response.set_header("Location", redirect_url) + api_options.response.set_status_code(303) + api_options.response.set_html_content("") + else: + return original_apple_redirect_post(form_post_info, api_options, user_context) + + original_implementation.apple_redirect_handler_post = apple_redirect_handler_post + return original_implementation +# highlight-end + +^{codeImportRecipeName}.init( + # highlight-start + override=^{codeImportRecipeName}.InputOverrideConfig( + apis=override_thirdparty_apis + ), + # highlight-end + ^{pythonSignInUpFeatureStart} + providers=[ + # ... + ] + ^{pythonSignInUpFeatureEnd} +) +``` + + + + + +In the code above we override the `appleRedirectHandlerPOST` API to check if the request was made by our Android app (You can skip checking the state if you only have a mobile app and no website). `sign_in_with_apple` requires us to parse the query params sent by apple and include them in the redirect URL in a specific way, and then we simply redirect to the deep link url. Refer to the README for `sign_in_with_apple` to read about the deep link setup required in Android. +
diff --git a/v2/thirdpartyemailpassword/custom-ui/email-password-login.mdx b/v2/thirdpartyemailpassword/custom-ui/email-password-login.mdx index 6fdc91f11..2d70f8be3 100644 --- a/v2/thirdpartyemailpassword/custom-ui/email-password-login.mdx +++ b/v2/thirdpartyemailpassword/custom-ui/email-password-login.mdx @@ -264,7 +264,7 @@ curl --location --request GET '^{form_apiDomain}^{form_apiBasePath}/signup/email The response body from the API call has a `status` property in it: -- `status: "OK"`: The response will also contain a `doesExist` boolean which will be `true` if the input email already belongs to an email password user. +- `status: "OK"`: The response will also contain a `exists` boolean which will be `true` if the input email already belongs to an email password user. - `status: "GENERAL_ERROR"`: This is only possible if you have overriden the backend API to send back a custom error message which should be displayed on the frontend.
diff --git a/v2/thirdpartyemailpassword/custom-ui/thirdparty-login.mdx b/v2/thirdpartyemailpassword/custom-ui/thirdparty-login.mdx index 497eb9ece..e1aa7feaa 100644 --- a/v2/thirdpartyemailpassword/custom-ui/thirdparty-login.mdx +++ b/v2/thirdpartyemailpassword/custom-ui/thirdparty-login.mdx @@ -326,6 +326,8 @@ Coming Soon +

Step 1) Fetching the authorisation token on the frontend

+ For iOS you use the normal sign in with apple flow and then use the id token to login with SuperTokens ```swift @@ -366,6 +368,8 @@ fileprivate class ViewController: UIViewController, ASAuthorizationControllerPre +

Step 1) Fetching the authorisation token on the frontend

+ For flutter we use the [sign_in_with_apple](https://pub.dev/packages/sign_in_with_apple) package, make sure to follow the prerequisites steps to get the package setup. After setup use the snippet below to trigger the apple sign in flow. ```dart @@ -373,12 +377,22 @@ import 'package:sign_in_with_apple/sign_in_with_apple.dart'; void loginWithApple() async { try { - var credential = await SignInWithApple.getAppleIDCredential(scopes: [ - AppleIDAuthorizationScopes.email, - AppleIDAuthorizationScopes.fullName, - ]); + var credential = await SignInWithApple.getAppleIDCredential( + scopes: [ + AppleIDAuthorizationScopes.email, + AppleIDAuthorizationScopes.fullName, + ], + // Required for Android only + webAuthenticationOptions: WebAuthenticationOptions( + clientId: "", + redirectUri: Uri.parse( + "//callback/apple", + ), + ), + ); String authorizationCode = credential.authorizationCode; + String? idToken = credential.identityToken; String? email = credential.email; String? firstname = credential.givenName; String? lastName = credential.familyName; @@ -390,6 +404,191 @@ void loginWithApple() async { } ``` +In the snippet above for Android we need to pass an additional `webAuthenticationOptions` property when signing in with Apple. This is because on Android the library uses the web login flow and we need to provide it with the client id and redirection uri. The `redirectUri` property here is the URL to which Apple will make a `POST` request after the user has logged in. The SuperTokens backend SDKs provide an API for this at `//callback/apple`. + +

Additional steps for Android

+ +For android we also need to provide a way for the web login flow to redirect back to the app. By default the API provided by the backend SDKs redirect to the website domain you provide when initialising the SDK, we can override the API to have it redirect to our app instead. For example if you were using the Node.js SDK: + + + + + +```tsx +import ^{recipeNameCapitalLetters} from "supertokens-node/recipe/^{codeImportRecipeName}"; + +^{recipeNameCapitalLetters}.init({ + ^{nodeSignInUpFeatureStart} + // highlight-start + override: { + apis: (original) => { + return { + ...original, + appleRedirectHandlerPOST: async (input) => { + if (original.appleRedirectHandlerPOST === undefined) { + throw Error("Should never come here"); + } + + // inut.formPostInfoFromProvider contains all the query params attached by Apple + const stateInBase64 = input.formPostInfoFromProvider.state; + + // The web SDKs add a default state + if (stateInBase64 === undefined) { + // Redirect to android app + // We create a dummy URL to create the query string + const dummyUrl = new URL("http://localhost:8080"); + for (const [key, value] of Object.entries(input.formPostInfoFromProvider)) { + dummyUrl.searchParams.set(key, `${value}`); + } + + const queryString = dummyUrl.searchParams.toString(); + // Refer to the README of sign_in_with_apple to understand what this url is + const redirectUrl = `intent://callback?${queryString}#Intent;package=YOUR.PACKAGE.IDENTIFIER;scheme=signinwithapple;end`; + + input.options.res.setHeader("Location", redirectUrl, false); + input.options.res.setStatusCode(303); + input.options.res.sendHTMLResponse(""); + } else { + // For the web flow we can use the original implementation + original.appleRedirectHandlerPOST(input); + } + }, + }; + }, + }, + // highlight-end + providers: [ + // ... + ], + ^{nodeSignInUpFeatureEnd} +}) +``` + + + + + +```go +import ( + "net/http" + "strings" + + "github.com/supertokens/supertokens-golang/recipe/^{codeImportRecipeName}" + ^{goTPModelsImport} + "github.com/supertokens/supertokens-golang/recipe/^{codeImportRecipeName}/^{goModelName}" +) + +func main() { + ^{codeImportRecipeName}.Init(^{goModelNameForInit}.TypeInput{ + Override: &^{goModelName}.OverrideStruct{ + // highlight-start + APIs: func(originalImplementation ^{goModelName}.APIInterface) ^{goModelName}.APIInterface { + originalAppleRedirectPost := *originalImplementation.AppleRedirectHandlerPOST + + *originalImplementation.AppleRedirectHandlerPOST = func(formPostInfoFromProvider map[string]interface{}, options tpmodels.APIOptions, userContext *map[string]interface{}) error { + // formPostInfoFromProvider contains all the query params attached by Apple + state, stateOk := formPostInfoFromProvider["state"].(string) + + queryParams := []string{} + if (!stateOk) || state == "" { + // Redirect to android app + for key, value := range formPostInfoFromProvider { + queryParams = append(queryParams, key+"="+value.(string)) + } + + queryString := "" + if len(queryParams) > 0 { + queryString = strings.Join(queryParams, "&") + } + + // Refer to the README of sign_in_with_apple to understand what this url is + redirectUri := "intent://callback?" + queryString + "#Intent;package=YOUR.PACKAGE.IDENTIFIER;scheme=signinwithapple;end" + + options.Res.Header().Set("Location", redirectUri) + options.Res.WriteHeader(http.StatusSeeOther) + return nil + } else { + return originalAppleRedirectPost(formPostInfoFromProvider, options, userContext) + } + } + + return originalImplementation + }, + }, + // highlight-end + ^{goSignInUpFeatureStart} + Providers: []tpmodels.ProviderInput{ + // ... + }, + ^{goSignInUpFeatureEnd} + }) +} +``` + + + + + +```python +from supertokens_python.recipe import ^{codeImportRecipeName} +from supertokens_python.recipe.^{codeImportRecipeName}.interfaces import APIInterface, APIOptions +from typing import Union, Dict, Any +from supertokens_python.recipe.thirdparty.provider import Provider, RedirectUriInfo + +# highlight-start +def override_thirdparty_apis(original_implementation: APIInterface): + original_apple_redirect_post = original_implementation.apple_redirect_handler_post + + async def apple_redirect_handler_post( + form_post_info: Dict[str, Any], + api_options: APIOptions, + user_context: Dict[str, Any] + ): + # form_post_info contains all the query params attached by Apple + state = form_post_info["state"] + + # The web SDKs add a default state + if state is None: + query_items = [] + + for key, value in form_post_info.items(): + query_items.append(f"{key}={value}") + + query_string = "&".join(query_items) + + # Refer to the README of sign_in_with_apple to understand what this url is + redirect_url = f"intent://callback?${query_string}#Intent;package=YOUR.PACKAGE.IDENTIFIER;scheme=signinwithapple;end" + + api_options.response.set_header("Location", redirect_url) + api_options.response.set_status_code(303) + api_options.response.set_html_content("") + else: + return original_apple_redirect_post(form_post_info, api_options, user_context) + + original_implementation.apple_redirect_handler_post = apple_redirect_handler_post + return original_implementation +# highlight-end + +^{codeImportRecipeName}.init( + # highlight-start + override=^{codeImportRecipeName}.InputOverrideConfig( + apis=override_thirdparty_apis + ), + # highlight-end + ^{pythonSignInUpFeatureStart} + providers=[ + # ... + ] + ^{pythonSignInUpFeatureEnd} +) +``` + + + + + +In the code above we override the `appleRedirectHandlerPOST` API to check if the request was made by our Android app (You can skip checking the state if you only have a mobile app and no website). `sign_in_with_apple` requires us to parse the query params sent by apple and include them in the redirect URL in a specific way, and then we simply redirect to the deep link url. Refer to the README for `sign_in_with_apple` to read about the deep link setup required in Android. +
diff --git a/v2/thirdpartypasswordless/custom-ui/thirdparty-login.mdx b/v2/thirdpartypasswordless/custom-ui/thirdparty-login.mdx index ba40cc5e3..e784682ab 100644 --- a/v2/thirdpartypasswordless/custom-ui/thirdparty-login.mdx +++ b/v2/thirdpartypasswordless/custom-ui/thirdparty-login.mdx @@ -326,6 +326,8 @@ Coming Soon +

Step 1) Fetching the authorisation token on the frontend

+ For iOS you use the normal sign in with apple flow and then use the id token to login with SuperTokens ```swift @@ -366,6 +368,8 @@ fileprivate class ViewController: UIViewController, ASAuthorizationControllerPre +

Step 1) Fetching the authorisation token on the frontend

+ For flutter we use the [sign_in_with_apple](https://pub.dev/packages/sign_in_with_apple) package, make sure to follow the prerequisites steps to get the package setup. After setup use the snippet below to trigger the apple sign in flow. ```dart @@ -373,12 +377,22 @@ import 'package:sign_in_with_apple/sign_in_with_apple.dart'; void loginWithApple() async { try { - var credential = await SignInWithApple.getAppleIDCredential(scopes: [ - AppleIDAuthorizationScopes.email, - AppleIDAuthorizationScopes.fullName, - ]); + var credential = await SignInWithApple.getAppleIDCredential( + scopes: [ + AppleIDAuthorizationScopes.email, + AppleIDAuthorizationScopes.fullName, + ], + // Required for Android only + webAuthenticationOptions: WebAuthenticationOptions( + clientId: "", + redirectUri: Uri.parse( + "//callback/apple", + ), + ), + ); String authorizationCode = credential.authorizationCode; + String? idToken = credential.identityToken; String? email = credential.email; String? firstname = credential.givenName; String? lastName = credential.familyName; @@ -390,6 +404,191 @@ void loginWithApple() async { } ``` +In the snippet above for Android we need to pass an additional `webAuthenticationOptions` property when signing in with Apple. This is because on Android the library uses the web login flow and we need to provide it with the client id and redirection uri. The `redirectUri` property here is the URL to which Apple will make a `POST` request after the user has logged in. The SuperTokens backend SDKs provide an API for this at `//callback/apple`. + +

Additional steps for Android

+ +For android we also need to provide a way for the web login flow to redirect back to the app. By default the API provided by the backend SDKs redirect to the website domain you provide when initialising the SDK, we can override the API to have it redirect to our app instead. For example if you were using the Node.js SDK: + + + + + +```tsx +import ^{recipeNameCapitalLetters} from "supertokens-node/recipe/^{codeImportRecipeName}"; + +^{recipeNameCapitalLetters}.init({ + ^{nodeSignInUpFeatureStart} + // highlight-start + override: { + apis: (original) => { + return { + ...original, + appleRedirectHandlerPOST: async (input) => { + if (original.appleRedirectHandlerPOST === undefined) { + throw Error("Should never come here"); + } + + // inut.formPostInfoFromProvider contains all the query params attached by Apple + const stateInBase64 = input.formPostInfoFromProvider.state; + + // The web SDKs add a default state + if (stateInBase64 === undefined) { + // Redirect to android app + // We create a dummy URL to create the query string + const dummyUrl = new URL("http://localhost:8080"); + for (const [key, value] of Object.entries(input.formPostInfoFromProvider)) { + dummyUrl.searchParams.set(key, `${value}`); + } + + const queryString = dummyUrl.searchParams.toString(); + // Refer to the README of sign_in_with_apple to understand what this url is + const redirectUrl = `intent://callback?${queryString}#Intent;package=YOUR.PACKAGE.IDENTIFIER;scheme=signinwithapple;end`; + + input.options.res.setHeader("Location", redirectUrl, false); + input.options.res.setStatusCode(303); + input.options.res.sendHTMLResponse(""); + } else { + // For the web flow we can use the original implementation + original.appleRedirectHandlerPOST(input); + } + }, + }; + }, + }, + // highlight-end + providers: [ + // ... + ], + ^{nodeSignInUpFeatureEnd} +}) +``` + + + + + +```go +import ( + "net/http" + "strings" + + "github.com/supertokens/supertokens-golang/recipe/^{codeImportRecipeName}" + ^{goTPModelsImport} + "github.com/supertokens/supertokens-golang/recipe/^{codeImportRecipeName}/^{goModelName}" +) + +func main() { + ^{codeImportRecipeName}.Init(^{goModelNameForInit}.TypeInput{ + Override: &^{goModelName}.OverrideStruct{ + // highlight-start + APIs: func(originalImplementation ^{goModelName}.APIInterface) ^{goModelName}.APIInterface { + originalAppleRedirectPost := *originalImplementation.AppleRedirectHandlerPOST + + *originalImplementation.AppleRedirectHandlerPOST = func(formPostInfoFromProvider map[string]interface{}, options tpmodels.APIOptions, userContext *map[string]interface{}) error { + // formPostInfoFromProvider contains all the query params attached by Apple + state, stateOk := formPostInfoFromProvider["state"].(string) + + queryParams := []string{} + if (!stateOk) || state == "" { + // Redirect to android app + for key, value := range formPostInfoFromProvider { + queryParams = append(queryParams, key+"="+value.(string)) + } + + queryString := "" + if len(queryParams) > 0 { + queryString = strings.Join(queryParams, "&") + } + + // Refer to the README of sign_in_with_apple to understand what this url is + redirectUri := "intent://callback?" + queryString + "#Intent;package=YOUR.PACKAGE.IDENTIFIER;scheme=signinwithapple;end" + + options.Res.Header().Set("Location", redirectUri) + options.Res.WriteHeader(http.StatusSeeOther) + return nil + } else { + return originalAppleRedirectPost(formPostInfoFromProvider, options, userContext) + } + } + + return originalImplementation + }, + }, + // highlight-end + ^{goSignInUpFeatureStart} + Providers: []tpmodels.ProviderInput{ + // ... + }, + ^{goSignInUpFeatureEnd} + }) +} +``` + + + + + +```python +from supertokens_python.recipe import ^{codeImportRecipeName} +from supertokens_python.recipe.^{codeImportRecipeName}.interfaces import APIInterface, APIOptions +from typing import Union, Dict, Any +from supertokens_python.recipe.thirdparty.provider import Provider, RedirectUriInfo + +# highlight-start +def override_thirdparty_apis(original_implementation: APIInterface): + original_apple_redirect_post = original_implementation.apple_redirect_handler_post + + async def apple_redirect_handler_post( + form_post_info: Dict[str, Any], + api_options: APIOptions, + user_context: Dict[str, Any] + ): + # form_post_info contains all the query params attached by Apple + state = form_post_info["state"] + + # The web SDKs add a default state + if state is None: + query_items = [] + + for key, value in form_post_info.items(): + query_items.append(f"{key}={value}") + + query_string = "&".join(query_items) + + # Refer to the README of sign_in_with_apple to understand what this url is + redirect_url = f"intent://callback?${query_string}#Intent;package=YOUR.PACKAGE.IDENTIFIER;scheme=signinwithapple;end" + + api_options.response.set_header("Location", redirect_url) + api_options.response.set_status_code(303) + api_options.response.set_html_content("") + else: + return original_apple_redirect_post(form_post_info, api_options, user_context) + + original_implementation.apple_redirect_handler_post = apple_redirect_handler_post + return original_implementation +# highlight-end + +^{codeImportRecipeName}.init( + # highlight-start + override=^{codeImportRecipeName}.InputOverrideConfig( + apis=override_thirdparty_apis + ), + # highlight-end + ^{pythonSignInUpFeatureStart} + providers=[ + # ... + ] + ^{pythonSignInUpFeatureEnd} +) +``` + + + + + +In the code above we override the `appleRedirectHandlerPOST` API to check if the request was made by our Android app (You can skip checking the state if you only have a mobile app and no website). `sign_in_with_apple` requires us to parse the query params sent by apple and include them in the redirect URL in a specific way, and then we simply redirect to the deep link url. Refer to the README for `sign_in_with_apple` to read about the deep link setup required in Android. +