Skip to content

Commit

Permalink
Merge branch 'master' into BREAKING_CHANGE_v4
Browse files Browse the repository at this point in the history
  • Loading branch information
desusai7 committed Aug 2, 2024
2 parents 4dd6594 + 1aa5e70 commit d398d0a
Show file tree
Hide file tree
Showing 21 changed files with 1,130 additions and 445 deletions.
95 changes: 95 additions & 0 deletions EXAMPLES.md
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
- [Log in to an organization](#log-in-to-an-organization)
- [Accept user invitations](#accept-user-invitations)
- [Bot Protection](#bot-protection)
- [Domain Switching](#domain-switching)

## Authentication API

Expand Down Expand Up @@ -263,3 +264,97 @@ auth0.webAuth.authorize({
screen_hint: 'signup', // 👈🏻
});
```

### Domain Switching

To switch between two different domains for authentication in your Android and iOS applications, follow these steps:

#### Android

To switch between two different domains for authentication in your Android application, you need to manually update your `AndroidManifest.xml` file. This involves adding an intent filter for the activity `com.auth0.android.provider.RedirectActivity`. Unlike using a single domain where you can add the domain and scheme values within the `manifestPlaceholders` of your app's `build.gradle` file, you need to add a `<data>` tag for each domain along with its scheme within the intent filter.

Here is an example:

```xml
<activity
android:name="com.auth0.android.provider.RedirectActivity"
tools:node="replace"
android:exported="true">
<intent-filter>
<action android:name="android.intent.action.VIEW" />
<category android:name="android.intent.category.DEFAULT" />
<category android:name="android.intent.category.BROWSABLE" />
<data
android:host="${domain1}"
android:pathPrefix="/android/${applicationId}/callback"
android:scheme="${applicationId}.auth0" />
<data
android:host="${domain2}"
android:pathPrefix="/android/${applicationId}/callback"
android:scheme="${applicationId}.auth0" />
</intent-filter>
</activity>
```

If you customize the scheme by removing the default value of `${applicationId}.auth0`, you will also need to pass it as the `customScheme` option parameter of the `authorize` and `clearSession` methods.

#### iOS

For iOS, if you are not customizing the scheme, adding `$(PRODUCT_BUNDLE_IDENTIFIER).auth0` as an entry to the `CFBundleURLSchemes` array in your `Info.plist` file should be sufficient. However, if you want to customize the scheme for the domains, you need to add the customized scheme for each domain as an entry to the `CFBundleURLSchemes` array.

Here is an example:

```
<key>CFBundleURLTypes</key>
<array>
<dict>
<key>CFBundleTypeRole</key>
<string>None</string>
<key>CFBundleURLName</key>
<string>auth0</string>
<key>CFBundleURLSchemes</key>
<array>
<string>$(customScheme1)</string>
<string>$(customScheme2)</string>
</array>
</dict>
</array>
```

By following these steps, you can configure your Android and iOS applications to handle authentication for multiple domains.

#### Expo

If using a single domain, you can simply pass an object in the format to the `react-native-auth0` plugin in your `app.json` as shown below:

```json
"plugins": [
"expo-router",
["react-native-auth0",
{
"domain": "sample.auth0.com",
"customScheme": "sampleScheme"
}
]
]
```

If you want to support multiple domains, you would have to pass an array of objects as shown below:

```json
"plugins": [
"expo-router",
["react-native-auth0",
[{
"domain": "sample.auth0.com",
"customScheme": "sampleScheme"
},
{
"domain": "sample2.auth0.com",
"customScheme": "sampleScheme2"
}]
]
]
```

You can skip sending the `customScheme` property if you do not want to customize it.
2 changes: 2 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -192,6 +192,8 @@ To use the SDK with Expo, configure the app at build time by providing the `doma
}
```

> :info: If you want to switch between multiple domains in your app, refer [here](https://github.com/auth0/react-native-auth0/blob/master/EXAMPLES.md#domain-switching)
| API | Description |
| ------------ | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| domain | Mandatory: Provide the Auth0 domain that can be found at the [Application Settings](https://manage.auth0.com/#/applications) |
Expand Down
37 changes: 26 additions & 11 deletions android/src/main/java/com/auth0/react/A0Auth0Module.java
Original file line number Diff line number Diff line change
Expand Up @@ -22,13 +22,16 @@
import com.facebook.react.bridge.ReactMethod;
import com.facebook.react.bridge.ReadableMap;
import com.facebook.react.bridge.UiThreadUtil;
import java.net.MalformedURLException;
import java.net.URL;

import java.util.HashMap;
import java.util.Map;

public class A0Auth0Module extends ReactContextBaseJavaModule implements ActivityEventListener {

private static final String ERROR_CODE = "a0.invalid_state.credential_manager_exception";
private static final String CREDENTIAL_MANAGER_ERROR_CODE = "a0.invalid_state.credential_manager_exception";
private static final String INVALID_DOMAIN_URL_ERROR_CODE = "a0.invalid_domain_url";
private static final String BIOMETRICS_AUTHENTICATION_ERROR_CODE = "a0.invalid_options_biometrics_authentication";
private static final int LOCAL_AUTH_REQUEST_CODE = 150;
public static final int UNKNOWN_ERROR_RESULT_CODE = 1405;
Expand Down Expand Up @@ -84,8 +87,20 @@ public void initializeAuth0(String clientId, String domain, ReadableMap localAut
}

@ReactMethod
public void hasValidAuth0Instance(Promise promise) {
promise.resolve(this.auth0 != null && this.secureCredentialsManager != null);
public void hasValidAuth0InstanceWithConfiguration(String clientId, String domain, Promise promise) {
if(this.auth0 == null) {
promise.resolve(false);
return;
}
String currentDomain;
try {
URL domainUrl = new URL(this.auth0.getDomainUrl());
currentDomain = domainUrl.getHost();
} catch (MalformedURLException e) {
promise.reject(INVALID_DOMAIN_URL_ERROR_CODE, "Invalid domain URL", e);
return;
}
promise.resolve(this.auth0.getClientId().equals(clientId) && currentDomain.equals(domain));
}

@ReactMethod
Expand All @@ -108,7 +123,7 @@ public void onSuccess(Credentials credentials) {

@Override
public void onFailure(@NonNull CredentialsManagerException e) {
promise.reject(ERROR_CODE, e.getMessage(), e);
promise.reject(CREDENTIAL_MANAGER_ERROR_CODE, e.getMessage(), e);
}
}));
}
Expand All @@ -119,7 +134,7 @@ public void saveCredentials(ReadableMap credentials, Promise promise) {
this.secureCredentialsManager.saveCredentials(CredentialsParser.fromMap(credentials));
promise.resolve(true);
} catch (CredentialsManagerException e) {
promise.reject(ERROR_CODE, e.getMessage(), e);
promise.reject(CREDENTIAL_MANAGER_ERROR_CODE, e.getMessage(), e);
}
}

Expand Down Expand Up @@ -201,12 +216,12 @@ public void onSuccess(Credentials result) {
webAuthPromise = null;
}

@Override
public void onFailure(@NonNull AuthenticationException error) {
handleError(error, promise);
webAuthPromise = null;
}
});
@Override
public void onFailure(@NonNull AuthenticationException error) {
handleError(error, promise);
webAuthPromise = null;
}
});
}

@ReactMethod
Expand Down
1 change: 0 additions & 1 deletion example/android/app/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -96,7 +96,6 @@ android {
namespace "com.auth0example"
defaultConfig {
applicationId "com.auth0example"
manifestPlaceholders = [auth0Domain: "brucke.auth0.com", auth0Scheme: "${applicationId}.auth0"]
minSdkVersion rootProject.ext.minSdkVersion
targetSdkVersion rootProject.ext.targetSdkVersion
versionCode 1
Expand Down
65 changes: 42 additions & 23 deletions example/android/app/src/main/AndroidManifest.xml
Original file line number Diff line number Diff line change
@@ -1,25 +1,44 @@
<manifest xmlns:android="http://schemas.android.com/apk/res/android">
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools">
<uses-permission android:name="android.permission.INTERNET" />

<uses-permission android:name="android.permission.INTERNET" />

<application
android:name=".MainApplication"
<application
android:name=".MainApplication"
android:label="@string/app_name"
android:icon="@mipmap/ic_launcher"
android:roundIcon="@mipmap/ic_launcher_round"
android:allowBackup="false"
android:theme="@style/AppTheme">
<activity
android:name=".MainActivity"
android:label="@string/app_name"
android:icon="@mipmap/ic_launcher"
android:roundIcon="@mipmap/ic_launcher_round"
android:allowBackup="false"
android:theme="@style/AppTheme">
<activity
android:name=".MainActivity"
android:label="@string/app_name"
android:configChanges="keyboard|keyboardHidden|orientation|screenLayout|screenSize|smallestScreenSize|uiMode"
android:launchMode="singleTask"
android:windowSoftInputMode="adjustResize"
android:exported="true">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
</application>
</manifest>
android:configChanges="keyboard|keyboardHidden|orientation|screenLayout|screenSize|smallestScreenSize|uiMode"
android:launchMode="singleTask"
android:windowSoftInputMode="adjustResize"
android:exported="true">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<activity
android:name="com.auth0.android.provider.RedirectActivity" tools:node="replace"
android:exported="true">
<intent-filter>
<action android:name="android.intent.action.VIEW" />

<category android:name="android.intent.category.DEFAULT" />
<category android:name="android.intent.category.BROWSABLE" />

<data
android:host="venkat-desu.us.auth0.com"
android:pathPrefix="/android/${applicationId}/callback"
android:scheme="${applicationId}.auth0" />
<data
android:host="brucke.auth0.com"
android:pathPrefix="/android/${applicationId}/callback"
android:scheme="${applicationId}.auth0" />
</intent-filter>
</activity>
</application>
</manifest>
16 changes: 14 additions & 2 deletions example/ios/Podfile.lock
Original file line number Diff line number Diff line change
Expand Up @@ -338,6 +338,8 @@ PODS:
- React-jsinspector (0.71.10)
- React-logger (0.71.10):
- glog
- react-native-safe-area-context (4.10.8):
- React-Core
- React-perflogger (0.71.10)
- React-RCTActionSheet (0.71.10):
- React-Core/RCTActionSheetHeaders (= 0.71.10)
Expand Down Expand Up @@ -422,6 +424,10 @@ PODS:
- React-jsi (= 0.71.10)
- React-logger (= 0.71.10)
- React-perflogger (= 0.71.10)
- RNScreens (3.32.0):
- RCT-Folly (= 2021.07.22.00)
- React-Core
- React-RCTImage
- SimpleKeychain (1.1.0)
- SocketRocket (0.6.1)
- Yoga (1.14.0)
Expand Down Expand Up @@ -475,6 +481,7 @@ DEPENDENCIES:
- React-jsiexecutor (from `../node_modules/react-native/ReactCommon/jsiexecutor`)
- React-jsinspector (from `../node_modules/react-native/ReactCommon/jsinspector`)
- React-logger (from `../node_modules/react-native/ReactCommon/logger`)
- react-native-safe-area-context (from `../node_modules/react-native-safe-area-context`)
- React-perflogger (from `../node_modules/react-native/ReactCommon/reactperflogger`)
- React-RCTActionSheet (from `../node_modules/react-native/Libraries/ActionSheetIOS`)
- React-RCTAnimation (from `../node_modules/react-native/Libraries/NativeAnimation`)
Expand All @@ -488,6 +495,7 @@ DEPENDENCIES:
- React-RCTVibration (from `../node_modules/react-native/Libraries/Vibration`)
- React-runtimeexecutor (from `../node_modules/react-native/ReactCommon/runtimeexecutor`)
- ReactCommon/turbomodule/core (from `../node_modules/react-native/ReactCommon`)
- RNScreens (from `../node_modules/react-native-screens`)
- Yoga (from `../node_modules/react-native/ReactCommon/yoga`)

SPEC REPOS:
Expand Down Expand Up @@ -554,6 +562,8 @@ EXTERNAL SOURCES:
:path: "../node_modules/react-native/ReactCommon/jsinspector"
React-logger:
:path: "../node_modules/react-native/ReactCommon/logger"
react-native-safe-area-context:
:path: "../node_modules/react-native-safe-area-context"
React-perflogger:
:path: "../node_modules/react-native/ReactCommon/reactperflogger"
React-RCTActionSheet:
Expand All @@ -580,6 +590,8 @@ EXTERNAL SOURCES:
:path: "../node_modules/react-native/ReactCommon/runtimeexecutor"
ReactCommon:
:path: "../node_modules/react-native/ReactCommon"
RNScreens:
:path: "../node_modules/react-native-screens"
Yoga:
:path: "../node_modules/react-native/ReactCommon/yoga"

Expand Down Expand Up @@ -619,6 +631,7 @@ SPEC CHECKSUMS:
React-jsiexecutor: 4bb480a183a354e4dbfb1012936b1a2bb9357de7
React-jsinspector: cdc854f8b13abd202afa54bc12578e5afb9cfae1
React-logger: ef2269b3afa6ba868da90496c3e17a4ec4f4cee0
react-native-safe-area-context: b7daa1a8df36095a032dff095a1ea8963cb48371
React-perflogger: 217095464d5c4bb70df0742fa86bf2a363693468
React-RCTActionSheet: 8deae9b85a4cbc6a2243618ea62a374880a2c614
React-RCTAnimation: 59c62353a8b59ce206044786c5d30e4754bffa64
Expand All @@ -632,10 +645,9 @@ SPEC CHECKSUMS:
React-RCTVibration: d13cc2d63286c633393d3a7f6f607cc2a09ec011
React-runtimeexecutor: a9a1cd79996c9a0846e3232ecb25c64e1cc0172e
ReactCommon: 65718685d4095d06b4b1af8042e12f1df2925c31
RNScreens: 0bd9eec783bed1032e02a4db9976dae1664a5c7b
SimpleKeychain: f8707c8e97b38c6a6e687b17732afc9bcef06439
SocketRocket: f32cd54efbe0f095c4d7594881e52619cfe80b17
Yoga: e7ea9e590e27460d28911403b894722354d73479
YogaKit: f782866e155069a2cca2517aafea43200b01fd5a

PODFILE CHECKSUM: 8b76cdfa2c2f558cb3fb9288d07f13c3d579c8c9

Expand Down
Loading

0 comments on commit d398d0a

Please sign in to comment.