From 59931dff4a48e75a6ecab1317ad780337c19c2da Mon Sep 17 00:00:00 2001 From: adamjmcgrath Date: Tue, 21 Jun 2022 15:54:34 +0100 Subject: [PATCH 1/7] README first pass: toc, java examples, other updates --- README.md | 735 ++++++++++++++++++++++++++++++++++++++++++++++++++---- 1 file changed, 690 insertions(+), 45 deletions(-) diff --git a/README.md b/README.md index 9ffc0173..959461be 100644 --- a/README.md +++ b/README.md @@ -6,7 +6,28 @@ [![Maven Central](https://img.shields.io/maven-central/v/com.auth0.android/auth0.svg?style=flat-square)](https://search.maven.org/artifact/com.auth0.android/auth0) [![javadoc](https://javadoc.io/badge2/com.auth0.android/auth0/javadoc.svg)](https://javadoc.io/doc/com.auth0.android/auth0) -Android Java & Kotlin toolkit for consuming the Auth0 Authentication API +Easily integrate Auth0 into Android apps. Add **login** and **logout**, store **credentials** securely, and access **user information**. + +## Table of contents + +- [Requirements](#requirements) +- [Installation](#installation) + + [Permissions](#permissions) +- [Getting Started](#getting-started) + * [Authentication with Universal Login](#authentication-with-universal-login) + * [Authentication API](#authentication-api) + * [Management API](#management-api) + * [Token Validation](#token-validation) + * [Organizations](#organizations) +- [Credentials Manager](#credentials-manager) + * [Basic](#basic) + * [Encryption enforced](#encryption-enforced) +- [Networking client customization](#networking-client-customization) +- [FAQ](#faq) +- [Proguard](#proguard) +- [What is Auth0?](#what-is-auth0-) +- [Issue Reporting](#issue-reporting) +- [License](#license) ## Requirements @@ -29,9 +50,7 @@ android { ## Installation -### Gradle - -Auth0.android is available through [Gradle](https://gradle.org/). To install it, simply add the following line to your `build.gradle` file: +To install Auth0.Android with [Gradle](https://gradle.org/), simply add the following line to your `build.gradle` file: ```gradle dependencies { @@ -39,7 +58,7 @@ dependencies { } ``` -### Permissions +#### Permissions Open your app's `AndroidManifest.xml` file and add the following permission. @@ -47,7 +66,7 @@ Open your app's `AndroidManifest.xml` file and add the following permission. ``` -## Usage +## Getting Started First, create an instance of `Auth0` with your Application information @@ -55,6 +74,15 @@ First, create an instance of `Auth0` with your Application information val account = Auth0("{YOUR_CLIENT_ID}", "{YOUR_DOMAIN}") ``` +
+ Using Java +```java +Auth0 account = new Auth0("{YOUR_CLIENT_ID}", "{YOUR_DOMAIN}"); +``` +
+ +
+ Configure using Android Context Alternatively, you can save your Application information in the `strings.xml` file using the following names: ```xml @@ -62,7 +90,6 @@ Alternatively, you can save your Application information in the `strings.xml` fi YOUR_CLIENT_ID YOUR_DOMAIN - ``` You can then create a new Auth0 instance by passing an Android Context: @@ -70,12 +97,7 @@ You can then create a new Auth0 instance by passing an Android Context: ```kotlin val account = Auth0(context) ``` - -### OIDC Conformant Mode - -Beginning in version 2, this SDK is OIDC-Conformant by default, and will not use any legacy authentication endpoints. - -For more information, please see the [OIDC adoption guide](https://auth0.com/docs/api-auth/tutorials/adoption). +
### Authentication with Universal Login @@ -85,8 +107,9 @@ First go to the [Auth0 Dashboard](https://manage.auth0.com/#/applications) and g https://{YOUR_AUTH0_DOMAIN}/android/{YOUR_APP_PACKAGE_NAME}/callback ``` -Remember to replace `{YOUR_APP_PACKAGE_NAME}` with your actual application's package name, available in your `app/build.gradle` file as the `applicationId` value. +> ⚠️ Make sure that the [application type](https://auth0.com/docs/configure/applications) of the Auth0 application is **Native**. +Replace `{YOUR_APP_PACKAGE_NAME}` with your actual application's package name, available in your `app/build.gradle` file as the `applicationId` value. Next, define the Manifest Placeholders for the Auth0 Domain and Scheme which are going to be used internally by the library to register an **intent-filter**. Go to your application's `build.gradle` file and add the `manifestPlaceholders` line as shown below: @@ -109,13 +132,9 @@ android { } ``` -It's a good practice to define reusable resources like `@string/com_auth0_domain`, but you can also hard-code the value. The scheme value can be either `https` or a custom one. Read [this section](#a-note-about-app-deep-linking) to learn more. - -Add the internet permission. - -```xml - -``` +It's a good practice to define reusable resources like `@string/com_auth0_domain`, but you can also hard-code the value. + +> The scheme value can be either `https` or a custom one. Read [this section](#a-note-about-app-deep-linking) to learn more. Declare the callback instance that will receive the authentication result. @@ -131,37 +150,74 @@ val callback = object : Callback { } ``` +
+ Using Java + +```java +Callback callback = new Callback() { + @Override + public void onFailure(@NonNull AuthenticationException exception) { + //failed with an exception + } + + @Override + public void onSuccess(@Nullable Credentials credentials) { + //succeeded! + } +}; +``` +
+ Finally, authenticate by showing the **Auth0 Universal Login**: ```kotlin -// Configure and launch the authentication WebAuthProvider.login(account) .start(this, callback) ``` +
+ Using Java + +```java +WebAuthProvider.login(account) + .start(MainActivity.this, callback); +``` +
+ + The callback will get invoked when the user returns to your application. There are a few scenarios where this may fail: * When the device cannot open the URL because it doesn't have any compatible browser application installed. You can check this scenario with `error.isBrowserAppNotAvailable`. * When the user manually closed the browser (e.g. pressing the back key). You can check this scenario with `error.isAuthenticationCanceled`. * When there was a server error. Check the received exception for details. -If the `redirect` URL is not found in the **Allowed Callback URLs** of your Auth0 Application, the server will not make the redirection and the browser will remain open. +> If the `redirect` URL is not found in the **Allowed Callback URLs** of your Auth0 Application, the server will not make the redirection and the browser will remain open. ##### A note about App Deep Linking: -If you followed the configuration steps documented here, you may have noticed the default scheme used for the Callback URI is `https`. This works best for Android API 23 or newer if you're using [Android App Links](https://auth0.com/docs/applications/enable-android-app-links), but in previous Android versions this _may_ show the intent chooser dialog prompting the user to choose either your application or the browser. You can change this behaviour by using a custom unique scheme so that the OS opens directly the link with your app. Note that the schemes [can only have lowercase letters](https://developer.android.com/guide/topics/manifest/data-element). +If you followed the configuration steps documented here, you may have noticed the default scheme used for the Callback URI is `https`. This works best for Android API 23 or newer if you're using [Android App Links](https://auth0.com/docs/applications/enable-android-app-links), but in previous Android versions this _may_ show the intent chooser dialog prompting the user to choose either your application or the browser. You can change this behaviour by using a custom unique scheme so that the OS opens directly the link with your app. 1. Update the `auth0Scheme` Manifest Placeholder on the `app/build.gradle` file or update the intent-filter declaration in the `AndroidManifest.xml` to use the new scheme. 2. Update the **Allowed Callback URLs** in your [Auth0 Dashboard](https://manage.auth0.com/#/applications) application's settings. 3. Call `withScheme()` in the `WebAuthProvider` builder passing the custom scheme you want to use. - ```kotlin WebAuthProvider.login(account) .withScheme("myapp") .start(this, callback) ``` +
+ Using Java + +```java +//Configure and launch the authentication +WebAuthProvider.login(account) + .start(MainActivity.this, callback); +``` +
+ +> Note that the schemes [can only have lowercase letters](https://developer.android.com/guide/topics/manifest/data-element). #### Authenticate with any Auth0 connection @@ -173,6 +229,16 @@ WebAuthProvider.login(account) .start(this, callback) ``` +
+ Using Java + +```java +WebAuthProvider.login(account) + .withConnection("twitter") + .start(MainActivity.this, callback); +``` +
+ #### Specify audience ```kotlin @@ -181,6 +247,16 @@ WebAuthProvider.login(account) .start(this, callback) ``` +
+ Using Java + +```java +WebAuthProvider.login(account) + .withAudience("https://{YOUR_AUTH0_DOMAIN}/api/v2/") + .start(MainActivity.this, callback); +``` +
+ The sample above requests tokens with the audience required to call the [Management API](https://auth0.com/docs/api/management/v2) endpoints. > Replace `{YOUR_AUTH0_DOMAIN}` with your actual Auth0 domain (i.e. `mytenant.auth0.com`). If you've set up the tenant to use "Custom Domains", use that value here. @@ -193,6 +269,16 @@ WebAuthProvider.login(account) .start(this, callback) ``` +
+ Using Java + +```java +WebAuthProvider.login(account) + .withScope("openid profile email read:users") + .start(MainActivity.this, callback); +``` +
+ > The default scope used is `openid profile email`. Regardless of the scopes passed here, the `openid` scope is always enforced. #### Specify Connection scope @@ -203,6 +289,16 @@ WebAuthProvider.login(account) .start(this, callback) ``` +
+ Using Java + +```java +WebAuthProvider.login(account) + .withConnectionScope("email", "profile", "calendar:read") + .start(MainActivity.this, callback); +``` +
+ #### Customize the Custom Tabs UI If the device where the app is running has a Custom Tabs compatible Browser, a Custom Tab will be preferred for the logout flow. You can customize the Page Title visibility, the Toolbar color, and the supported Browser applications by using the `CustomTabsOptions` class. @@ -218,15 +314,29 @@ WebAuthProvider.login(account) .start(this, callback) ``` +
+ Using Java -### Clearing the session +```java +CustomTabsOptions options = CustomTabsOptions.newBuilder() + .withToolbarColor(R.color.ct_toolbar_color) + .showTitle(true) + .build(); -To log the user out and clear the SSO cookies that the Auth0 Server keeps attached to your browser app, you need to call the [logout endpoint](https://auth0.com/docs/api/authentication?#logout). This can be done is a similar fashion to how you authenticated before: using the `WebAuthProvider` class. +WebAuthProvider.login(account) + .withCustomTabsOptions(options) + .start(MainActivity.this, callback); +``` +
-Make sure to [revisit that section](#authentication-with-universal-login) to configure the Manifest Placeholders if you still cannot authenticate successfully. The values set there are used to generate the URL that the server will redirect the user back to after a successful log out. -In order for this redirection to happen, you must copy the **Allowed Callback URLs** value you added for authentication into the **Allowed Logout URLs** field in your [application settings](https://manage.auth0.com/#/applications). Both fields should have an URL with the following format: +#### Clearing the session + +To log the user out and clear the SSO cookies that the Auth0 Server keeps attached to your browser app, you need to call the [logout endpoint](https://auth0.com/docs/api/authentication?#logout). This can be done in a similar fashion to how you authenticated before: using the `WebAuthProvider` class. +Make sure to [revisit this section](#authentication-with-universal-login) to configure the Manifest Placeholders if you still cannot authenticate successfully. The values set there are used to generate the URL that the server will redirect the user back to after a successful log out. + +In order for this redirection to happen, you must copy the **Allowed Callback URLs** value you added for authentication into the **Allowed Logout URLs** field in your [application settings](https://manage.auth0.com/#/applications). Both fields should have an URL with the following format: ``` https://{YOUR_AUTH0_DOMAIN}/android/{YOUR_APP_PACKAGE_NAME}/callback @@ -234,7 +344,6 @@ https://{YOUR_AUTH0_DOMAIN}/android/{YOUR_APP_PACKAGE_NAME}/callback Remember to replace `{YOUR_APP_PACKAGE_NAME}` with your actual application's package name, available in your `app/build.gradle` file as the `applicationId` value. - Initialize the provider, this time calling the static method `logout`. ```kotlin @@ -254,6 +363,29 @@ val logoutCallback = object: Callback { } ``` +
+ Using Java + +```java +//Configure and launch the log out +WebAuthProvider.logout(account) + .start(MainActivity.this, logoutCallback); + +//Declare the callback that will receive the result +Callback logoutCallback = new Callback() { + @Override + public void onFailure(@NonNull Auth0Exception exception) { + //failed with an exception + } + + @Override + public void onSuccess(@Nullable Void payload) { + //succeeded! + } +}; +``` +
+ The callback will get invoked when the user returns to your application. There are a few scenarios where this may fail: * When the device cannot open the URL because it doesn't have any compatible browser application installed. You can check this scenario with `error.isBrowserAppNotAvailable`. @@ -270,6 +402,17 @@ WebAuthProvider.logout(account) .start(this, logoutCallback) ``` +
+ Using Java + +```java +WebAuthProvider.login(account) + .withScheme("myapp") + .start(MainActivity.this, callback); +``` +
+ + #### Customize the Custom Tabs UI If the device where the app is running has a Custom Tabs compatible Browser, a Custom Tab will be preferred for the logout flow. You can customize the Page Title visibility, the Toolbar color, and the supported Browser applications by using the `CustomTabsOptions` class. @@ -285,9 +428,22 @@ WebAuthProvider.logout(account) .start(this, logoutCallback) ``` -## Next steps +
+ Using Java + +```java +CustomTabsOptions options = CustomTabsOptions.newBuilder() + .withToolbarColor(R.color.ct_toolbar_color) + .showTitle(true) + .build(); + +WebAuthProvider.logout(account) + .withCustomTabsOptions(options) + .start(MainActivity.this, logoutCallback); +``` +
-### Learning resources +#### Learning resources Check out the [Android QuickStart Guide](https://auth0.com/docs/quickstart/native/android) to find out more about the Auth0.Android toolkit and explore our tutorials and sample projects. @@ -301,6 +457,14 @@ Create a new instance by passing the account: val authentication = AuthenticationAPIClient(account) ``` +
+ Using Java + +```java +AuthenticationAPIClient authentication = new AuthenticationAPIClient(account); +``` +
+ **Note:** If your Auth0 account has the ["Bot Protection"](https://auth0.com/docs/anomaly-detection/bot-protection) feature enabled, your requests might be flagged for verification. Read how to handle this scenario on the [Bot Protection](#bot-protection) section. #### Login with database connection @@ -308,6 +472,7 @@ val authentication = AuthenticationAPIClient(account) ```kotlin authentication .login("info@auth0.com", "a secret password", "my-database-connection") + .validateClaims() //mandatory .start(object: Callback { override fun onFailure(exception: AuthenticationException) { } @@ -315,8 +480,28 @@ authentication }) ``` -> The default scope used is `openid profile email`. Regardless of the scopes set to the request, the `openid` scope is always enforced. +
+ Using Java + +```java +authentication + .login("info@auth0.com", "a secret password", "my-database-connection") + .validateClaims() //mandatory + .start(new Callback() { + @Override + public void onSuccess(@Nullable Credentials payload) { + //Logged in! + } + @Override + public void onFailure(@NonNull AuthenticationException error) { + //Error! + } + }); +``` +
+ +> The default scope used is `openid profile email`. Regardless of the scopes set to the request, the `openid` scope is always enforced. #### Login using MFA with One Time Password code @@ -335,16 +520,36 @@ authentication }) ``` -> The default scope used is `openid profile email`. Regardless of the scopes set to the request, the `openid` scope is always enforced. +
+ Using Java + +```java +authentication + .loginWithOTP("the mfa token", "123456") + .validateClaims() //mandatory + .start(new Callback() { + @Override + public void onSuccess(@Nullable Credentials payload) { + //Logged in! + } + + @Override + public void onFailure(@NonNull AuthenticationException error) { + //Error! + } + }); +``` +
+> The default scope used is `openid profile email`. Regardless of the scopes set to the request, the `openid` scope is always enforced. #### Passwordless Login This feature requires your Application to have the *Passwordless OTP* enabled. See [this article](https://auth0.com/docs/clients/client-grant-types) to learn how to enable it. -Passwordless it's a 2 steps flow: +Passwordless is a 2 step flow: -Step 1: Request the code +##### Step 1: Request the code ```kotlin authentication @@ -356,8 +561,27 @@ authentication }) ``` +
+ Using Java + +```java +authentication + .passwordlessWithEmail("info@auth0.com", PasswordlessType.CODE, "my-passwordless-connection") + .start(new Callback() { + @Override + public void onSuccess(Void payload) { + //Code sent! + } + + @Override + public void onFailure(@NonNull AuthenticationException error) { + //Error! + } + }); +``` +
-Step 2: Input the code +##### Step 2: Input the code ```kotlin authentication @@ -370,9 +594,30 @@ authentication }) ``` +
+ Using Java + +```java +authentication + .loginWithEmail("info@auth0.com", "123456", "my-passwordless-connection") + .validateClaims() //mandatory + .start(new Callback() { + @Override + public void onSuccess(@Nullable Credentials payload) { + //Logged in! + } + + @Override + public void onFailure(@NonNull AuthenticationException error) { + //Error! + } + }); +``` +
+ > The default scope used is `openid profile email`. Regardless of the scopes set to the request, the `openid` scope is always enforced. -#### Sign Up with database connection +#### Sign Up with a database connection ```kotlin authentication @@ -385,6 +630,27 @@ authentication }) ``` +
+ Using Java + +```java +authentication + .signUp("info@auth0.com", "a secret password", "my-database-connection") + .validateClaims() //mandatory + .start(new Callback() { + @Override + public void onSuccess(@Nullable Credentials payload) { + //Signed Up & Logged in! + } + + @Override + public void onFailure(@NonNull AuthenticationException error) { + //Error! + } + }); +``` +
+ > The default scope used is `openid profile email`. Regardless of the scopes set to the request, the `openid` scope is always enforced. #### Get user information @@ -399,6 +665,26 @@ authentication }) ``` +
+ Using Java + +```java +authentication + .userInfo("user access_token") + .start(new Callback() { + @Override + public void onSuccess(@Nullable UserProfile payload) { + //Got the profile! + } + + @Override + public void onFailure(@NonNull AuthenticationException error) { + //Error! + } + }); +``` +
+ #### Bot Protection If you are using the [Bot Protection](https://auth0.com/docs/anomaly-detection/bot-protection) feature and performing database login/signup via the Authentication API, you need to handle the `AuthenticationException#isVerificationRequired()` error. It indicates that the request was flagged as suspicious and an additional verification step is necessary to log the user in. That verification step is web-based, so you need to use Universal Login to complete it. @@ -409,7 +695,7 @@ val password = "a secret password" val realm = "my-database-connection" val authentication = AuthenticationAPIClient(account) -authentication.login(email, password, realm) +authentication.login(email, password, realm).validateClaims() .start(object: Callback { override fun onFailure(exception: AuthenticationException) { if (exception.isVerificationRequired()) { @@ -438,6 +724,55 @@ authentication.login(email, password, realm) }) ``` +
+ Using Java + +```java +final String email = "info@auth0.com"; +final String password = "a secret password"; +final String realm = "my-database-connection"; + +AuthenticationAPIClient authentication = new AuthenticationAPIClient(account); +authentication.login(email, password, realm).validateClaims() + .start(new Callback() { + + @Override + public void onSuccess(@Nullable Credentials payload) { + // Handle API success + } + + @Override + public void onFailure(@NonNull AuthenticationException error) { + if (error.isVerificationRequired()){ + Map params = new HashMap<>(); + params.put("login_hint", email); // So the user doesn't have to type it again + WebAuthProvider.login(account) + .withConnection(realm) + .withParameters(params) + .start(LoginActivity.this, new AuthCallback() { + // You might already have an AuthCallback instance defined + + @Override + public void onFailure(@NonNull Dialog dialog) { + // Error dialog available + } + + @Override + public void onFailure(AuthenticationException exception) { + // Error + } + + @Override + public void onSuccess(@NonNull Credentials credentials) { + // Handle WebAuth success + } + }); + } + } + }); +``` +
+ In the case of signup, you can add [an additional parameter](https://auth0.com/docs/universal-login/new-experience#signup) to make the user land directly on the signup page: ```kotlin @@ -447,6 +782,14 @@ val params = mapOf( ) ``` +
+ Using Java + +```java +params.put("screen_hint", "signup"); +``` +
+ Check out how to set up Universal Login in the [Authentication with Universal Login](#authentication-with-universal-login) section. ### Management API @@ -459,6 +802,15 @@ Create a new instance passing the account and an access token with the Managemen val users = UsersAPIClient(account, "api access token") ``` +
+ Using Java + +```java +Auth0 account = new Auth0("client id", "domain"); +UsersAPIClient users = new UsersAPIClient(account, "api token"); +``` +
+ #### Link users ```kotlin @@ -472,6 +824,26 @@ users }) ``` +
+ Using Java + +```java +users + .link("primary user id", "secondary user token") + .start(new Callback, ManagementException>() { + @Override + public void onSuccess(List payload) { + //Got the updated identities! Accounts linked. + } + + @Override + public void onFailure(@NonNull ManagementException error) { + //Error! + } + }); +``` +
+ #### Unlink users ```kotlin @@ -485,6 +857,26 @@ users }) ``` +
+ Using Java + +```java +users + .unlink("primary user id", "secondary user id", "secondary provider") + .start(new Callback, ManagementException>() { + @Override + public void onSuccess(List payload) { + //Got the updated identities! Accounts linked. + } + + @Override + public void onFailure(@NonNull ManagementException error) { + //Error! + } + }); +``` +
+ #### Get User Profile ```kotlin @@ -498,6 +890,26 @@ users }) ``` +
+ Using Java + +```java +users + .getProfile("user id") + .start(new Callback() { + @Override + public void onSuccess(@Nullable UserProfile payload) { + //Profile received + } + + @Override + public void onFailure(@NonNull ManagementException error) { + //Error! + } + }); +``` +
+ #### Update User Metadata ```kotlin @@ -516,6 +928,30 @@ users }) ``` +
+ Using Java + +```java +Map metadata = new HashMap<>(); +metadata.put("name", Arrays.asList("My", "Name", "Is")); +metadata.put("phoneNumber", "1234567890"); + +users + .updateMetadata("user id", metadata) + .start(new Callback() { + @Override + public void onSuccess(@Nullable UserProfile payload) { + //User Metadata updated + } + + @Override + public void onFailure(@NonNull ManagementException error) { + //Error! + } + }); +``` +
+ > In all the cases, the `user ID` parameter is the unique identifier of the auth0 account instance. i.e. in `google-oauth2|123456789` it would be the part after the '|' pipe: `123456789`. ### Token Validation @@ -532,6 +968,18 @@ WebAuthProvider.login(account) .start(this, callback) ``` +
+ Using Java + +```java +Auth0 account = new Auth0("client id", "domain"); + +WebAuthProvider.login(account) + .withIdTokenVerificationIssuer("https://{YOUR_AUTH0_DOMAIN}/") + .start(MainActivity.this, callback); +``` +
+ For Authentication Client, the method `validateClaims()` has to be called to enable it. ```kotlin @@ -547,6 +995,30 @@ client }) ``` +
+ Using Java + +```java +Auth0 auth0 = new Auth0("client id", "domain"); +AuthenticationAPIClient client = new AuthenticationAPIClient(account); +client + .login("{username or email}", "{password}", "{database connection name}") + .validateClaims() + .withIdTokenVerificationIssuer("https://{YOUR_AUTH0_DOMAIN}/") + .start(new Callback() { + @Override + public void onSuccess(@Nullable Credentials payload) { + //Logged in! + } + + @Override + public void onFailure(@NonNull AuthenticationException error) { + //Error! + } + }); +``` +
+ ### Organizations [Organizations](https://auth0.com/docs/organizations) is a set of features that provide better support for developers who build and maintain SaaS and Business-to-Business (B2B) applications. @@ -569,6 +1041,16 @@ WebAuthProvider.login(account) .start(this, callback) ``` +
+ Using Java + +```java +WebAuthProvider.login(account) + .withOrganization(organizationId) + .start(MainActivity.this, callback); +``` +
+ #### Accept user invitations Users can be invited to your organization via a link. Tapping on the invitation link should open your app. Since invitations links are `https` only, is recommended that your app supports [Android App Links](https://developer.android.com/training/app-links). In [Enable Android App Links Support](https://auth0.com/docs/applications/enable-android-app-links-support), you will find how to make the Auth0 server publish the Digital Asset Links file required by your application. @@ -583,6 +1065,8 @@ getIntent()?.data?.let { } ``` +TODO - java example + If the URL doesn't contain the expected values, an error will be raised through the provided callback. ## Credentials Manager @@ -603,6 +1087,16 @@ val storage = SharedPreferencesStorage(this) val manager = CredentialsManager(authentication, storage) ``` +
+ Using Java + +```java +AuthenticationAPIClient authentication = new AuthenticationAPIClient(account); +Storage storage = new SharedPreferencesStorage(this); +CredentialsManager manager = new CredentialsManager(authentication, storage); +``` +
+ 2. **Save credentials:** The credentials to save **must have** `expires_at` and at least an `access_token` or `id_token` value. If one of the values is missing when trying to set the credentials, the method will throw a `CredentialsManagerException`. If you want the manager to successfully renew the credentials when expired you must also request the `offline_access` scope when logging in in order to receive a `refresh_token` value along with the rest of the tokens. i.e. Logging in with a database connection and saving the credentials: @@ -621,6 +1115,29 @@ authentication } }) ``` + +
+ Using Java + +```java +authentication + .login("info@auth0.com", "a secret password", "my-database-connection") + .setScope("openid email profile offline_access") + .start(new BaseCallback() { + @Override + public void onSuccess(Credentials payload) { + //Save the credentials + manager.saveCredentials(credentials); + } + + @Override + public void onFailure(AuthenticationException error) { + //Error! + } + }); +``` +
+ **Note:** This method has been made thread-safe after version 2.7.0. 3. **Check credentials existence:** @@ -630,6 +1147,14 @@ authentication val authenticated = manager.hasValidCredentials() ``` +
+ Using Java + +```java +boolean authenticated = manager.hasValidCredentials(); +``` +
+ 4. **Retrieve credentials:** Existing credentials will be returned if they are still valid, otherwise the `refresh_token` will be used to attempt to renew them. If the `expires_at` or both the `access_token` and `id_token` values are missing, the method will throw a `CredentialsManagerException`. The same will happen if the credentials have expired and there's no `refresh_token` available. @@ -644,6 +1169,25 @@ manager.getCredentials(object : Callback + Using Java + +```java +manager.getCredentials(new BaseCallback() { + @Override + public void onSuccess(Credentials credentials){ + //Use the Credentials + } + + @Override + public void onFailure(CredentialsManagerException error){ + //Error! + } +}); +``` + + **Note:** In the scenario where the stored credentials have expired and a `refresh_token` is available, the newly obtained tokens are automatically saved for you by the Credentials Manager. This method has been made thread-safe after version 2.7.0. 5. **Clear credentials:** @@ -653,12 +1197,18 @@ manager.getCredentials(object : Callback + Using Java + +```java +manager.clearCredentials(); +``` + ### Encryption enforced This version adds encryption to the data storage. Additionally, in those devices where a Secure Lock Screen has been configured it can require the user to authenticate before letting them obtain the stored credentials. The class is called `SecureCredentialsManager`. - #### Usage The usage is similar to the previous version, with the slight difference that the manager now requires a valid android `Context` as shown below: @@ -668,6 +1218,16 @@ val storage = SharedPreferencesStorage(this) val manager = SecureCredentialsManager(this, authentication, storage) ``` +
+ Using Java + +```java +AuthenticationAPIClient authentication = new AuthenticationAPIClient(account); +Storage storage = new SharedPreferencesStorage(this); +SecureCredentialsManager manager = new SecureCredentialsManager(this, authentication, storage); +``` +
+ #### Requiring Authentication You can require the user authentication to obtain credentials. This will make the manager prompt the user with the device's configured Lock Screen, which they must pass correctly in order to obtain the credentials. **This feature is only available on devices where the user has setup a secured Lock Screen** (PIN, Pattern, Password or Fingerprint). @@ -683,6 +1243,17 @@ companion object { manager.requireAuthentication(this, AUTH_REQ_CODE, null, null) ``` +
+ Using Java + +```java +//You might want to define a constant with the Request Code +private static final int AUTH_REQ_CODE = 11; + +manager.requireAuthentication(this, AUTH_REQ_CODE, null, null); +``` +
+ When the above conditions are met and the manager requires the user authentication, it will use the activity context to launch the Lock Screen activity and wait for its result. If your activity is a subclass of `ComponentActivity`, this will be handled automatically for you internally. Otherwise, your activity must override the `onActivityResult` method and pass the request code and result code to the manager's `checkAuthenticationResult` method to verify if this request was successful or not. ```kotlin @@ -694,6 +1265,20 @@ When the above conditions are met and the manager requires the user authenticati } ``` +
+ Using Java + +```java +@Override +protected void onActivityResult(int requestCode, int resultCode, Intent data) { + if (manager.checkAuthenticationResult(requestCode, resultCode)) { + return; + } + super.onActivityResult(requestCode, resultCode, data); +} +``` +
+ If the manager consumed the event, it will return true and later invoke the callback's `onSuccess` with the decrypted credentials. @@ -724,6 +1309,19 @@ val account = Auth0("{YOUR_CLIENT_ID}", "{YOUR_DOMAIN}") account.networkingClient = netClient ``` +
+ Using Java + +```java +DefaultClient netClient = new DefaultClient( + connectTimeout = 30, + readTimeout = 30 +); +Auth0 account = new Auth0("client id", "domain"); +account.networkingClient = netClient; +``` +
+ ### Logging configuration ```kotlin @@ -735,6 +1333,18 @@ val account = Auth0("{YOUR_CLIENT_ID}", "{YOUR_DOMAIN}") account.networkingClient = netClient ``` +
+ Using Java + +```java +DefaultClient netClient = new DefaultClient( + enableLogging = true +); +Auth0 account = new Auth0("client id", "domain"); +account.networkingClient = netClient; +``` +
+ ### Set additional headers for all requests ```kotlin @@ -746,6 +1356,21 @@ val account = Auth0("{YOUR_CLIENT_ID}", "{YOUR_DOMAIN}") account.networkingClient = netClient ``` +
+ Using Java + +```java +Map defaultHeaders = new HashMap<>(); +defaultHeaders.put("{HEADER-NAME}", "{HEADER-VALUE}"); + +DefaultClient netClient = new DefaultClient( + defaultHeaders = defaultHeaders +); +Auth0 account = new Auth0("client id", "domain"); +account.networkingClient = netClient; +``` +
+ ### Advanced configuration For more advanced configuration of the networking client, you can provide a custom implementation of `NetworkingClient`. This may be useful when you wish to reuse your own networking client, configure a proxy, etc. @@ -753,17 +1378,37 @@ For more advanced configuration of the networking client, you can provide a cust ```kotlin class CustomNetClient : NetworkingClient { override fun load(url: String, options: RequestOptions): ServerResponse { - // Create and execute the request to the specified URL with the given options - val response = // ... + // Create and execute the request to the specified URL with the given options + val response = // ... - // Return a ServerResponse from the received response data - return ServerResponse(responseCode, responseBody, responseHeaders) + // Return a ServerResponse from the received response data + return ServerResponse(responseCode, responseBody, responseHeaders) } } val account = Auth0("{YOUR_CLIENT_ID}", "{YOUR_DOMAIN}") -account.networkingClient = netClient +account.networkingClient = CustomNetClient() +``` + +
+ Using Java + +```java +class CustomNetClient extends NetworkingClient { + @Override + public ServerResponse load(String url) { + // Create and execute the request to the specified URL with the given options + ServerResponse response = // ... + + // Return a ServerResponse from the received response data + return ServerResponse(responseCode, responseBody, responseHeaders) + } +}; + +Auth0 account = new Auth0("client id", "domain"); +account.networkingClient = new CustomNetClient(); ``` +
## FAQ From 443df343cb3dbef2d1c4d651c74e026ce941e6cd Mon Sep 17 00:00:00 2001 From: adamjmcgrath Date: Tue, 21 Jun 2022 15:58:17 +0100 Subject: [PATCH 2/7] add back next steps --- README.md | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index 959461be..b47e4e21 100644 --- a/README.md +++ b/README.md @@ -15,6 +15,8 @@ Easily integrate Auth0 into Android apps. Add **login** and **logout**, store ** + [Permissions](#permissions) - [Getting Started](#getting-started) * [Authentication with Universal Login](#authentication-with-universal-login) + * [Clearing the session](#clearing-the-session) +- [Next steps](#next-steps) * [Authentication API](#authentication-api) * [Management API](#management-api) * [Token Validation](#token-validation) @@ -330,7 +332,7 @@ WebAuthProvider.login(account) -#### Clearing the session +### Clearing the session To log the user out and clear the SSO cookies that the Auth0 Server keeps attached to your browser app, you need to call the [logout endpoint](https://auth0.com/docs/api/authentication?#logout). This can be done in a similar fashion to how you authenticated before: using the `WebAuthProvider` class. @@ -447,6 +449,8 @@ WebAuthProvider.logout(account) Check out the [Android QuickStart Guide](https://auth0.com/docs/quickstart/native/android) to find out more about the Auth0.Android toolkit and explore our tutorials and sample projects. +## Next steps + ### Authentication API The client provides methods to authenticate the user against the Auth0 server. From 205a01b645720d14fc244e6717eba8c685bdb3b5 Mon Sep 17 00:00:00 2001 From: adamjmcgrath Date: Wed, 22 Jun 2022 12:46:36 +0100 Subject: [PATCH 3/7] Add async examples --- README.md | 209 +++++++++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 208 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index b47e4e21..917d6069 100644 --- a/README.md +++ b/README.md @@ -484,6 +484,21 @@ authentication }) ``` +
+ Using suspend + +```kotlin +try { + val credentials = authentication + .loginAsync("info@auth0.com", "a secret password", "my-database-connection") + .validateClaims() + println(credentials) +} catch (e: AuthenticationException) { + e.printStacktrace() +} +``` +
+
Using Java @@ -524,6 +539,21 @@ authentication }) ``` +
+ Using suspend + +```kotlin +try { + val credentials = authentication + .loginWithOTP("the mfa token", "123456") + .validateClaims() + println(credentials) +} catch (e: AuthenticationException) { + e.printStacktrace() +} +``` +
+
Using Java @@ -565,6 +595,20 @@ authentication }) ``` +
+ Using suspend + +```kotlin +try { + val result = authentication + .passwordlessWithEmailAsync("info@auth0.com", PasswordlessType.CODE, "my-passwordless-connection") + println(result) +} catch (e: AuthenticationException) { + e.printStacktrace() +} +``` +
+
Using Java @@ -598,6 +642,22 @@ authentication }) ``` +
+ Using suspend + +```kotlin +try { + val credentials = authentication + .loginWithEmailAsync("info@auth0.com", "123456", "my-passwordless-connection") + .validateClaims() + println(credentials) +} catch (e: AuthenticationException) { + e.printStacktrace() +} +``` +
+ +
Using Java @@ -634,6 +694,21 @@ authentication }) ``` +
+ Using suspend + +```kotlin +try { + val credentials = authentication + .signUpAsync("info@auth0.com", "a secret password", "my-database-connection") + .validateClaims() + println(credentials) +} catch (e: AuthenticationException) { + e.printStacktrace() +} +``` +
+
Using Java @@ -669,6 +744,20 @@ authentication }) ``` +
+ Using suspend + +```kotlin +try { + val user = authentication + .userInfoAsync("user access_token") + println(user) +} catch (e: AuthenticationException) { + e.printStacktrace() +} +``` +
+
Using Java @@ -828,6 +917,20 @@ users }) ``` +
+ Using suspend + +```kotlin +try { + val identities = users + .linkAsync("primary user id", "secondary user token") + println(identities) +} catch (e: ManagementException) { + e.printStacktrace() +} +``` +
+
Using Java @@ -861,6 +964,20 @@ users }) ``` +
+ Using suspend + +```kotlin +try { + val identities = users + .unlinkAsync("primary user id", "secondary user id", "secondary provider") + println(identities) +} catch (e: ManagementException) { + e.printStacktrace() +} +``` +
+
Using Java @@ -894,6 +1011,20 @@ users }) ``` +
+ Using suspend + +```kotlin +try { + val user = users + .getProfileAsync("user id") + println(user) +} catch (e: ManagementException) { + e.printStacktrace() +} +``` +
+
Using Java @@ -932,6 +1063,25 @@ users }) ``` +
+ Using suspend + +```kotlin +val metadata = mapOf( + "name" to listOf("My", "Name", "Is"), + "phoneNumber" to "1234567890" +) + +try { + val user = users + .updateMetadataAsync("user id", metadata) + println(user) +} catch (e: ManagementException) { + e.printStacktrace() +} +``` +
+
Using Java @@ -999,6 +1149,25 @@ client }) ``` +
+ Using suspend + +```kotlin +val auth0 = Auth0("YOUR_CLIENT_ID", "YOUR_DOMAIN") +val client = AuthenticationAPIClient(auth0) + +try { + val credentials = client + .loginAsync("{username or email}", "{password}", "{database connection name}") + .validateClaims() + .withIdTokenVerificationIssuer("https://{YOUR_AUTH0_DOMAIN}/") + println(credentials) +} catch (e: AuthenticationException) { + e.printStacktrace() +} +``` +
+
Using Java @@ -1069,7 +1238,17 @@ getIntent()?.data?.let { } ``` -TODO - java example +
+ Using Java + +```java +if (getIntent() != null && getIntent().getData() != null) { + WebAuthProvider.login(account) + .withInvitationUrl(getIntent().getData()) + .start(this, callback); +} +``` +
If the URL doesn't contain the expected values, an error will be raised through the provided callback. @@ -1120,6 +1299,21 @@ authentication }) ``` +
+ Using suspend + +```kotlin +try { + val credentials = authentication + .loginAsync("info@auth0.com", "a secret password", "my-database-connection") + .setScope("openid email profile offline_access") + manager.saveCredentials(credentials) +} catch (e: AuthenticationException) { + e.printStacktrace() +} +``` +
+
Using Java @@ -1174,6 +1368,19 @@ manager.getCredentials(object : Callback + Using suspend + +```kotlin +try { + val credentials = manager.getCredentialsAsync() + println(credentials) +} catch (e: CredentialsManagerException) { + e.printStacktrace() +} +``` +
+
Using Java From f05fc37cfb61f0495f605ddbd9037d881d5374b1 Mon Sep 17 00:00:00 2001 From: adamjmcgrath Date: Thu, 23 Jun 2022 12:24:35 +0100 Subject: [PATCH 4/7] fix async examples --- README.md | 36 ++++++++++++++++++++++++------------ 1 file changed, 24 insertions(+), 12 deletions(-) diff --git a/README.md b/README.md index 917d6069..e9c7c1bd 100644 --- a/README.md +++ b/README.md @@ -490,8 +490,9 @@ authentication ```kotlin try { val credentials = authentication - .loginAsync("info@auth0.com", "a secret password", "my-database-connection") + .login("info@auth0.com", "a secret password", "my-database-connection") .validateClaims() + .await() println(credentials) } catch (e: AuthenticationException) { e.printStacktrace() @@ -547,6 +548,7 @@ try { val credentials = authentication .loginWithOTP("the mfa token", "123456") .validateClaims() + .await() println(credentials) } catch (e: AuthenticationException) { e.printStacktrace() @@ -601,7 +603,8 @@ authentication ```kotlin try { val result = authentication - .passwordlessWithEmailAsync("info@auth0.com", PasswordlessType.CODE, "my-passwordless-connection") + .passwordlessWithEmail("info@auth0.com", PasswordlessType.CODE, "my-passwordless-connection") + .await() println(result) } catch (e: AuthenticationException) { e.printStacktrace() @@ -648,8 +651,9 @@ authentication ```kotlin try { val credentials = authentication - .loginWithEmailAsync("info@auth0.com", "123456", "my-passwordless-connection") + .loginWithEmail("info@auth0.com", "123456", "my-passwordless-connection") .validateClaims() + .await() println(credentials) } catch (e: AuthenticationException) { e.printStacktrace() @@ -700,8 +704,9 @@ authentication ```kotlin try { val credentials = authentication - .signUpAsync("info@auth0.com", "a secret password", "my-database-connection") + .signUp("info@auth0.com", "a secret password", "my-database-connection") .validateClaims() + .await() println(credentials) } catch (e: AuthenticationException) { e.printStacktrace() @@ -750,7 +755,8 @@ authentication ```kotlin try { val user = authentication - .userInfoAsync("user access_token") + .userInfo("user access_token") + .await() println(user) } catch (e: AuthenticationException) { e.printStacktrace() @@ -923,7 +929,8 @@ users ```kotlin try { val identities = users - .linkAsync("primary user id", "secondary user token") + .link("primary user id", "secondary user token") + .await() println(identities) } catch (e: ManagementException) { e.printStacktrace() @@ -970,7 +977,8 @@ users ```kotlin try { val identities = users - .unlinkAsync("primary user id", "secondary user id", "secondary provider") + .unlink("primary user id", "secondary user id", "secondary provider") + .await() println(identities) } catch (e: ManagementException) { e.printStacktrace() @@ -1017,7 +1025,8 @@ users ```kotlin try { val user = users - .getProfileAsync("user id") + .getProfile("user id") + .await() println(user) } catch (e: ManagementException) { e.printStacktrace() @@ -1074,7 +1083,8 @@ val metadata = mapOf( try { val user = users - .updateMetadataAsync("user id", metadata) + .updateMetadata("user id", metadata) + .await() println(user) } catch (e: ManagementException) { e.printStacktrace() @@ -1158,9 +1168,10 @@ val client = AuthenticationAPIClient(auth0) try { val credentials = client - .loginAsync("{username or email}", "{password}", "{database connection name}") + .login("{username or email}", "{password}", "{database connection name}") .validateClaims() .withIdTokenVerificationIssuer("https://{YOUR_AUTH0_DOMAIN}/") + .await() println(credentials) } catch (e: AuthenticationException) { e.printStacktrace() @@ -1305,8 +1316,9 @@ authentication ```kotlin try { val credentials = authentication - .loginAsync("info@auth0.com", "a secret password", "my-database-connection") + .login("info@auth0.com", "a secret password", "my-database-connection") .setScope("openid email profile offline_access") + .await() manager.saveCredentials(credentials) } catch (e: AuthenticationException) { e.printStacktrace() @@ -1373,7 +1385,7 @@ manager.getCredentials(object : Callback Date: Thu, 23 Jun 2022 12:26:54 +0100 Subject: [PATCH 5/7] fix creds async example --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index e9c7c1bd..cf56b956 100644 --- a/README.md +++ b/README.md @@ -1385,7 +1385,7 @@ manager.getCredentials(object : Callback Date: Thu, 23 Jun 2022 22:02:20 +0200 Subject: [PATCH 6/7] Updating README to avoid unwanted samples --- README.md | 163 +++++++++++------------------------------------------- 1 file changed, 32 insertions(+), 131 deletions(-) diff --git a/README.md b/README.md index cf56b956..2e88c13b 100644 --- a/README.md +++ b/README.md @@ -27,7 +27,7 @@ Easily integrate Auth0 into Android apps. Add **login** and **logout**, store ** - [Networking client customization](#networking-client-customization) - [FAQ](#faq) - [Proguard](#proguard) -- [What is Auth0?](#what-is-auth0-) +- [What is Auth0?](#what-is-auth0) - [Issue Reporting](#issue-reporting) - [License](#license) @@ -78,6 +78,7 @@ val account = Auth0("{YOUR_CLIENT_ID}", "{YOUR_DOMAIN}")
Using Java + ```java Auth0 account = new Auth0("{YOUR_CLIENT_ID}", "{YOUR_DOMAIN}"); ``` @@ -85,6 +86,7 @@ Auth0 account = new Auth0("{YOUR_CLIENT_ID}", "{YOUR_DOMAIN}");
Configure using Android Context + Alternatively, you can save your Application information in the `strings.xml` file using the following names: ```xml @@ -135,10 +137,10 @@ android { ``` It's a good practice to define reusable resources like `@string/com_auth0_domain`, but you can also hard-code the value. - + > The scheme value can be either `https` or a custom one. Read [this section](#a-note-about-app-deep-linking) to learn more. -Declare the callback instance that will receive the authentication result. +Declare the callback instance that will receive the authentication result and authenticate by showing the **Auth0 Universal Login**: ```kotlin val callback = object : Callback { @@ -150,6 +152,9 @@ val callback = object : Callback { // Success! Access token and ID token are presents } } + +WebAuthProvider.login(account) + .start(this, callback) ```
@@ -167,26 +172,12 @@ Callback callback = new Callback - -Finally, authenticate by showing the **Auth0 Universal Login**: -```kotlin WebAuthProvider.login(account) - .start(this, callback) -``` - -
- Using Java - -```java -WebAuthProvider.login(account) - .start(MainActivity.this, callback); + .start(this, callback); ```
- The callback will get invoked when the user returns to your application. There are a few scenarios where this may fail: * When the device cannot open the URL because it doesn't have any compatible browser application installed. You can check this scenario with `error.isBrowserAppNotAvailable`. @@ -209,16 +200,6 @@ WebAuthProvider.login(account) .start(this, callback) ``` -
- Using Java - -```java -//Configure and launch the authentication -WebAuthProvider.login(account) - .start(MainActivity.this, callback); -``` -
- > Note that the schemes [can only have lowercase letters](https://developer.android.com/guide/topics/manifest/data-element). #### Authenticate with any Auth0 connection @@ -231,16 +212,6 @@ WebAuthProvider.login(account) .start(this, callback) ``` -
- Using Java - -```java -WebAuthProvider.login(account) - .withConnection("twitter") - .start(MainActivity.this, callback); -``` -
- #### Specify audience ```kotlin @@ -249,16 +220,6 @@ WebAuthProvider.login(account) .start(this, callback) ``` -
- Using Java - -```java -WebAuthProvider.login(account) - .withAudience("https://{YOUR_AUTH0_DOMAIN}/api/v2/") - .start(MainActivity.this, callback); -``` -
- The sample above requests tokens with the audience required to call the [Management API](https://auth0.com/docs/api/management/v2) endpoints. > Replace `{YOUR_AUTH0_DOMAIN}` with your actual Auth0 domain (i.e. `mytenant.auth0.com`). If you've set up the tenant to use "Custom Domains", use that value here. @@ -271,16 +232,6 @@ WebAuthProvider.login(account) .start(this, callback) ``` -
- Using Java - -```java -WebAuthProvider.login(account) - .withScope("openid profile email read:users") - .start(MainActivity.this, callback); -``` -
- > The default scope used is `openid profile email`. Regardless of the scopes passed here, the `openid` scope is always enforced. #### Specify Connection scope @@ -291,16 +242,6 @@ WebAuthProvider.login(account) .start(this, callback) ``` -
- Using Java - -```java -WebAuthProvider.login(account) - .withConnectionScope("email", "profile", "calendar:read") - .start(MainActivity.this, callback); -``` -
- #### Customize the Custom Tabs UI If the device where the app is running has a Custom Tabs compatible Browser, a Custom Tab will be preferred for the logout flow. You can customize the Page Title visibility, the Toolbar color, and the supported Browser applications by using the `CustomTabsOptions` class. @@ -349,10 +290,6 @@ Remember to replace `{YOUR_APP_PACKAGE_NAME}` with your actual application's pac Initialize the provider, this time calling the static method `logout`. ```kotlin -//Configure and launch the log out -WebAuthProvider.logout(account) - .start(this, logoutCallback) - //Declare the callback that will receive the result val logoutCallback = object: Callback { override fun onFailure(exception: AuthenticationException) { @@ -363,16 +300,16 @@ val logoutCallback = object: Callback { // Success! The browser session was cleared } } + +//Configure and launch the log out +WebAuthProvider.logout(account) + .start(this, logoutCallback) ```
Using Java ```java -//Configure and launch the log out -WebAuthProvider.logout(account) - .start(MainActivity.this, logoutCallback); - //Declare the callback that will receive the result Callback logoutCallback = new Callback() { @Override @@ -385,6 +322,10 @@ Callback logoutCallback = new Callback @@ -404,17 +345,6 @@ WebAuthProvider.logout(account) .start(this, logoutCallback) ``` -
- Using Java - -```java -WebAuthProvider.login(account) - .withScheme("myapp") - .start(MainActivity.this, callback); -``` -
- - #### Customize the Custom Tabs UI If the device where the app is running has a Custom Tabs compatible Browser, a Custom Tab will be preferred for the logout flow. You can customize the Page Title visibility, the Toolbar color, and the supported Browser applications by using the `CustomTabsOptions` class. @@ -485,7 +415,7 @@ authentication ```
- Using suspend + Using coroutines ```kotlin try { @@ -541,7 +471,7 @@ authentication ```
- Using suspend + Using coroutines ```kotlin try { @@ -598,7 +528,7 @@ authentication ```
- Using suspend + Using coroutines ```kotlin try { @@ -646,7 +576,7 @@ authentication ```
- Using suspend + Using coroutines ```kotlin try { @@ -699,7 +629,7 @@ authentication ```
- Using suspend + Using coroutines ```kotlin try { @@ -750,7 +680,7 @@ authentication ```
- Using suspend + Using coroutines ```kotlin try { @@ -877,7 +807,7 @@ In the case of signup, you can add [an additional parameter](https://auth0.com/d ```kotlin val params = mapOf( "login_hint" to email, - "screen_hint", "signup" + "screen_hint" to "signup" ) ``` @@ -885,6 +815,7 @@ val params = mapOf( Using Java ```java +params.put("login_hint", email); params.put("screen_hint", "signup"); ```
@@ -924,7 +855,7 @@ users ```
- Using suspend + Using coroutines ```kotlin try { @@ -972,7 +903,7 @@ users ```
- Using suspend + Using coroutines ```kotlin try { @@ -1020,7 +951,7 @@ users ```
- Using suspend + Using coroutines ```kotlin try { @@ -1073,7 +1004,7 @@ users ```
- Using suspend + Using coroutines ```kotlin val metadata = mapOf( @@ -1132,18 +1063,6 @@ WebAuthProvider.login(account) .start(this, callback) ``` -
- Using Java - -```java -Auth0 account = new Auth0("client id", "domain"); - -WebAuthProvider.login(account) - .withIdTokenVerificationIssuer("https://{YOUR_AUTH0_DOMAIN}/") - .start(MainActivity.this, callback); -``` -
- For Authentication Client, the method `validateClaims()` has to be called to enable it. ```kotlin @@ -1160,7 +1079,7 @@ client ```
- Using suspend + Using coroutines ```kotlin val auth0 = Auth0("YOUR_CLIENT_ID", "YOUR_DOMAIN") @@ -1225,16 +1144,6 @@ WebAuthProvider.login(account) .start(this, callback) ``` -
- Using Java - -```java -WebAuthProvider.login(account) - .withOrganization(organizationId) - .start(MainActivity.this, callback); -``` -
- #### Accept user invitations Users can be invited to your organization via a link. Tapping on the invitation link should open your app. Since invitations links are `https` only, is recommended that your app supports [Android App Links](https://developer.android.com/training/app-links). In [Enable Android App Links Support](https://auth0.com/docs/applications/enable-android-app-links-support), you will find how to make the Auth0 server publish the Digital Asset Links file required by your application. @@ -1311,7 +1220,7 @@ authentication ```
- Using suspend + Using coroutines ```kotlin try { @@ -1381,7 +1290,7 @@ manager.getCredentials(object : Callback - Using suspend + Using coroutines ```kotlin try { @@ -1420,14 +1329,6 @@ manager.getCredentials(new BaseCallback - Using Java - -```java -manager.clearCredentials(); -``` -
- ### Encryption enforced This version adds encryption to the data storage. Additionally, in those devices where a Secure Lock Screen has been configured it can require the user to authenticate before letting them obtain the stored credentials. The class is called `SecureCredentialsManager`. From 2dea1a694c5e2ab68e2332f01a7d1a2bfd241029 Mon Sep 17 00:00:00 2001 From: adamjmcgrath Date: Fri, 24 Jun 2022 13:53:28 +0100 Subject: [PATCH 7/7] Add async web auth --- README.md | 28 ++++++++++++++++++++++++++++ 1 file changed, 28 insertions(+) diff --git a/README.md b/README.md index 2e88c13b..a1e06351 100644 --- a/README.md +++ b/README.md @@ -157,6 +157,20 @@ WebAuthProvider.login(account) .start(this, callback) ``` +
+ Using coroutines + +```kotlin +try { + val credentials = WebAuthProvider.login(account) + .await(requireContext()) + println(credentials) +} catch(e: AuthenticationException) { + e.printStacktrace() +} +``` +
+
Using Java @@ -306,6 +320,20 @@ WebAuthProvider.logout(account) .start(this, logoutCallback) ``` +
+ Using coroutines + +```kotlin +try { + WebAuthProvider.logout(account) + .await(requireContext()) + println("Logged out") +} catch(e: AuthenticationException) { + e.printStacktrace() +} +``` +
+
Using Java