Skip to content

feat: architectural refactor for multi-platform extensibility #1233

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 53 commits into
base: master
Choose a base branch
from

Conversation

subhankarmaiti
Copy link
Contributor

@subhankarmaiti subhankarmaiti commented Jul 11, 2025

Summary & Motivation

This pull request introduces a major architectural refactor of the react-native-auth0 library. The primary goal is to evolve from the existing tightly-coupled implementation to a highly abstracted, modular, and extensible architecture that cleanly supports multiple platforms (Native and Web) in a maintainable way.

The previous structure made it difficult to add new features or platforms without significant code duplication and risk of regressions. This new architecture establishes a clear separation of concerns, making the library more robust, performant, and easier for future contributors to understand and extend.

The New Architecture

The new design is built on the Dependency Inversion Principle, using a Factory pattern to provide the correct platform-specific implementation at build time. High-level modules (like the React hooks) are now completely decoupled from low-level platform details (the native bridge or auth0-spa-js).

High-Level Diagram

This diagram illustrates the new flow of control. The key concept is that the consumer-facing API is decoupled from the platform implementations via a Factory that chooses the correct module at build time.

graph TD
    subgraph " "
        direction LR
        A["React Hooks / Developer"]
    end
    
    A --> B[Auth0 Facade Class];
    B --> C{Auth0ClientFactory};
    
    subgraph " "
        direction LR
        C -- instantiates --> D["IAuth0Client (The Contract)"];
    end
    
    subgraph "Platform Implementations"
        direction LR
        subgraph " "
            E[NativeAuth0Client] --> D;
        end
        subgraph " "
            F[WebAuth0Client] --> D;
        end
    end

    subgraph " "
        direction LR
        E -- uses --> G[Native Bridge & Adapters];
    end
    
    subgraph " "
        direction LR
        F -- uses --> H[auth0-spa-js & Adapters];
    end

    G --> I[iOS / Android];
    H --> J[Browser];

    style A fill:#cde4ff,stroke:#6a9fde,stroke-width:2px
    style B fill:#d5e8d4,stroke:#82b366,stroke-width:2px
    style C fill:#d5e8d4,stroke:#82b366,stroke-width:2px
    style D fill:#fff2cc,stroke:#d6b656,stroke-width:2px
Loading

Key Architectural Components

  1. src/core: The platform-agnostic heart of the library.

    • interfaces: Defines the "contract" for what our client can do (IAuth0Client, IWebAuthProvider, etc.). This is the cornerstone of the abstraction.
    • models: Concrete data models like Auth0User and Credentials that encapsulate data and related logic (e.g., isExpired()).
    • services: "Orchestrator" classes that contain the business logic for authentication flows (e.g., CredentialsOrchestrator handles the token refresh flow).
  2. src/platforms: Contains the platform-specific implementations.

    • native: The complete module for iOS and Android, containing the NativeBridgeManager for low-level communication and a set of adapters that implement the core interfaces.
    • web: The complete module for React Native Web, containing a set of adapters that wrap the @auth0/auth0-spa-js library to make it conform to our core interfaces.
  3. src/factory: The "decision-making" layer that runs at build time.

    • Uses platform-specific file extensions (.ts, .web.ts) to ensure the bundler (Metro/Webpack) includes only the code for the target platform. This completely severs the dependency on @auth0/auth0-spa-js in native builds.
  4. src/hooks & src/index.ts (Public API):

    • The Auth0 class now acts as a simple Facade, which uses the factory to get the correct client. This maintains backward compatibility.
    • The Auth0Provider uses this facade to power the useAuth0 hook, providing a seamless and performant stateful experience. Issues with UI hanging on logout and infinite re-renders have been fixed.

Key Breaking Changes for Users

A full MIGRATION_GUIDE.md has been created, but the most critical changes are:

  1. camelCase Properties: Properties on the user object are now camelCase (e.g., user.givenName instead of user.given_name).
  2. expiresAt Timestamp: The Credentials object now provides a expiresAt UNIX timestamp instead of expiresIn.
  3. Unified AuthError: All errors are now instances of a single, consistent AuthError class.
  4. Separated Method Arguments: Methods like authorize now separate OIDC parameters and SDK options into two distinct arguments: authorize({scope}, {options}).

Testing Strategy

A comprehensive, co-located test suite has been implemented for the new architecture.

  • All legacy test cases have been migrated to validate the new components, ensuring full functional parity.
  • The testing setup now uses a global __mocks__ directory for react-native, creating a clean and stable test environment.
  • The new structure is significantly more unit-testable, allowing for isolated testing of core services, adapters, and utilities.

How to Review This PR

