Chat file attachments, stage 1: protocol + data model + pure seams
First slice of in-chat file/photo sharing (dedicated file plane, images inline + file chips, session-only). This stage adds the wire types and the pure, unit-tested logic; no transport or UI yet. - protocol: new FILES_ALPN / FILES_PROTO (peerspeak/files/1) for the dedicated file-transfer plane. Bump GOSSIP_PROTO 1->2 + sig domain v2 (Chat gained an attachment field, so cross-version peers fail fast rather than half-work) and Cargo 0.2.0 -> 0.3.0 per VERSIONING.md. BREAKING wire change: all peers must run >= 0.3.0. - new src/files.rs: ChatAttachment descriptor (name/size/kind/id; bytes travel off-gossip), AttachmentKind, plus pure seams — sanitize_filename (path-traversal/control-char/length-safe), size_within_cap, image magic-byte sniffing + defensive limited decode (decode-bomb guard), 32-byte request parsing, human_size. 13 unit tests. - GossipMessage::Chat and RoomEvent::ChatMessage carry an optional ChatAttachment; send_chat takes Option<ChatAttachment>. Untrusted inbound descriptors are filename-sanitized + size-validated on ingest. serde(default) keeps the field forward-compatible at the JSON layer; +round-trip and pre-v2 back-compat tests. The attachment id is a random 32-byte handle (rand, already a dep), not a content hash — the fetch is authenticated + encrypted + member-gated, so no crypto-hash dep is needed. 349 lib tests pass, clippy clean. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
+1
-1
@@ -1,6 +1,6 @@
|
||||
[package]
|
||||
name = "peerspeak"
|
||||
version = "0.2.0"
|
||||
version = "0.3.0"
|
||||
edition = "2024"
|
||||
# Application crate, not a crates.io library — refuse `cargo publish` and let
|
||||
# cargo-deny's [licenses.private] skip the missing-license check.
|
||||
|
||||
Reference in New Issue
Block a user