Skip to content

πŸš€ Auto-PR: Merge test β†’ main - #987

Open
proxy-smart-releaser[bot] wants to merge 15 commits into
mainfrom
test
Open

πŸš€ Auto-PR: Merge test β†’ main#987
proxy-smart-releaser[bot] wants to merge 15 commits into
mainfrom
test

Conversation

@proxy-smart-releaser

@proxy-smart-releaser proxy-smart-releaser Bot commented Aug 9, 2026

Copy link
Copy Markdown
Contributor

Automated Pull Request πŸ€–

This PR was automatically created to merge changes from test into main.

Changes:

  • Commits ahead of main: 14
  • Commits behind main: 0
  • TODOs remaining in codebase: 3

Review: Please review the changes before merging.

Last updated: 2026-08-09 15:37:35 UTC

quotentiroler and others added 15 commits August 9, 2026 09:50
…ry loop

/admin/profile/ kept answering 401 to a logged-in admin, once per render, after
the per-request token work landed. The refresh succeeded and the replay was
rejected identically, which rules out expiry: the token was being refused for a
reason no new token could fix.

Every admin route drives Keycloak's Admin REST API with the CALLER's token
through keycloakPlugin's getAdmin, so this affects all of them, not just profile
β€” which is why the first report showed /admin/smart-apps/ failing too.

createAdminClient required realm-management client roles ON TOP of the admin
check the guard had already made, and raised that refusal as AuthenticationError.
handleAdminError turned it into 401 with the fixed body
`{ error: 'Authorization header required' }` β€” for a request that carried a
perfectly good header. So an admin holding proxy-smart-admin (or any configured
admin realm role) but no realm-management role got 401, the client refreshed and
retried on the client's 401 rule, and the pair repeated for as long as the page
was open. The message named the wrong cause throughout.

- createAdminClient no longer defines its own role policy. It carried its own
  ADMIN_REALM_ROLES/ADMIN_CLIENT_ROLES sets and read resource_access['admin-ui']
  literally: the exact drift lib/admin-roles.ts exists to prevent and had already
  fixed for validateAdminToken. Two policies meant the guard could admit a caller
  this factory then refused.
- Both refusals here are AuthorizationError now. The realm-management one names
  the missing grant, because that is what an operator needs in order to act.
- handleAdminError maps AuthorizationError to 403 β€” it previously did not handle
  the type at all, so correcting the type alone would have produced a 500 β€” and
  a 401 now carries its actual reason. Keycloak's own refusals say so, since the
  proxy already accepted the token and an unqualified "Unauthorized" points at
  the wrong hop.
- The client treats only 401 as refreshable. A 403 means the token was accepted
  and the grant is short, so refreshing mints an equally short one; that rule is
  what turned a missing role into an unbounded loop.
- ProfileSettings stores a message KEY and translates at render, so `t` leaves
  the load effect's dependencies. It is not stable across renders, and the effect
  sets state on failure, so it re-fired the request on every error.

The 403 body now states which realm-management roles are missing, so if beta
still refuses after this deploys, the response says why instead of blaming the
Authorization header.
πŸ§ͺ Auto-PR: Merge `develop` β†’ `test`
Three admin tools were being dropped from every client session. Tool names are
constrained to `^[a-zA-Z0-9_-]{1,64}$`, and a name over the cap is not truncated
β€” the whole tool is rejected. Nothing on this side notices: the registry lists
it, the route answers fine over HTTP, and it is simply absent wherever the tools
are actually used.

  67  delete_admin_healthcare-users_userId_client-roles_clientId_roleName
  66  create_admin_healthcare-users_userId_federated-identities_provider
  66  delete_admin_healthcare-users_userId_federated-identities_provider

Over the cap, path PARAMETERS are dropped first. They are the least informative
part of a name β€” each one is already an argument in the tool's input schema,
described there β€” so shedding them keeps the segments that say what the tool
acts on:

  42  delete_admin_healthcare-users_client-roles
  50  create_admin_healthcare-users_federated-identities
  50  delete_admin_healthcare-users_federated-identities

Only if that still does not fit is the name cut and given a stable FNV-1a digest,
so it stays unique and identical across deploys. A name changing between deploys
would break saved client prompts, which is why the digest is deterministic rather
than crypto or counter based.

Names at or under the cap are returned byte-for-byte as before. The first cut of
this built the name from filtered path segments, which silently dropped the empty
segment of a trailing-slash route and would have renamed 30 live tools
(get_admin_profile_ -> get_admin_profile) to fix 3 unreachable ones. Verified
against the real 180-tool surface: exactly 3 names change, longest is still 61.

Dropping parameters can also make two routes agree on a name, and the registry is
a Map keyed by name β€” the second would have overwritten the first and a tool
would have vanished with no error anywhere. extractRouteTools now disambiguates
instead of overwriting.

The trailing underscores are left alone deliberately. They are ugly, and fixing
them is a rename of tools clients call today, so it belongs in its own change.
πŸ§ͺ Auto-PR: Merge `develop` β†’ `test`
…s bump

1.5.21 -> 1.6.5. Verified by rebuilding the IG locally and diffing the generated
package against what consumers import:

  MaxHealthShareConsent              present
  validateMaxHealthShareConsent      present
  MaxHealthConsentCategoryVSConcepts present (valuesets/)

So the three symbols backend/src/lib/consent/shl-consent.ts imports are
unchanged. The bump is additive: 1.6.5 also emits namingsystems/, giving
NamingSystem-MaxHealthShlSession a generated form β€” the identifier system the
FSH already declared for SHL session ids and that 1.5.21 simply dropped.

publish-ig.yml now also triggers on package.json. Its build key includes
`babelfhir@${BABELFHIR_VERSION}`, read from that file, but the file was not in
the trigger paths β€” so a generator bump changed the key while firing no run, and
the new output sat unpublished until some unrelated fhir/ commit happened to
carry it. This very commit would have been invisible to consumers.

Backend 1367/1367 (shl-consent 11/11) against the published 0.1.3, which is
unaffected until the workflow republishes.
πŸ§ͺ Auto-PR: Merge `develop` β†’ `test`
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