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>
16 lines
584 B
TypeScript
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.",
|
|
);
|
|
};
|