Skip to content
Open
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
6 changes: 3 additions & 3 deletions CLAUDE.md
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@ react-native-auth0/
│ ├── index.ts # Public API exports (entry point)
│ ├── Auth0.ts # Main Auth0 facade class
│ ├── core/ # Platform-agnostic core
│ │ ├── interfaces/ # Contracts every platform implements (IAuth0Client, …)
│ │ ├── interfaces/ # Contracts every platform implements (Auth0Client, …)
│ │ ├── models/ # Credentials, Auth0User, AuthError hierarchy
│ │ ├── services/ # HttpClient, AuthenticationOrchestrator
│ │ └── utils/ # scope, validation, telemetry, deepCamelCase
Expand All @@ -65,7 +65,7 @@ react-native-auth0/
| -------------------------------------------------------- | --------------------------------------------------------- |
| `src/index.ts` | Public API surface — everything exported to consumers |
| `src/Auth0.ts` | Main facade class |
| `src/core/interfaces/IAuth0Client.ts` | Primary client interface; new methods start here |
| `src/core/interfaces/Auth0Client.ts` | Primary client interface; new methods start here |
| `src/core/services/HttpClient.ts` | HTTP wrapper; injects the `Auth0-Client` telemetry header |
| `src/core/services/AuthenticationOrchestrator.ts` | Authentication API calls |
| `src/core/utils/telemetry.ts` | Telemetry payload (version injected at prebuild) |
Expand Down Expand Up @@ -143,7 +143,7 @@ The default `yarn test` suite is unit-only — no credentials or live tenant req
## Code Style

- **CI-enforced:** single quotes, trailing commas, 2-space indent (Prettier); `@typescript-eslint/unbound-method` is an error; strict TS with `noUnusedLocals`/`noUnusedParameters`. `prettier/prettier` failures fail lint.
- Naming: `PascalCase` types/classes/interfaces (interfaces prefixed `I`), `camelCase` functions/vars, `snake_case` only for raw API wire payloads (converted via `deepCamelCase`).
- Naming: `PascalCase` types/classes/interfaces (interfaces are **not** `I`-prefixed — the contract keeps the plain name, implementations carry the platform prefix), `camelCase` functions/vars, `snake_case` only for raw API wire payloads (converted via `deepCamelCase`).

See [references/code-style.md](references/code-style.md) for good/bad examples and the dominant patterns (interface-driven design, factory selection, orchestrators). Read when writing non-trivial new code.

Expand Down
15 changes: 15 additions & 0 deletions MIGRATION_GUIDE.md
Original file line number Diff line number Diff line change
Expand Up @@ -235,6 +235,21 @@ Two codes were added for the new Auth0.swift cases, both iOS-only: `AUTHENTICATI

`SSO_EXCHANGE_FAILED` (iOS and Android) and `CLEAR_FAILED` (iOS) are now reported instead of being collapsed into a generic credentials-manager error. No action is required unless you exhaustively match on these codes.

### 10. Interfaces no longer use the `I` prefix ✅

The platform contracts in `src/core/interfaces/` dropped their `I` prefix, so the interface now takes the plain name and the implementations keep their platform prefix (`Auth0Client` is the contract; `NativeAuth0Client` and `WebAuth0Client` implement it).

Only one of these was exported to consumers:

```diff
- import type { IMfaClient } from 'react-native-auth0';
+ import type { MfaClient } from 'react-native-auth0';
```

**✅ Action Required:** rename the import if you annotated anything with `IMfaClient` — typically a variable holding `auth0.mfa` or the `mfa` object from `useAuth0()`. This is a type-only change; runtime behaviour is identical.

The rest (`AuthenticationProvider`, `CredentialsManager`, `MyAccountClient`, `PasswordlessClient`, `WebAuthProvider`, `NativeBridge`) were never exported from the package entry point, so nothing to do there.

### Recommended Reading

- The [FAQ](FAQ.md) for guidance on the `authorize()` redirect flow on web and the importance of the `offline_access` scope.
Expand Down
6 changes: 3 additions & 3 deletions references/code-style.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@

## Naming

- `PascalCase` for classes, types, and interfaces; interfaces are `I`-prefixed (`IAuth0Client`, `ICredentialsManager`).
- `PascalCase` for classes, types, and interfaces. Interfaces are **not** `I`-prefixed — the contract takes the plain name (`Auth0Client`, `CredentialsManager`) and implementations carry the platform prefix (`NativeAuth0Client`, `WebCredentialsManager`).
- `camelCase` for functions, methods, variables.
- `snake_case` appears only in raw API wire payloads; convert to camelCase via `deepCamelCase` (`src/core/utils`) before it reaches public types.
- Errors extend `AuthError` and carry a programmatic `code`, a `message`, and an optional `cause`.
Expand All @@ -21,7 +21,7 @@
```ts
import type { Credentials } from '../../types';

