-
Notifications
You must be signed in to change notification settings - Fork 9
Description
Goal
Refactor the Create flow to use the real Access Key API contract and show a one-time reveal dialog with copy. Remove legacy “virtual key” fields, but park provider configuration UI for future reuse.
- Parent: Access Keys FE #64
- Depends on: Access Keys — Data hooks (CRUD) + mutation keys + API types #65
- Blocks: (complements) Access Keys — List view + Status badges + Sorting #66, Access Keys — Edit / Revoke / Delete #68
Description
Replace the temporary compatibility shim in KeyCreateModal.tsx with a production-ready create flow:
- Form fields:
name(optional, 1–100),description(optional, ≤500). - Submit to
POST /api/access-keys(viauseCreateAccessKeyMutationfrom Access Keys — Data hooks (CRUD) + mutation keys + API types #65). - On success, open a KeyRevealDialog that displays the full key (copyable) once.
- After the reveal is dismissed, the list only ever shows the preview (
lr_…abcd). - Extract the existing provider-related UI into
ProviderConfigSection.tsx(parked; not rendered).
Important UX / security rules
- No “preview copy” anywhere in the list or edit flows.
- Do not persist the full key beyond the reveal dialog; avoid logging it.
- Clear the full key from state when the dialog closes.
Tasks
A) Replace the shim in KeyCreateModal.tsx
-
Remove the local
CreateVirtualKeySchemaand imports of provider/API key fields. -
Use
CreateAccessKeySchemafrom@lib/validationwithuseFormWithSchema. -
Fields:
name(input label “Name of the key”; placeholder “Production / Staging / Local…”)description(textarea or input; up to 500 chars)
-
Submit handler:
- Call
useCreateAccessKeyMutation().mutateAsync(payload). - On success, close the sheet and open KeyRevealDialog with the returned
{ accessKey: { id, key, createdAt, name?, description? } }. - Errors: route to
handleFormError(err, { setError: form.setError }).
- Call
-
Button / UX:
- Disable submit while pending; show loading text.
- Keep SearchBar visible; no filtering needed now.
-
Copy/terminology updates:
- Replace any “virtual key” copy with “Access Key”.
B) KeyRevealDialog component
-
Create
src/app/(client)/(core)/key-management/components/KeyRevealDialog.tsx-
Use shadcn
Dialog. -
Title: “Your Access Key (shown once)”
-
Body: masked field with Show/Hide toggle (mono font), Copy button.
-
Security note: “Store this key securely. You won’t be able to view it again.”
-
Actions: primary “I’ve saved it” to close.
-
Optional: “Create another” secondary button (re-opens create sheet).
-
Clear the in-memory key when
onOpenChange(false)fires. -
Minimal prop example (do not implement fully here):
type KeyRevealDialogProps = { open: boolean; onOpenChange: (v: boolean) => void; fullKey?: string; // undefined when closed createdAt?: string; name?: string | null; description?: string | null; };
-
-
Implement copy using
navigator.clipboard.writeText(fullKey)with a success toast; show an error toast if the API is unavailable. -
Ensure no preview copy affordance is added here—only the full key can be copied, and only now.
C) Park the provider UI (future reuse)
-
Extract current provider bits into
src/app/(client)/(core)/common/ProviderConfigSection.tsx- Keep the fields and labels intact, but export in a disabled/read-only state with a banner: “Provider configuration coming soon.”
- Add a docblock comment: “Parked for Secrets UI; not used in Phase 2.”
-
Remove provider/API key selects from
KeyCreateModal.tsxand do not render the parked section.
D) Wiring & cleanup
- Ensure the list invalidation occurs after create (handled by Access Keys — Data hooks (CRUD) + mutation keys + API types #65 hook; just verify).
- Confirm the sheet close/re-open flows don’t leak the full key in state or logs.
- Remove any remaining references to
alias,provider,apiKeyfields in this route group.
Tests (manual)
-
Happy path
- Open “Create Access Key” sheet → fill valid
name/description→ submit. - Reveal dialog opens with full key; Copy works; Show/Hide toggles.
- Click “I’ve saved it” → dialog closes; creating another key works as expected.
- Refresh list: newly created key shows with preview (never the full key).
- Open “Create Access Key” sheet → fill valid
-
Validation & errors
- Client-side: empty
nameis allowed (optional);description> 500 shows inline error. - Server errors (422/500) show toast from envelope
error.message; inputs remain editable.
- Client-side: empty
-
Security
- After dialog close, re-opening the sheet does not show any previous full key.
- No “copy preview” button present anywhere.
-
Edge cases
- Close the sheet or dialog midway → state cleans up; no stale key in memory.
- Clipboard unavailable → shows error toast and leaves the dialog open.
Acceptance Criteria
KeyCreateModal.tsxsubmits to the real API usingCreateAccessKeySchemaand Access Keys — Data hooks (CRUD) + mutation keys + API types #65 hooks.- A KeyRevealDialog displays the full key once with copy and a clear security notice.
- Post-create, the list only ever shows preview; no UI allows copying the preview.
- Provider fields are parked in a reusable component and not rendered.
- Errors use the standard envelope; inline Zod errors show under fields.
Notes
- Keep component code minimal and aligned with the existing shadcn + RHF patterns already used in auth pages.
- Do not introduce a global clipboard util unless we decide to standardize later; local usage with a toast is fine here.
- Confirm dialog design will be added in Access Keys — Edit / Revoke / Delete #68 (for Revoke/Delete); this issue should not add a generic confirm.