mirror of
https://github.com/block/buzz.git
synced 2026-08-18 06:50:31 +02:00
Add a NIP-98 client for the /api/admin/v1 relay API, surfaced as an "Admin console" section in Settings. Relay operators view deployment-wide moderation reports and product feedback, resolve/dismiss reports, update feedback status, and manage the operator/moderator staffing roster — no browser extension or bearer token required. The console auto-discovers the relay's admin origin from its NIP-11 document (admin_api field): on mount it fetches the connected relay's relay-information document, validates the advertised origin through AdminOrigin::parse, and auto-probes. The manual origin field remains as a pre-filled fallback for relays that do not advertise. Rust: - AdminOrigin value object: validates scheme+host+optional-port, rejects credentials/path/query/fragment; http:// only for loopback hosts - AdminRoute closed enum: no IPC surface accepts arbitrary URLs or paths; the signed URL is byte-identical to the fetched URL - Dedicated no-redirect reqwest client (SSRF guard: relay 3xx surfaced as error, NIP-98 header never forwarded across origins) - admin_probe: typed state enum (Nip98Authorized/Denied, TokenMode, Disabled, NotAdminApi, NetworkOrIntercepted); Nip98Authorized only on authenticated 2xx - NIP-11 admin-origin discovery command; advertised value treated as untrusted input and revalidated before use - NIP-98 signing via AppState::signing_keys() (Err in recovery mode); one retry on 401 with a fresh event - Response bounds enforced by Content-Length preflight and streaming byte counter; per-pubkey origin storage (atomic write, 0o600) TypeScript: - admin-console API wrappers for all Tauri commands; attachments return a Blob URL from caller-supplied MIME - AdminConsoleSettingsCard: auto-discovery + probe flow, per-pubkey state, honest copy for every probe state - AdminConsolePanel with Reports / Feedback / Staffing tabs - Settings panels split under the file-size ratchet Co-authored-by: Will Pfleger <pfleger.will@gmail.com> Signed-off-by: Will Pfleger <pfleger.will@gmail.com>
49 lines
1.9 KiB
JavaScript
49 lines
1.9 KiB
JavaScript
import path from "node:path";
|
|
import { fileURLToPath } from "node:url";
|
|
import { runPubkeyTruncationCheck } from "../../scripts/check-pubkey-truncation-core.mjs";
|
|
|
|
const __dirname = path.dirname(fileURLToPath(import.meta.url));
|
|
const projectRoot = path.resolve(__dirname, "..");
|
|
|
|
// Truncated pubkey prefixes are forgeable (vanity grinding), so all display
|
|
// truncation goes through the canonical `truncatePubkey` / `<PubKey>` — this
|
|
// guard keeps ad-hoc `pubkey.slice(0, N)` forms from fragmenting again.
|
|
const rules = [
|
|
{
|
|
root: "src",
|
|
extensions: new Set([".ts", ".tsx"]),
|
|
},
|
|
];
|
|
|
|
// Non-display uses: array windows over pubkey lists, color/initials
|
|
// derivation where the value is never presented as an identity.
|
|
const overrides = new Set([
|
|
// HexAvatar: 6-char badge + hue derivation inside a color-coded disc,
|
|
// clearly decorative (paired with a full truncatePubkey aria-label).
|
|
"src/features/huddle/components/ParticipantList.tsx:150",
|
|
"src/features/huddle/components/ParticipantList.tsx:151",
|
|
// clientId (not a pubkey) sliced in a debug log next to the real thing.
|
|
"src/features/channels/readState/readStateManager.ts:338",
|
|
// Array windows (first N pubkeys), not string truncation.
|
|
"src/features/messages/lib/threadPanel.ts:395",
|
|
"src/features/projects/ui/ProjectsView.tsx:166",
|
|
"src/features/projects/ui/ProjectsOverviewPanel.tsx:209",
|
|
// Error message prefix in a console-internal action error (never rendered as identity).
|
|
"src/features/admin-console/AdminConsoleStaffingTab.tsx:108",
|
|
]);
|
|
|
|
await runPubkeyTruncationCheck({
|
|
projectRoot,
|
|
rules,
|
|
overrides,
|
|
allowedFiles: new Set([
|
|
// The canonical helper itself.
|
|
"src/shared/lib/pubkey.ts",
|
|
// E2E mock bridge fabricates ids/nsecs from pubkeys; nothing here is a
|
|
// user-facing identity display.
|
|
"src/testing/e2eBridge.ts",
|
|
]),
|
|
label: "Desktop",
|
|
scriptPath: "desktop/scripts/check-pubkey-truncation.mjs",
|
|
});
|