Skip to content

fix(auth): expose roles[] on session user so admin promotion preserves business roles#1729

Merged
os-zhuang merged 1 commit into
mainfrom
fix/auth-session-roles-array
Jun 11, 2026
Merged

fix(auth): expose roles[] on session user so admin promotion preserves business roles#1729
os-zhuang merged 1 commit into
mainfrom
fix/auth-session-roles-array

Conversation

@os-zhuang

Copy link
Copy Markdown
Contributor

Problem

The better-auth customSession plugin in plugin-auth returns { user: { ...user, role: 'admin' }, session } when the user is a platform admin or active-org admin. This replaces the stored role string — which may be comma-separated multi-role, e.g. 'admin,manager' — with the literal 'admin'.

Consequence: an admin's business roles (e.g. manager) never reach the frontend through the session, so the Console approvals inbox (objectui ApprovalsInboxPage), which matches pending_approvers by role:<name> literals, never shows admins their role-based todos.

Fix (additive — user.role semantics unchanged)

The customSession callback now always returns user.roles: string[]:

  • base = stored user.role split on commas, trimmed, empty values dropped (no role → [])
  • on promotion (platform admin or active-org admin), 'admin' is appended, deduplicated
  • user.role behavior is exactly as before (still replaced by 'admin' on promotion, kept otherwise) — the codebase has many strict user.role === 'admin' checks

objectui consumers already prefer user.roles when present (useIsWorkspaceAdmin, AuthGuard, buildApproverIdentities), so no objectui change is needed.

Tests

New customSession – derived role and roles array suite in auth-manager.test.ts covering: no stored role → roles=[]; non-admin 'manager'roles=['manager'] with role untouched; platform admin storing 'manager'role='admin', roles=['manager','admin']; stored 'admin,manager' → no duplicate append; user without id passes through untouched.

  • pnpm vitest run (plugin-auth): 114 passed
  • pnpm --filter @objectstack/plugin-auth build: ESM/CJS/DTS pass

🤖 Generated with Claude Code

…s business roles

The customSession plugin replaces user.role with the literal 'admin' when
the user is a platform admin or active-org admin, which destroyed any
stored business roles (e.g. 'manager' in a comma-separated 'admin,manager'
value). Consumers matching pending approvers by role:<name> (Console
approvals inbox) therefore never saw an admin's role-based todos.

The session payload now always carries user.roles: string[] — the stored
role string split on commas, with 'admin' appended (deduplicated) on
promotion. user.role semantics are unchanged: existing strict
user.role === 'admin' checks keep working.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
@vercel

vercel Bot commented Jun 11, 2026

Copy link
Copy Markdown

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated (UTC)
spec Building Building Preview, Comment Jun 11, 2026 1:37pm

Request Review

@os-zhuang
os-zhuang merged commit 695cd29 into main Jun 11, 2026
7 of 8 checks passed
@os-zhuang
os-zhuang deleted the fix/auth-session-roles-array branch June 11, 2026 13:37
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant