Skip to content

feat(react): add PermissionProvider, usePermissions hook and PermissionDeniedTooltip - #419

Open
grandmaester wants to merge 5 commits into
feat/permission-gating-infrastructurefrom
feat/permission-context-and-hook
Open

feat(react): add PermissionProvider, usePermissions hook and PermissionDeniedTooltip#419
grandmaester wants to merge 5 commits into
feat/permission-gating-infrastructurefrom
feat/permission-context-and-hook

Conversation

@grandmaester

@grandmaester grandmaester commented Jul 22, 2026

Copy link
Copy Markdown
Contributor

Summary

Adds the runtime permission layer on top of PR 1's manifest/utilities: a PermissionProvider context that eagerly fetches the user's permissions, a usePermissions hook to consume them, and a PermissionDeniedTooltip for gating disabled controls.

This is PR 2 of 2 for the permission infrastructure. it targets PR 1's branch (feat/permission-gating-infrastructure).

Why

With the manifest and utilities in place (PR 1), components need a way to (a) load the current user's permissions once at app init and (b) read/check them anywhere in the tree. this follows the Permission Manifest Provider pattern with eager (app-init) fetching, and provides the standardized "missing permission" affordance the gating work will attach to disabled actions.

What

packages/react

  • providers/permission-context.tsxPermissionProvider + PermissionContext. On mount it requests the full PERMISSION_MANIFEST (comma-separated) from GET /my-org/user-permissions via React Query, caching the granted subset for 5 minutes (PERMISSION_STALE_TIME_MS). Query is keyed by permissionQueryKeys.list() and gated on coreClient.
  • hooks/my-organization/use-permissions.tsusePermissions consumes the context and exposes permissions, isLoading, hasProvider, hasPermission, hasAnyPermission, hasAllPermissions, getUserTier, and refetch. When used outside a provider it falls back to admin-level access (the full manifest) for backwards compatibility with the legacy readOnly flow.
  • components/auth0/shared/permission-denied-tooltip.tsxPermissionDeniedTooltip wraps a (typically disabled) control with a standardized tooltip, defaulting to common.errors.forbidden with a customMessage override. Children are wrapped in a focusable span so the tooltip still fires on disabled elements.
  • Added configuration.members.get to the shared core-client test mock.

Packages

  • packages/core
  • packages/react
  • examples

Testing

Unit tests cover: the provider (eager fetch sends the manifest as a comma-separated list, exposes the granted subset, empty set until data resolves, 5-min cache constant); the hook (in-provider values/checks/loading/refetch, and out-of-provider admin fallback); and the tooltip (renders children, standardized + custom messages on hover, no wrapper when disabled).

  • 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

    • Added permission loading and context support for MyOrganization access controls.
    • Added permission-checking helpers, user-tier lookup, loading status, and refresh support.
    • Added a tooltip for disabled controls with customizable messaging and positioning.
    • Exposed permission providers, hooks, and related types through the public package API.
  • Tests

    • Added coverage for permission fetching, fallback behavior, permission helpers, and denied-access tooltip interactions.

@coderabbitai

coderabbitai Bot commented Jul 22, 2026

Copy link
Copy Markdown
Contributor

Review Change Stack

Important

Review skipped

Auto reviews are disabled on base/target branches other than the default branch.

Please check the settings in the CodeRabbit UI or the .coderabbit.yaml file in this repository. To trigger a single review, invoke the @coderabbitai review command.

⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro Plus

Run ID: 7a547b33-bf3c-42f2-830d-1c681bb6ac97

You can disable this status message by setting the reviews.review_status to false in the CodeRabbit configuration file.

Use the checkbox below for a quick retry:

  • 🔍 Trigger review
📝 Walkthrough

Walkthrough

Adds MyOrganization permission context and hook APIs with provider and admin fallback behavior, exports them publicly, and introduces a configurable tooltip for denied controls with accompanying tests.

Changes

MyOrganization permissions

Layer / File(s) Summary
Permission provider and API fetch
packages/react/src/providers/permission-context.tsx, packages/react/src/providers/__tests__/permission-context.test.tsx, packages/react/src/public-api.ts, packages/react/src/tests/utils/__mocks__/core/core-client.mocks.ts, packages/react/src/types/my-organization/permissions/permissions-types.ts
PermissionProvider fetches member permissions through React Query, exposes loading and refetch state, and is publicly exported with its supporting types and mocks.
Permission hook and public types
packages/react/src/hooks/my-organization/shared/services/use-permissions.ts, packages/react/src/hooks/my-organization/shared/services/__tests__/use-permissions.test.tsx, packages/react/src/index.ts
usePermissions provides provider-backed permission helpers or manifest-based admin fallback permissions, with tests covering both paths and package exports.

Permission denied tooltip

Layer / File(s) Summary
Disabled-control tooltip behavior
packages/react/src/components/auth0/shared/permission-denied-tooltip.tsx, packages/react/src/components/auth0/shared/__tests__/permission-denied-tooltip.test.tsx
PermissionDeniedTooltip displays the translated or custom forbidden message around enabled children and renders children directly when disabled; tests cover rendering and hover behavior.

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

Sequence Diagram(s)

sequenceDiagram
  participant PermissionProvider
  participant ReactQuery
  participant coreClient
  participant usePermissions
  PermissionProvider->>ReactQuery: query member permissions
  ReactQuery->>coreClient: request PERMISSION_MANIFEST permissions
  coreClient-->>ReactQuery: return granted permissions
  ReactQuery-->>PermissionProvider: update loading and permissions
  PermissionProvider-->>usePermissions: expose context values
  usePermissions-->>usePermissions: compute permission and tier helpers
Loading

Possibly related PRs

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Docstring Coverage ✅ Passed Docstring coverage is 100.00% which is sufficient. The required threshold is 80.00%.
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.
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title clearly and accurately summarizes the main additions: PermissionProvider, usePermissions, and PermissionDeniedTooltip.
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch feat/permission-context-and-hook

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.

@grandmaester grandmaester changed the title feat(permissions): add PermissionProvider, usePermissions hook, and PermissionDeniedTooltip [PR 2/2] feat(react): add PermissionProvider, usePermissions hook and PermissionDeniedTooltip Jul 22, 2026
@grandmaester grandmaester self-assigned this Jul 22, 2026
@grandmaester grandmaester added the enhancement New feature or request label Jul 22, 2026
@grandmaester

Copy link
Copy Markdown
Contributor Author

@coderabbitai Review the PR changes

@coderabbitai

coderabbitai Bot commented Jul 22, 2026

Copy link
Copy Markdown
Contributor

@grandmaester I’ll review the changes in #419.

✅ Action performed

Review finished.

Note: CodeRabbit is an incremental review system and does not re-review already reviewed commits. This command is applicable only when automatic reviews are paused.

@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: 2

🤖 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-permissions.ts`:
- Around line 27-46: Separate the public permission hook from its internal
implementation: move the logic from usePermissions in
packages/react/src/hooks/my-organization/shared/services/use-permissions.ts into
use-permissions-service.ts, add the public use-permissions.ts wrapper under
hooks/my-organization, and have it delegate to the service. Update imports in
packages/react/src/providers/__tests__/permission-context.test.tsx and
packages/react/src/hooks/my-organization/shared/services/__tests__/use-permissions.test.tsx
to use the wrapper, and export that wrapper from packages/react/src/index.ts.

In `@packages/react/src/providers/permission-context.tsx`:
- Around line 33-35: Move the PermissionProviderProps interface from
permission-context.tsx into
types/my-organization/permissions/permissions-types.ts, export it there, and
import it in the PermissionProvider implementation. Keep the interface shape
unchanged and remove the local definition.
🪄 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: 95ed0a4b-a6d6-46eb-acef-57088938510d

📥 Commits

Reviewing files that changed from the base of the PR and between 47935eb and 0ebf39d.

📒 Files selected for processing (10)
  • packages/react/src/components/auth0/shared/__tests__/permission-denied-tooltip.test.tsx
  • packages/react/src/components/auth0/shared/permission-denied-tooltip.tsx
  • packages/react/src/hooks/my-organization/shared/services/__tests__/use-permissions.test.tsx
  • packages/react/src/hooks/my-organization/shared/services/use-permissions.ts
  • packages/react/src/index.ts
  • packages/react/src/providers/__tests__/permission-context.test.tsx
  • packages/react/src/providers/permission-context.tsx
  • packages/react/src/public-api.ts
  • packages/react/src/tests/utils/__mocks__/core/core-client.mocks.ts
  • packages/react/src/types/my-organization/permissions/permissions-types.ts

Comment thread packages/react/src/hooks/my-organization/shared/services/use-permissions.ts Outdated
Comment thread packages/react/src/providers/permission-context.tsx Outdated
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

enhancement New feature or request

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant