Repository navigation
feat(client): add permission and organization role checks for the client user - #241
Merged
Merged
Conversation
…ent user Add hasPermission, hasAllPermissions, hasRole and hasOrganizationRole over the /users/me user, re-exported from every binding, and a usePermissions hook in @seamless-auth/react. For UI only: the server must still enforce. Closes #233
hasPermission and hasAllPermissions now take { organization: true }, the option the server
guards use in fells-code/seamless-auth-server#275.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Closes #233
Permissions and organization roles on the client user, for showing and hiding UI. The client reads them from
GET users/meand still never decodes a token. The server must still enforce, and the docs say so.Public API
From
@seamless-auth/client, re-exported by React, React Native, Angular, Vue and Svelte:hasPermission(user, required, { organization? }): any ofrequiredhasAllPermissions(user, required, { organization? }): all ofrequired, and an empty list answers falsehasRole(user, required): instance roles only, scoped matching throughhasScopedRolehasOrganizationRole(user, required): active organization roles only, exact matchingPermissionCheckOptionsandUserAuthorizationFrom
@seamless-auth/reactonly:usePermissions()andUsePermissionsResult. It returns the same four checks without the user argument, plusloading,roles,permissions,organizationRoles,organizationPermissionsandactiveOrganizationId.Decisions
hasOrganizationRole, not an option onhasRole. The two match differently (scoped and exact), and a forgotten option would be the failure ADR 0004 P2 rules out.{ organization: true }counts only the active organization, the same option asrequirePermissionin feat(guards): add organization aware requirePermission guards seamless-auth-server#275. The default is the union ofpermissionsandorganizationPermissions(ADR P6).hasRoleis scoped, whileuseAuth().hasRolestays exact and answersundefinedwhen signed out. Same name, different semantics foradmin:read. I left the existing method alone and documented the difference.@seamless-auth/types. The client imports@seamless-auth/types/permission/matching, which has no Zod. It is external in the client build, andAGENTS.mdnow records the exception. Each Jest config maps and transforms that one file, because the package ships ESM under theimportcondition only. An adopter whose Jest runs our client through its own transform allowlist needs@seamless-auth/typesin that allowlist too.What was run
All on Node 24, in this branch:
npm run lint: passnpm run typecheck: pass, all six packagesnpm run format:check: passnpm run check:types-current: pass, 0.38.0npm run build: pass, includingcheck-react-distandcheck-vue-distnpm test -- --coverage --runInBand: pass. Jest 59 suites, 896 tests. Vitest (Svelte) 3 files, 56 tests.permissions.tsandusePermissions.tsat 100 percentnpm run check-npm-build: passpackages/client/dist/index.jsandpackages/react/dist/index.jswith esbuild for the browser and read the metafile: no Zod input, and the only@seamless-auth/typesinput ispermission/matching.jsWhat was not run
/users/meresponses shaped byMeUserSchema. An API without it answers false everywhere, by designconformanceworkflow and the seamless-cli browser harnessLeft out
usePermissionsequivalents in React Native, Vue, Svelte and Angular. The issue names React, and those bindings get the helpers through their re-export lists. They also have nohasPermissionmethod on their service or session class../seamless-auth-docsis not updatedNoticed, not changed
packages/client/src/scopedRoles.tsis a hand-kept copy of@seamless-auth/types/role/matching. Now that a Zod-free runtime subpath is in use, it could import rather than copymeHandlerinseamless-auth-server/packages/core/src/handlers/me.tsreturns onlyuserandcredentials, soorganizations,activeOrganizationandrecoverydo not reach the client through it.userpasses through whole, so the new fields do