diff options
Diffstat (limited to 'src/concord.js')
| -rw-r--r-- | src/concord.js | 25 |
1 files changed, 25 insertions, 0 deletions
diff --git a/src/concord.js b/src/concord.js index 63a83b9..521bfc8 100644 --- a/src/concord.js +++ b/src/concord.js @@ -187,6 +187,11 @@ export const foldControl = (entries, { ownerHex, cid }) => { // entries: [{ rumor, author }] โ group by (vsk, eid), take highest intact version let byEntity = new Map(); for (let e of entries) { + // Only the owner's editions are honored below, so only they compete for + // a head: anyone holding the control stream's key (every member of a + // public community) could otherwise sign a higher version and blank the + // owner's ban list, name or channels. + if (e.author !== ownerHex) continue; let tag = (k) => e.rumor.tags?.find((t) => t[0] === k)?.[1]; let vsk = tag("vsk"), eid = tag("eid"), ev = +tag("ev"); if (vsk === undefined || !eid || !(ev >= 1)) continue; @@ -225,6 +230,26 @@ export const foldControl = (entries, { ownerHex, cid }) => { return state; }; +// The owner's ban list as it stands: the head edition (its version, and the +// hash a successor chains to) and the keys on it. Same winner as the fold. +export const banlistHead = (entries, { ownerHex, cid }) => { + let eid = banlistEid(cid), cur = null; + for (let e of entries) { + if (e.author !== ownerHex || e.rumor.kind !== 3308) continue; + let tag = (k) => e.rumor.tags?.find((t) => t[0] === k)?.[1]; + let ev = +tag("ev"); + if (tag("vsk") !== "4" || tag("eid") !== eid || !(ev >= 1)) continue; + if (!cur || ev > cur.ev || (ev === cur.ev && e.rumor.id < cur.id)) cur = { ev, id: e.rumor.id, ep: tag("ep") || null, content: e.rumor.content }; + } + let list = []; + try { let c = cur && JSON.parse(cur.content); if (Array.isArray(c)) list = c.filter((x) => /^[0-9a-f]{64}$/.test(x)); } catch {} + return { eid, version: cur ? cur.ev : 0, hash: cur ? editionHash(eid, cur.ev, cur.ep, cur.content) : null, list }; +}; + +// The next ban-list edition: `list` replaces the one that stands. +export const makeBanlist = (head, list, nowMs) => + makeEdition({ vsk: 4, eid: head.eid, version: head.version + 1, prev: head.hash || undefined, content: JSON.stringify(list) }, nowMs); + // ---- CORD-02 ยง5 guestbook fold ---- // entries: [{ rumor, author }], returns Map(npub -> { state: 'join'|'leave'|'kick', t }) export const foldGuestbook = (entries, { nowMs, banned = new Set(), ownerHex } = {}) => { |
