mirror of
https://github.com/prosolis/gogobee.git
synced 2026-07-15 08:32:41 +00:00
Pete news: salted per-event GUID token + zone_clear taxonomy
Closes the two deferred code-review follow-ups on the adventure-news seam, plus folds in two pre-committed WIP fixes. A. Privacy — the public GUID no longer leaks a stable per-player id. Replaced userHash(userID)=sha256(userID)[:6] with eventToken(userID, discriminator)=HMAC-SHA256(salt, userID‖disc). The salt is 32 random bytes, auto-generated once and persisted in the durable news_config table (cached via sync.Once). Because each event uses a distinct HMAC message, tokens are a PRF output and are BOTH uncomputable from a Matrix handle (no enumeration of a player's events, incl. ones anonymized after !news optout) AND mutually unlinkable (a named event can't be walked back to a player's other, anonymized events). Updated all emit sites: pete.go zone, dnd_combat death, adventure_duel rival, dnd_setup arrival, achievements milestone, bootstrap x3. B. Taxonomy — repeat zone clears were mislabeled zone_first. Now emit zone_clear (bulletin) vs zone_first (realm-first, priority). Adopted the invariant GUID-prefix == event_type, which also fixes latent permalink mislabels (achv->milestone, rival->rival_result rendered a neutral "Dispatch" on their permalink pages). Folded-in WIP fixes: create the news_config table b42beec's newsEmissionOn reads but never created; reap sent pete_emit_queue rows in RunMaintenance; don't burn a retry attempt when shutdown cancels an in-flight send. Tests: TestEventToken (salted/stable/per-event/persisted), TestEmitZoneClearTaxonomy (first->zone_first, repeat->zone_clear), updated pete_test.go prefixes. Full internal suite + vet green. Unshipped. Deploy Pete first (it must know zone_clear), then gogobee.
This commit is contained in:
@@ -616,6 +616,10 @@ func RunMaintenance() {
|
||||
{"urban_cache", `DELETE FROM urban_cache WHERE cached_at < ?`, []interface{}{cutoff30d}},
|
||||
{"url_cache", `DELETE FROM url_cache WHERE cached_at < ?`, []interface{}{cutoff30d}},
|
||||
|
||||
// Pete adventure-news queue — reap delivered rows (kept only for
|
||||
// idempotency); undelivered rows stay so the sender can retry/park them.
|
||||
{"pete_emit_queue", `DELETE FROM pete_emit_queue WHERE sent_at IS NOT NULL AND sent_at < ?`, []interface{}{cutoff7d}},
|
||||
|
||||
// Rate limits — purge entries older than today
|
||||
{"rate_limits", `DELETE FROM rate_limits WHERE date < ?`, []interface{}{today}},
|
||||
|
||||
@@ -979,6 +983,14 @@ CREATE TABLE IF NOT EXISTS news_realm_firsts (
|
||||
PRIMARY KEY (kind, target)
|
||||
);
|
||||
|
||||
-- Durable runtime config for adventure news (e.g. the emission kill-switch).
|
||||
-- Deliberately NOT stored in api_cache: RunMaintenance prunes that table after
|
||||
-- 7 days, which would silently revert an operator's !news off back to on.
|
||||
CREATE TABLE IF NOT EXISTS news_config (
|
||||
key TEXT PRIMARY KEY,
|
||||
value TEXT NOT NULL
|
||||
);
|
||||
|
||||
-- Birthdays
|
||||
CREATE TABLE IF NOT EXISTS birthdays (
|
||||
user_id TEXT PRIMARY KEY,
|
||||
|
||||
Reference in New Issue
Block a user