import type { Event } from "nostr-tools"; export function getGitCommitHash() { try { const { stdout } = Bun.spawnSync({ cmd: ["git", "rev-parse", "HEAD"], stdout: "pipe", stderr: "pipe", }); const out = stdout?.toString()?.trim(); return out?.split("\n")[0] || "unknown"; } catch { return "unknown"; } } export async function validateAuthEvent( event: Event, challenge: string, ): Promise { if (event.kind !== 22242) return false; const last30Seconds = Math.floor(Date.now() / 1000) - 30; if (event.created_at < last30Seconds) return false; const challengeTag = event.tags.find((tag) => tag[0] === "challenge")?.[1]; if (challengeTag !== challenge) return false; if(!await isPubkeyAllowed(event)) return false; return await isKindAllowed(event); } export async function isPubkeyAllowed(event: Event): Promise { const file = Bun.file("./allowed-pubkeys.json"); if (!(await file.exists())) return true; try { const allowedPubkeys = JSON.parse(await file.text()); return ( Array.isArray(allowedPubkeys) && allowedPubkeys.includes(event.pubkey) ); } catch { // If the file is malformed, default to deny return false; } } export async function getAllAllowedPubkeys() { const file = Bun.file("./allowed-pubkeys.json"); try { if (await file.exists()) return JSON.parse(await file.text()); } catch {} return [] as string[]; } export async function saveAllowedPubkeys(pubkeys: string[]): Promise { const file = Bun.file("./allowed-pubkeys.json"); const unique = Array.from(new Set(pubkeys)); return await file.write(JSON.stringify(unique)); } export async function allowPubkey(pubkey: string): Promise { const pubkeys = await getAllAllowedPubkeys(); if (!pubkeys.includes(pubkey)) pubkeys.push(pubkey); return await saveAllowedPubkeys(pubkeys); } export async function banPubkey(pubkey: string): Promise { const pubkeys = await getAllAllowedPubkeys(); const filtered = pubkeys.filter((p: string) => p !== pubkey); return await saveAllowedPubkeys(filtered); } export async function isKindAllowed(event: Event): Promise { const file = Bun.file("./allowed-kinds.json"); if (!(await file.exists())) return true; try { const allowedKinds = JSON.parse(await file.text()); if(!Array.isArray(allowedKinds)) return true; if(allowedKinds.length === 0) return true; return ( Array.isArray(allowedKinds) && allowedKinds.includes(event.kind) ); } catch { // If the file is malformed, default to allow return true; } } export async function getAllAllowedKinds(): Promise { const file = Bun.file("./allowed-kinds.json"); try { if (await file.exists()) return JSON.parse(await file.text()); } catch {} return [] as number[]; } export async function saveAllowedKinds(kinds: number[]): Promise { const file = Bun.file("./allowed-kinds.json"); const unique = Array.from(new Set(kinds)); return await file.write(JSON.stringify(unique)); } export async function allowKind(kind: number): Promise { const kinds = await getAllAllowedKinds(); if (!kinds.includes(kind)) kinds.push(kind); return await saveAllowedKinds(kinds); } export async function disallowKind(kind: number): Promise { const kinds = await getAllAllowedKinds(); const filtered = kinds.filter((p: number) => p !== kind); return await saveAllowedKinds(filtered); }