/** * Patch: swarm-loc-guard * * Only accept OwnYourSwarm Micropub posts that contain the text "Loc" * in their content. Check-ins without "Loc" are rejected with 422. * * Workflow: Sven adds "Loc" to Swarm check-ins he wants published. * Check-ins without that text (stealth, accidental, no-content) are rejected. */ import { readFile, writeFile, access } from "node:fs/promises"; const MARKER = "// [patch] swarm-loc-guard"; const candidates = [ "node_modules/@indiekit/endpoint-micropub/lib/post-data.js", "node_modules/@indiekit/indiekit/node_modules/@indiekit/endpoint-micropub/lib/post-data.js", ]; const oldSnippet = ` if ( type === "note" && (hasCheckinProperty || hasSwarmSyndication) ) { properties.visibility = "unlisted"; }`; const newSnippet = ` if ( type === "note" && (hasCheckinProperty || hasSwarmSyndication) ) { // Guard: only accept OwnYourSwarm posts that contain "Loc" in content. ${MARKER} // Extract raw text before normaliseProperties converts content to {html,text} object. // After normalisation, String(properties.content) yields "[object Object]" — not useful. // We read .text/.html from the normalised object, then fall back to raw string. const rawContent = (() => { const c = properties.content; if (!c) return ""; if (typeof c === "string") return c; if (typeof c === "object") return String(c.text || c.html || ""); return String(c); })(); if (hasSwarmSyndication && !rawContent.includes("Loc")) { throw new IndiekitError("OwnYourSwarm post without 'Loc' in content rejected", { status: 422, code: "invalid_request" }); } properties.visibility = "unlisted"; }`; async function exists(path) { try { await access(path); return true; } catch { return false; } } let patched = 0; for (const filePath of candidates) { if (!(await exists(filePath))) continue; const source = await readFile(filePath, "utf8"); if (source.includes(MARKER)) { console.log(`[postinstall] swarm-loc-guard: already patched (${filePath})`); continue; } if (!source.includes(oldSnippet)) { console.log(`[postinstall] swarm-loc-guard: target snippet not found in ${filePath} — skipping`); continue; } await writeFile(filePath, source.replace(oldSnippet, newSnippet), "utf8"); console.log(`[postinstall] swarm-loc-guard: patched ${filePath}`); patched++; } if (patched === 0) { console.log("[postinstall] swarm-loc-guard: nothing patched"); }