From 1a509c6102dc8b9dcddabb0179edc8882d1df78a Mon Sep 17 00:00:00 2001 From: Hugo Richard Date: Tue, 21 Apr 2026 18:05:56 +0200 Subject: [PATCH] feat(app): expose full token scoping + polish audit logs UI MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Tokens - Replace the cramped create-token popover with a modal so there is room for the full scope surface the backend already supports: teams, projects, environments, and IP allowlist (CIDR ranges with inline validation). Project/environment pickers cascade from the selected teams. - Show a clear "unscoped token" warning when no restriction is applied. - Table now shows what each token is actually scoped to (teams / projects / envs / CIDRs counts, tooltip with the ids) instead of a generic "scoped" badge. - Type: Token.allowedCidrs is now part of the public Token type (the API already returned it). Audit logs - Color-code action badges by category (create=success, delete=error, update/token.*=warning, auth.*=info) and add resource icons. - Actor badges carry a matching icon (user/key-round/cpu). - IP rendered as a monospace pill. - Parse the raw User-Agent into a friendly client label (e.g. "Shelve CLI 5.0.0", "Chrome 147 · macOS", "Node.js", "curl 8.6.0") with the full UA on hover, instead of taking half the row. - New metadata popover ({} icon) showing the full JSON payload for each event. - Empty state + centered "Load more". --- .changeset/token-ui-restrictions.md | 21 + apps/shelve/app/components/token/Create.vue | 393 ++++++++++++++++-- apps/shelve/app/components/token/Scopes.vue | 58 +++ .../app/pages/[teamSlug]/team/audit-logs.vue | 144 ++++++- apps/shelve/app/pages/user/tokens.vue | 22 +- apps/shelve/app/utils/userAgent.ts | 71 ++++ packages/types/src/Token.ts | 1 + 7 files changed, 640 insertions(+), 70 deletions(-) create mode 100644 .changeset/token-ui-restrictions.md create mode 100644 apps/shelve/app/components/token/Scopes.vue create mode 100644 apps/shelve/app/utils/userAgent.ts diff --git a/.changeset/token-ui-restrictions.md b/.changeset/token-ui-restrictions.md new file mode 100644 index 00000000..0827671f --- /dev/null +++ b/.changeset/token-ui-restrictions.md @@ -0,0 +1,21 @@ +--- +"@shelve/app": minor +--- + +Two related UI improvements around the v5 security surface. + +**Tokens** + +- Token creation now exposes the full scope surface that the backend already supports: restrict a token to specific **teams**, **projects**, and **environments** via cascading multi-select pickers, and add an **IP allowlist** (CIDR ranges) with inline validation. +- A clear "unscoped token" warning when no restriction is applied. +- The tokens table shows what each token is actually scoped to (teams / projects / envs / CIDRs counts) instead of a generic "scoped" badge. +- The popover form was replaced with a roomier modal so the new options have space to breathe. `Token.allowedCidrs` is now part of the public `Token` type. + +**Audit logs** + +- Color-coded action badges (create=success, delete=error, update / token.* = warning, auth.* = info) and resource icons (variable / environment / project / token / …). +- Actor badges include a matching icon (`user`, `key-round`, `cpu`). +- IP rendered as a monospace pill. +- The very long raw `User-Agent` string is parsed to a friendly client label (e.g. `Shelve CLI 5.0.0`, `Chrome 147 · macOS`, `Node.js`, `curl 8.6.0`) with the full UA available on hover. +- New per-row metadata popover (`{}` icon) showing the full JSON payload for that event, instead of having no way to inspect it. +- Empty state and centered "Load more" button. diff --git a/apps/shelve/app/components/token/Create.vue b/apps/shelve/app/components/token/Create.vue index 6fbeaacd..6839dccb 100644 --- a/apps/shelve/app/components/token/Create.vue +++ b/apps/shelve/app/components/token/Create.vue @@ -1,14 +1,35 @@ diff --git a/apps/shelve/app/components/token/Scopes.vue b/apps/shelve/app/components/token/Scopes.vue new file mode 100644 index 00000000..a7107712 --- /dev/null +++ b/apps/shelve/app/components/token/Scopes.vue @@ -0,0 +1,58 @@ + + + diff --git a/apps/shelve/app/pages/[teamSlug]/team/audit-logs.vue b/apps/shelve/app/pages/[teamSlug]/team/audit-logs.vue index 44b5d2f2..a81d2870 100644 --- a/apps/shelve/app/pages/[teamSlug]/team/audit-logs.vue +++ b/apps/shelve/app/pages/[teamSlug]/team/audit-logs.vue @@ -1,6 +1,7 @@