Skip to content

Access Keys — Create flow refactor + One-time Reveal #67

@mahid797

Description

@mahid797

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.



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 (via useCreateAccessKeyMutation from 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 CreateVirtualKeySchema and imports of provider/API key fields.

  • Use CreateAccessKeySchema from @lib/validation with useFormWithSchema.

  • 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 }).
  • 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.tsx and do not render the parked section.

D) Wiring & cleanup


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).
  • Validation & errors

    • Client-side: empty name is allowed (optional); description > 500 shows inline error.
    • Server errors (422/500) show toast from envelope error.message; inputs remain editable.
  • 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.tsx submits to the real API using CreateAccessKeySchema and 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.

Metadata

Metadata

Assignees

No one assigned

    Labels

    ⚡ ImportantHigh-impact issue that needs to be resolved before the next release.🎨 FrontendFrontend related issue.🖌️ UX/UI ChangeUser experience or interface design change.🧩 CoreChanges to core system architecture or critical modules.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions