From b7e2c2c2b9dd949aa0931c3b90ed66b5de46825e Mon Sep 17 00:00:00 2001 From: Andrew Smith Date: Wed, 17 Jul 2024 22:14:08 +0000 Subject: [PATCH] feat: add sign_in_with_id_token method (#548) --- supabase_auth/_async/gotrue_client.py | 39 +++++++++++++++++++++++++++ supabase_auth/_sync/gotrue_client.py | 39 +++++++++++++++++++++++++++ supabase_auth/types.py | 16 +++++++++++ 3 files changed, 94 insertions(+) diff --git a/supabase_auth/_async/gotrue_client.py b/supabase_auth/_async/gotrue_client.py index 9556c3d6..c3d2b417 100644 --- a/supabase_auth/_async/gotrue_client.py +++ b/supabase_auth/_async/gotrue_client.py @@ -63,6 +63,7 @@ Provider, Session, SignInAnonymouslyCredentials, + SignInWithIdTokenCredentials, SignInWithOAuthCredentials, SignInWithPasswordCredentials, SignInWithPasswordlessCredentials, @@ -293,6 +294,44 @@ async def sign_in_with_password( self._notify_all_subscribers("SIGNED_IN", response.session) return response + async def sign_in_with_id_token( + self, + credentials: SignInWithIdTokenCredentials, + ) -> AuthResponse: + """ + Allows signing in with an OIDC ID token. The authentication provider used should be enabled and configured. + """ + await self._remove_session() + provider = credentials.get("provider") + token = credentials.get("token") + access_token = credentials.get("access_token") + nonce = credentials.get("nonce") + options = credentials.get("options", {}) + captcha_token = options.get("captcha_token") + + response = await self._request( + "POST", + "token", + body={ + "provider": provider, + "id_token": token, + "access_token": access_token, + "nonce": nonce, + "gotrue_meta_security": { + "captcha_token": captcha_token, + }, + }, + query={ + "grant_type": "id_token", + }, + xform=parse_auth_response, + ) + + if response.session: + await self._save_session(response.session) + self._notify_all_subscribers("SIGNED_IN", response.session) + return response + async def sign_in_with_sso(self, credentials: SignInWithSSOCredentials): """ Attempts a single-sign on using an enterprise Identity Provider. A diff --git a/supabase_auth/_sync/gotrue_client.py b/supabase_auth/_sync/gotrue_client.py index ace93194..fd7d3240 100644 --- a/supabase_auth/_sync/gotrue_client.py +++ b/supabase_auth/_sync/gotrue_client.py @@ -63,6 +63,7 @@ Provider, Session, SignInAnonymouslyCredentials, + SignInWithIdTokenCredentials, SignInWithOAuthCredentials, SignInWithPasswordCredentials, SignInWithPasswordlessCredentials, @@ -293,6 +294,44 @@ def sign_in_with_password( self._notify_all_subscribers("SIGNED_IN", response.session) return response + def sign_in_with_id_token( + self, + credentials: SignInWithIdTokenCredentials, + ) -> AuthResponse: + """ + Allows signing in with an OIDC ID token. The authentication provider used should be enabled and configured. + """ + self._remove_session() + provider = credentials.get("provider") + token = credentials.get("token") + access_token = credentials.get("access_token") + nonce = credentials.get("nonce") + options = credentials.get("options", {}) + captcha_token = options.get("captcha_token") + + response = self._request( + "POST", + "token", + body={ + "provider": provider, + "id_token": token, + "access_token": access_token, + "nonce": nonce, + "gotrue_meta_security": { + "captcha_token": captcha_token, + }, + }, + query={ + "grant_type": "id_token", + }, + xform=parse_auth_response, + ) + + if response.session: + self._save_session(response.session) + self._notify_all_subscribers("SIGNED_IN", response.session) + return response + def sign_in_with_sso(self, credentials: SignInWithSSOCredentials): """ Attempts a single-sign on using an enterprise Identity Provider. A diff --git a/supabase_auth/types.py b/supabase_auth/types.py index 17e730cb..63d23fd4 100644 --- a/supabase_auth/types.py +++ b/supabase_auth/types.py @@ -303,6 +303,22 @@ class SignInWithPhoneAndPasswordCredentials(TypedDict): ] +class SignInWithIdTokenCredentials(TypedDict): + """ + Provider name or OIDC `iss` value identifying which provider should be used to verify the provided token. Supported names: `google`, `apple`, `azure`, `facebook`, `kakao`, `keycloak` (deprecated). + """ + + provider: Literal["google", "apple", "azure", "facebook", "kakao"] + token: str + access_token: NotRequired[str] + nonce: NotRequired[str] + options: NotRequired[SignInWithIdTokenCredentialsOptions] + + +class SignInWithIdTokenCredentialsOptions(TypedDict): + captcha_token: NotRequired[str] + + class SignInWithEmailAndPasswordlessCredentialsOptions(TypedDict): email_redirect_to: NotRequired[str] should_create_user: NotRequired[bool]