Files
keep/src/cli/commands/recipient.ts
Fredrik Johansson 5f31eb76c7 overview: show when each vault was last updated, and by whom
Was silently dropping updatedAt/updatedBy even though the server
already returned them — the CLI just never printed them. Also
resolves updatedBy to the recipient's label server-side (matching how
grants already show a label alongside the recipient id) instead of
printing a bare recipient_id.

Verified against a live server: overview now prints "demo/production
(updated <iso timestamp> by test-box)" instead of omitting that line
entirely.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-07-12 20:30:02 +02:00

42 lines
1.8 KiB
TypeScript

import { adminFetch, expectOk } from '../signedFetch.js';
export async function recipientAdd(label: string, publicKey: string): Promise<void> {
const data = await expectOk(await adminFetch('POST', '/api/admin/recipients', { label, publicKey }));
console.log(`recipient created: ${data.recipientId}`);
console.log(`Give this id back to whoever owns this identity — they set it with 'keep identity set-id ${data.recipientId}'.`);
}
export async function recipientList(): Promise<void> {
const data = await expectOk(await adminFetch('GET', '/api/admin/recipients'));
if (!data.length) { console.log('no recipients yet.'); return; }
for (const r of data) {
console.log(`${r.recipientId} ${r.label} ${r.publicKey.slice(0, 16)}`);
}
}
export async function recipientRemove(recipientId: string): Promise<void> {
await expectOk(await adminFetch('DELETE', `/api/admin/recipients/${encodeURIComponent(recipientId)}`));
console.log(`recipient removed: ${recipientId} (and all their vault grants)`);
}
export async function adminOverview(): Promise<void> {
const data = await expectOk(await adminFetch('GET', '/api/admin/overview'));
console.log('recipients:');
if (!data.recipients.length) console.log(' none yet.');
for (const r of data.recipients) {
console.log(` ${r.recipientId} ${r.label}`);
}
console.log('\nvaults:');
if (!data.vaults.length) console.log(' none yet.');
for (const v of data.vaults) {
const updated = v.updatedAt ? new Date(v.updatedAt * 1000).toISOString() : 'unknown';
const by = v.updatedByLabel ?? v.updatedBy ?? 'unknown';
console.log(` ${v.vaultKey} (updated ${updated} by ${by})`);
for (const g of v.grants) {
console.log(` ${g.canWrite ? 'rw' : 'r-'} ${g.recipientId} ${g.label ?? '(unknown recipient)'}`);
}
}
}