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>
16 lines
583 B
JavaScript
16 lines
583 B
JavaScript
// Install jsdom globals before any test module (including React) is evaluated.
|
|
// This ensures React's canUseDOM = true so isInputEventSupported is set correctly.
|
|
import { JSDOM } from "jsdom";
|
|
const dom = new JSDOM("<!DOCTYPE html>", { url: "http://localhost" });
|
|
const jsdomWindow = dom.window;
|
|
globalThis.window = jsdomWindow;
|
|
globalThis.document = jsdomWindow.document;
|
|
for (const key of Object.getOwnPropertyNames(jsdomWindow)) {
|
|
if (!(key in globalThis)) {
|
|
try {
|
|
globalThis[key] = jsdomWindow[key];
|
|
} catch {}
|
|
}
|
|
}
|
|
globalThis.IS_REACT_ACT_ENVIRONMENT = true;
|