Skip to content

refactor(react): sso domain tab hook architecture separation#346

Open
harishsundar-okta wants to merge 6 commits into
mainfrom
refactor/sso-domain-tab-hook-architecture
Open

refactor(react): sso domain tab hook architecture separation#346
harishsundar-okta wants to merge 6 commits into
mainfrom
refactor/sso-domain-tab-hook-architecture

Conversation

@harishsundar-okta

@harishsundar-okta harishsundar-okta commented Jun 10, 2026

Copy link
Copy Markdown
Contributor

Summary

Refactors the useSsoDomainTab hook to follow the hook architecture pattern — two hooks internally, only one exposed publicly.

Why

The SSO domain tab hook previously combined data operations (TanStack Query, API calls, cache management) with UI orchestration (modals, toasts, event handlers) in a single hook. This refactor separates concerns to match the established pattern from the SSO provider table and domain table implementations.

What

  • Extracted data/API layer from use-sso-domain-tab.ts to a new internal service hook at shared/services/use-sso-domain-tab-service.ts
  • Refactored use-sso-domain-tab.ts to consume the service hook internally, handling only UI state (modals, selections, toasts, error handling)
  • Extracted ssoDomainQueryKeys to core for consistent cache key management
  • Added UseSsoDomainTabServiceOptions and UseSsoDomainTabServiceReturn types
  • Created unit tests for the service hook layer
  • Rewrote public hook tests to mock the service layer and focus on UI orchestration

Packages

  • packages/core
  • packages/react
  • examples

References

Testing

How can this be verified? Note anything intentionally not covered by tests and why.

  • This change adds unit test coverage
  • Tested for both SPA and RWA flows, all example apps working
  • All existing and new tests complete without errors

Checklist

  • Breaking change
  • Requires docs update
  • Backward compatible

Contributing

Summary by CodeRabbit

  • New Features
    • Improved SSO domain management for organizations, including create, verify, delete, and provider association actions.
    • Added clearer loading and status handling for domain-related operations.
  • Bug Fixes
    • Domain actions now handle errors more consistently and surface fallback messages when something goes wrong.
    • Verification and provider toggle behavior is more reliable, with updated state after successful actions.
  • Tests
    • Expanded automated coverage for domain listing, creation, verification, deletion, and provider association flows.

@harishsundar-okta harishsundar-okta added the refactor Restructuring existing code and logic to reduce technical debt and improve quality label Jun 10, 2026
@codecov-commenter

codecov-commenter commented Jun 10, 2026

Copy link
Copy Markdown

Codecov Report

❌ Patch coverage is 92.91667% with 17 lines in your changes missing coverage. Please review.
✅ Project coverage is 88.77%. Comparing base (25c419c) to head (eb3304f).

Files with missing lines Patch % Lines
...tion/shared/services/use-sso-domain-tab-service.ts 91.23% 17 Missing ⚠️
Additional details and impacted files
@@            Coverage Diff             @@
##             main     #346      +/-   ##
==========================================
+ Coverage   88.73%   88.77%   +0.03%     
==========================================
  Files         203      204       +1     
  Lines       17351    17411      +60     
  Branches     1816     1803      -13     
==========================================
+ Hits        15397    15456      +59     
- Misses       1954     1955       +1     

☔ View full report in Codecov by Harness.
📢 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.

@harishsundar-okta
harishsundar-okta marked this pull request as ready for review June 10, 2026 12:28
rax7389

This comment was marked as off-topic.

Comment on lines +19 to +23
// ===== Mock packages =====

const { initMockCoreClient } = mockCore();

// Test data

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

can we remove these comments?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Removed all comments

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Image

still we have these comments

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Removed the remaining comments

Comment thread packages/react/src/hooks/my-organization/__tests__/use-sso-domain-tab.test.ts Outdated
rax7389
rax7389 previously approved these changes Jun 25, 2026
@harishsundar-okta
harishsundar-okta force-pushed the refactor/sso-domain-tab-hook-architecture branch from 9f5f983 to d40bd8f Compare July 2, 2026 04:48
@coderabbitai

coderabbitai Bot commented Jul 2, 2026

Copy link
Copy Markdown
Contributor

Review Change Stack

Warning

Review limit reached

@harishsundar-okta, you've reached your PR review limit, so we couldn't start this review.

Next review available in: 56 minutes

Enable usage-based reviews in Billing to review now. Otherwise, wait until the next included review is available.
You're only billed for reviews past your plan's rate limits ($0.25/file).

