Add keep overview command and a docker-compose deploy wrapper
All checks were successful
Docker / build-and-push (push) Successful in 1m57s
All checks were successful
Docker / build-and-push (push) Successful in 1m57s
keep overview gives an admin a cross-vault view of every recipient and grant in one screen, instead of walking vaults one at a time via /vaults/:key/recipients. scripts/deploy.sh pulls a project's env from keep before running docker compose up, for VPS deploys of several docker-compose projects. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
This commit is contained in:
@@ -1,6 +1,6 @@
|
||||
import { Router } from 'express';
|
||||
import { randomBytes } from 'node:crypto';
|
||||
import { listRecipients, createRecipient, deleteRecipient, deleteGrant, getAccessLog, logAccess } from './db.js';
|
||||
import { listRecipients, createRecipient, deleteRecipient, deleteGrant, getAccessLog, logAccess, listVaults, listGrantsForVault } from './db.js';
|
||||
import { requireAdminAuth } from './auth.js';
|
||||
|
||||
export const router = Router();
|
||||
@@ -45,3 +45,26 @@ router.delete('/vaults/:key/grants/:recipientId', (req, res) => {
|
||||
router.get('/vaults/:key/log', (req, res) => {
|
||||
res.json(getAccessLog(req.params.key));
|
||||
});
|
||||
|
||||
// Cross-vault view — "which things have access to what" in one call,
|
||||
// instead of walking every vault by hand with /vaults/:key/recipients
|
||||
// (which is itself grant-gated per vault, and only shows one vault at a
|
||||
// time). Admin-only since it reveals every vault's full grant list at
|
||||
// once, not just the ones the caller happens to have a grant on.
|
||||
router.get('/overview', (_req, res) => {
|
||||
const byId = new Map(listRecipients().map(r => [r.recipient_id, r]));
|
||||
const vaults = listVaults().map(v => ({
|
||||
vaultKey: v.vault_key,
|
||||
updatedAt: v.updated_at,
|
||||
updatedBy: v.updated_by,
|
||||
grants: listGrantsForVault(v.vault_key).map(g => ({
|
||||
recipientId: g.recipient_id,
|
||||
label: byId.get(g.recipient_id)?.label ?? null,
|
||||
canWrite: g.can_write === 1,
|
||||
})),
|
||||
}));
|
||||
res.json({
|
||||
recipients: listRecipients().map(r => ({ recipientId: r.recipient_id, label: r.label, publicKey: r.public_key, createdAt: r.created_at })),
|
||||
vaults,
|
||||
});
|
||||
});
|
||||
|
||||
@@ -206,6 +206,12 @@ export function listGrantsForVault(vaultKey: string): GrantRow[] {
|
||||
return db.prepare(`SELECT * FROM vault_grants WHERE vault_key = ?`).all(vaultKey) as GrantRow[];
|
||||
}
|
||||
|
||||
export function listVaults(): { vault_key: string; updated_at: number; updated_by: string }[] {
|
||||
return db.prepare(`SELECT vault_key, updated_at, updated_by FROM vaults ORDER BY vault_key`).all() as {
|
||||
vault_key: string; updated_at: number; updated_by: string;
|
||||
}[];
|
||||
}
|
||||
|
||||
export function setGrant(vaultKey: string, recipientId: string, wrappedKeyB64: string, canWrite: boolean): void {
|
||||
db.prepare(
|
||||
`INSERT INTO vault_grants (vault_key, recipient_id, wrapped_key, can_write, granted_at)
|
||||
|
||||
Reference in New Issue
Block a user