Jason Tudisco 41f66ae366 feat(kez-chat/web): in-browser claim verification with per-channel plugins
Plugin layout (one file per channel — easy to extend):
  lib/verifiers/{dns,web,github,nostr,bluesky,ap}.ts
  lib/verifiers/types.ts   — VerifyResult + ok/fail/skipped builders
  lib/verify.ts            — dispatcher routing on claim.channel

Live verifiers (browser-native, no CORS proxy):
  • DNS     — Cloudflare DoH /dns-query, TXT at _kez.<domain>
  • web     — fetch <base>/.well-known/kez.json
  • github  — public gists API for kez.md + <user>/<user> README

Deferred to v0.2 (stubs return "skipped" with a hint):
  • nostr   — needs ws relay pool + NIP-19
  • bluesky — needs AT-Proto client
  • ap      — WebFinger CORS hostile from browsers

Verification flow (all channels):
  1. Fetch the published artifact via the channel's transport
  2. parseAnyEnvelope() handles kez:z1: compact, ```kez fences, or raw
  3. Check subject + primary against the stored claim
  4. Re-canonicalize payload (JCS) and verify ed25519 signature

UI changes on /claims:
  • Status badge per claim: ✓ Verified / ✗ Failed / — Skipped / Not verified
  • Per-claim "Verify" button + a "Verify all" button at the top
  • Expandable details panel showing the evidence URL and any error info
  • Latest result persists in IndexedDB (with $state.snapshot for cloning)

kez.ts gains verifyEnvelope() and parseAnyEnvelope() — also useful to
any future verifier (CLI, sig-server, third-party).

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-05-25 13:40:07 -06:00

16 lines
584 B
TypeScript

// ActivityPub channel verifier — v0.2.
//
// WebFinger → actor JSON → look for the kez fence in `summary` or
// `attachment[].value`. Most fediverse instances do not send CORS
// headers on /.well-known/webfinger, so verifying from the browser
// would require a server-side proxy. Deferred.
import { skipped, type Verifier } from "./types.js";
export const verifyAp: Verifier = async () => {
return skipped(
"ActivityPub verification is coming in v0.2",
"WebFinger lookups require a server-side proxy (CORS). You can still publish the artifact manually.",
);
};