Skip to content

feat(oauth): add owner app freeze, delete, and richer client settings - #68

Merged
matthew-demidoff merged 2 commits into
masterfrom
feat/oauth-app-lifecycle
Aug 28, 2026
Merged

feat(oauth): add owner app freeze, delete, and richer client settings#68
matthew-demidoff merged 2 commits into
masterfrom
feat/oauth-app-lifecycle

Conversation

@matthew-demidoff

Copy link
Copy Markdown
Collaborator

Developer-experience pass on the OAuth app dashboard.

What

  • New per-app settings for owners: app name, post-logout redirect URIs, allowed scopes, allowed grant types, refresh-token issuance. Validated against the canonical scope/grant lists, now exported from the oauth service instead of living as three inline copies.
  • Freeze/unfreeze: new frozen app status, owner-set and owner-reversible (migration 026 widens the status check). Every enforcement path already requires status = active, so a frozen app is rejected at authorize/token/userinfo/introspect and the activation API, and its issued tokens stop validating until unfrozen.
  • Permanent delete with type-the-slug confirmation. FK cascades remove tokens, secrets, codes, webhook endpoints, and authorizations; bearer_requests history survives with external_app_id nulled, so the stashed plaintext api key is cleared first.
  • Pastel red danger styling: danger-soft/border/strong tokens, the Button danger variant is filled at rest, Section gains a danger tone, applied to the app danger zone and the settings Delete section.

Decisions worth review

  • frozen vs disabled: owners flip active<->frozen only (guarded in SQL), so an admin-disabled app cannot be revived by its owner; the admin Enable action now refuses frozen apps instead of silently overriding the owner.
  • Frozen apps still count toward the 10-app cap, since owners can thaw them at will.
  • The Button danger restyle intentionally applies to every existing danger button (webhooks, admin, account deletion).

Tests: integration coverage for freeze transitions, ownership guards, cap counting, and delete cascades in tests/integration/external-app-owner-lifecycle.test.ts.

Owners can now suspend (freeze) or permanently delete their OAuth apps
from the dashboard, and edit the app name, post-logout redirect URIs,
allowed scopes, grant types, and refresh-token issuance.

A new frozen status sits beside admin-only disabled; every enforcement
path already requires status = active, so frozen apps are rejected at
authorize, token, userinfo, introspection, and the activation API with
no enforcement changes, and their issued tokens stop validating until
unfrozen. Guarded transitions keep owners from reviving admin-disabled
apps and admins from overriding an owner freeze. Deletion cascades
tokens, secrets, codes, webhook endpoints, and authorizations, and
clears any stashed bearer plaintext key first.

Destructive controls now wear a pastel red fill at rest (new danger
tokens, filled Button danger variant, Section danger tone) so dangerous
actions read as dangerous before hover, in the app pages and settings.
getAll on the permissions form can carry duplicate values from a tampered
submit. Collapse them the way parseOAuthScopes already does for the
authorize path, so the stored allowlist stays a clean set.
@matthew-demidoff
matthew-demidoff merged commit 0f3f100 into master Aug 28, 2026
4 checks passed
@matthew-demidoff
matthew-demidoff deleted the feat/oauth-app-lifecycle branch August 28, 2026 11:00
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