fix(cli): accept generic uploads, surface message edits, list DMs - #2781
JQuantAnalytics wants to merge 2 commits into
Conversation
Align buzz-cli with relay/desktop behavior so smoke quirks stop looking like nest misconfig: deny-list MIME for uploads (text/docs), overlay kind:40003 edits in get/thread and search edits, and list DMs via membership metadata instead of obsolete kind 41001. Co-authored-by: Cursor <cursoragent@cursor.com> Co-authored-by: jquant <115501859+JQuantAnalytics@users.noreply.github.com> Signed-off-by: jquant <115501859+JQuantAnalytics@users.noreply.github.com>
Fresh-install allowlist omitted message edits, so NIP-50 search could not find post-edit text even when the CLI requested kind 40003. Expand the allowlist via migration 0025, update the maintenance script, and overlay edit hits onto their target messages in `messages search`. Co-authored-by: Cursor <cursoragent@cursor.com> Co-authored-by: jquant <115501859+JQuantAnalytics@users.noreply.github.com> Signed-off-by: jquant <115501859+JQuantAnalytics@users.noreply.github.com>
|
The message-edit part of this PR overlays a kind In It is also a suppression primitive, because the ranking runs before any validation: an attacker who publishes an edit with a The fix is a gate in the first loop, before the entry is inserted — not a check on the winner afterwards. Resolve target authors in a pass over the non-edit events first, then skip any edit whose let mut target_pubkeys: HashMap<&str, &str> = HashMap::new();
for e in events {
if is_edit(e) { continue; }
if let (Some(id), Some(pk)) = (id_of(e), pubkey_of(e)) {
target_pubkeys.insert(id, pk);
}
}
for e in events {
if !is_edit(e) { continue; }
let Some(target_id) = first_e_tag_id(e) else { continue };
// Author gate must run before ranking, or a forged edit wins the slot
// and suppresses the genuine one.
if target_pubkeys.get(target_id) != pubkey_of(e).as_ref() { continue; }
// ... rank by (created_at, id)
}Placing the check after winner selection looks equivalent and is not: it is only equivalent when exactly one edit exists for a target, which is the case most test fixtures cover. A three-event fixture — target(author), edit(author, t=2000), edit(other, t=3000) — distinguishes them. With the gate after ranking, that case renders the original content; with the gate before ranking, it renders the author's edit. Worth adding as a test case either way. Same argument applies to |
Summary
application/octet-stream(HTML/SVG/executables still blocked).messages get/threadoverlay the latest kind40003edit onto the original (and hide raw edit rows by default);messages searchincludes40003, resolves edit hits to overlaid originals, and migration0025adds40003to the fresh-install FTS allowlist so edited text is indexed.dms listno longer queries obsolete kind41001; it lists membership + kind39000channels taggedt=dm(matches Desktop).Context
Found during nest setup smoke on a fresh Buzz community: text upload failed client-side even though the relay already accepts generic files; edits succeeded but CLI reads looked stale; search missed edited bodies because the FTS allowlist omitted kind
40003;dms openworked butdms liststayed empty.Test plan
cargo test -p buzz-cli --lib upload_mime_cargo test -p buzz-cli --lib apply_message_editscargo test -p buzz-db --lib embedded_migrator_contains_consolidated_initial_schemadms listreturns seeded DM;messages getshows overlaid edit body0025:buzz messages search --query "<edited text>"hitsbuzz upload file --file note.txt/dms list/ edit overlay