Skip to content

feat(admin): widen AdminPermission to accept plugin-declared actions - #5

Merged
zumbrunn merged 1 commit into
mainfrom
feat/plugin-extensible-authz-schema
Sep 2, 2026
Merged

feat(admin): widen AdminPermission to accept plugin-declared actions#5
zumbrunn merged 1 commit into
mainfrom
feat/plugin-extensible-authz-schema

Conversation

@zumbrunn

@zumbrunn zumbrunn commented Sep 2, 2026

Copy link
Copy Markdown
Member

What

Widens AdminPermission from a closed union of the built-in admin actions to also accept any string (AdminPermission | (string & {}) pattern — keeps autocomplete for the built-ins, accepts anything else).

Why

Companion to @dune/core's DunePlugin.authzActions (separate PR, @dune/core@^0.34.4), which lets a plugin declare its own admin-permission action (e.g. "billing.manage") merged into the site's authz schema at bootstrap. checkPermission()/requirePermission()/withGuards() already just forward whatever permission string they're given straight to authz.check() — the real authority either way — so the closed union here was the only thing stopping a plugin author from actually using this without a permission: "..." as never workaround. Pure type change, no runtime behavior change.

Also fixed guards.ts's own doc example, which referenced an undeclared "settings.update" permission that was never a real built-in — would have failed deno check had the example itself ever been type-checked. Now shows a plugin declaring authzActions and gating a route behind it.

Testing

  • New test: a non-built-in permission string type-checks through withGuards() with no cast, forwards correctly to authz.check() in both directions (allow/deny).
  • Full suite: deno test -A — 233 passed, 0 failed.
  • deno lint src/ and deno check clean.

Requires

@dune/core@^0.34.4 — see that repo's companion PR. Note @dune/core@0.34.4 has not itself published to JSR yet as of this PR.

🤖 Generated with Claude Code

@dune/core@^0.34.4's DunePlugin.authzActions lets a plugin declare its
own admin-permission action and gate a route behind it via
withGuards()/requirePermission() the identical way as a built-in one.
AdminPermission was a closed union listing only the built-ins, so a
plugin author could only pass a custom action through with a
`permission: "..." as never` type-level workaround — checkPermission()/
requirePermission()/withGuards() were already just forwarding whatever
string they were given straight to authz.check(), so this is purely a
type change, no runtime behavior change.

guards.ts's own doc example now shows a plugin declaring authzActions
and gating a mount()-registered route behind it (previously used an
undeclared "settings.update" permission that would have failed
deno check had the example itself ever been type-checked).

New test proving a non-built-in permission string type-checks through
withGuards() with no cast and forwards correctly to authz.check() in
both directions (allow/deny).

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
@zumbrunn
zumbrunn force-pushed the feat/plugin-extensible-authz-schema branch from b30621e to 6ee6b12 Compare September 2, 2026 08:58
@zumbrunn
zumbrunn merged commit edb1c79 into main Sep 2, 2026
3 checks passed
@zumbrunn
zumbrunn deleted the feat/plugin-extensible-authz-schema branch September 2, 2026 08:59
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