guibranco / guibranco/logstream-ui

[FEATURE] Scoped read token management in Applications screen

Open
#164 0 comments 0 reactions 0 assignees View on GitHub
✨ feature 🚨 security enhancement good first issue hacktoberfest help wanted
Dominant language
TypeScript
Stars
1
Forks
0
Avg merge
15m
Merged PRs (30d)
49

Description

## Summary

Extend the Applications screen to support generating and rotating **scoped read tokens** per client, with a secure one-time display modal matching the existing API token reveal flow.

> **Depends on:** [`[FEATURE] Scoped read keys per registered client`](https://github.com/guibranco/logstream-server/issues) in `guibranco/logstream-server`

## Motivation

Once the server supports per-client read tokens, operators need a UI to generate them for individual teams without exposing the admin `UI_SECRET`.

## Proposed changes

### ClientTable β€” new action

Add a **"Generate read token"** button (key icon) in the Actions column alongside the existing Edit, Rotate API token, and Delete buttons.

### TokenRevealModal β€” reuse for read token

Reuse the existing `TokenRevealModal` component with adjusted copy:

```
β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚ β”‚
β”‚ πŸ”‘ Scoped read token for billing-api β”‚
β”‚ β”‚
β”‚ This token grants read-only access to logs from β”‚
β”‚ billing-api only. Store it now β€” it will not be β”‚
β”‚ shown again. β”‚
β”‚ β”‚
β”‚ Token: [____________________________] [Copy] βœ“ β”‚
β”‚ β”‚
β”‚ Usage: β”‚
β”‚ Authorization: Bearer β”‚
β”‚ β†’ Can only read logs where app_key = billing-api β”‚
β”‚ β”‚
β”‚ [ I've saved the token ] β”‚
β”‚ β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
```

### RotateConfirmModal β€” read token variant

```
Rotate read token for "billing-api"?

Anyone currently using the old read token will lose
access until they update their configuration.

[Cancel] [Rotate read token]
```

## Files to modify / create

- `src/components/clients/ClientTable.tsx` β€” add Generate read token action button
- `src/components/clients/TokenRevealModal.tsx` β€” accept a `tokenType` prop (`'api' | 'read'`) to adjust copy
- `src/components/clients/RotateConfirmModal.tsx` β€” accept `tokenType` prop
- `src/hooks/useClients.ts` β€” add `useRotateReadToken()` mutation calling `POST /api/clients/{key}/rotate-read-token`

## UX details

- The read token action is shown as a secondary (outline) button to visually distinguish it from the primary API token rotation
- Tooltip on the button: *"Generate a read-only token scoped to this application's logs"*
- `has_read_token: true/false` field on the client list response determines whether the button label is "Generate" or "Rotate"

## Acceptance criteria

- [ ] "Generate / Rotate read token" button in client table Actions column
- [ ] `TokenRevealModal` shows correct copy for read vs API token
- [ ] `RotateConfirmModal` shows correct warning for read token rotation
- [ ] Modal cannot be dismissed without clicking the confirmation button
- [ ] `POST /api/clients/{key}/rotate-read-token` called correctly
- [ ] Table reflects `has_read_token` status

Contributor guide

Open the contributing guide

Research direction

Start by reading src/components/clients/ClientTable.tsx, TokenRevealModal.tsx, RotateConfirmModal.tsx, and src/hooks/useClients.ts to trace the existing API-token flow. Confirm the server-side scoped-token dependency and the expected has_read_token response field. Done means the generate/rotate action, token-specific modal copy, confirmation behavior, mutation endpoint, and table status all meet the listed acceptance criteria.

Written by the indexing model from the issue text.

Assessment

Tech stack
react, typescript, vite
Domain
api, frontend
Issue type
Feature
Difficulty
4/5
Estimated time
3-5 days
Activity status
Quiet
Clarity
Mostly clear
Newbie friendliness
55/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.