Skip to content

feat(core): implement fetcher for My Account and My Organization clients#163

Open
jacobovidal wants to merge 19 commits intoauth0:mainfrom
jacobovidal:feat/implement-services-with-fetcher
Open

feat(core): implement fetcher for My Account and My Organization clients#163
jacobovidal wants to merge 19 commits intoauth0:mainfrom
jacobovidal:feat/implement-services-with-fetcher

Conversation

@jacobovidal
Copy link

@jacobovidal jacobovidal commented Mar 15, 2026

Description

Replaces the old service layer with a simplified architecture using the SDK's custom fetcher pattern, enabling DPoP token support.

The current implementation uses a service layer that wraps SDK clients and manually handles scope injection via withScopes(). This approach doesn't support DPoP tokens (required for enhanced security) and adds unnecessary abstraction.

The new implementation leverages the SDK's custom fetcher pattern:

  • Proxy mode: Injects scopes via auth0-scope header for the proxy to handle token requests.
  • SPA mode: Uses Auth0 SDK's createFetcher() which natively supports DPoP tokens.

Changes in core

  • Added custom fetcher builders that create SDK clients configured for proxy or SPA mode:

My account example:

export function createMyAccountClient(config: ClientAuthConfig): MyAccountClient {
  if (config.mode === 'proxy') {
    return new MyAccountClient({
      domain: '',
      baseUrl: new URL(MY_ACCOUNT_PROXY_PATH, config.proxyUrl).href,
      telemetry: false,
      fetcher: createProxyFetcher(),
    });
  }

  return new MyAccountClient({
    domain: config.domain,
    telemetry: false,
    fetcher: createSpaFetcher(config, MY_ACCOUNT_DPOP_NONCE_ID),
  });
}
  • Removes previously implemented abstractions to handle scopes that are no longer needed.

Breaking changes (with backward compatibility)

This PR maintains full backward compatibility with the existing withScopes() method (deprecated but functional):

// Still works - withScopes() is now a noop that returns the client unchanged
const client = coreClient.getMyOrganizationApiClient();
const result = await client.withScopes('read:my_org:details')
  .organizationDetails.get();

// Recommended - Scopes are automatically handled by the SDK fetcher
const client = coreClient.getMyOrganizationApiClient();
const result = await client.organizationDetails.get();

All scope constants (USER_MFA_SCOPES, MY_ORGANIZATION_DOMAIN_SCOPES, etc.) remain exported for backward compatibility.

A follow-up PR to the react package will remove usage of withScopes() and scope constants.

@codecov-commenter
Copy link

codecov-commenter commented Mar 15, 2026

Codecov Report

❌ Patch coverage is 95.04950% with 5 lines in your changes missing coverage. Please review.
✅ Project coverage is 87.95%. Comparing base (b17766f) to head (e302456).
⚠️ Report is 4 commits behind head on main.

Files with missing lines Patch % Lines
packages/core/src/auth/auth-utils.ts 78.57% 3 Missing ⚠️
packages/core/src/api/scope-constants.ts 0.00% 2 Missing ⚠️
Additional details and impacted files
@@            Coverage Diff             @@
##             main     #163      +/-   ##
==========================================
- Coverage   88.07%   87.95%   -0.13%     
==========================================
  Files         145      145              
  Lines       12360    12353       -7     
  Branches     1633     1623      -10     
==========================================
- Hits        10886    10865      -21     
- Misses       1474     1488      +14     

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

export interface BasicAuth0ContextInterface {
getConfiguration: () => Readonly<ClientConfiguration>;
mfa: MfaApiClient;
createFetcher?: CreateFetcherFunction;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

looks like this should be required attribute not optional?

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Changed!

expect(headers.get('Authorization')).toBe('Bearer mock-access-token');
});
});
});
Copy link
Contributor

@rax7389 rax7389 Mar 16, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

maybe we should not remove this file and we should add test for addDeprecatedWithScopes, createProxyFetcher, createSpaFetcher

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Indeed, it's better we add unit tests for those functions, although in practice it was covered in my organization and my account tests

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Added!

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.

4 participants