How can I continue?

After more reviews become available, a review can be triggered using the @coderabbitai review command as a PR comment. Alternatively, push new commits to this PR.

To avoid repeated limits, reduce automatic review volume by pausing incremental auto-reviews earlier, using label-based review opt-in, excluding WIP or generated PR titles, or requesting reviews manually when the PR is ready. If your team needs uninterrupted high-volume reviews, an organization admin can enable usage-based reviews.

How do review limits work?

CodeRabbit enforces per-developer PR review limits for each organization. Most developers receive the normal plan review availability.

For paid Pro and Pro+ PR reviews, CodeRabbit uses adaptive limits for sustained high-volume activity. When a developer's recent PR review activity reaches the 95th percentile or higher among CodeRabbit users, additional reviews become available more gradually as earlier reviews age out of the rolling window.

Please refer docs for additional details.

Review details
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro Plus

Run ID: 442e6daf-4d41-41d0-ae7f-ce599444869f

📥 Commits

Reviewing files that changed from the base of the PR and between 9f40ede and eb3304f.

📒 Files selected for processing (6)
  • packages/react/src/hooks/my-organization/__tests__/use-sso-domain-tab.test.ts
  • packages/react/src/hooks/my-organization/shared/services/__tests__/use-domain-table-service.test.ts
  • packages/react/src/hooks/my-organization/shared/services/__tests__/use-sso-domain-tab-service.test.ts
  • packages/react/src/hooks/my-organization/shared/services/use-sso-domain-tab-service.ts
  • packages/react/src/hooks/my-organization/use-sso-domain-tab.ts
  • packages/react/src/types/my-organization/idp-management/sso-domain/sso-domain-tab-types.ts
📝 Walkthrough

Walkthrough

Introduces a new useSsoDomainTabService hook that centralizes TanStack Query fetching and mutations (create, verify, delete, associate, delete-from-provider) for SSO domains. useSsoDomainTab is refactored to delegate to this service, new type contracts are added, and test suites for both hooks are rewritten accordingly.

Changes

SSO domain service extraction

Layer / File(s) Summary
Service type contracts
packages/react/src/types/my-organization/idp-management/sso-domain/sso-domain-tab-types.ts
Adds UseSsoDomainTabServiceOptions and UseSsoDomainTabServiceReturn interfaces and a new import for CreateOrganizationDomainRequestContent.
useSsoDomainTabService implementation
packages/react/src/hooks/my-organization/shared/services/use-sso-domain-tab-service.ts
New hook fetching organization domains via TanStack Query, deriving idpDomains, routing errors through useErrorHandler, and providing create/verify/delete/associate/delete-from-provider mutations with cache invalidation.
Service hook test suite
packages/react/src/hooks/my-organization/shared/services/__tests__/use-sso-domain-tab-service.test.ts
New Vitest suite covering listing, creation, verification, deletion, provider association/disassociation, and a missing-coreClient edge case.
useSsoDomainTab refactor to consume service
packages/react/src/hooks/my-organization/use-sso-domain-tab.ts
Replaces local query/mutation logic with calls into useSsoDomainTabService, updating handleCreate, handleVerify, handleDelete, handleVerifyActionColumn, handleToggleSwitch, and returned loading flags.
useSsoDomainTab test suite update
packages/react/src/hooks/my-organization/__tests__/use-sso-domain-tab.test.ts
Rewrites tests to mock useSsoDomainTabService directly, validating initialization, create/verify/delete flows, provider association toggles, and modal state management; several prior edge-case tests were removed.

Estimated code review effort: 3 (Moderate) | ~25 minutes

Sequence Diagram(s)

sequenceDiagram
  participant Component
  participant useSsoDomainTabService
  participant CoreClient
  participant QueryCache

  Component->>useSsoDomainTabService: verifyDomain(domain)
  useSsoDomainTabService->>CoreClient: verify endpoint call
  CoreClient-->>useSsoDomainTabService: status: verified
  useSsoDomainTabService->>QueryCache: setQueryData(updated domain)
  useSsoDomainTabService-->>Component: isVerified true
  Component->>useSsoDomainTabService: associateToProvider(domain)
  useSsoDomainTabService->>CoreClient: IdP domain association call
  useSsoDomainTabService->>QueryCache: invalidate IdP detail query
