Skip to content
Merged
Show file tree
Hide file tree
Changes from all 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
5 changes: 3 additions & 2 deletions EXAMPLES.md
Original file line number Diff line number Diff line change
Expand Up @@ -667,7 +667,7 @@ function MyComponent() {

## Android Networking Configuration

> **Platform Support:** Android only. Accepted on iOS for API compatibility but has no effect.
> **Platform Support:** The timeout and header fields are Android only and have no effect on iOS. `enableLogging` is honored on both iOS and Android.

The `networkingOptions` configuration option lets you tune the native networking client (`DefaultClient` from Auth0.Android's OkHttp-based stack) used for every request the native SDK makes on your behalf — web auth token exchange, credential renewal, MFA, passkeys, and My Account API calls.

Expand All @@ -685,7 +685,8 @@ networkingOptions?: {
Any option you omit falls back to Auth0.Android's own default.

> [!WARNING]
> `enableLogging` is **debug-only**. When enabled, Auth0.Android logs full HTTP request and response bodies to Logcat — including access, refresh, and ID tokens returned from token-endpoint calls, in plaintext. Never enable it in a production build.
> On **Android**, `enableLogging` is **debug-only**: Auth0.Android logs full HTTP request and response bodies to Logcat — including access, refresh, and ID tokens from token-endpoint calls, in plaintext — and the flag is ignored on release builds. Never enable it in a production build.
> On **iOS**, `enableLogging` maps to Auth0.swift's `.logging(enabled:)`, which traces requests and responses to the unified logging system (OSLog) with access, refresh, and ID tokens redacted. There is no release-build gate, so enable it only while debugging.

### Using Networking Options with Hooks

Expand Down
14 changes: 8 additions & 6 deletions ios/A0Auth0.mm
Original file line number Diff line number Diff line change
Expand Up @@ -109,8 +109,10 @@ - (dispatch_queue_t)methodQueue
networkingOptions:(NSDictionary * _Nullable)networkingOptions
resolve:(RCTPromiseResolveBlock)resolve
reject:(RCTPromiseRejectBlock)reject) {
// networkingOptions is Android-only; intentionally not forwarded to NativeBridge.
[self tryAndInitializeNativeBridge:clientId domain:domain withLocalAuthenticationOptions:localAuthenticationOptions useDPoP:useDPoP maxRetries:(NSInteger)maxRetries credentialsManagerStorageKey:credentialsManagerStorageKey resolve:resolve reject:reject];
// networkingOptions is otherwise Android-only; on iOS we honor just `enableLogging`,
// which maps to Auth0.swift's `.logging(enabled:)` (HTTP tracing with token redaction).
BOOL enableLogging = [networkingOptions[@"enableLogging"] boolValue];
[self tryAndInitializeNativeBridge:clientId domain:domain withLocalAuthenticationOptions:localAuthenticationOptions useDPoP:useDPoP maxRetries:(NSInteger)maxRetries credentialsManagerStorageKey:credentialsManagerStorageKey enableLogging:enableLogging resolve:resolve reject:reject];
}


Expand Down Expand Up @@ -415,12 +417,12 @@ - (BOOL)checkHasValidNativeBridgeInstance:(NSString*) clientId domain:(NSString
return valid;
}

- (void)tryAndInitializeNativeBridge:(NSString *)clientId domain:(NSString *)domain withLocalAuthenticationOptions:(NSDictionary*) options useDPoP:(NSNumber *)useDPoP maxRetries:(NSInteger)maxRetries credentialsManagerStorageKey:(NSString * _Nullable)credentialsManagerStorageKey resolve:(RCTPromiseResolveBlock)resolve reject:(RCTPromiseRejectBlock)reject {
- (void)tryAndInitializeNativeBridge:(NSString *)clientId domain:(NSString *)domain withLocalAuthenticationOptions:(NSDictionary*) options useDPoP:(NSNumber *)useDPoP maxRetries:(NSInteger)maxRetries credentialsManagerStorageKey:(NSString * _Nullable)credentialsManagerStorageKey enableLogging:(BOOL)enableLogging resolve:(RCTPromiseResolveBlock)resolve reject:(RCTPromiseRejectBlock)reject {
BOOL useDPoPBool = [useDPoP boolValue];
NativeBridge *bridge = [[NativeBridge alloc] initWithClientId:clientId domain:domain localAuthenticationOptions:options useDPoP:useDPoPBool maxRetries:maxRetries credentialsManagerStorageKey:credentialsManagerStorageKey resolve:resolve reject:reject];
NativeBridge *bridge = [[NativeBridge alloc] initWithClientId:clientId domain:domain localAuthenticationOptions:options useDPoP:useDPoPBool maxRetries:maxRetries credentialsManagerStorageKey:credentialsManagerStorageKey enableLogging:enableLogging resolve:resolve reject:reject];
self.nativeBridge = bridge;
self.myAccount = [[A0MyAccount alloc] initWithDomain:domain useDPoP:useDPoPBool];
self.passwordless = [[A0Passwordless alloc] initWithClientId:clientId domain:domain useDPoP:useDPoPBool];
self.myAccount = [[A0MyAccount alloc] initWithDomain:domain useDPoP:useDPoPBool enableLogging:enableLogging];
self.passwordless = [[A0Passwordless alloc] initWithClientId:clientId domain:domain useDPoP:useDPoPBool enableLogging:enableLogging];
}
- (std::shared_ptr<facebook::react::TurboModule>)getTurboModule:(const facebook::react::ObjCTurboModule::InitParams &)params {
return std::make_shared<facebook::react::NativeA0Auth0SpecJSI>(params);
Expand Down
5 changes: 4 additions & 1 deletion ios/A0MfaClient.swift
Original file line number Diff line number Diff line change
Expand Up @@ -31,19 +31,22 @@ class A0MfaClient {
private let clientId: String
private let domain: String
private let useDPoP: Bool
private let enableLogging: Bool

private lazy var mfaClient: MFAClient = {
var client = Auth0.mfa(clientId: clientId, domain: domain)
if useDPoP {
client = client.useDPoP()
}
client = client.logging(enabled: enableLogging)
return client
}()

init(clientId: String, domain: String, useDPoP: Bool) {
init(clientId: String, domain: String, useDPoP: Bool, enableLogging: Bool) {
self.clientId = clientId
self.domain = domain
self.useDPoP = useDPoP
self.enableLogging = enableLogging
}

// Maps the public MfaFactorType vocabulary (otp/sms/voice/email/push) onto
Expand Down
5 changes: 4 additions & 1 deletion ios/MyAccount.swift
Original file line number Diff line number Diff line change
Expand Up @@ -8,17 +8,20 @@ public class A0MyAccount: NSObject {

private let domain: String
private let useDPoP: Bool
private let enableLogging: Bool

@objc public init(domain: String, useDPoP: Bool) {
@objc public init(domain: String, useDPoP: Bool, enableLogging: Bool) {
self.domain = domain
self.useDPoP = useDPoP
self.enableLogging = enableLogging
}

private func createClient(accessToken: String) -> any MyAccount {
var client = Auth0.myAccount(token: accessToken, domain: self.domain)
if self.useDPoP {
client = client.useDPoP()
}
client = client.logging(enabled: self.enableLogging)
Comment thread
subhankarmaiti marked this conversation as resolved.
return client
}

Expand Down
15 changes: 12 additions & 3 deletions ios/NativeBridge.swift
Original file line number Diff line number Diff line change
Expand Up @@ -48,20 +48,23 @@ public class NativeBridge: NSObject {
var domain: String
var useDPoP: Bool
var maxRetries: Int
var enableLogging: Bool
private(set) lazy var mfaClient: A0MfaClient = {
A0MfaClient(clientId: self.clientId, domain: self.domain, useDPoP: self.useDPoP)
A0MfaClient(clientId: self.clientId, domain: self.domain, useDPoP: self.useDPoP, enableLogging: self.enableLogging)
}()
@objc public init(clientId: String, domain: String, localAuthenticationOptions: [String: Any]?, useDPoP: Bool, maxRetries: Int, credentialsManagerStorageKey: String?, resolve: @escaping RCTPromiseResolveBlock, reject: @escaping RCTPromiseRejectBlock) {

@objc public init(clientId: String, domain: String, localAuthenticationOptions: [String: Any]?, useDPoP: Bool, maxRetries: Int, credentialsManagerStorageKey: String?, enableLogging: Bool, resolve: @escaping RCTPromiseResolveBlock, reject: @escaping RCTPromiseRejectBlock) {
var auth0 = Auth0
.authentication(clientId: clientId, domain: domain)
self.clientId = clientId
self.domain = domain
self.useDPoP = useDPoP
self.maxRetries = maxRetries
self.enableLogging = enableLogging
if self.useDPoP {
auth0 = auth0.useDPoP()
}
auth0 = auth0.logging(enabled: enableLogging)
// Namespace the keychain per client when a storage key is provided, else use the default service.
if let key = credentialsManagerStorageKey, !key.isEmpty {
self.credentialsManager = CredentialsManager(authentication: auth0, storage: SimpleKeychain(service: key), maxRetries: maxRetries)
Expand Down Expand Up @@ -104,6 +107,7 @@ public class NativeBridge: NSObject {
if self.useDPoP {
builder = builder.useDPoP()
}
builder = builder.logging(enabled: self.enableLogging)
if let value = URL(string: redirectUri) {
builder = builder.redirectURL(value)
}
Expand Down Expand Up @@ -160,6 +164,7 @@ public class NativeBridge: NSObject {

@objc public func webAuthLogout(scheme: String, federated: Bool, redirectUri: String, resolve: @escaping RCTPromiseResolveBlock, reject: @escaping RCTPromiseRejectBlock) {
var builder = Auth0.webAuth(clientId: self.clientId, domain: self.domain)
builder = builder.logging(enabled: self.enableLogging)
if let value = URL(string: redirectUri) {
builder = builder.redirectURL(value)
}
Expand Down Expand Up @@ -423,6 +428,7 @@ public class NativeBridge: NSObject {
if self.useDPoP {
auth = auth.useDPoP()
}
auth = auth.logging(enabled: self.enableLogging)

let finalScope = scope ?? "openid profile email"

Expand Down Expand Up @@ -491,6 +497,7 @@ public class NativeBridge: NSObject {
if self.useDPoP {
auth = auth.useDPoP()
}
auth = auth.logging(enabled: self.enableLogging)

auth.passkeySignupChallenge(
email: finalEmail,
Expand Down Expand Up @@ -539,6 +546,7 @@ public class NativeBridge: NSObject {
if self.useDPoP {
auth = auth.useDPoP()
}
auth = auth.logging(enabled: self.enableLogging)

auth.passkeyLoginChallenge(
connection: realmValue,
Expand Down Expand Up @@ -590,6 +598,7 @@ public class NativeBridge: NSObject {
if self.useDPoP {
auth = auth.useDPoP()
}
auth = auth.logging(enabled: self.enableLogging)

if let attestationObjectString = responseDict["attestationObject"] as? String {
let attestationObject = Data(base64URLEncoded: attestationObjectString)
Expand Down
3 changes: 2 additions & 1 deletion ios/Passwordless.swift
Original file line number Diff line number Diff line change
Expand Up @@ -7,11 +7,12 @@ public class A0Passwordless: NSObject {

private let client: Authentication

@objc public init(clientId: String, domain: String, useDPoP: Bool) {
@objc public init(clientId: String, domain: String, useDPoP: Bool, enableLogging: Bool) {
var client = Auth0.authentication(clientId: clientId, domain: domain)
if useDPoP {
client = client.useDPoP()
}
client = client.logging(enabled: enableLogging)
self.client = client
}

Expand Down
2 changes: 1 addition & 1 deletion src/platforms/native/bridge/NativeBridge.ts
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@ export interface NativeBridge {
* @param useDPoP Whether to enable DPoP (Demonstrating Proof-of-Possession) for token requests.
* @param maxRetries The maximum number of retry attempts for transient errors during credential renewal. **iOS only** - ignored on Android. Defaults to 0.
* @param credentialsManagerStorageKey Namespaces the credentials store. **Android only** SharedPreferences file name. **iOS only** Keychain service name. Defaults to the shared store when omitted.
* @param networkingOptions Configures the native networking client. **Android only** - ignored on iOS.
* @param networkingOptions Configures the native networking client. Timeouts and headers are **Android only**; `enableLogging` is honored on both platforms.
*/
initialize(
clientId: string,
Expand Down
18 changes: 12 additions & 6 deletions src/types/common.ts
Original file line number Diff line number Diff line change
Expand Up @@ -217,7 +217,8 @@ export interface Auth0Options {
/**
* Configures the native networking client (OkHttp) that Auth0.Android uses for every
* request it makes (web auth token exchange, credential renewal, MFA, passkeys, etc.).
* @remarks Android only. Accepted on iOS for API compatibility but has no effect.
* @remarks The timeout and header fields are Android only and have no effect on iOS.
* `enableLogging` is honored on both platforms (see {@link NetworkingOptions.enableLogging}).
*/
networkingOptions?: NetworkingOptions;
// Telemetry and localAuthenticationOptions are platform-specific extensions
Expand All @@ -227,7 +228,8 @@ export interface Auth0Options {
* Configuration for the native networking client used by Auth0.Android.
* Mirrors `DefaultClient.Builder` from the Auth0.Android SDK.
*
* @remarks Android only. Has no effect on iOS or web.
* @remarks The timeout and header fields are Android only and have no effect on iOS or web.
* `enableLogging` is honored on iOS as well (it maps to Auth0.swift's `.logging(enabled:)`).
*
* @example
* ```ts
Expand All @@ -254,12 +256,16 @@ export interface NetworkingOptions {
*/
defaultHeaders?: Record<string, string>;
/**
* Enables verbose HTTP request/response logging to Logcat.
* Enables verbose HTTP request/response logging for the native SDKs.
*
* @remarks
* **Debug-only.** Auth0.Android logs full request and response bodies at this level,
* which includes access, refresh, and ID tokens in plaintext for token-endpoint calls.
* Never enable this in production.
* On **Android** this maps to the OkHttp logging interceptor and writes full request and
* response bodies to Logcat — including access, refresh, and ID tokens in plaintext — so it is
* **debug-only** (ignored on release builds) and must never be enabled in production.
*
* On **iOS** this maps to Auth0.swift's `.logging(enabled:)`, which traces requests and responses
* to the unified logging system (OSLog) with access, refresh, and ID tokens redacted. It has no
* build-type gate, so still enable it only while debugging.
* @default false
*/
enableLogging?: boolean;
Expand Down
Loading