diff --git a/apps/docs/docs/ref/python/installing.mdx b/apps/docs/docs/ref/python/installing.mdx index 58a56b8d9fe..fb1be005e46 100644 --- a/apps/docs/docs/ref/python/installing.mdx +++ b/apps/docs/docs/ref/python/installing.mdx @@ -10,7 +10,7 @@ custom_edit_url: https://github.com/supabase/supabase/edit/master/apps/docs/spec - You can install supabase-py via the terminal. (for > Python 3.7) + You can install supabase-py via the terminal. (for Python > 3.8) diff --git a/apps/docs/spec/supabase_py_v2.yml b/apps/docs/spec/supabase_py_v2.yml index 96c8894f4c5..2c25f99baf2 100644 --- a/apps/docs/spec/supabase_py_v2.yml +++ b/apps/docs/spec/supabase_py_v2.yml @@ -104,6 +104,13 @@ functions: )) ``` + - id: auth-api + title: 'Overview' + notes: | + - The auth methods can be accessed via the `supabase.auth` namespace. + - By default, the supabase client sets `persist_session` to true and attempts to store the session in memory. + - Any email links and one-time passwords (OTPs) sent have a default expiry of 24 hours. We have the following [rate limits](/docs/guides/platform/going-into-prod#auth-rate-limits) in place to guard against brute force attacks. + - The expiry of an access token can be set in the "JWT expiry limit" field in [your project's auth settings](/dashboard/project/_/settings/auth). A refresh token never expires and can only be used once. - id: sign-up title: 'sign_up()' params: @@ -1053,104 +1060,59 @@ functions: {"email": "email@example.com", "token_hash": "", "type": "email"} ) ``` - - id: auth-mfa-api - title: 'Overview' + - id: get-session + title: 'get_session' notes: | - This section contains methods commonly used for Multi-Factor Authentication (MFA) and are invoked behind the `supabase.auth.mfa` namespace. - - Currently, we only support time-based one-time password (TOTP) as the 2nd factor. We don't support recovery codes but we allow users to enroll more than 1 TOTP factor, with an upper limit of 10. - - Having a 2nd TOTP factor for recovery frees the user of the burden of having to store their recovery codes somewhere. It also reduces the attack surface since multiple recovery codes are usually generated compared to just having 1 backup TOTP factor. - - id: mfa-enroll - title: 'mfa.enroll()' - notes: | - - Currently, `totp` is the only supported `factor_type`. The returned `id` should be used to create a challenge. - - To create a challenge, see [`mfa.challenge()`](/docs/reference/python/auth-mfa-challenge). - - To verify a challenge, see [`mfa.verify()`](/docs/reference/python/auth-mfa-verify). - - To create and verify a challenge in a single step, see [`mfa.challenge_and_verify()`](/docs/reference/python/auth-mfa-challengeandverify). + - This method retrieves the current local session (i.e in memory). + - The session contains a signed JWT and unencoded session data. + - Since the unencoded session data is retrieved from the local storage medium, **do not** rely on it as a source of trusted data on the server. It could be tampered with by the sender. If you need verified, trustworthy user data, call [`get_user`](/docs/reference/python/auth-getuser) instead. + - If the session has an expired access token, this method will use the refresh token to get a new session. examples: - - id: enroll-totp-factor - name: Enroll a time-based, one-time password (TOTP) factor + - id: get-the-session-data + name: Get the session data isSpotlight: true code: | + ```python + response = supabase.auth.get_session() ``` - res = supabase.auth.mfa.enroll({ - "factor_type": "totp", - "friendly_name": "your_friendly_name" - }) - ``` - - id: mfa-challenge - title: 'mfa.challenge()' - notes: | - - An [enrolled factor](/docs/reference/python/auth-mfa-enroll) is required before creating a challenge. - - To verify a challenge, see [`mfa.verify()`](/docs/reference/python/auth-mfa-verify). - examples: - - id: create-mfa-challenge - name: Create a challenge for a factor - isSpotlight: true - code: | - ``` - res = supabase.auth.mfa.challenge({ - "factor_id": '34e770dd-9ff9-416c-87fa-43b31d7ef225' - }) - ``` - - id: mfa-verify - title: 'mfa.verify()' - notes: | - - To verify a challenge, please [create a challenge](/docs/reference/python/auth-mfa-challenge) first. - examples: - - id: verify-challenge - name: Verify a challenge for a factor - isSpotlight: true - code: | - ``` - res = supabase.auth.mfa.verify({ - "factor_id": '34e770dd-9ff9-416c-87fa-43b31d7ef225', - "challenge_id": '4034ae6f-a8ce-4fb5-8ee5-69a5863a7c15', - "code": '123456' - }) - ``` - - id: mfa-challenge-and-verify - title: 'mfa.challenge_and_verify()' - notes: | - - An [enrolled factor](/docs/reference/python/auth-mfa-enroll) is required before invoking `challengeAndVerify()`. - - Executes [`mfa.challenge()`](/docs/reference/python/auth-mfa-challenge) and [`mfa.verify()`](/docs/reference/python/auth-mfa-verify) in a single step. - examples: - - id: challenge-and-verify - name: Create and verify a challenge for a factor - isSpotlight: true - code: | - ``` - res = supabase.auth.mfa.challenge_and_verify({ - "factor_id": '34e770dd-9ff9-416c-87fa-43b31d7ef225', - "code": '123456' - }) - ``` - - id: mfa-unenroll - title: 'mfa.unenroll()' - examples: - - id: unenroll-a-factor - name: Unenroll a factor - isSpotlight: true - code: | - ``` - res = supabase.auth.mfa.unenroll({ - "factor_id": '34e770dd-9ff9-416c-87fa-43b31d7ef225', - }) - ``` - - id: mfa-get-authenticator-assurance-level - title: 'mfa.get_authenticator_assurance_level()' - notes: | - - Authenticator Assurance Level (AAL) is the measure of the strength of an authentication mechanism. - - In Supabase, having an AAL of `aal1` refers to having the 1st factor of authentication such as an email and password or OAuth sign-in while `aal2` refers to the 2nd factor of authentication such as a time-based, one-time-password (TOTP). - - If the user has a verified factor, the `next_level` field will return `aal2`, else, it will return `aal1`. - examples: - - id: get-aal - name: Get the AAL details of a session - isSpotlight: true - code: | - ``` - res = supabase.auth.mfa.get_authenticator_assurance_level() + response: | + ```json + { + "provider_token": null, + "provider_refresh_token": null, + "access_token": "", + "refresh_token": "", + "expires_in": 3600, + "expires_at": 1700000000, + "token_type": "bearer", + "user": { + "id": "11111111-1111-1111-1111-111111111111", + "app_metadata": { + "provider": "email", + "providers": [] + }, + "user_metadata": {}, + "aud": "authenticated", + "confirmation_sent_at": "2023-02-19T00:01:51.147035Z", + "recovery_sent_at": "2024-07-21T22:20:00.366959Z", + "email_change_sent_at": null, + "new_email": null, + "invited_at": null, + "action_link": null, + "email": "email@example.com", + "phone": "", + "created_at": "2023-02-19T00:01:51.142802Z", + "confirmed_at": "2023-02-19T00:01:51.351735Z", + "email_confirmed_at": "2023-02-19T00:01:51.351735Z", + "phone_confirmed_at": null, + "last_sign_in_at": "2024-07-21T22:36:45.194120Z", + "role": "authenticated", + "updated_at": "2024-07-21T22:36:45.196044Z", + "identities": [], + "factors": null, + "is_anonymous": false + } + } ``` - id: get-user title: 'get_user' @@ -1210,62 +1172,349 @@ functions: ``` response = supabase.auth.get_user(jwt) ``` - - - id: get-session - title: 'get_session' + - id: update-user + title: 'update_user()' notes: | - - This method retrieves the current local session (i.e in memory). - - The session contains a signed JWT and unencoded session data. - - Since the unencoded session data is retrieved from the local storage medium, **do not** rely on it as a source of trusted data on the server. It could be tampered with by the sender. If you need verified, trustworthy user data, call [`get_user`](/docs/reference/python/auth-getuser) instead. - - If the session has an expired access token, this method will use the refresh token to get a new session. + - In order to use the `update_user()` method, the user needs to be signed in first. + - By default, email updates sends a confirmation link to both the user's current and new email. + To only send a confirmation link to the user's new email, disable **Secure email change** in your project's [email auth provider settings](/dashboard/project/_/auth/providers). + examples: - - id: get-the-session-data - name: Get the session data - isSpotlight: true + - id: update-the-email-for-an-authenticated-user + name: Update the email for an authenticated user + description: Sends a "Confirm Email Change" email to the new email address. + isSpotlight: false code: | ```python - response = supabase.auth.get_session() + response = supabase.auth.update_user({ + "email": "new@email.com" + }) ``` response: | ```json { - "provider_token": null, - "provider_refresh_token": null, - "access_token": "", - "refresh_token": "", - "expires_in": 3600, - "expires_at": 1700000000, - "token_type": "bearer", "user": { "id": "11111111-1111-1111-1111-111111111111", + "aud": "authenticated", + "role": "authenticated", + "email": "example@email.com", + "email_confirmed_at": "2024-01-01T00:00:00Z", + "phone": "", + "confirmed_at": "2024-01-01T00:00:00Z", + "new_email": "new@email.com", + "email_change_sent_at": "2024-01-01T00:00:00Z", + "last_sign_in_at": "2024-01-01T00:00:00Z", "app_metadata": { "provider": "email", - "providers": [] + "providers": [ + "email" + ] }, - "user_metadata": {}, - "aud": "authenticated", - "confirmation_sent_at": "2023-02-19T00:01:51.147035Z", - "recovery_sent_at": "2024-07-21T22:20:00.366959Z", - "email_change_sent_at": null, - "new_email": null, - "invited_at": null, - "action_link": null, - "email": "email@example.com", - "phone": "", - "created_at": "2023-02-19T00:01:51.142802Z", - "confirmed_at": "2023-02-19T00:01:51.351735Z", - "email_confirmed_at": "2023-02-19T00:01:51.351735Z", - "phone_confirmed_at": null, - "last_sign_in_at": "2024-07-21T22:36:45.194120Z", - "role": "authenticated", - "updated_at": "2024-07-21T22:36:45.196044Z", - "identities": [], - "factors": null, + "user_metadata": { + "email": "example@email.com", + "email_verified": false, + "phone_verified": false, + "sub": "11111111-1111-1111-1111-111111111111" + }, + "identities": [ + { + "identity_id": "22222222-2222-2222-2222-222222222222", + "id": "11111111-1111-1111-1111-111111111111", + "user_id": "11111111-1111-1111-1111-111111111111", + "identity_data": { + "email": "example@email.com", + "email_verified": false, + "phone_verified": false, + "sub": "11111111-1111-1111-1111-111111111111" + }, + "provider": "email", + "last_sign_in_at": "2024-01-01T00:00:00Z", + "created_at": "2024-01-01T00:00:00Z", + "updated_at": "2024-01-01T00:00:00Z", + "email": "example@email.com" + } + ], + "created_at": "2024-01-01T00:00:00Z", + "updated_at": "2024-01-01T00:00:00Z", "is_anonymous": false } } ``` + - id: update-the-phone-for-an-authenticated-user + name: Update the phone number for an authenticated user + description: Sends a one-time password (OTP) to the new phone number. + isSpotlight: false + code: | + ```python + response = supabase.auth.update_user({ + "phone": "123456789" + }) + ``` + - id: update-the-password-for-an-authenticated-user + name: Update the password for an authenticated user + isSpotlight: false + code: | + ```python + response = supabase.auth.update_user({ + "password": "new password" + }) + ``` + - id: update-the-users-metadata + name: Update the user's metadata + isSpotlight: true + code: | + ```python + response = supabase.auth.update_user({ + "data": { "hello": "world" } + }) + ``` + - id: update-password-with-reauthentication + name: Update the user's password with a nonce + description: | + If **Secure password change** is enabled in your [project's email provider settings](/dashboard/project/_/auth/providers), updating the user's password would require a nonce if the user **hasn't recently signed in**. The nonce is sent to the user's email or phone number. A user is deemed recently signed in if the session was created in the last 24 hours. + isSpotlight: true + code: | + ```python + response = supabase.auth.update_user({ + "password": "new password", + "nonce": "123456" + }) + ``` + - id: get-user-identities + title: 'get_user_identities()' + notes: | + Gets all the identities linked to a user. + - The user needs to be signed in to call `get_user_identities()`. + examples: + - id: get-user-identities + name: Returns a list of identities linked to the user + isSpotlight: true + code: | + ```python + response = supabase.auth.get_user_identities() + ``` + response: | + ```json + { + "identities": [ + { + "identity_id": "22222222-2222-2222-2222-222222222222", + "id": "2024-01-01T00:00:00Z", + "user_id": "2024-01-01T00:00:00Z", + "identity_data": { + "email": "example@email.com", + "email_verified": false, + "phone_verified": false, + "sub": "11111111-1111-1111-1111-111111111111" + }, + "provider": "email", + "last_sign_in_at": "2024-01-01T00:00:00Z", + "created_at": "2024-01-01T00:00:00Z", + "updated_at": "2024-01-01T00:00:00Z", + "email": "example@email.com" + } + ] + } + ``` + - id: link-identity + title: 'link_identity()' + params: + - name: credentials + isOptional: false + type: SignInWithOAuthCredentials + subContent: + - name: provider + isOptional: false + type: boolean + description: One of the providers supported by GoTrue. + - name: options + isOptional: true + type: object + subContent: + - name: scopes + isOptional: true + type: string + description: A space-separated list of scopes granted to the OAuth application. + - name: redirect_to + isOptional: true + type: string + description: A URL to send the user to after they are confirmed. + - name: query_params + isOptional: true + type: string + description: An object of query params + notes: | + - The **Enable Manual Linking** option must be enabled from your [project's authentication settings](/dashboard/project/_/settings/auth). + - The user needs to be signed in to call `link_identity()`. + - If the candidate identity is already linked to the existing user or another user, `link_identity()` will fail. + - If `link_identity` is run on the server, you should handle the redirect. + examples: + - id: link-identity + name: Link an identity to a user + isSpotlight: true + code: | + ```python + response = supabase.auth.link_identity({ + provider: 'github' + }) + ``` + response: | + ```json + { + "provider": "github", + "url": "" + } + ``` + - id: unlink-identity + title: 'unlink_identity()' + params: + - name: identity + isOptional: false + type: UserIdentity + subContent: + - name: id + isOptional: false + type: string + - name: identity_id + isOptional: false + type: string + - name: provider + isOptional: false + type: string + - name: user_id + isOptional: false + type: string + - name: created_at + isOptional: true + type: string + - name: identity_data + isOptional: true + type: Dict[str, Any] + - name: last_sign_in_at + isOptional: true + type: string + - name: updated_at + isOptional: true + type: string + notes: | + - The **Enable Manual Linking** option must be enabled from your [project's authentication settings](/dashboard/project/_/settings/auth). + - The user needs to be signed in to call `unlink_identity()`. + - The user must have at least 2 identities in order to unlink an identity. + - The identity to be unlinked must belong to the user. + examples: + - id: unlink-identity + name: Unlink an identity + isSpotlight: true + code: | + ```python + # retrieve all identites linked to a user + res = supabase.auth.get_user_identities() + # find the google identity + google_identity = list( + filter(lambda identity: identity.provider == "google", res.identities) + ).pop() + + # unlink the google identity + response = supabase.auth.unlink_identity(google_identity) + ``` + - id: send-password-reauthentication + title: 'reauthenticate()' + notes: | + - This method is used together with `updateUser()` when a user's password needs to be updated. + - If you require your user to reauthenticate before updating their password, you need to enable the **Secure password change** option in your [project's email provider settings](/dashboard/project/_/auth/providers). + - A user is only require to reauthenticate before updating their password if **Secure password change** is enabled and the user **hasn't recently signed in**. A user is deemed recently signed in if the session was created in the last 24 hours. + - This method will send a nonce to the user's email. If the user doesn't have a confirmed email address, the method will send the nonce to the user's confirmed phone number instead. + examples: + - id: send-reauthentication-nonce + name: Send reauthentication nonce + description: Sends a reauthentication nonce to the user's email or phone number. + isSpotlight: true + code: | + ```python + response = supabase.auth.reauthenticate() + ``` + - id: resend-email-or-phone-otps + title: 'resend()' + params: + - name: credentials + isOptional: false + type: ResendCredentials + subContent: + - name: email + isOptional: true + type: string + description: One of email or phone must be provided. + - name: phone + isOptional: true + type: string + description: One of email or phone must be provided. + - name: type + isOptional: false + type: signup | email_change | sms | phone_change + - name: options + isOptional: true + type: object + subContent: + - name: captcha_token + isOptional: true + type: string + description: Verification token received when the user completes the captcha on the site. + - name: email_redirect_to + isOptional: true + type: string + description: A URL to send the user to after they have signed-in. + notes: | + - Resends a signup confirmation, email change or phone change email to the user. + - Passwordless sign-ins can be resent by calling the `sign_in_with_otp()` method again. + - Password recovery emails can be resent by calling the `reset_password_for_email()` method again. + - This method will only resend an email or phone OTP to the user if there was an initial signup, email change or phone change request being made. + - You can specify a redirect url when you resend an email link using the `email_redirect_to` option. + examples: + - id: resend-email-signup-confirmation + name: Resend an email signup confirmation + description: Resends the email signup confirmation to the user + isSpotlight: true + code: | + ```python + response = supabase.auth.resend({ + "type": "signup", + "email": "email@example.com", + "options": { + "email_redirect_to": "https://example.com/welcome" + } + }) + ``` + - id: resend-phone-signup-confirmation + name: Resend a phone signup confirmation + description: Resends the phone signup confirmation email to the user + code: | + ```python + response = supabase.auth.resend({ + "type": "sms", + "phone": "1234567890" + }) + ``` + - id: resend-email-change-email + name: Resend email change email + description: Resends the email change email to the user + code: | + ```python + response = supabase.auth.resend({ + "type": "email_change", + "email": "email@example.com" + }) + ``` + - id: resend-phone-change + name: Resend phone change OTP + description: Resends the phone change OTP to the user + code: | + ```python + response = supabase.auth.resend({ + "type": "phone_change", + "phone": "1234567890" + }) + ``` - id: set-session title: 'set_session()' params: @@ -1448,6 +1697,1015 @@ functions: } } ``` + + - id: exchange-code-for-session + title: 'exchange_code_for_session()' + params: + - name: auth_code + isOptional: false + type: string + notes: | + Log in an existing user by exchanging an Auth Code issued during the PKCE flow. + + - Used when `flow_type` is set to `pkce` in client options. + examples: + - id: exchange-auth-code + name: Exchange Auth Code + isSpotlight: true + code: | + ```python + response = supabase.auth.exchange_code_for_session("auth_code": "34e770dd-9ff9-416c-87fa-43b31d7ef225") + ``` + response: | + ```json + { + "session": { + "access_token": "", + "token_type": "bearer", + "expires_in": 3600, + "expires_at": 1700000000, + "refresh_token": "", + "user": { + "id": "11111111-1111-1111-1111-111111111111", + "aud": "authenticated", + "role": "authenticated", + "email": "example@email.com", + "email_confirmed_at": "2024-01-01T00:00:00Z", + "phone": "", + "confirmation_sent_at": "2024-01-01T00:00:00Z", + "confirmed_at": "2024-01-01T00:00:00Z", + "last_sign_in_at": "2024-01-01T00:00:00Z", + "app_metadata": { + "provider": "email", + "providers": [ + "email", + "" + ] + }, + "user_metadata": { + "email": "email@email.com", + "email_verified": true, + "full_name": "User Name", + "iss": "", + "name": "User Name", + "phone_verified": false, + "provider_id": "", + "sub": "" + }, + "identities": [ + { + "identity_id": "22222222-2222-2222-2222-222222222222", + "id": "11111111-1111-1111-1111-111111111111", + "user_id": "11111111-1111-1111-1111-111111111111", + "identity_data": { + "email": "example@email.com", + "email_verified": false, + "phone_verified": false, + "sub": "11111111-1111-1111-1111-111111111111" + }, + "provider": "email", + "last_sign_in_at": "2024-01-01T00:00:00Z", + "created_at": "2024-01-01T00:00:00Z", + "updated_at": "2024-01-01T00:00:00Z", + "email": "email@example.com" + }, + { + "identity_id": "33333333-3333-3333-3333-333333333333", + "id": "", + "user_id": "", + "identity_data": { + "email": "example@email.com", + "email_verified": true, + "full_name": "User Name", + "iss": "", + "name": "User Name", + "phone_verified": false, + "provider_id": "", + "sub": "" + }, + "provider": "", + "last_sign_in_at": "2024-01-01T00:00:00Z", + "created_at": "2024-01-01T00:00:00Z", + "updated_at": "2024-01-01T00:00:00Z", + "email": "example@email.com" + } + ], + "created_at": "2024-01-01T00:00:00Z", + "updated_at": "2024-01-01T00:00:00Z", + "is_anonymous": false + }, + "provider_token": "", + "provider_refresh_token": "" + }, + "user": { + "id": "11111111-1111-1111-1111-111111111111", + "aud": "authenticated", + "role": "authenticated", + "email": "example@email.com", + "email_confirmed_at": "2024-01-01T00:00:00Z", + "phone": "", + "confirmation_sent_at": "2024-01-01T00:00:00Z", + "confirmed_at": "2024-01-01T00:00:00Z", + "last_sign_in_at": "2024-01-01T00:00:00Z", + "app_metadata": { + "provider": "email", + "providers": [ + "email", + "" + ] + }, + "user_metadata": { + "email": "email@email.com", + "email_verified": true, + "full_name": "User Name", + "iss": "", + "name": "User Name", + "phone_verified": false, + "provider_id": "", + "sub": "" + }, + "identities": [ + { + "identity_id": "22222222-2222-2222-2222-222222222222", + "id": "11111111-1111-1111-1111-111111111111", + "user_id": "11111111-1111-1111-1111-111111111111", + "identity_data": { + "email": "example@email.com", + "email_verified": false, + "phone_verified": false, + "sub": "11111111-1111-1111-1111-111111111111" + }, + "provider": "email", + "last_sign_in_at": "2024-01-01T00:00:00Z", + "created_at": "2024-01-01T00:00:00Z", + "updated_at": "2024-01-01T00:00:00Z", + "email": "email@example.com" + }, + { + "identity_id": "33333333-3333-3333-3333-333333333333", + "id": "", + "user_id": "", + "identity_data": { + "email": "example@email.com", + "email_verified": true, + "full_name": "User Name", + "iss": "", + "name": "User Name", + "phone_verified": false, + "provider_id": "", + "sub": "" + }, + "provider": "", + "last_sign_in_at": "2024-01-01T00:00:00Z", + "created_at": "2024-01-01T00:00:00Z", + "updated_at": "2024-01-01T00:00:00Z", + "email": "example@email.com" + } + ], + "created_at": "2024-01-01T00:00:00Z", + "updated_at": "2024-01-01T00:00:00Z", + "is_anonymous": false + }, + "redirect_type": null + } + ``` + - id: auth-mfa-api + title: 'Overview' + notes: | + This section contains methods commonly used for Multi-Factor Authentication (MFA) and are invoked behind the `supabase.auth.mfa` namespace. + + Currently, we only support time-based one-time password (TOTP) as the 2nd factor. We don't support recovery codes but we allow users to enroll more than 1 TOTP factor, with an upper limit of 10. + + Having a 2nd TOTP factor for recovery frees the user of the burden of having to store their recovery codes somewhere. It also reduces the attack surface since multiple recovery codes are usually generated compared to just having 1 backup TOTP factor. + - id: mfa-enroll + title: 'mfa.enroll()' + notes: | + - Currently, `totp` is the only supported `factor_type`. The returned `id` should be used to create a challenge. + - To create a challenge, see [`mfa.challenge()`](/docs/reference/python/auth-mfa-challenge). + - To verify a challenge, see [`mfa.verify()`](/docs/reference/python/auth-mfa-verify). + - To create and verify a challenge in a single step, see [`mfa.challenge_and_verify()`](/docs/reference/python/auth-mfa-challengeandverify). + examples: + - id: enroll-totp-factor + name: Enroll a time-based, one-time password (TOTP) factor + isSpotlight: true + code: | + ``` + res = supabase.auth.mfa.enroll({ + "factor_type": "totp", + "friendly_name": "your_friendly_name" + }) + ``` + - id: mfa-challenge + title: 'mfa.challenge()' + notes: | + - An [enrolled factor](/docs/reference/python/auth-mfa-enroll) is required before creating a challenge. + - To verify a challenge, see [`mfa.verify()`](/docs/reference/python/auth-mfa-verify). + examples: + - id: create-mfa-challenge + name: Create a challenge for a factor + isSpotlight: true + code: | + ``` + res = supabase.auth.mfa.challenge({ + "factor_id": '34e770dd-9ff9-416c-87fa-43b31d7ef225' + }) + ``` + - id: mfa-verify + title: 'mfa.verify()' + notes: | + - To verify a challenge, please [create a challenge](/docs/reference/python/auth-mfa-challenge) first. + examples: + - id: verify-challenge + name: Verify a challenge for a factor + isSpotlight: true + code: | + ``` + res = supabase.auth.mfa.verify({ + "factor_id": '34e770dd-9ff9-416c-87fa-43b31d7ef225', + "challenge_id": '4034ae6f-a8ce-4fb5-8ee5-69a5863a7c15', + "code": '123456' + }) + ``` + - id: mfa-challenge-and-verify + title: 'mfa.challenge_and_verify()' + notes: | + - An [enrolled factor](/docs/reference/python/auth-mfa-enroll) is required before invoking `challengeAndVerify()`. + - Executes [`mfa.challenge()`](/docs/reference/python/auth-mfa-challenge) and [`mfa.verify()`](/docs/reference/python/auth-mfa-verify) in a single step. + examples: + - id: challenge-and-verify + name: Create and verify a challenge for a factor + isSpotlight: true + code: | + ``` + res = supabase.auth.mfa.challenge_and_verify({ + "factor_id": '34e770dd-9ff9-416c-87fa-43b31d7ef225', + "code": '123456' + }) + ``` + - id: mfa-unenroll + title: 'mfa.unenroll()' + examples: + - id: unenroll-a-factor + name: Unenroll a factor + isSpotlight: true + code: | + ``` + res = supabase.auth.mfa.unenroll({ + "factor_id": '34e770dd-9ff9-416c-87fa-43b31d7ef225', + }) + ``` + - id: mfa-get-authenticator-assurance-level + title: 'mfa.get_authenticator_assurance_level()' + notes: | + - Authenticator Assurance Level (AAL) is the measure of the strength of an authentication mechanism. + - In Supabase, having an AAL of `aal1` refers to having the 1st factor of authentication such as an email and password or OAuth sign-in while `aal2` refers to the 2nd factor of authentication such as a time-based, one-time-password (TOTP). + - If the user has a verified factor, the `next_level` field will return `aal2`, else, it will return `aal1`. + examples: + - id: get-aal + name: Get the AAL details of a session + isSpotlight: true + code: | + ``` + res = supabase.auth.mfa.get_authenticator_assurance_level() + ``` + - id: admin-api + title: 'Overview' + notes: | + - Any method under the `supabase.auth.admin` namespace requires a `service_role` key. + - These methods are considered admin methods and should be called on a trusted server. Never expose your `service_role` key in the browser. + examples: + - id: create-auth-admin-client + name: Create server-side auth client + isSpotlight: true + code: | + ```python + from supabase import create_client + from supabase.lib.client_options import ClientOptions + + supabase = create_client( + supabase_url, + service_role_key, + options=ClientOptions( + auto_refresh_token=False, + persist_session=False, + ) + ) + + # Access auth admin api + admin_auth_client = supabase.auth.admin + ``` + + - id: get-user-by-id + title: 'get_user_by_id()' + params: + - name: uid + isOptional: false + type: string + description: | + The user's unique identifier + + This function should only be called on a server. Never expose your `service_role` key in the browser. + notes: | + - Fetches the user object from the database based on the user's id. + - The `get_user_by_id()` method requires the user's id which maps to the `auth.users.id` column. + examples: + - id: fetch-the-user-object-using-the-access-token-jwt + name: Fetch the user object using the access_token jwt + isSpotlight: true + code: | + ```python + response = supabase.auth.admin.get_user_by_id(1) + ``` + response: | + ```json + { + "user": { + "id": "1", + "aud": "authenticated", + "role": "authenticated", + "email": "example@email.com", + "email_confirmed_at": "2024-01-01T00:00:00Z", + "phone": "", + "confirmation_sent_at": "2024-01-01T00:00:00Z", + "confirmed_at": "2024-01-01T00:00:00Z", + "last_sign_in_at": "2024-01-01T00:00:00Z", + "app_metadata": {}, + "user_metadata": {}, + "identities": [ + { + "identity_id": "22222222-2222-2222-2222-222222222222", + "id": "1", + "user_id": "1", + "identity_data": { + "email": "example@email.com", + "email_verified": true, + "phone_verified": false, + "sub": "1" + }, + "provider": "email", + "last_sign_in_at": "2024-01-01T00:00:00Z", + "created_at": "2024-01-01T00:00:00Z", + "updated_at": "2024-01-01T00:00:00Z", + "email": "email@example.com" + } + ], + "created_at": "2024-01-01T00:00:00Z", + "updated_at": "2024-01-01T00:00:00Z", + "is_anonymous": false + } + } + ``` + - id: list-users + title: 'list_users()' + params: + - name: params + isOptional: true + type: PageParams + description: | + An object which supports page and perPage as numbers, to alter the paginated results. + subContent: + - name: page + isOptional: true + type: number + description: The page number + - name: per_page + isOptional: true + type: number + description: Number of items returned per page + notes: | + - Defaults to return 50 users per page. + examples: + - id: get-a-full-list-of-users + name: Get a page of users + isSpotlight: true + code: | + ```python + response = supabase.auth.admin.list_users() + ``` + - id: get-paginated-list-of-users + name: Paginated list of users + isSpotlight: false + code: | + ```python + response = supabase.auth.admin.list_users( + page=1, + perPage=1000 + ) + ``` + - id: create-user + title: 'create_user()' + params: + - name: attributes + isOptional: false + type: AdminUserAttributes + subContent: + - name: app_metadata + isOptional: true + type: object + description: | + A custom data object to store the user's application specific metadata. This maps to the `auth.users.app_metadata` column. + - name: ban_duration + isOptional: true + type: string + description: Determines how long a user is banned for. + - name: email + isOptional: true + type: string + description: The user's email. + - name: email_confirm + isOptional: true + type: boolean + description: Confirms the user's email address if set to true. + - name: nonce + isOptional: true + type: string + description: The nonce sent for reauthentication if the user's password is to be updated. + - name: password + isOptional: true + type: string + description: The user's password. + - name: phone + isOptional: true + type: string + description: The user's phone. + - name: phone_confirm + isOptional: true + type: boolean + description: Confirms the user's phone number if set to true. + - name: role + isOptional: true + type: string + description: The `role` claim set in the user's access token JWT. + - name: user_metadata + isOptional: true + type: object + description: | + A custom data object to store the user's metadata. This maps to the `auth.users.raw_user_meta_data` column. + notes: | + - To confirm the user's email address or phone number, set `email_confirm` or `phone_confirm` to true. Both arguments default to false. + - `create_user()` will not send a confirmation email to the user. You can use [`invite_user_by_email()`](/docs/reference/python/auth-admin-inviteuserbyemail) if you want to send them an email invite instead. + - If you are sure that the created user's email or phone number is legitimate and verified, you can set the `email_confirm` or `phone_confirm` param to `true`. + examples: + - id: create-a-new-user-with-custom-user-metadata + name: With custom user metadata + isSpotlight: true + code: | + ```python + response = supabase.auth.admin.create_user({ + "email": "user@email.com", + "password": "password", + "user_metadata": { "name": "Yoda" } + }) + ``` + response: | + ```json + { + "user": { + "id": "1", + "aud": "authenticated", + "role": "authenticated", + "email": "example@email.com", + "email_confirmed_at": "2024-01-01T00:00:00Z", + "phone": "", + "confirmation_sent_at": "2024-01-01T00:00:00Z", + "confirmed_at": "2024-01-01T00:00:00Z", + "last_sign_in_at": "2024-01-01T00:00:00Z", + "app_metadata": {}, + "user_metadata": {}, + "identities": [ + { + "identity_id": "22222222-2222-2222-2222-222222222222", + "id": "1", + "user_id": "1", + "identity_data": { + "email": "example@email.com", + "email_verified": true, + "phone_verified": false, + "sub": "1" + }, + "provider": "email", + "last_sign_in_at": "2024-01-01T00:00:00Z", + "created_at": "2024-01-01T00:00:00Z", + "updated_at": "2024-01-01T00:00:00Z", + "email": "email@example.com" + } + ], + "created_at": "2024-01-01T00:00:00Z", + "updated_at": "2024-01-01T00:00:00Z", + "is_anonymous": false + } + } + ``` + - id: auto-confirm-the-users-email + name: Auto-confirm the user's email + code: | + ```python + response = supabase.auth.admin.create_user({ + "email": "user@email.com", + "email_confirm": True + }) + ``` + - id: auto-confirm-the-users-phone-number + name: Auto-confirm the user's phone number + code: | + ```python + response = supabase.auth.admin.create_user({ + "phone": "1234567890", + "phone_confirm": True + }) + ``` + - id: delete-user + title: 'delete_user()' + params: + - name: id + isOptional: false + type: string + description: The user id you want to remove. + - name: should_soft_delete + isOptional: true + type: boolean + description: | + If true, then the user will be soft-deleted (setting `deleted_at` to the current timestamp and disabling their account while preserving their data) from the auth schema. Defaults to false for backward compatibility. + + This function should only be called on a server. Never expose your `service_role` key in the browser. + description: Delete a user. Requires a `service_role` key. + notes: | + - The `delete_user()` method requires the user's ID, which maps to the `auth.users.id` column. + examples: + - id: removes-a-user + name: Removes a user + isSpotlight: true + code: | + ```python + supabase.auth.admin.delete_user( + "715ed5db-f090-4b8c-a067-640ecee36aa0" + ) + ``` + - id: invite-user-by-email + title: 'invite_user_by_email()' + params: + - name: email + isOptional: false + type: string + description: The email address of the user. + - name: options + isOptional: true + type: InviteUserByEmailOptions + subContent: + - name: data + isOptional: true + type: object + description: | + A custom data object to store additional metadata about the user. This maps to the `auth.users.user_metadata` column. + - name: redirect_to + isOptional: true + type: string + description: | + The URL which will be appended to the email link sent to the user's email address. Once clicked the user will end up on this URL. + description: Sends an invite link to an email address. + notes: | + - Sends an invite link to the user's email address. + - The `invite_user_by_email()` method is typically used by administrators to invite users to join the application. + - Note that PKCE is not supported when using `invite_user_by_email`. This is because the browser initiating the invite is often different from the browser accepting the invite which makes it difficult to provide the security guarantees required of the PKCE flow. + examples: + - id: invite-a-user + name: Invite a user + isSpotlight: true + code: | + ```python + response = supabase.auth.admin.invite_user_by_email("email@example.com") + ``` + response: | + ```json + { + "user": { + "id": "11111111-1111-1111-1111-111111111111", + "aud": "authenticated", + "role": "authenticated", + "email": "example@email.com", + "invited_at": "2024-01-01T00:00:00Z", + "phone": "", + "confirmation_sent_at": "2024-01-01T00:00:00Z", + "app_metadata": { + "provider": "email", + "providers": [ + "email" + ] + }, + "user_metadata": {}, + "identities": [ + { + "identity_id": "22222222-2222-2222-2222-222222222222", + "id": "11111111-1111-1111-1111-111111111111", + "user_id": "11111111-1111-1111-1111-111111111111", + "identity_data": { + "email": "example@email.com", + "email_verified": false, + "phone_verified": false, + "sub": "11111111-1111-1111-1111-111111111111" + }, + "provider": "email", + "last_sign_in_at": "2024-01-01T00:00:00Z", + "created_at": "2024-01-01T00:00:00Z", + "updated_at": "2024-01-01T00:00:00Z", + "email": "example@email.com" + } + ], + "created_at": "2024-01-01T00:00:00Z", + "updated_at": "2024-01-01T00:00:00Z", + "is_anonymous": false + } + } + ``` + - id: generate-link + title: 'generate_link()' + params: + - name: params + type: GenerateLinkParams + subContent: + - name: type + type: 'signup | invite | magiclink | recovery | email_change_current | email_change_new' + - name: email + type: string + - name: password + type: string + isOptional: true + description: Only required if type is `signup`. + - name: new_email + type: string + isOptional: true + description: Only required if type is `email_change_current` or `email_change_new`. + - name: options + type: object + isOptional: true + subContent: + - name: data + type: object + description: > + Custom JSON object containing user metadata, to be stored in the `raw_user_meta_data` column. + Only accepted if type is `signup`, `invite`, or `magiclink`. + - name: redirect_to + type: string + description: > + A redirect URL which will be appended to the generated email link. + notes: | + - The following types can be passed into `generate_link()`: `signup`, `magiclink`, `invite`, `recovery`, `email_change_current`, `email_change_new`, `phone_change`. + - `generate_link()` only generates the email link for `email_change_email` if the **Secure email change** is enabled in your project's [email auth provider settings](/dashboard/project/_/auth/providers). + - `generate_link()` handles the creation of the user for `signup`, `invite` and `magiclink`. + examples: + - id: generate-a-signup-link + name: Generate a signup link + isSpotlight: true + code: | + ```python + response = supabase.auth.admin.generate_link({ + "type": "signup", + "email": "email@example.com", + "password": "secret" + }) + ``` + response: | + ```json + { + "properties": { + "action_link": "", + "email_otp": "999999", + "hashed_token": "", + "verification_type": "signup" + }, + "user": { + "id": "11111111-1111-1111-1111-111111111111", + "aud": "authenticated", + "role": "authenticated", + "email": "email@example.com", + "phone": "", + "confirmation_sent_at": "2024-01-01T00:00:00Z", + "app_metadata": { + "provider": "email", + "providers": [ + "email" + ] + }, + "user_metadata": {}, + "identities": [ + { + "identity_id": "22222222-2222-2222-2222-222222222222", + "id": "11111111-1111-1111-1111-111111111111", + "user_id": "11111111-1111-1111-1111-111111111111", + "identity_data": { + "email": "email@example.com", + "email_verified": false, + "phone_verified": false, + "sub": "11111111-1111-1111-1111-111111111111" + }, + "provider": "email", + "last_sign_in_at": "2024-01-01T00:00:00Z", + "created_at": "2024-01-01T00:00:00Z", + "updated_at": "2024-01-01T00:00:00Z", + "email": "email@example.com" + } + ], + "created_at": "2024-01-01T00:00:00Z", + "updated_at": "2024-01-01T00:00:00Z", + "is_anonymous": false + } + } + ``` + - id: generate-an-invite-link + name: Generate an invite link + isSpotlight: false + code: | + ```python + response = supabase.auth.admin.generate_link({ + "type": "invite", + "email": "email@example.com" + }) + ``` + - id: generate-a-magic-link + name: Generate a magic link + isSpotlight: false + code: | + ```python + response = supabase.auth.admin.generate_link({ + "type": "magiclink", + "email": "email@example.com" + }) + ``` + - id: generate-a-recovery-link + name: Generate a recovery link + isSpotlight: false + code: | + ```python + response = supabase.auth.admin.generate_link({ + "type": "recovery", + "email": "email@example.com" + }) + ``` + - id: generate-links-to-change-current-email-address + name: Generate links to change current email address + isSpotlight: false + code: | + ```python + # generate an email change link to be sent to the current email address + response = supabase.auth.admin.generate_link({ + "type": "email_change_current", + "email": "current.email@example.com", + "new_email": "new.email@example.com" + }) + + # generate an email change link to be sent to the new email address + response = supabase.auth.admin.generate_link({ + "type": "email_change_new", + "email": "current.email@example.com", + "new_email": "new.email@example.com" + }) + ``` + - id: update-user-by-id + title: 'update_user_by_id()' + params: + - name: uid + isOptional: false + type: string + - name: attributes + isOptional: false + type: AdminUserAttributes + description: | + The data you want to update. + + This function should only be called on a server. Never expose your `service_role` key in the browser. + subContent: + - name: app_metadata + isOptional: true + type: object + description: | + A custom data object to store the user's application specific metadata. This maps to the `auth.users.app_metadata` column. + - name: ban_duration + isOptional: true + type: string + description: Determines how long a user is banned for. + - name: email + isOptional: true + type: string + description: The user's email. + - name: email_confirm + isOptional: true + type: boolean + description: Confirms the user's email address if set to true. + - name: nonce + isOptional: true + type: string + description: The nonce sent for reauthentication if the user's password is to be updated. + - name: password + isOptional: true + type: string + description: The user's password. + - name: phone + isOptional: true + type: string + description: The user's phone. + - name: phone_confirm + isOptional: true + type: boolean + description: Confirms the user's phone number if set to true. + - name: role + isOptional: true + type: string + description: The `role` claim set in the user's access token JWT. + - name: user_metadata + isOptional: true + type: string + description: A custom data object to store the user's metadata. This maps to the `auth.users.raw_user_meta_data` column. + examples: + - id: updates-a-users-email + name: Updates a user's email + isSpotlight: false + code: | + ```python + response = supabase.auth.admin.update_user_by_id( + "11111111-1111-1111-1111-111111111111", + { "email": "new@email.com" } + ) + ``` + response: | + ```json + { + "user": { + "id": "11111111-1111-1111-1111-111111111111", + "aud": "authenticated", + "role": "authenticated", + "email": "new@email.com", + "email_confirmed_at": "2024-01-01T00:00:00Z", + "phone": "", + "confirmed_at": "2024-01-01T00:00:00Z", + "recovery_sent_at": "2024-01-01T00:00:00Z", + "last_sign_in_at": "2024-01-01T00:00:00Z", + "app_metadata": { + "provider": "email", + "providers": [ + "email" + ] + }, + "user_metadata": { + "email": "example@email.com", + "email_verified": false, + "phone_verified": false, + "sub": "11111111-1111-1111-1111-111111111111" + }, + "identities": [ + { + "identity_id": "22222222-2222-2222-2222-222222222222", + "id": "11111111-1111-1111-1111-111111111111", + "user_id": "11111111-1111-1111-1111-111111111111", + "identity_data": { + "email": "example@email.com", + "email_verified": false, + "phone_verified": false, + "sub": "11111111-1111-1111-1111-111111111111" + }, + "provider": "email", + "last_sign_in_at": "2024-01-01T00:00:00Z", + "created_at": "2024-01-01T00:00:00Z", + "updated_at": "2024-01-01T00:00:00Z", + "email": "example@email.com" + } + ], + "created_at": "2024-01-01T00:00:00Z", + "updated_at": "2024-01-01T00:00:00Z", + "is_anonymous": false + } + } + ``` + - id: updates-a-users-password + name: Updates a user's password + isSpotlight: false + code: | + ```python + response = supabase.auth.admin.update_user_by_id( + "6aa5d0d4-2a9f-4483-b6c8-0cf4c6c98ac4", + { "password": "new_password" } + ) + ``` + - id: updates-a-users-metadata + name: Updates a user's metadata + isSpotlight: true + code: | + ```python + response = supabase.auth.admin.update_user_by_id( + "6aa5d0d4-2a9f-4483-b6c8-0cf4c6c98ac4", + { "user_metadata": { "hello": "world" } } + ) + ``` + - id: updates-a-users-app-metadata + name: Updates a user's app_metadata + isSpotlight: false + code: | + ```python + response = supabase.auth.admin.update_user_by_id( + "6aa5d0d4-2a9f-4483-b6c8-0cf4c6c98ac4", + { "app_metadata": { "plan": "trial" } } + ) + ``` + - id: confirms-a-users-email-address + name: Confirms a user's email address + isSpotlight: false + code: | + ```python + response = supabase.auth.admin.update_user_by_id( + "6aa5d0d4-2a9f-4483-b6c8-0cf4c6c98ac4", + { "email_confirm": True } + ) + ``` + - id: confirms-a-users-phone-number + name: Confirms a user's phone number + isSpotlight: false + code: | + ```python + response = supabase.auth.admin.update_user_by_id( + "6aa5d0d4-2a9f-4483-b6c8-0cf4c6c98ac4", + { "phone_confirm": True } + ) + ``` + - id: mfa-delete-factor + title: 'mfa.delete_factor()' + params: + - name: params + isOptional: false + type: AuthMFAAdminDeleteFactorParams + subContent: + - name: id + isOptional: false + type: string + description: ID of the MFA factor to delete. + - name: user_id + isOptional: false + type: string + description: ID of the user whose factor is being deleted. + notes: | + Deletes a factor on a user. This will log the user out of all active sessions if the deleted factor was verified. + examples: + - id: delete-factor + name: Delete a factor for a user + isSpotlight: true + code: | + ```python + response = supabase.auth.admin.mfa.delete_factor({ + "id": "34e770dd-9ff9-416c-87fa-43b31d7ef225", + "user_id": "a89baba7-b1b7-440f-b4bb-91026967f66b", + }) + ``` + response: | + ```json + { + "id": "34e770dd-9ff9-416c-87fa-43b31d7ef225" + } + ``` + + - id: reset-password-for-email + title: 'reset_password_for_email()' + params: + - name: email + isOptional: false + type: string + description: The email address of the user. + - name: options + isOptional: true + type: object + subContent: + - name: redirect_to + isOptional: true + type: string + description: > + The URL to send the user to after they click the password reset link. + Must be in your configured redirect URLs. + - name: captcha_token + isOptional: true + type: string + description: Verification token received when the user completes the captcha on the site. + notes: | + - The password reset flow consist of 2 broad steps: (i) Allow the user to login via the password reset link; (ii) Update the user's password. + - The `reset_password_for_email()` only sends a password reset link to the user's email. + To update the user's password, see [`update_user()`](/docs/reference/python/auth-updateuser). + - When the user clicks the reset link in the email they are redirected back to your application. + You can configure the URL that the user is redirected to with the `redirectTo` parameter. + See [redirect URLs and wildcards](/docs/guides/auth#redirect-urls-and-wildcards) to add additional redirect URLs to your project. + - After the user has been redirected successfully, prompt them for a new password and call `update_user()`: + ```python + response = supabase.auth.update_user({ + "password": new_password + }) + ``` + examples: + - id: reset-password + name: Reset password + isSpotlight: true + code: | + ```python + supabase.auth.reset_password_for_email(email, { + "redirect_to": "https://example.com/update-password", + }) + ``` + - id: select title: 'Fetch data: select()' notes: |