Repository navigation
Move ThunderID Management feature capabilities (Groups, Roles, etc.) - #155
Merged
Merged
Conversation
|
Important
This repository does not receive automatic reviews because it has fewer than 10 stars.
|
🔀 Cross-SDK feature parity, ports raisedThis pull request is labelled Ports (DO NOT EDIT)
3 of 3 sibling SDKs accounted for. Every sibling SDK is accounted for. The contract is in the SDK development specification. |
This was referenced Nov 4, 2026
Merged
Open
brionmario
force-pushed
the
feat-group-role-details
branch
from
November 4, 2026 15:21
ded9536 to
ef5df2c
Compare
brionmario
force-pushed
the
feat-group-role-details
branch
from
November 4, 2026 15:31
ef5df2c to
ee5fa36
Compare
brionmario
force-pushed
the
feat-group-role-details
branch
from
November 4, 2026 16:42
ee5fa36 to
ed7a872
Compare
brionmario
force-pushed
the
feat-group-role-details
branch
from
November 4, 2026 17:48
ed7a872 to
6971ff7
Compare
Draft
2 of 4 tasks
… operations and components, group and role details, and rename the admin components group to management
Show a group with its members, and a role with its permissions and assignments, in one view. Both fetch the record, show its name, description and organization unit, embed the existing GroupMembers, RolePermissions and RoleAssignments, and can delete it (through its administration flow in flow mode) after confirmation. Read-only roles are never offered for deletion. Ships for React and Vue with Base variants and custom rendering, Next.js wrappers, Nuxt auto-imports, strings in every locale, tests and playground stories.
Rename the components/admin folder to components/management in React, Vue and Next.js, so the UI group matches the data layer (api/management, hooks/management, composables/management) and the specification's management operations. Folder paths only: exports, component names and the admin.* translation keys are unchanged.
Add management operations for credential configurations (OpenID4VCI,
openid4vci/credential-configurations) and presentation definitions
(OpenID4VP, openid4vp/presentation-definitions), dynamic client
registration (RFC 7591/7592, oauth2/dcr/register: register, get, update,
delete), and a gateway's master, its history and one resource's history.
Each resolves its URL like the other management resources, with the
credentialConfigurations, presentationDefinitions and clientRegistrations
endpoint keys. Client registrations map the snake_case wire format, set
client_id from the argument on update and may send the current secret for
the server to check, and keep the secret out of logs and printed output.
An OAuth error body ({error, error_description}) is read into serverError,
and 401/403/404 keep distinct codes. Path parameters are percent-encoded
per segment.
Add the rest of the SDK specification's 0.10 surface. Organization
operations: list the units the signed-in user can access
(/users/me/ous), read the current unit from the token's claims, sign in
bounded to a unit (/ou/{ouId}/oauth2/authorize and token in redirect
mode, ouId on the flow start in embedded mode, ouId on the backend
sign-in), switch units (a failed switch leaves the session as it was),
render Resolve OU flow steps, and an OrganizationUnitSwitcher
component. Management: sharing policies and overlay rules for roles and
flows, flow variables, groups by path, projects, authorization detail
types and the public authorization details types, and editable
RolePermissions. Optional operations: pushed authorization requests
(pushedAuthorizationRequests), device authorization, and CIBA where the
platform's spec scope allows it.
JavaScript also adds, in Node only, the device side of device
authorization, token introspection and access evaluation (AuthZEN, with
an Express requireAccess guard), renames the user-side device grant to
verifyDeviceCode (the old name stays as a deprecated alias), and renders
the Resolve OU input the flow renderers used to skip.
Add components for them: ProjectList, ProjectCreate, ProjectDetails and a
ProjectSwitcher that keeps the current project as client-side context,
OrganizationUnitList, OrganizationUnitCreate and OrganizationUnitDetails,
and SharingPolicies for a user, application, role or flow, in React and
Vue with Next.js wrappers and Nuxt auto-imports. A project id is not an
organization unit id: application and agent lists and creates take the
current project as projectId (the operations gain it), other creates keep
their organization unit default, and AgentList offers no search while a
project scopes it, since the server can't combine the two. Server
refusals map to translated messages by code.
Signed-off-by: Brion <info@brionmario.com>
brionmario
force-pushed
the
feat-group-role-details
branch
from
November 6, 2026 05:11
6971ff7 to
1c568a1
Compare
DonOmalVindula
approved these changes
Nov 6, 2026
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.
Purpose
The SDK ships details views for users, agents and applications, but none for groups or roles. An app that shows one, such as the ThunderID Admin Console, fetches the group or role itself, draws its name and description, and then places
GroupMembers, orRolePermissionsandRoleAssignments, under it. This addsGroupDetailsandRoleDetails, so that view comes from the SDK.GroupDetailsfetches the group and shows its name, description and organization unit, with its members under them.RoleDetailsdoes the same for a role, with what it grants and who holds it.editablelets the signed-in user add and remove members or assignments, which are offered from the group's or role's own organization unit.deletableadds a delete action that asks for confirmation, then reports the deletion so the app can navigate away.administrationMode: flowdeletes the group or role, and removes members and assignments, through the administration flow the server configures for it, which can revoke grants and end sessions first. With no flow configured, the API is called directly.Folder layout. The UI group for these components was
components/admin, while the data layer, the hooks and composables, and the specification all say management. This renamescomponents/admintocomponents/managementin React, Vue and Next.js (and Next.js's internalclient/admin.tstoclient/management.ts), so every SDK uses the same names:api/{account,auth,management}andcomponents/{account,auth,management,common}. Only folder paths change: exports, component names and theadmin.*translation keys stay as they are.Approach
Basevariants for React and Vue, followingAgentDetails.BaseGroupDetailsandBaseRoleDetailshold no data: the group or role, loading and error state, andonDeleteare props. The embedded sections are slots (membersfor groups;permissionsandassignmentsfor roles), as a React prop or a Vue named slot.childrenfunction (React) or the default scoped slot (Vue) receivesgroup/role,isLoading,error,isDeletingandonDelete.onDeleteis undefined unless deletion is allowed and the record is deletable. It replaces the whole view, embedded sections included.RoleDetailsrendersBaseRolePermissionsfrom it rather than mountingRolePermissions, which would fetch the role again.GroupDetailsandRoleDetailswrappers, plus theBase*exports inclient/admin. Nuxt: all four are added to the management auto-imports.admin.groups.details.*andadmin.roles.details.*(overview, error, delete action, confirmation and error) in all 9 locales.editable,deletableandadministrationMode, in the React, Vue, Next.js and Nuxt playgrounds. React also has a custom-rendering story.New management operations
The SDK development specification (0.11, thunder-id/thunderid#6080) adds these resources; this PR implements them, under the same management rules as the rest: the signed-in user's token, the URL from an explicit
url, then theendpointsoverride, thenbaseUrlplus the collection, a replaceablefetcher, and no side effects.getCredentialConfigurations,getCredentialConfiguration,createCredentialConfiguration,updateCredentialConfiguration,deleteCredentialConfiguration. Collectionopenid4vci/credential-configurations, endpoint keycredentialConfigurations.getPresentationDefinitions,getPresentationDefinition,createPresentationDefinition,updatePresentationDefinition,deletePresentationDefinition. Collectionopenid4vp/presentation-definitions, endpoint keypresentationDefinitions.registerClient,getClientRegistration,updateClientRegistration,deleteClientRegistration. Collectionoauth2/dcr/register, endpoint keyclientRegistrations.client_idfrom the argument, and may send the client's current secret for the server to check (the server never stores it).getGatewayMaster,getGatewayMasterHistory,getGatewayMasterResource, on the existing gateways resource. Each path segment is percent-encoded.{error, error_description}body is read intoserverError(code and message), so client registration errors carry the server's reason. 401, 403 and 404 keep distinct codes. Management error bodies, which carrycode, are unaffected.ThunderIDNodeManagementClientgainscredentialConfigurations,presentationDefinitionsandclientRegistrations(register,get,update,delete), andgateways.getMaster,getMasterHistoryandgetMasterResource. The three collections join the management relay allowlist that the Next.js and Nuxt relays use.useManagementEndpointaccepts the new keys.Verified locally: build passes for javascript, browser, node, react, vue, nextjs and nuxt, and typecheck for every package except nuxt (
vue-tscmissing locally). Tests: javascript 1155, node 205, nextjs 148, React management components 87. The Vue run has failures in the auth flow tests (flow-select-field, sign-up and device code); they fail the same way without this PR.Organization units and the rest of the 0.10 surface
Implements the rest of the SDK development specification 0.11 (thunder-id/thunderid#6080), including the organization operations it now defines for the organization unit work in flight (thunder-id/thunderid#5625, #6302; server side in #6303 on
feature/ou-authz-and-projects).Organization units
getAccessibleOrganizationUnitsreads/users/me/ous(optionalscope: siblings, paging);getCurrentOrganizationUnitreads theouId,ouHandleandouNameclaims, for display only.organizationUnitId: redirect mode authorizes at/ou/{ouId}/oauth2/authorizeand redeems the code at/ou/{ouId}/oauth2/token; embedded mode sendsouIdonly on the flow start; backend mode passesouIdto the backend sign-in. The unit id is percent-encoded.switchOrganizationUnit: signs in again bounded to the unit, reusing the SSO session; success replaces the whole token set (the refresh token is bound to its unit), failure leaves the old session exactly as it was.unauthorized_clientmaps to one documented error.OrganizationUnitSwitcherandBaseOrganizationUnitSwitcher(account group), with custom render, paging and translated errors in every shipped locale.Management
isOwned,isOwnedByOUorowned, which also fixes user and application overlays).ouIdrequired, as the server requires it), groups by handle path, projects (endpoint keyprojects), authorization detail types (endpoint keyauthorizationDetailTypes) and the public supported authorization details types.RolePermissionsedits a role's permissions wheneditable(off by default, never for read-only roles, removal confirmed);RoleDetailspasses itseditablethrough.Components for projects, organization units and sharing (UI requirements 11 and 12 in thunder-id/thunderid#6080), in React and Vue, with Next.js wrappers and Nuxt auto-imports
ProjectList,ProjectCreate,ProjectDetailsandProjectSwitcher. Projects are a control plane concept, and a project id is not an organization unit id. The switcher keeps the current project as client-side context (currentProject/setCurrentProjecton the provider; persisted per vendor inlocalStorage, read after mount so server rendering stays safe).getApplications/getAgentstake an optionalprojectIdquery parameter and the application and agent create requests an optionalprojectId(an agent'souIdbecomes optional).ApplicationListandAgentListdefaultprojectIdto the current project, andApplicationCreateandAgentCreatesend it when the app passes no organization unit. Other creates keep their organization unit default.AgentListhides its search while a project scopes it, because the server can't combine another filter withprojectId.OrganizationUnitList(root units or the children ofparentId),OrganizationUnitCreateandOrganizationUnitDetails(child units and the users, groups and roles in the unit, read only).SharingPoliciesfor a user, application, role or flow: paged, with create, edit and delete only wheneditable(delete confirmed, read-only policies offer no actions), and the overlay rules for anouId.PRJ-1006/PRJ-1012(id or handle in use),PRJ-1007(handle can't change),OU-1004/OU-1008(name or handle in use),OU-1006(unit still has children),OU-1012(declarative).toManagementErrorMessagetakes an optional code-to-key map for this.Basevariant and a custom render, strings in all 9 locales, tests, and playground stories (React, Vue, Next.js, Nuxt) including Custom rendering. The Nuxt auto-import count test now expects 26.Optional operations
pushedAuthorizationRequests(default false; never overrides a server that requires PAR).verifyDeviceCode(the old name stays as a deprecated alias).startDeviceAuthorization/pollDeviceAuthorization,introspectToken, and access evaluation (evaluateAccess,evaluateAccesses,searchActions; endpoints from the AuthZEN metadata, the secret inDirect-Auth-Secret, a denial returned as a result). Express gains arequireAccessguard.Framework notes: the browser tries a silent
prompt=noneswitch in an iframe before a full redirect. Next.js and Nuxt switch through server actions and routes (always a redirect); Nuxt addsGET /api/auth/user/organization-units.useThunderIDexposesswitchOrganizationUnitand the current unit.Also fixed: the Nuxt test that counts management auto-imports expected 16 and now expects 18, after GroupDetails and RoleDetails.
Verified locally: build passes for javascript, browser, node, express, react, vue, nextjs and nuxt, and typecheck for all but nuxt (
vue-tscis missing locally). Tests: javascript 1244, browser 154, node 233, express 30, nextjs 160, nuxt 255, react 685 (all pass). Vue: 465 pass; 13 fail in six auth and primitive test files (flow-select-field,user-select-flow-wiring,authorization-details,consent-decisions,key-value-list,otp-field), which fail the same way without this PR. Prettier is clean on every changed file.On top of attribute verification (#145). The PR is rebased onto
main, which added self user attribute verification and released@thunderid/react1.14.0 without the components here. The VueBaseVerifyAttributereads the shared admin translation helper fromcomponents/management/shared, the playgrounds keep the verification stories next to the new ones, and the Nuxt module serves both the self-flow and organization-units routes.Related Issues
Related PRs
b2b/managetomanagement/adminand shows these components there. Draft until the@thunderid/reactrelease with these components (1.15.0).Checklist
adminComponents.test.tsxand Vueadmin-components.test.ts: the built-in view, members and assignments listed from the record's organization unit, one role fetch, delete after confirmation, no delete for a read-only role, custom rendering, and load errors.)breaking changelabel added.parity/prs-raisedorparity/prs-not-neededadded.parity/prs-raised, the port links are posted as a reply on the parity check's comment.Verified locally, after the rename: the React management tests (87) and Vue management tests (68) pass, React, Vue, Next.js and Nuxt build, typecheck passes for React, Vue and Next.js, and ESLint reports nothing new. The Nuxt typecheck was not run (
vue-tscis missing from the local install).Security checks