Loading
🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title accurately summarizes the main change: refactoring the SSO domain tab hook into a separated architecture.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch refactor/sso-domain-tab-hook-architecture

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Actionable comments posted: 3

♻️ Duplicate comments (1)
packages/react/src/hooks/my-organization/shared/services/use-sso-domain-tab-service.ts (1)

181-196: 🩺 Stability & Availability | 🟠 Major | ⚡ Quick win

Previously "fixed" provider.id check appears reverted.

A prior review thread on this file flagged that provider.id is optional and recommended checking if (!provider?.id) to safely drop the ! at Line 196. The author noted this was fixed, but the current code still shows if (!provider) (Line 183) and provider.id! (Line 196) — the original issue persists.

🛡️ Proposed fix
   const deleteFromProviderMutation = useMutation({
     mutationFn: async (domain: Domain) => {
-      if (!provider) {
+      if (!provider?.id) {
         return domain;
       }
       ...
       await coreClient!
         .getMyOrganizationApiClient()
-        .organization.identityProviders.domains.delete(provider.id!, domain.domain);
+        .organization.identityProviders.domains.delete(provider.id, domain.domain);
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In
`@packages/react/src/hooks/my-organization/shared/services/use-sso-domain-tab-service.ts`
around lines 181 - 196, The provider ID safety fix is still incomplete in
deleteFromProviderMutation. Update the guard in use-sso-domain-tab-service so it
checks provider?.id before proceeding, not just provider, and remove the
non-null assertion when calling organization.identityProviders.domains.delete.
Keep the existing onBefore flow intact, but ensure the mutation returns early
whenever provider or provider.id is missing.
🧹 Nitpick comments (2)
packages/react/src/hooks/my-organization/shared/services/__tests__/use-sso-domain-tab-service.test.ts (2)

40-40: 📐 Maintainability & Code Quality | 🔵 Trivial | 💤 Low value

Redundant initial mockHandleError assignment.

Line 40's vi.fn() assignment is immediately overwritten by the destructure at Line 72; the first assignment is dead code.

Also applies to: 65-73

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In
`@packages/react/src/hooks/my-organization/shared/services/__tests__/use-sso-domain-tab-service.test.ts`
at line 40, Remove the redundant initial assignment of mockHandleError in the
use-sso-domain-tab-service test setup, since it is immediately replaced by the
later destructured value. Update the test initialization around mockHandleError
so there is only one source of truth, and ensure any related setup in the
useSsoDomainTabService test block uses the destructured vi.fn() instance
consistently.

292-304: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick win

Missing test coverage for mutations under null coreClient.

Only the listing query is tested under a null coreClient (Line 293-303). Once the guard gap in create/verify/associate/deleteFromProvider mutations (flagged in use-sso-domain-tab-service.ts) is fixed, add coverage here to lock in the expected behavior and close the Codecov-reported coverage gap for this file.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In
`@packages/react/src/hooks/my-organization/shared/services/__tests__/use-sso-domain-tab-service.test.ts`
around lines 292 - 304, Add test coverage in useSsoDomainTabService for null
coreClient across the mutation paths, not just the list query. Extend the
existing edge-case suite in use-sso-domain-tab-service.test.ts to verify the
create, verify, associate, and deleteFromProvider actions from
useSsoDomainTabService do not call organization.domains when useCoreClient
returns null and instead fail gracefully in the same way as the existing
missing-client test. Focus on the mutation methods and the existing
setupMockUseCoreClientNull helper so the expected guarded behavior is locked in.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In
`@packages/react/src/hooks/my-organization/shared/services/use-sso-domain-tab-service.ts`:
- Around line 76-97: The mutation handlers in use-sso-domain-tab-service.ts are
inconsistent in how they handle a null coreClient, since deleteDomainMutation
already guards but createDomainMutation, verifyDomainMutation,
associateToProviderMutation, and deleteFromProviderMutation still use
coreClient! directly. Add the same null-check/failure path used by
deleteDomainMutation to each of those mutationFn blocks before calling
getMyOrganizationApiClient(), and ensure the error is surfaced gracefully
instead of causing a runtime TypeError.
- Around line 99-126: The verify flow in use-sso-domain-tab-service is passing
stale data to verifyAction.onAfter. Update the mutationFn in
verifyDomainMutation so onAfter receives the post-verification result from
updatedDomain instead of the original domain, and keep the updatedDomain value
available for any downstream consumers that need the verified status.
- Around line 76-92: `createAction.onBefore` is typed for `Domain`, but
`useSsoDomainTabService` invokes it with
`CreateOrganizationDomainRequestContent`; update the shared hook and prop types
so `SsoDomainsTabEditProps.createAction` accepts the create request payload
shape instead of `Domain`. Align the `useMutation` callback in
`use-sso-domain-tab-service` and the related `createAction` definitions to the
request-content type so the pre-submit hook only sees fields available during
creation.

---

Duplicate comments:
In
`@packages/react/src/hooks/my-organization/shared/services/use-sso-domain-tab-service.ts`:
- Around line 181-196: The provider ID safety fix is still incomplete in
deleteFromProviderMutation. Update the guard in use-sso-domain-tab-service so it
checks provider?.id before proceeding, not just provider, and remove the
non-null assertion when calling organization.identityProviders.domains.delete.
Keep the existing onBefore flow intact, but ensure the mutation returns early
whenever provider or provider.id is missing.

---

Nitpick comments:
In
`@packages/react/src/hooks/my-organization/shared/services/__tests__/use-sso-domain-tab-service.test.ts`:
- Line 40: Remove the redundant initial assignment of mockHandleError in the
use-sso-domain-tab-service test setup, since it is immediately replaced by the
later destructured value. Update the test initialization around mockHandleError
so there is only one source of truth, and ensure any related setup in the
useSsoDomainTabService test block uses the destructured vi.fn() instance
consistently.
- Around line 292-304: Add test coverage in useSsoDomainTabService for null
coreClient across the mutation paths, not just the list query. Extend the
existing edge-case suite in use-sso-domain-tab-service.test.ts to verify the
create, verify, associate, and deleteFromProvider actions from
useSsoDomainTabService do not call organization.domains when useCoreClient
returns null and instead fail gracefully in the same way as the existing
missing-client test. Focus on the mutation methods and the existing
setupMockUseCoreClientNull helper so the expected guarded behavior is locked in.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro Plus

Run ID: 3824ee3c-5207-4e4c-9c4f-10a68140e22e

📥 Commits

Reviewing files that changed from the base of the PR and between d8c1da7 and d40bd8f.

📒 Files selected for processing (5)
  • packages/react/src/hooks/my-organization/__tests__/use-sso-domain-tab.test.ts
  • packages/react/src/hooks/my-organization/shared/services/__tests__/use-sso-domain-tab-service.test.ts
  • packages/react/src/hooks/my-organization/shared/services/use-sso-domain-tab-service.ts
  • packages/react/src/hooks/my-organization/use-sso-domain-tab.ts
  • packages/react/src/types/my-organization/idp-management/sso-domain/sso-domain-tab-types.ts

Comment on lines +76 to +92
const createDomainMutation = useMutation({
mutationFn: async (data: CreateOrganizationDomainRequestContent) => {
if (domains?.createAction?.onBefore) {
const canProceed = domains.createAction.onBefore(data as Domain);
if (!canProceed) {
throw new BusinessError({ message: t('domain_create.on_before') });
}
}

const result: Domain = await coreClient!
.getMyOrganizationApiClient()
.organization.domains.create(data);

domains?.createAction?.onAfter?.(result);

return result;
},

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

🎯 Functional Correctness | 🟡 Minor | ⚡ Quick win

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
# Locate the definition of createAction.onBefore to check its expected parameter type
rg -n -B3 -A8 'createAction' --type=ts packages/react/src/types

Repository: auth0/auth0-ui-components

Length of output: 15911


🏁 Script executed:

#!/bin/bash
set -euo pipefail

printf '\n== ComponentAction definition ==\n'
rg -n -B3 -A12 'export interface ComponentAction|type ComponentAction' packages/react/src -g '*.ts' -g '*.tsx'

printf '\n== SSO domain tab types ==\n'
sed -n '1,120p' packages/react/src/types/my-organization/idp-management/sso-domain/sso-domain-tab-types.ts

printf '\n== use-sso-domain-tab-service ==\n'
sed -n '1,180p' packages/react/src/hooks/my-organization/shared/services/use-sso-domain-tab-service.ts

printf '\n== Search onBefore usages for domains ==\n'
rg -n 'onBefore\(' packages/react/src -g '*.ts' -g '*.tsx'

Repository: auth0/auth0-ui-components

Length of output: 18603


🏁 Script executed:

#!/bin/bash
set -euo pipefail

printf '\n== ComponentAction-related type comments/usages ==\n'
rg -n -B2 -A8 'ComponentAction<' packages/react/src/types packages/react/src/hooks -g '*.ts' -g '*.tsx'

printf '\n== domain-table service create path ==\n'
sed -n '1,170p' packages/react/src/hooks/my-organization/shared/services/use-domain-table-service.ts

printf '\n== domain-table types ==\n'
sed -n '1,120p' packages/react/src/types/my-organization/domain-management/domain-table-types.ts

Repository: auth0/auth0-ui-components

Length of output: 45556


🏁 Script executed:

#!/bin/bash
set -euo pipefail

printf '\n== use-domain-table-service create path ==\n'
sed -n '1,140p' packages/react/src/hooks/my-organization/shared/services/use-domain-table-service.ts

printf '\n== domain-table type definitions ==\n'
sed -n '1,100p' packages/react/src/types/my-organization/domain-management/domain-table-types.ts

printf '\n== provider create pattern for comparison ==\n'
sed -n '110,160p' packages/react/src/hooks/my-organization/shared/services/use-sso-provider-create-service.ts

Repository: auth0/auth0-ui-components

Length of output: 9841


Type createAction.onBefore to accept the create payload, not Domain. useSsoDomainTabService calls it with CreateOrganizationDomainRequestContent, so the current Domain signature advertises fields that are unavailable at this point. Update SsoDomainsTabEditProps.createAction (and the shared hook types) to the request-content shape.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In
`@packages/react/src/hooks/my-organization/shared/services/use-sso-domain-tab-service.ts`
around lines 76 - 92, `createAction.onBefore` is typed for `Domain`, but
`useSsoDomainTabService` invokes it with
`CreateOrganizationDomainRequestContent`; update the shared hook and prop types
so `SsoDomainsTabEditProps.createAction` accepts the create request payload
shape instead of `Domain`. Align the `useMutation` callback in
`use-sso-domain-tab-service` and the related `createAction` definitions to the
request-content type so the pre-submit hook only sees fields available during
creation.

Comment on lines +76 to +97
const createDomainMutation = useMutation({
mutationFn: async (data: CreateOrganizationDomainRequestContent) => {
if (domains?.createAction?.onBefore) {
const canProceed = domains.createAction.onBefore(data as Domain);
if (!canProceed) {
throw new BusinessError({ message: t('domain_create.on_before') });
}
}

const result: Domain = await coreClient!
.getMyOrganizationApiClient()
.organization.domains.create(data);

domains?.createAction?.onAfter?.(result);

return result;
},
onSuccess: () => {
queryClient.invalidateQueries({ queryKey: ssoDomainQueryKeys.list(idpId) });
queryClient.invalidateQueries({ queryKey: ssoProviderQueryKeys.detail(idpId) });
},
});

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

🩺 Stability & Availability | 🟠 Major | ⚡ Quick win

Inconsistent coreClient null-guard across mutations.

deleteDomainMutation (Line 130) guards against a null coreClient, but createDomainMutation, verifyDomainMutation, associateToProviderMutation, and deleteFromProviderMutation all dereference coreClient! unguarded (Lines 85, 108, 164, 194). If coreClient is ever null when these fire, they'll throw a runtime TypeError instead of failing gracefully like deleteDomainMutation. This also matches the Codecov-reported coverage gap for this file — none of these guard paths are exercised by tests.

🛡️ Proposed fix (example for createDomainMutation)
   const createDomainMutation = useMutation({
     mutationFn: async (data: CreateOrganizationDomainRequestContent) => {
+      if (!coreClient) {
+        throw new Error('Core client is not available');
+      }
       if (domains?.createAction?.onBefore) {
         const canProceed = domains.createAction.onBefore(data as Domain);
         if (!canProceed) {
           throw new BusinessError({ message: t('domain_create.on_before') });
         }
       }

-      const result: Domain = await coreClient!
+      const result: Domain = await coreClient
         .getMyOrganizationApiClient()
         .organization.domains.create(data);

Also applies to: 99-126, 155-179, 181-207

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In
`@packages/react/src/hooks/my-organization/shared/services/use-sso-domain-tab-service.ts`
around lines 76 - 97, The mutation handlers in use-sso-domain-tab-service.ts are
inconsistent in how they handle a null coreClient, since deleteDomainMutation
already guards but createDomainMutation, verifyDomainMutation,
associateToProviderMutation, and deleteFromProviderMutation still use
coreClient! directly. Add the same null-check/failure path used by
deleteDomainMutation to each of those mutationFn blocks before calling
getMyOrganizationApiClient(), and ensure the error is surfaced gracefully
instead of causing a runtime TypeError.

Comment on lines +99 to +126
const verifyDomainMutation = useMutation({
mutationFn: async (domain: Domain) => {
if (domains?.verifyAction?.onBefore) {
const canProceed = domains.verifyAction.onBefore(domain);
if (!canProceed) {
throw new BusinessError({ message: t('domain_verify.on_before') });
}
}

const updatedDomain = await coreClient!
.getMyOrganizationApiClient()
.organization.domains.verify.create(domain.id);

if (domains?.verifyAction?.onAfter) {
await domains.verifyAction.onAfter(domain);
}

return { updatedDomain, isVerified: updatedDomain.status === 'verified' };
},
onSuccess: ({ updatedDomain, isVerified }, domain) => {
if (isVerified) {
queryClient.setQueryData<Domain[]>(ssoDomainQueryKeys.list(idpId), (oldDomains) => {
if (!oldDomains) return oldDomains;
return oldDomains.map((d) => (d.id === domain.id ? { ...d, ...updatedDomain } : d));
});
}
},
});

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

🎯 Functional Correctness | 🟡 Minor | ⚡ Quick win

verifyAction.onAfter receives the stale pre-verification domain.

updatedDomain (Line 108) reflects the post-verification state (e.g., new status), but onAfter (Line 112-114) is invoked with the original domain argument instead. Consumers relying on onAfter to know the verification result get outdated data, even though updatedDomain is already available in scope.

🐛 Proposed fix
       const updatedDomain = await coreClient!
         .getMyOrganizationApiClient()
         .organization.domains.verify.create(domain.id);

       if (domains?.verifyAction?.onAfter) {
-        await domains.verifyAction.onAfter(domain);
+        await domains.verifyAction.onAfter(updatedDomain);
       }
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
const verifyDomainMutation = useMutation({
mutationFn: async (domain: Domain) => {
if (domains?.verifyAction?.onBefore) {
const canProceed = domains.verifyAction.onBefore(domain);
if (!canProceed) {
throw new BusinessError({ message: t('domain_verify.on_before') });
}
}
const updatedDomain = await coreClient!
.getMyOrganizationApiClient()
.organization.domains.verify.create(domain.id);
if (domains?.verifyAction?.onAfter) {
await domains.verifyAction.onAfter(domain);
}
return { updatedDomain, isVerified: updatedDomain.status === 'verified' };
},
onSuccess: ({ updatedDomain, isVerified }, domain) => {
if (isVerified) {
queryClient.setQueryData<Domain[]>(ssoDomainQueryKeys.list(idpId), (oldDomains) => {
if (!oldDomains) return oldDomains;
return oldDomains.map((d) => (d.id === domain.id ? { ...d, ...updatedDomain } : d));
});
}
},
});
const verifyDomainMutation = useMutation({
mutationFn: async (domain: Domain) => {
if (domains?.verifyAction?.onBefore) {
const canProceed = domains.verifyAction.onBefore(domain);
if (!canProceed) {
throw new BusinessError({ message: t('domain_verify.on_before') });
}
}
const updatedDomain = await coreClient!
.getMyOrganizationApiClient()
.organization.domains.verify.create(domain.id);
if (domains?.verifyAction?.onAfter) {
await domains.verifyAction.onAfter(updatedDomain);
}
return { updatedDomain, isVerified: updatedDomain.status === 'verified' };
},
onSuccess: ({ updatedDomain, isVerified }, domain) => {
if (isVerified) {
queryClient.setQueryData<Domain[]>(ssoDomainQueryKeys.list(idpId), (oldDomains) => {
if (!oldDomains) return oldDomains;
return oldDomains.map((d) => (d.id === domain.id ? { ...d, ...updatedDomain } : d));
});
}
},
});
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In
`@packages/react/src/hooks/my-organization/shared/services/use-sso-domain-tab-service.ts`
around lines 99 - 126, The verify flow in use-sso-domain-tab-service is passing
stale data to verifyAction.onAfter. Update the mutationFn in
verifyDomainMutation so onAfter receives the post-verification result from
updatedDomain instead of the original domain, and keep the updatedDomain value
available for any downstream consumers that need the verified status.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

refactor Restructuring existing code and logic to reduce technical debt and improve quality

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants