import type { Command } from "commander"; import { getStoredBoardCredential, loginBoardCli, removeStoredBoardCredential, revokeStoredBoardCredential, } from "../../client/board-auth.js"; import { addCommonClientOptions, handleCommandError, printOutput, resolveCommandContext, type BaseClientOptions, } from "./common.js"; interface AuthLoginOptions extends BaseClientOptions { instanceAdmin?: boolean; } interface AuthLogoutOptions extends BaseClientOptions {} interface AuthWhoamiOptions extends BaseClientOptions {} export function registerClientAuthCommands(auth: Command): void { addCommonClientOptions( auth .command("login") .description("Authenticate the CLI for board-user access") .option("--instance-admin", "Request instance-admin approval instead of plain board access", false) .action(async (opts: AuthLoginOptions) => { try { const ctx = resolveCommandContext(opts); const login = await loginBoardCli({ apiBase: ctx.api.apiBase, requestedAccess: opts.instanceAdmin ? "instance_admin_required" : "board", requestedCompanyId: ctx.companyId ?? null, command: "paperclipai auth login", }); printOutput( { ok: true, apiBase: ctx.api.apiBase, userId: login.userId ?? null, approvalUrl: login.approvalUrl, }, { json: ctx.json }, ); } catch (err) { handleCommandError(err); } }), { includeCompany: true }, ); addCommonClientOptions( auth .command("logout") .description("Remove the stored board-user credential for this API base") .action(async (opts: AuthLogoutOptions) => { try { const ctx = resolveCommandContext(opts); const credential = getStoredBoardCredential(ctx.api.apiBase); if (!credential) { printOutput({ ok: true, apiBase: ctx.api.apiBase, revoked: false, removedLocalCredential: false }, { json: ctx.json }); return; } let revoked = false; try { await revokeStoredBoardCredential({ apiBase: ctx.api.apiBase, token: credential.token, }); revoked = true; } catch { // Remove the local credential even if the server-side revoke fails. } const removedLocalCredential = removeStoredBoardCredential(ctx.api.apiBase); printOutput( { ok: true, apiBase: ctx.api.apiBase, revoked, removedLocalCredential, }, { json: ctx.json }, ); } catch (err) { handleCommandError(err); } }), ); addCommonClientOptions( auth .command("whoami") .description("Show the current board-user identity for this API base") .action(async (opts: AuthWhoamiOptions) => { try { const ctx = resolveCommandContext(opts); const me = await ctx.api.get<{ user: { id: string; name: string; email: string } | null; userId: string; isInstanceAdmin: boolean; companyIds: string[]; source: string; keyId: string | null; }>("/api/cli-auth/me"); printOutput(me, { json: ctx.json }); } catch (err) { handleCommandError(err); } }), ); }