export interface IAuthenticationProvider {
export interface AuthenticationProvider {
passwordRealm: (params: PasswordRealmParameters) => Promise<Credentials>;
}

Expand All @@ -37,7 +37,7 @@ export class InvalidTokenError extends AuthError {
```ts
import { Credentials } from '../../types'; // should be `import type`

export interface IAuthenticationProvider {
export interface AuthenticationProvider {
passwordRealm(params: any): Promise<any>; // any + method syntax
}

Expand Down
14 changes: 7 additions & 7 deletions src/Auth0.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import type { IAuth0Client } from './core/interfaces/IAuth0Client';
import type { IMfaClient } from './core/interfaces/IMfaClient';
import type { Auth0Client } from './core/interfaces/Auth0Client';
import type { MfaClient } from './core/interfaces/MfaClient';
import { Auth0ClientFactory } from './factory/Auth0ClientFactory';
import type {
Auth0Options,
Expand Down Expand Up @@ -29,7 +29,7 @@ import type {
* ```
*/
class Auth0 {
private client: IAuth0Client;
private client: Auth0Client;

/**
* Creates an instance of the Auth0 client.
Expand All @@ -43,23 +43,23 @@ class Auth0 {

/**
* Provides access to the web-based authentication methods.
* @see IWebAuthProvider
* @see WebAuthProvider
*/
get webAuth() {
return this.client.webAuth;
}

/**
* Provides access to the credentials management methods.
* @see ICredentialsManager
* @see CredentialsManager
*/
get credentialsManager() {
return this.client.credentialsManager;
}

/**
* Provides access to direct authentication methods (e.g., password-realm).
* @see IAuthenticationProvider
* @see AuthenticationProvider
*/
get auth() {
return this.client.auth;
Expand Down Expand Up @@ -165,7 +165,7 @@ class Auth0 {
* const credentials = await auth0.mfa.verify({ mfaToken, otp: '123456' });
* ```
*/
get mfa(): IMfaClient {
get mfa(): MfaClient {
return this.client.mfa;
}

Expand Down
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
import type { IWebAuthProvider } from './IWebAuthProvider';
import type { ICredentialsManager } from './ICredentialsManager';
import type { IAuthenticationProvider } from './IAuthenticationProvider';
import type { IMyAccountClient } from './IMyAccountClient';
import type { IPasswordlessClient } from './IPasswordlessClient';
import type { IMfaClient } from './IMfaClient';
import type { WebAuthProvider } from './WebAuthProvider';
import type { CredentialsManager } from './CredentialsManager';
import type { AuthenticationProvider } from './AuthenticationProvider';
import type { MyAccountClient } from './MyAccountClient';
import type { PasswordlessClient } from './PasswordlessClient';
import type { MfaClient } from './MfaClient';
import type {
DPoPHeadersParams,
CustomTokenExchangeParameters,
Expand All @@ -21,33 +21,33 @@ import type {
* into a single, cohesive contract. Platform-specific factories will produce an
* object that conforms to this interface.
*/
export interface IAuth0Client {
export interface Auth0Client {
/**
* Provides access to methods for handling web-based authentication flows.
*/
readonly webAuth: IWebAuthProvider;
readonly webAuth: WebAuthProvider;

/**
* Provides access to methods for securely managing user credentials on the device.
*/
readonly credentialsManager: ICredentialsManager;
readonly credentialsManager: CredentialsManager;

/**
* Provides access to methods for direct authentication grants (e.g., password-realm).
*/
readonly auth: IAuthenticationProvider;
readonly auth: AuthenticationProvider;

/**
* Provides access to methods for interacting with the My Account API for managing authentication methods.
*/
readonly myAccount: IMyAccountClient;
readonly myAccount: MyAccountClient;

/**
* Provides access to the passwordless OTP flow for database connections.
*
* @remarks Native only (iOS, Android). Not supported on web.
*/
readonly passwordless: IPasswordlessClient;
readonly passwordless: PasswordlessClient;

/**
* Generates DPoP headers for making authenticated requests to custom APIs.
Expand Down Expand Up @@ -101,7 +101,7 @@ export interface IAuth0Client {
* const credentials = await auth0.mfa.verify({ mfaToken, otp: '123456' });
* ```
*/
readonly mfa: IMfaClient;
readonly mfa: MfaClient;

/**
* Requests a passkey signup challenge from Auth0.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ import type {
* Defines the contract for direct authentication methods that interact with Auth0's
* Authentication API endpoints without a web-based redirect.
*/
export interface IAuthenticationProvider {
export interface AuthenticationProvider {
passwordRealm(parameters: PasswordRealmParameters): Promise<Credentials>;
refreshToken(parameters: RefreshTokenParameters): Promise<Credentials>;
userInfo(parameters: UserInfoParameters): Promise<User>;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ import { ApiCredentials } from '../models';
* Implementations are responsible for secure storage (e.g., Keychain on iOS,
* EncryptedSharedPreferences on Android) and token refresh logic.
*/
export interface ICredentialsManager {
export interface CredentialsManager {
/**
* Securely saves a set of credentials to the device's storage.
*
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ import type {
* from an MFA_REQUIRED error. It provides methods to list authenticators,
* enroll new factors, challenge existing factors, and verify MFA codes.
*/
export interface IMfaClient {
export interface MfaClient {
/**
* Lists the user's enrolled MFA authenticators.
*
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ import type {
Factor,
} from '../../types';

export interface IMyAccountClient {
export interface MyAccountClient {
// --- Passkey Enrollment ---

passkeyEnrollmentChallenge(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ import type {
*
* @remarks Native only (iOS, Android). Not supported on web.
*/
export interface IPasswordlessClient {
export interface PasswordlessClient {
/**
* Issues an OTP challenge to an email address for a database connection.
*
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ import type {
* Defines the contract for a provider that handles web-based authentication flows,
* such as redirecting to the Auth0 Universal Login page.
*/
export interface IWebAuthProvider {
export interface WebAuthProvider {
/**
* Initiates the web-based authentication flow.
*
Expand Down
14 changes: 7 additions & 7 deletions src/core/interfaces/index.ts
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
export * from './common';
export * from './IAuth0Client';
export * from './IAuthenticationProvider';
export * from './ICredentialsManager';
export * from './IMyAccountClient';
export * from './IPasswordlessClient';
export * from './IWebAuthProvider';
export * from './IMfaClient';
export * from './Auth0Client';
export * from './AuthenticationProvider';
export * from './CredentialsManager';
export * from './MyAccountClient';
export * from './PasswordlessClient';
export * from './WebAuthProvider';
export * from './MfaClient';
6 changes: 3 additions & 3 deletions src/core/models/ApiCredentials.ts
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
import type { ApiCredentials as IApiCredentials } from '../../types';
import type { ApiCredentials as ApiCredentialsData } from '../../types';

/**
* A class representation of API-specific user credentials.
* It encapsulates the tokens and provides helper methods for convenience.
*/
export class ApiCredentials implements IApiCredentials {
export class ApiCredentials implements ApiCredentialsData {
public accessToken: string;
public tokenType: string;
public expiresAt: number;
Expand All @@ -15,7 +15,7 @@ export class ApiCredentials implements IApiCredentials {
*
* @param params An object conforming to the ApiCredentials type definition.
*/
constructor(params: IApiCredentials) {
constructor(params: ApiCredentialsData) {
this.accessToken = params.accessToken;
this.tokenType = params.tokenType;
this.expiresAt = params.expiresAt;
Expand Down
6 changes: 3 additions & 3 deletions src/core/models/Credentials.ts
Original file line number Diff line number Diff line change
@@ -1,13 +1,13 @@
import type {
Credentials as ICredentials,
Credentials as CredentialsData,
NativeCredentialsResponse,
} from '../../types';

/**
* A class representation of user credentials.
* It encapsulates the tokens and provides helper methods for convenience.
*/
export class Credentials implements ICredentials {
export class Credentials implements CredentialsData {
public idToken: string;
public accessToken: string;
public tokenType: string;
Expand All @@ -25,7 +25,7 @@ export class Credentials implements ICredentials {
*
* @param params An object conforming to the Credentials type definition.
*/
constructor(params: ICredentials) {
constructor(params: CredentialsData) {
this.idToken = params.idToken;
this.accessToken = params.accessToken;
this.tokenType = params.tokenType;
Expand Down
4 changes: 2 additions & 2 deletions src/core/services/AuthenticationOrchestrator.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import type { IAuthenticationProvider } from '../interfaces';
import type { AuthenticationProvider } from '../interfaces';
import type {
Credentials,
SessionTransferCredentials,
Expand Down Expand Up @@ -67,7 +67,7 @@ function includeRequiredScope(scope?: string): string {
* Orchestrates all direct authentication flows by making calls to the Auth0 Authentication API.
* This class is platform-agnostic and relies on an injected HttpClient.
*/
export class AuthenticationOrchestrator implements IAuthenticationProvider {
export class AuthenticationOrchestrator implements AuthenticationProvider {
private readonly client: HttpClient;
private readonly clientId: string;
private readonly tokenType: TokenType;
Expand Down
8 changes: 4 additions & 4 deletions src/factory/Auth0ClientFactory.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import type { IAuth0Client } from '../core/interfaces';
import type { Auth0Client } from '../core/interfaces';
import type { Auth0Options } from '../types';
import type { NativeAuth0Options } from '../types/platform-specific';
import { validateAuth0Options, getConfigSignature } from '../core/utils';
Expand All @@ -7,20 +7,20 @@ import { validateAuth0Options, getConfigSignature } from '../core/utils';
import { NativeAuth0Client } from '../platforms/native';

/**
* Creates the Native-specific IAuth0Client; selected by Metro for iOS/Android.
* Creates the Native-specific Auth0Client; selected by Metro for iOS/Android.
* Clients are cached by config signature so remounts reuse the same instance
* (avoiding duplicate refresh exchanges); a config change yields a fresh client.
*/
export class Auth0ClientFactory {
private static clientCache = new Map<string, IAuth0Client>();
private static clientCache = new Map<string, Auth0Client>();

/**
* Creates or returns a cached NativeAuth0Client instance.
*
* @param options The configuration options for the Auth0 client.
* @returns An instance of NativeAuth0Client.
*/
static createClient(options: Auth0Options): IAuth0Client {
static createClient(options: Auth0Options): Auth0Client {
validateAuth0Options(options);

const cacheKey = getConfigSignature(options);
Expand Down
8 changes: 4 additions & 4 deletions src/factory/Auth0ClientFactory.web.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import type { IAuth0Client } from '../core/interfaces';
import type { Auth0Client } from '../core/interfaces';
import type { Auth0Options } from '../types';
import type { WebAuth0Options } from '../types/platform-specific';
import { validateAuth0Options, getConfigSignature } from '../core/utils';
Expand All @@ -7,20 +7,20 @@ import { validateAuth0Options, getConfigSignature } from '../core/utils';
import { WebAuth0Client } from '../platforms/web';

/**
* Creates the Web-specific IAuth0Client; selected by bundlers when targeting web.
* Creates the Web-specific Auth0Client; selected by bundlers when targeting web.
* Clients are cached by config signature so remounts reuse the same instance
* (avoiding duplicate refresh exchanges); a config change yields a fresh client.
*/
export class Auth0ClientFactory {
private static clientCache = new Map<string, IAuth0Client>();
private static clientCache = new Map<string, Auth0Client>();

/**
* Creates or returns a cached WebAuth0Client instance.
*
* @param options The configuration options for the Auth0 client.
* @returns An instance of WebAuth0Client.
*/
static createClient(options: Auth0Options): IAuth0Client {
static createClient(options: Auth0Options): Auth0Client {
validateAuth0Options(options);

const cacheKey = getConfigSignature(options);
Expand Down
Loading
Loading