Given the scope of the refactor, a commit-by-commit review is highly recommended. The commits have been structured logically to tell the story of the new architecture's construction:

  1. feat(core): Introduce foundational types and interfaces...: Establishes the core contracts.
  2. feat(core): Implement core data models and utility functions...: Adds the reusable building blocks.
  3. feat(core): Implement platform-agnostic service orchestrators...: Introduces the platform-agnostic business logic.
  4. feat(factory): Implement platform detector and client factory...: Builds the platform-selection mechanism.
  5. feat(platform): Implement native platform...: Adds the complete native implementation.
  6. feat(platform): Implement web platform...: Adds the complete web implementation.
  7. feat(hooks): Implement public Auth0 facade and update hooks...: Wires everything up to the consumer-facing API.
  8. test: Implement comprehensive test suite...: Adds all the new tests.

guabu and others added 30 commits April 2, 2025 12:39
…tecture

This commit lays the groundwork for the new, multi-platform architecture by introducing a set of clean, platform-agnostic types and interfaces.

This establishes the core "contracts" that all future platform adapters (Native, Web, etc.) must adhere to, enabling a decoupled and extensible system.

- **`src/types`**: Defines all public-facing data structures (`Credentials`, `User`) and parameter objects for API calls. Separates common types from platform-specific ones.
- **`src/core/interfaces`**: Defines the high-level contracts for all major functionalities.
This commit adds the concrete implementations for our core data models and a set of shared, platform-agnostic utility functions.

- **`src/core/models`**: Implements `AuthError`, `Auth0User`, and `Credentials` classes. These models encapsulate data and provide helper methods.
- **`src/core/utils`**: Implements pure helper functions for validation, data conversion (camel-casing), and scope finalization.
This commit introduces the core business logic layer, which orchestrates authentication flows in a platform-agnostic way.

These services operate exclusively on the previously defined interfaces and depend on an injected `HttpClient` to perform their work, making them completely decoupled from the underlying platform.
This commit introduces the factory layer, which is responsible for detecting the runtime environment and creating the appropriate platform-specific client. This is the central hub that connects the public API to the correct platform implementation.
This commit introduces the complete, self-contained module for the native (iOS/Android) platform. It defines the bridge for communicating with the native code and a set of adapters that implement the core library interfaces by delegating calls to the bridge.
This commit introduces the complete implementation for the web platform. It uses the Adapter pattern to wrap the `@auth0/auth0-spa-js` library, making it conform to our internal `IAuth0Client` interface and providing a consistent API surface.
This commit introduces the complete implementation for the web platform. It uses the Adapter pattern to wrap the `@auth0/auth0-spa-js` library, making it conform to our internal `IAuth0Client` interface and providing a consistent API surface.
This commit adds a full suite of co-located unit and integration tests for the new architecture, validating every layer from the core utilities to the platform adapters and hooks.

All legacy test cases have been migrated to test their new component counterparts, ensuring functional parity. Global mocks are now handled via a `__mocks__` directory for a cleaner test setup.
- Deleted `addDefaultLocalAuthOptions.ts`, `baseError.ts`, `camel.ts`, `deepEqual.ts`, `fetchWithTimeout.ts`, `nativeHelper.ts`, `timestampConversion.ts`, `userConversion.ts`, and `whitelist.ts` as they are no longer needed.
- Removed mock files for `auth0.js` and `react-native.js` as they are obsolete.
- Cleared out test files `webauth.spec.js`, `agent.spec.js`, and snapshot files as they are no longer relevant.
- Removed the `Agent` and `WebAuth` classes along with their associated methods and types, streamlining the authentication process.
- Created Button component for reusable button UI.
- Added Header component for consistent header display.
- Implemented LabeledInput component for labeled text input fields.
- Developed Result component to display API call results and errors.
- Created UserInfo component to show user profile information.
- Set up AuthStackNavigator for unauthenticated user navigation.
- Established ClassDemoNavigator for class-based demo navigation.
- Implemented HooksDemoNavigator for hooks-based demo navigation.
- Created MainTabNavigator for authenticated user tab navigation.
- Developed RootNavigator to manage overall app navigation.
- Added SelectionScreen for initial demo selection.
- Implemented ClassApiTestsScreen for direct API testing in class-based demo.
- Created ClassLoginScreen for class-based user login.
- Developed ClassProfileScreen to display user profile in class-based demo.
- Added ApiScreen for API calls in hooks-based demo.
- Implemented HomeScreen for hooks-based demo login options.
- Created MoreScreen for additional authentication methods in hooks-based demo.
- Developed ProfileScreen to manage user profile and credentials in hooks-based demo.
@subhankarmaiti subhankarmaiti marked this pull request as ready for review July 14, 2025 03:55
@subhankarmaiti subhankarmaiti requested a review from a team as a code owner July 14, 2025 03:55
…hProvider to use Auth0Client directly and add unit tests for WebWebAuthProvider
…hProvider to use Auth0Client directly and add unit tests for WebWebAuthProvider
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants