Skip to content

fix(auth): recognize multi-role owner/admin in my-capabilities endpoint#4949

Merged
pedrofrxncx merged 1 commit into
mainfrom
fix/my-capabilities-multirole-admin-w1
Jul 21, 2026
Merged

fix(auth): recognize multi-role owner/admin in my-capabilities endpoint#4949
pedrofrxncx merged 1 commit into
mainfrom
fix/my-capabilities-multirole-admin-w1

Conversation

@pedrofrxncx

@pedrofrxncx pedrofrxncx commented Jul 21, 2026

Copy link
Copy Markdown
Collaborator

Source: found while sweeping recent auth-related merges (#4944, #4947, #4943 — all fixed the same active-org-vs-target-org role confusion) for other latent multi-role bugs in the same neighborhood.

Why a maintainer wants this: GET /api/auth/custom/my-capabilities/:slug is documented as "the single source of truth for proactive UI gating" and is supposed to mirror AccessControl's owner/admin bypass. AccessControl uses hasAdminRole(this.role) (access-control.ts:227), which correctly splits Better Auth's comma-joined multi-role string and checks each entry. This route instead did a plain role === "owner" || role === "admin", which only matches a single-role member.

Failure scenario: a member holds a multi-role assignment like "admin,billing-manager" (assignable via ORGANIZATION_MEMBER_ADD/member-update-role, which take role: string[] and store it comma-joined — see auth/roles.ts's hasAdminRole/canAssignRole docstrings for the same failure mode already fixed there). For such a member, role === "admin" is false, so the endpoint falls through to the custom-role permission lookup instead of returning allCapabilitiesGranted() — the UI hides admin capabilities from a user the server would actually treat as a full admin. Not a privilege escalation (real enforcement is in AccessControl, unaffected), but a real, user-visible capability-gating bug matching this repo's established multi-role-correctness bug class (#4900, #4909, #4918, #4923).

Fix: swap the manual === check for the already-existing, already-tested hasAdminRole() helper (imported alongside ADMIN_ROLES, which this file already uses elsewhere in notifyAdminsOfJoinRequest with the same comma-split pattern).

Command a reviewer runs: cd apps/mesh && bunx tsc --noEmit; bun test apps/mesh/src/auth/roles.test.ts (covers hasAdminRole, including the "admin,billing-manager" multi-role case this fix now relies on).

Locally run: bun run fmt, cd apps/mesh && bunx tsc --noEmit, bun test apps/mesh/src/auth/roles.test.ts — all green. No new test added: the swapped-in helper is already exhaustively tested, and the route itself needs a live DB session to exercise (not unit-testable per TESTING.md). Full CI validates the rest.


Summary by cubic

Fixes the my-capabilities endpoint to honor multi‑role owner/admin. Uses hasAdminRole so comma‑joined roles (e.g. "admin,billing-manager") get full capabilities, matching AccessControl and preventing incorrect UI gating.

Written for commit 61df2a3. Summary will update on new commits.

Review in cubic

Match AccessControl's hasAdminRole check so a comma-joined multi-role
owner/admin (e.g. "admin,billing-manager") isn't shown a restricted-UI
capability set the server would actually grant in full.
@pedrofrxncx
pedrofrxncx enabled auto-merge (squash) July 21, 2026 19:02
@pedrofrxncx
pedrofrxncx merged commit e8fd3eb into main Jul 21, 2026
15 checks passed
@pedrofrxncx
pedrofrxncx deleted the fix/my-capabilities-multirole-admin-w1 branch July 21, 2026 19:04
decocms Bot pushed a commit that referenced this pull request Jul 21, 2026
PR: #4949 fix(auth): recognize multi-role owner/admin in my-capabilities endpoint
Bump type: patch

- decocms (apps/mesh/package.json): 4.84.0 -> 4.84.1

Deploy-Scope: server
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.

1 participant