Skip to content
Merged
Show file tree
Hide file tree
Changes from 7 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 3 additions & 3 deletions A0Auth0.podspec
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ Pod::Spec.new do |s|
s.requires_arc = true

s.dependency 'React-Core'
s.dependency 'Auth0', '2.7.2'
s.dependency 'JWTDecode', '3.1.0'
s.dependency 'SimpleKeychain', '1.1.0'
s.dependency 'Auth0', '2.10'
s.dependency 'JWTDecode', '3.2.0'
s.dependency 'SimpleKeychain', '1.2.0'
Comment thread
subhankarmaiti marked this conversation as resolved.
end
57 changes: 41 additions & 16 deletions EXAMPLES.md
Original file line number Diff line number Diff line change
@@ -1,21 +1,26 @@
# Examples using react-native-auth0

- [Authentication API](#authentication-api)
- [Login with Password Realm Grant](#login-with-password-realm-grant)
- [Get user information using user's access_token](#get-user-information-using-users-access_token)
- [Getting new access token with refresh token](#getting-new-access-token-with-refresh-token)
- [Using custom scheme for web authentication redirection](#using-custom-scheme-for-web-authentication-redirection)
- [Login using MFA with One Time Password code](#login-using-mfa-with-one-time-password-code)
- [Login with Passwordless](#login-with-passwordless)
- [Create user in database connection](#create-user-in-database-connection)
- [Management API (Users)](#management-api-users)
- [Patch user with user_metadata](#patch-user-with-user_metadata)
- [Get full user profile](#get-full-user-profile)
- [Organizations](#organizations)
- [Log in to an organization](#log-in-to-an-organization)
- [Accept user invitations](#accept-user-invitations)
- [Bot Protection](#bot-protection)
- [Domain Switching](#domain-switching)
- [Examples using react-native-auth0](#examples-using-react-native-auth0)
Comment thread
subhankarmaiti marked this conversation as resolved.
Outdated
- [Authentication API](#authentication-api)
- [Login with Password Realm Grant](#login-with-password-realm-grant)
- [Get user information using user's access_token](#get-user-information-using-users-access_token)
- [Getting new access token with refresh token](#getting-new-access-token-with-refresh-token)
- [Using custom scheme for web authentication redirection](#using-custom-scheme-for-web-authentication-redirection)
- [Login using MFA with One Time Password code](#login-using-mfa-with-one-time-password-code)
- [Login with Passwordless](#login-with-passwordless)
- [Create user in database connection](#create-user-in-database-connection)
- [Using HTTPS callback URLs](#using-https-callback-urls)
- [Management API (Users)](#management-api-users)
- [Patch user with user_metadata](#patch-user-with-user_metadata)
- [Get full user profile](#get-full-user-profile)
- [Organizations](#organizations)
- [Log in to an organization](#log-in-to-an-organization)
- [Accept user invitations](#accept-user-invitations)
- [Bot Protection](#bot-protection)
- [Domain Switching](#domain-switching)
- [Android](#android)
- [iOS](#ios)
- [Expo](#expo)

## Authentication API

Expand Down Expand Up @@ -154,6 +159,26 @@ auth0.auth
.catch(console.error);
```

### Using HTTPS callback URLs

HTTPS callback URLs provide enhanced security compared to custom URL schemes. They work with Android App Links and iOS Universal Links to prevent URL scheme hijacking:

```js
auth0.webAuth
.authorize(
{ scope: 'openid profile email' },
{ customScheme: 'https://yourdomain.com' }
Comment thread
subhankarmaiti marked this conversation as resolved.
Outdated
)
.then((credentials) => console.log(credentials))
.catch((error) => console.log(error));
```

For this to work:

Register https://yourdomain.com/{YOUR_APP_BUNDLE_ID}/{PLATFORM}/callback as an allowed callback URL in your Auth0 Dashboard
Configure your app to handle Universal Links (iOS) and App Links (Android)
Set up your domain with proper verification for these deep linking mechanisms
Comment thread
subhankarmaiti marked this conversation as resolved.
Outdated

## Management API (Users)

### Patch user with user_metadata
Expand Down
29 changes: 19 additions & 10 deletions FAQ.md
Original file line number Diff line number Diff line change
@@ -1,14 +1,23 @@
# Frequently Asked Questions

1. [How can I have separate Auth0 domains for each environment on Android?](#1-how-can-i-have-separate-auth0-domains-for-each-environment-on-android)
2. [How can I disable the iOS _login_ alert box?](#2-how-can-i-disable-the-ios-login-alert-box)
3. [How can I disable the iOS _logout_ alert box?](#3-how-can-i-disable-the-ios-logout-alert-box)
4. [Is there a way to disable the iOS _login_ alert box without `ephemeralSession`?](#4-is-there-a-way-to-disable-the-ios-login-alert-box-without-ephemeralsession)
5. [How can I change the message in the iOS alert box?](#5-how-can-i-change-the-message-in-the-ios-alert-box)
6. [How can I programmatically close the iOS alert box?](#6-how-can-i-programmatically-close-the-ios-alert-box)
7. [Auth0 web browser gets killed when going to the background on Android](#7-auth0-web-browser-gets-killed-when-going-to-the-background-on-android)
8. [How to resolve the _Failed to start this transaction, as there is an active transaction at the moment_ error?](#8-how-to-resolve-the-failed-to-start-this-transaction-as-there-is-an-active-transaction-at-the-moment-error)
9. [How can I prevent the autogenerated redirect_uri from breaking if the applicationId has mixed cases or special characters in it on Android?](#9-how-can-i-prevent-the-autogenerated-redirect_uri-from-breaking-if-the-applicationId-has-mixed-cases-or-special-characters-in-it-on-android)
- [Frequently Asked Questions](#frequently-asked-questions)
Comment thread
subhankarmaiti marked this conversation as resolved.
Outdated
- [1. How can I have separate Auth0 domains for each environment on Android?](#1-how-can-i-have-separate-auth0-domains-for-each-environment-on-android)
- [2. How can I disable the iOS _login_ alert box?](#2-how-can-i-disable-the-ios-login-alert-box)
- [Use ephemeral sessions](#use-ephemeral-sessions)
- [Use `SFSafariViewController`](#use-sfsafariviewcontroller)
- [3. How can I disable the iOS _logout_ alert box?](#3-how-can-i-disable-the-ios-logout-alert-box)
- [4. Is there a way to disable the iOS _login_ alert box without `ephemeralSession`?](#4-is-there-a-way-to-disable-the-ios-login-alert-box-without-ephemeralsession)
- [5. How can I change the message in the iOS alert box?](#5-how-can-i-change-the-message-in-the-ios-alert-box)
- [6. How can I programmatically close the iOS alert box?](#6-how-can-i-programmatically-close-the-ios-alert-box)
- [7. Auth0 web browser gets killed when going to the background on Android](#7-auth0-web-browser-gets-killed-when-going-to-the-background-on-android)
- [The problem](#the-problem)
- [The solution](#the-solution)
- [8. How to resolve the _Failed to start this transaction, as there is an active transaction at the moment_ error?](#8-how-to-resolve-the-failed-to-start-this-transaction-as-there-is-an-active-transaction-at-the-moment-error)
- [Workarounds](#workarounds)
- [Clear the login transaction when handling the `transactionActiveAlready` error](#clear-the-login-transaction-when-handling-the-transactionactivealready-error)
- [Clear the login transaction when the app moves to the background/foreground](#clear-the-login-transaction-when-the-app-moves-to-the-backgroundforeground)
- [Avoid the login/logout alert box](#avoid-the-loginlogout-alert-box)
- [9. How can I prevent the autogenerated redirect_uri from breaking if the applicationId has mixed cases or special characters in it on Android ?](#9-how-can-i-prevent-the-autogenerated-redirect_uri-from-breaking-if-the-applicationid-has-mixed-cases-or-special-characters-in-it-on-android-)

## 1. How can I have separate Auth0 domains for each environment on Android?

Expand Down Expand Up @@ -261,4 +270,4 @@ If you don't need SSO, consider using `ephemeral sessions` or `SFSafariViewContr

## 9. How can I prevent the autogenerated redirect_uri from breaking if the applicationId has mixed cases or special characters in it on Android ?

It is recommended to have your applicationId in lower case without special characters to prevent any mismatch with the generated redirect_uri. But in the scenario where you require your applicationId to be of mixed case, to avoid any mismatch , the user can pass a `redirectUri` whihc matches the one provided in the manage dashboard as part of the `AgentLoginOptions` property.
It is recommended to have your applicationId in lower case without special characters to prevent any mismatch with the generated redirect_uri. But in the scenario where you require your applicationId to be of mixed case, to avoid any mismatch , the user can pass a `redirectUri` which matches the one provided in the manage dashboard as part of the `AgentLoginOptions` property.
24 changes: 12 additions & 12 deletions example/ios/Podfile.lock
Original file line number Diff line number Diff line change
@@ -1,12 +1,12 @@
PODS:
- A0Auth0 (4.4.0):
- Auth0 (= 2.7.2)
- JWTDecode (= 3.1.0)
- Auth0 (= 2.10)
- JWTDecode (= 3.2.0)
- React-Core
- SimpleKeychain (= 1.1.0)
- Auth0 (2.7.2):
- JWTDecode (~> 3.1)
- SimpleKeychain (~> 1.1)
- SimpleKeychain (= 1.2.0)
- Auth0 (2.10.0):
- JWTDecode (= 3.2.0)
- SimpleKeychain (= 1.2.0)
- boost (1.84.0)
- DoubleConversion (1.1.6)
- fast_float (6.1.4)
Expand All @@ -16,7 +16,7 @@ PODS:
- hermes-engine (0.77.0):
- hermes-engine/Pre-built (= 0.77.0)
- hermes-engine/Pre-built (0.77.0)
- JWTDecode (3.1.0)
- JWTDecode (3.2.0)
- RCT-Folly (2024.11.18.00):
- boost
- DoubleConversion
Expand Down Expand Up @@ -1619,7 +1619,7 @@ PODS:
- ReactCommon/turbomodule/bridging
- ReactCommon/turbomodule/core
- Yoga
- SimpleKeychain (1.1.0)
- SimpleKeychain (1.2.0)
- SocketRocket (0.7.1)
- Yoga (0.0.0)

Expand Down Expand Up @@ -1845,16 +1845,16 @@ EXTERNAL SOURCES:
:path: "../node_modules/react-native/ReactCommon/yoga"

SPEC CHECKSUMS:
A0Auth0: 1a9d69121ff2455486a2a4ddc40c4f36585e5260
Auth0: 28cb24cb19ebd51f0b07751f16d83b59f4019532
A0Auth0: c54e2b28344e08ab2387986d00f2a418044fdbf9
Auth0: 2876d0c36857422eda9cb580a6cc896c7d14cb36
boost: 7e761d76ca2ce687f7cc98e698152abd03a18f90
DoubleConversion: cb417026b2400c8f53ae97020b2be961b59470cb
fast_float: 06eeec4fe712a76acc9376682e4808b05ce978b6
FBLazyVector: 2bc03a5cf64e29c611bbc5d7eb9d9f7431f37ee6
fmt: a40bb5bd0294ea969aaaba240a927bd33d878cdd
glog: eb93e2f488219332457c3c4eafd2738ddc7e80b8
hermes-engine: 1f783c3d53940aed0d2c84586f0b7a85ab7827ef
JWTDecode: 3eaab1e06b6f4dcbdd6716aff09ba4c2104ca8b7
JWTDecode: 7dae24cb9bf9b608eae61e5081029ec169bb5527
RCT-Folly: e78785aa9ba2ed998ea4151e314036f6c49e6d82
RCTDeprecation: f5c19ebdb8804b53ed029123eb69914356192fc8
RCTRequired: 6ae6cebe470486e0e0ce89c1c0eabb998e7c51f4
Expand Down Expand Up @@ -1915,7 +1915,7 @@ SPEC CHECKSUMS:
ReactCodegen: c08a5113d9c9c895fe10f3c296f74c6b705a60a9
ReactCommon: 1bd2dc684d7992acbf0dfee887b89a57a1ead86d
RNScreens: b32d0d59b53acb574fa795a9343591ef4e7ab7c2
SimpleKeychain: f8707c8e97b38c6a6e687b17732afc9bcef06439
SimpleKeychain: 768cf43ae778b1c21816e94dddf01bb8ee96a075
SocketRocket: d4aabe649be1e368d1318fdf28a022d714d65748
Yoga: 78d74e245ed67bb94275a1316cdc170b9b7fe884

Expand Down
4 changes: 2 additions & 2 deletions ios/A0Auth0.m
Original file line number Diff line number Diff line change
Expand Up @@ -51,11 +51,11 @@ - (dispatch_queue_t)methodQueue
}

RCT_EXPORT_METHOD(webAuth:(NSString *)scheme redirectUri:(NSString *)redirectUri state:(NSString *)state nonce:(NSString *)nonce audience:(NSString *)audience scope:(NSString *)scope connection:(NSString *)connection maxAge:(NSInteger)maxAge organization:(NSString *)organization invitationUrl:(NSString *)invitationUrl leeway:(NSInteger)leeway ephemeralSession:(BOOL)ephemeralSession safariViewControllerPresentationStyle:(NSInteger)safariViewControllerPresentationStyle additionalParameters:(NSDictionary *)additionalParameters resolver:(RCTPromiseResolveBlock)resolve rejecter:(RCTPromiseRejectBlock)reject) {
[self.nativeBridge webAuthWithState:state redirectUri:redirectUri nonce:nonce audience:audience scope:scope connection:connection maxAge:maxAge organization:organization invitationUrl:invitationUrl leeway:leeway ephemeralSession:ephemeralSession safariViewControllerPresentationStyle:safariViewControllerPresentationStyle additionalParameters:additionalParameters resolve:resolve reject:reject];
[self.nativeBridge webAuthWithScheme:scheme state:state redirectUri:redirectUri nonce:nonce audience:audience scope:scope connection:connection maxAge:maxAge organization:organization invitationUrl:invitationUrl leeway:leeway ephemeralSession:ephemeralSession safariViewControllerPresentationStyle:safariViewControllerPresentationStyle additionalParameters:additionalParameters resolve:resolve reject:reject];
}

RCT_EXPORT_METHOD(webAuthLogout:(NSString *)scheme federated:(BOOL)federated redirectUri:(NSString *)redirectUri resolver:(RCTPromiseResolveBlock)resolve rejecter:(RCTPromiseRejectBlock)reject) {
[self.nativeBridge webAuthLogoutWithFederated:federated redirectUri:redirectUri resolve:resolve reject:reject];
[self.nativeBridge webAuthLogoutWithScheme:scheme federated:federated redirectUri:redirectUri resolve:resolve reject:reject];
}

RCT_EXPORT_METHOD(resumeWebAuth:(NSString *)url resolver:(RCTPromiseResolveBlock)resolve rejecter:(RCTPromiseRejectBlock)reject) {
Expand Down
17 changes: 14 additions & 3 deletions ios/NativeBridge.swift
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,7 @@ public class NativeBridge: NSObject {
resolve(true)
}

@objc public func webAuth(state: String?, redirectUri: String, nonce: String?, audience: String?, scope: String?, connection: String?, maxAge: Int, organization: String?, invitationUrl: String?, leeway: Int, ephemeralSession: Bool, safariViewControllerPresentationStyle: Int, additionalParameters: [String: String], resolve: @escaping RCTPromiseResolveBlock, reject: @escaping RCTPromiseRejectBlock) {
@objc public func webAuth(scheme: String, state: String?, redirectUri: String, nonce: String?, audience: String?, scope: String?, connection: String?, maxAge: Int, organization: String?, invitationUrl: String?, leeway: Int, ephemeralSession: Bool, safariViewControllerPresentationStyle: Int, additionalParameters: [String: String], resolve: @escaping RCTPromiseResolveBlock, reject: @escaping RCTPromiseRejectBlock) {
let builder = Auth0.webAuth(clientId: self.clientId, domain: self.domain)
if let value = URL(string: redirectUri) {
let _ = builder.redirectURL(value)
Expand Down Expand Up @@ -89,6 +89,12 @@ public class NativeBridge: NSObject {
if(ephemeralSession) {
let _ = builder.useEphemeralSession()
}

// Check if scheme starts with https and use HTTPS if it does
if scheme.starts(with: "https") {
let _ = builder.useHTTPS()
}

//Since we cannot have a null value here, the JS layer sends 99 if we have to ignore setting this value
if let presentationStyle = UIModalPresentationStyle(rawValue: safariViewControllerPresentationStyle), safariViewControllerPresentationStyle != 99 {
let _ = builder.provider(WebAuthentication.safariProvider(style: presentationStyle))
Expand All @@ -103,14 +109,19 @@ public class NativeBridge: NSObject {
reject(error.reactNativeErrorCode(), error.errorDescription, error)
}
}

}

@objc public func webAuthLogout(federated: Bool, redirectUri: String, resolve: @escaping RCTPromiseResolveBlock, reject: @escaping RCTPromiseRejectBlock) {
@objc public func webAuthLogout(scheme: String, federated: Bool, redirectUri: String, resolve: @escaping RCTPromiseResolveBlock, reject: @escaping RCTPromiseRejectBlock) {
let builder = Auth0.webAuth(clientId: self.clientId, domain: self.domain)
if let value = URL(string: redirectUri) {
let _ = builder.redirectURL(value)
}

// Check if scheme starts with https and use HTTPS if it does
if scheme.starts(with: "https") {
let _ = builder.useHTTPS()
}

builder.clearSession(federated: federated) { result in
switch result {
case .success:
Expand Down
2 changes: 1 addition & 1 deletion src/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -119,7 +119,7 @@ export interface WebAuthorizeOptions {
*/
ephemeralSession?: boolean;
/**
* **Android only:** Custom scheme to build the callback URL with.
* Custom scheme to build the callback URL with.
*/
customScheme?: string;
/**
Expand Down
7 changes: 5 additions & 2 deletions src/webauth/agent.ts
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,8 @@ class Agent {
);
let redirectUri =
options.redirectUrl ?? this.callbackUri(parameters.domain, scheme);

// The native modules will now check if scheme.startsWith("https") internally
let credentials = await A0Auth0.webAuth(
scheme,
redirectUri,
Expand All @@ -62,8 +64,7 @@ class Agent {
options.invitationUrl,
options.leeway ?? 0,
options.ephemeralSession ?? false,
options.safariViewControllerPresentationStyle ?? 99, //Since we can't pass null to the native layer, and we need a value to represent this parameter is not set, we are using 99.
Comment thread
subhankarmaiti marked this conversation as resolved.
//The native layer will check for this and ignore if the value is 99
options.safariViewControllerPresentationStyle ?? 99,
options.additionalParameters ?? {}
);
resolve(credentials);
Expand Down Expand Up @@ -113,6 +114,8 @@ class Agent {
);
let redirectUri =
options.returnToUrl ?? this.callbackUri(parameters.domain, scheme);

// The native modules will now check if scheme.startsWith("https") internally
await _ensureNativeModuleIsInitializedWithConfiguration(
NativeModules.A0Auth0,
parameters.clientId,
Expand Down