Skip to content

feat(admin): users and organizations admin verbs#57

Merged
Bccorb merged 1 commit into
mainfrom
feat/admin-verbs
Jul 14, 2026
Merged

feat(admin): users and organizations admin verbs#57
Bccorb merged 1 commit into
mainfrom
feat/admin-verbs

Conversation

@Bccorb

@Bccorb Bccorb commented Jul 14, 2026

Copy link
Copy Markdown
Contributor

Summary

Eighth issue in the CLI auth epic (#38). Adds terminal access to the instance admin endpoints for user and organization management, built on the authenticated client (#41). All commands require an admin role.

Commands

Users (/admin/users*):

  • users list [--limit <n>] [--offset <n>] [--json]
  • users delete <id> (confirmation; DELETE /admin/users with body { userId })
  • users credentials <id> [--json] (from GET /admin/users/:id detail)
  • users prepare-device-replacement <id> [--keep-sessions] [--keep-passkeys] [--keep-totp]

Organizations (/admin/organizations*):

  • org list [--json], org create <name> [--slug], org get <id> [--json], org update <id> [--name] [--slug]
  • org members list <orgId> [--json]
  • org members add <orgId> (--user <id> | --email <email>) [--roles a,b] [--scopes a,b]
  • org members update <orgId> <userId> [--roles a,b] [--scopes a,b]
  • org members remove <orgId> <userId> (confirmation)

Notes / decisions

  • Endpoint shapes from source: DELETE /admin/users takes the id in the body ({ userId }), not the path. Per-user credentials come from the GET /admin/users/:id detail response ({ user, sessions, credentials, events }); there is no dedicated per-user credential route (/admin/credential-count is a global count). Create/get/update org return an { organization } envelope; member add/update return { membership }. All unwrapped in the core layer.
  • Paging: GET /admin/users has no server-side paging, so --limit/--offset slice the returned list client-side and the footer reports showing X-Y of total.
  • Step-up: prepare-device-replacement also requires a step-up session (requireStepUp), which the CLI cannot establish yet. A 401/403 there is surfaced as a clear "requires an elevated step-up admin session, use the dashboard" message rather than a generic error.
  • Permissions: every verb maps 403 to a clear permission error via a shared reporter.

Structure

  • src/core/admin.ts: all admin network functions (listUsers, deleteUser, getUserDetail, prepareDeviceReplacement, listOrgs, createOrg, getOrg, updateOrg, listMembers, addMember, updateMember, removeMember), AdminApiError, reusing PermissionError.
  • src/commands/users.ts, src/commands/org.ts, and a small shared adminShared.ts (error reporter + comma-list parser).

Tests / verification

  • npm run build (tsc strict): passing.
  • npm test (vitest): 81 passing (12 new): users list/delete (body userId)/404, credentials from detail, device-replacement step-up handling, 403 to PermissionError, org list/create/update envelope unwrap, member list/add/update/remove with encoded paths, and org 404.
  • Smoke-tested dispatch, unknown-subcommand usage, not-logged-in handling, and help output.

Live end-to-end (admin login, then drive these) fits as a conformance spec under #47, now unblocked by the Node 24 Dockerfile fix (#50).

Acceptance criteria

  • An admin can list and manage users and organizations from the CLI.
  • A non-admin user receives a clear permission error.

Closes #46

Add terminal access to the instance admin endpoints. seamless users covers list
(with client-side --limit/--offset paging and --json), delete <id> (with
confirmation, via the DELETE /admin/users body userId), credentials <id> (from
the GET /admin/users/:id detail response), and prepare-device-replacement <id>
for admin-assisted recovery. seamless org covers list, create, get, and update,
and seamless org members covers list, add (by --user id or --email, with
--roles/--scopes), update, and remove (with confirmation).

Every command surfaces a 403 as a clear permission error, and device
replacement explains the step-up requirement when the session is not elevated.
The network layer lives in core/admin.ts and is unit tested against an injected
client; commands/users.ts and commands/org.ts are the front ends. Accepts
--profile and honors SEAMLESS_PROFILE.

Closes #46
@Bccorb
Bccorb merged commit 335e4cd into main Jul 14, 2026
1 check failed
@Bccorb
Bccorb deleted the feat/admin-verbs branch July 14, 2026 11:40
Bccorb added a commit that referenced this pull request Jul 17, 2026
feat(admin): users and organizations admin verbs
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.

Admin verbs: users and organizations

1 participant