From 4378c4c0cc87a613bbdace3cc6884d83d8c4c636 Mon Sep 17 00:00:00 2001 From: KeelrLeek <156356974+KeelrLeek@users.noreply.github.com> Date: Wed, 2 Sep 2026 15:26:30 -0500 Subject: [PATCH] community: the encrypted inbox, friend requests and shares travel sealed to a box key when the other side has published one --- Cargo.lock | 110 +++++ crates/persona-state/Cargo.toml | 2 + crates/persona-state/src/inbox.rs | 468 ++++++++++++++++++++++ crates/persona-state/src/lib.rs | 1 + src-tauri/assets/inbox_contract.wasm | Bin 0 -> 245327 bytes src-tauri/assets/inbox_desc_contract.wasm | Bin 0 -> 175902 bytes src-tauri/src/friends.rs | 315 +++++++++------ src-tauri/src/inbox.rs | 443 ++++++++++++++++++++ src-tauri/src/lib.rs | 5 + src-tauri/src/shared_playlists.rs | 93 ++++- src-tauri/src/slsk_link.rs | 16 + src/lib/api.js | 4 + src/lib/community.svelte.js | 34 +- src/views/Community.svelte | 41 +- 14 files changed, 1387 insertions(+), 145 deletions(-) create mode 100644 crates/persona-state/src/inbox.rs create mode 100644 src-tauri/assets/inbox_contract.wasm create mode 100644 src-tauri/assets/inbox_desc_contract.wasm create mode 100644 src-tauri/src/inbox.rs diff --git a/Cargo.lock b/Cargo.lock index f8b6cb0..4b0eb16 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -8,6 +8,16 @@ version = "2.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "320119579fcad9c21884f5c4861d16174d0e06250625266f50fe6898340abefa" +[[package]] +name = "aead" +version = "0.5.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d122413f284cf2d62fb1b7db97e02edb8cda96d769b16e443a4f6195e35662b0" +dependencies = [ + "crypto-common 0.1.7", + "generic-array", +] + [[package]] name = "ahash" version = "0.8.12" @@ -512,6 +522,30 @@ version = "1.0.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9330f8b2ff13f34540b44e946ef35111825727b38d33286ef986142615121801" +[[package]] +name = "chacha20" +version = "0.9.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c3613f74bd2eac03dad61bd53dbe620703d4371614fe0bc3b9f04dd36fe4e818" +dependencies = [ + "cfg-if", + "cipher", + "cpufeatures 0.2.17", +] + +[[package]] +name = "chacha20poly1305" +version = "0.10.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "10cd79432192d1c0f4e1a0fef9527696cc039165d729fb41b3f4f4f354c2dc35" +dependencies = [ + "aead", + "chacha20", + "cipher", + "poly1305", + "zeroize", +] + [[package]] name = "chrono" version = "0.4.45" @@ -524,6 +558,17 @@ dependencies = [ "windows-link 0.2.1", ] +[[package]] +name = "cipher" +version = "0.4.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "773f3b9af64447d2ce9850330c473515014aa235e6a783b02db81ff39e4a3dad" +dependencies = [ + "crypto-common 0.1.7", + "inout", + "zeroize", +] + [[package]] name = "cmov" version = "0.5.4" @@ -726,6 +771,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "78c8292055d1c1df0cce5d180393dc8cce0abec0a7102adb6c7b1eef6016d60a" dependencies = [ "generic-array", + "rand_core 0.6.4", "typenum", ] @@ -2230,6 +2276,15 @@ dependencies = [ "cfb", ] +[[package]] +name = "inout" +version = "0.1.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "879f10e63c20629ecabbb64a8010319738c66a5cd0c29b02d63d272b03751d01" +dependencies = [ + "generic-array", +] + [[package]] name = "ipnet" version = "2.12.1" @@ -3121,6 +3176,12 @@ version = "1.70.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "384b8ab6d37215f3c5301a95a4accb5d64aa607f1fcb26a11b5303878451b4fe" +[[package]] +name = "opaque-debug" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c08d65885ee38876c4f86fa503fb49d7b507c2b62552df7c70b2fce627e06381" + [[package]] name = "openssl" version = "0.10.81" @@ -3236,8 +3297,10 @@ version = "1.6.0-alpha" dependencies = [ "bincode", "blake3", + "chacha20poly1305", "ed25519-dalek", "serde", + "x25519-dalek", ] [[package]] @@ -3367,6 +3430,17 @@ dependencies = [ "miniz_oxide 0.8.9", ] +[[package]] +name = "poly1305" +version = "0.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8159bd90725d2df49889a078b54f4f79e87f1f8a8444194cdca81d38f5393abf" +dependencies = [ + "cpufeatures 0.2.17", + "opaque-debug", + "universal-hash", +] + [[package]] name = "portable-atomic" version = "1.15.0" @@ -5653,6 +5727,16 @@ version = "1.13.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c6f5d3c3b1bf09027a88a6bc961fc00497d651009560b5463668dc81b0fa87a8" +[[package]] +name = "universal-hash" +version = "0.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fc1de2c688dc15305988b563c3854064043356019f97a4b46276fe734c4f07ea" +dependencies = [ + "crypto-common 0.1.7", + "subtle", +] + [[package]] name = "untrusted" version = "0.9.0" @@ -6593,6 +6677,18 @@ dependencies = [ "pkg-config", ] +[[package]] +name = "x25519-dalek" +version = "2.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c7e468321c81fb07fa7f4c636c3972b9100f0346e5b6a9f2bd0603a52f7ed277" +dependencies = [ + "curve25519-dalek", + "rand_core 0.6.4", + "serde", + "zeroize", +] + [[package]] name = "xml-rs" version = "0.8.29" @@ -6677,6 +6773,20 @@ name = "zeroize" version = "1.9.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e13c156562582aa81c60cb29407084cdb54c4164760106ab78e6c5b0858cf64e" +dependencies = [ + "zeroize_derive", +] + +[[package]] +name = "zeroize_derive" +version = "1.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3c50655cbb0fe3fc43170059e702f1ce5e19b84cec58dc87b037a09935c2f328" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.119", +] [[package]] name = "zerotrie" diff --git a/crates/persona-state/Cargo.toml b/crates/persona-state/Cargo.toml index a57de67..e084ae8 100644 --- a/crates/persona-state/Cargo.toml +++ b/crates/persona-state/Cargo.toml @@ -13,6 +13,8 @@ serde.workspace = true bincode = "1" ed25519-dalek = { version = "2", default-features = false, features = ["alloc"] } blake3 = "1" +x25519-dalek = { version = "2", features = ["static_secrets"] } +chacha20poly1305 = "0.10" [dev-dependencies] ed25519-dalek = { version = "2", features = ["rand_core"] } diff --git a/crates/persona-state/src/inbox.rs b/crates/persona-state/src/inbox.rs new file mode 100644 index 0000000..ad3dbeb --- /dev/null +++ b/crates/persona-state/src/inbox.rs @@ -0,0 +1,468 @@ +//! The invitation inbox — F5's exact shapes: recipient-addressed sealed +//! envelopes in a bounded multi-writer contract with a deterministic merge +//! (validate → dedup → caps → tombstones), an owner PruneRecord, and the +//! owner-signed InboxDescriptor that says how to reach a persona. BYTE- +//! COMPATIBILITY IS THE CONTRACT: the bundled inbox / descriptor wasm +//! validate exactly these (built from research/freenet-f5, code hashes +//! pinned by the app's tests). +//! +//! Signing rides `soulstream.friend/v1` — the delegate generation in the +//! app has no inbox domain yet (F5's deferred item); the contracts were +//! built to that. Sealing: X25519 (sender ephemeral → recipient box key) +//! into ChaCha20-Poly1305 with the signed header as AAD. + +use ed25519_dalek::VerifyingKey; +use serde::{Deserialize, Serialize}; +use std::collections::BTreeMap; + +pub const SCHEMA_VERSION: u32 = 1; +pub const INBOX_PARAMS_FAMILY: &[u8] = b"soulstream.inbox.v1"; +pub const DESC_PARAMS_FAMILY: &[u8] = b"soulstream.inbox-desc.v1"; +pub const ENVELOPE_DOMAIN: &str = "soulstream.friend/v1"; +pub const DESC_DOMAIN: &str = "soulstream.friend/v1"; + +pub const MAX_STATE_BYTES: usize = 1024 * 1024; +pub const MAX_ENVELOPES: usize = 64; +pub const PER_SENDER_CAP: usize = 4; +pub const ANON_POOL_CAP: usize = 8; +pub const MAX_CIPHERTEXT: usize = 8 * 1024; +pub const MAX_AAD: usize = 256; +pub const MAX_LIFETIME_SECS: u64 = 30 * 24 * 3600; +pub const MAX_TOMBSTONES: usize = 256; +pub const ANON_POW_BITS: u32 = 12; + +// ---------------------------------------------------------------- envelope + +#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)] +pub enum SenderClass { + Known([u8; 32]), + Anonymous, +} + +#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)] +pub struct Envelope { + pub envelope_id: [u8; 16], + pub recipient: [u8; 32], + pub sender: SenderClass, + pub created_at: u64, + pub expires_at: u64, + /// Known: empty. Anonymous: a nonce whose blake3(id ‖ nonce) carries + /// ANON_POW_BITS leading zero bits. + pub admission: Vec, + /// Sender ephemeral X25519 public key (32) ‖ ChaCha20-Poly1305 + /// ciphertext of the cargo. + pub sealed: Vec, + /// Known sender's signature over the header (delegate-signed). + pub sender_sig: Vec, +} + +#[derive(Serialize)] +struct EnvelopeHeader<'a> { + envelope_id: &'a [u8; 16], + recipient: &'a [u8; 32], + sender: &'a SenderClass, + created_at: u64, + expires_at: u64, +} + +/// The signed / authenticated header — also the AAD for the seal. +pub fn envelope_header_bytes(e: &Envelope) -> Vec { + bincode::serialize(&EnvelopeHeader { + envelope_id: &e.envelope_id, + recipient: &e.recipient, + sender: &e.sender, + created_at: e.created_at, + expires_at: e.expires_at, + }) + .expect("serializes") +} + +/// What the delegate is handed to sign for a header / prune / descriptor. +pub fn sign_payload(body: &[u8]) -> Vec { + blake3::hash(body).as_bytes().to_vec() +} + +pub fn box_key(shared_secret: &[u8; 32]) -> [u8; 32] { + blake3::derive_key("soulstream.inbox-box.v1", shared_secret) +} +pub fn box_nonce(eph_pub: &[u8; 32], envelope_id: &[u8; 16]) -> [u8; 12] { + let mut input = Vec::with_capacity(48); + input.extend_from_slice(eph_pub); + input.extend_from_slice(envelope_id); + let h = blake3::hash(&input); + h.as_bytes()[..12].try_into().unwrap() +} + +pub fn anon_admission_ok(envelope_id: &[u8; 16], admission: &[u8]) -> bool { + if admission.len() != 16 { + return false; + } + let mut input = Vec::with_capacity(32); + input.extend_from_slice(envelope_id); + input.extend_from_slice(admission); + let h = blake3::hash(&input); + let mut zeros = 0u32; + for b in h.as_bytes() { + if *b == 0 { + zeros += 8; + } else { + zeros += b.leading_zeros(); + break; + } + } + zeros >= ANON_POW_BITS +} + +#[derive(Debug, PartialEq, Eq)] +pub enum EnvelopeInvalid { + AadTooBig(usize), + CiphertextTooBig(usize), + WrongRecipient, + LifetimeInsane, + BadSenderKey, + BadSenderSig, + BadAdmission, + SealedTooShort, +} + +/// Structural + authorization validation, cheapest first. +pub fn validate_envelope(owner: &[u8; 32], e: &Envelope) -> Result<(), EnvelopeInvalid> { + if e.sealed.len() > 32 + MAX_CIPHERTEXT { + return Err(EnvelopeInvalid::CiphertextTooBig(e.sealed.len())); + } + if e.sealed.len() < 32 + 16 { + return Err(EnvelopeInvalid::SealedTooShort); + } + if e.admission.len() > MAX_AAD { + return Err(EnvelopeInvalid::AadTooBig(e.admission.len())); + } + if &e.recipient != owner { + return Err(EnvelopeInvalid::WrongRecipient); + } + if e.expires_at <= e.created_at || e.expires_at - e.created_at > MAX_LIFETIME_SECS { + return Err(EnvelopeInvalid::LifetimeInsane); + } + match &e.sender { + SenderClass::Known(key) => { + if VerifyingKey::from_bytes(key).is_err() { + return Err(EnvelopeInvalid::BadSenderKey); + } + if !crate::verify_sig_in( + ENVELOPE_DOMAIN, + key, + &sign_payload(&envelope_header_bytes(e)), + &e.sender_sig, + ) { + return Err(EnvelopeInvalid::BadSenderSig); + } + } + SenderClass::Anonymous => { + if !anon_admission_ok(&e.envelope_id, &e.admission) { + return Err(EnvelopeInvalid::BadAdmission); + } + } + } + Ok(()) +} + +// ---------------------------------------------------------------- sealing + +/// Seal `cargo` to a recipient's box key. `eph_secret` is 32 fresh random +/// bytes from the caller (this crate draws no entropy of its own). +pub fn seal( + recipient_box_pub: &[u8; 32], + envelope_id: &[u8; 16], + header_aad: &[u8], + cargo: &[u8], + eph_secret: [u8; 32], +) -> Vec { + use chacha20poly1305::aead::{Aead, KeyInit, Payload}; + use chacha20poly1305::{ChaCha20Poly1305, Key, Nonce}; + let eph = x25519_dalek::StaticSecret::from(eph_secret); + let eph_pub = x25519_dalek::PublicKey::from(&eph); + let shared = eph.diffie_hellman(&x25519_dalek::PublicKey::from(*recipient_box_pub)); + let key = box_key(shared.as_bytes()); + let nonce = box_nonce(eph_pub.as_bytes(), envelope_id); + let ct = ChaCha20Poly1305::new(Key::from_slice(&key)) + .encrypt(Nonce::from_slice(&nonce), Payload { msg: cargo, aad: header_aad }) + .expect("seal"); + let mut out = eph_pub.as_bytes().to_vec(); + out.extend_from_slice(&ct); + out +} + +/// Open an envelope with the recipient's box secret. None = not for this +/// key, or tampered — the caller quarantines, never crashes. +pub fn open(box_secret: &[u8; 32], e: &Envelope) -> Option> { + use chacha20poly1305::aead::{Aead, KeyInit, Payload}; + use chacha20poly1305::{ChaCha20Poly1305, Key, Nonce}; + if e.sealed.len() < 32 { + return None; + } + let eph_pub: [u8; 32] = e.sealed[..32].try_into().ok()?; + let secret = x25519_dalek::StaticSecret::from(*box_secret); + let shared = secret.diffie_hellman(&x25519_dalek::PublicKey::from(eph_pub)); + let key = box_key(shared.as_bytes()); + let nonce = box_nonce(&eph_pub, &e.envelope_id); + ChaCha20Poly1305::new(Key::from_slice(&key)) + .decrypt( + Nonce::from_slice(&nonce), + Payload { msg: &e.sealed[32..], aad: &envelope_header_bytes(e) }, + ) + .ok() +} + +/// The X25519 public key for a box secret. +pub fn box_public(box_secret: &[u8; 32]) -> [u8; 32] { + let s = x25519_dalek::StaticSecret::from(*box_secret); + *x25519_dalek::PublicKey::from(&s).as_bytes() +} + +// ---------------------------------------------------------------- state + +#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)] +pub struct PruneRecord { + pub seq: u64, + pub removed_ids: Vec<[u8; 16]>, + /// Everything with expires_at <= this floor stays out permanently. + pub floor_expiry: u64, + pub sig: Vec, +} + +#[derive(Serialize)] +struct PruneSigBody<'a> { + seq: u64, + removed_ids: &'a [[u8; 16]], + floor_expiry: u64, +} + +pub fn prune_sig_body(p: &PruneRecord) -> Vec { + bincode::serialize(&PruneSigBody { + seq: p.seq, + removed_ids: &p.removed_ids, + floor_expiry: p.floor_expiry, + }) + .expect("serializes") +} + +pub fn prune_valid(owner: &[u8; 32], p: &PruneRecord) -> bool { + p.removed_ids.len() <= MAX_TOMBSTONES + && crate::verify_sig_in(ENVELOPE_DOMAIN, owner, &sign_payload(&prune_sig_body(p)), &p.sig) +} + +#[derive(Debug, Clone, Default, PartialEq, Eq, Serialize, Deserialize)] +pub struct InboxState { + pub schema_version: u32, + pub owner: [u8; 32], + pub envelopes: Vec, + pub prune: Option, +} + +pub fn make_inbox_params(owner: &[u8; 32]) -> Vec { + let mut p = Vec::with_capacity(INBOX_PARAMS_FAMILY.len() + 32); + p.extend_from_slice(INBOX_PARAMS_FAMILY); + p.extend_from_slice(owner); + p +} + +/// Deterministic multi-writer merge. Inputs are RAW candidate states (any +/// mix of replicas and single-envelope offers); output is the bounded +/// canonical state. Mirrors the bundled contract exactly. +pub fn merge_inbox(owner: &[u8; 32], candidates: &[&[u8]]) -> InboxState { + let mut best_prune: Option<(u64, [u8; 32], PruneRecord)> = None; + let mut parsed: Vec = Vec::new(); + for bytes in candidates { + if bytes.is_empty() || bytes.len() > MAX_STATE_BYTES { + continue; + } + let Ok(st) = bincode::deserialize::(bytes) else { continue }; + if st.schema_version != SCHEMA_VERSION || &st.owner != owner { + continue; + } + if let Some(p) = &st.prune { + if prune_valid(owner, p) { + let rank = (p.seq, *blake3::hash(&prune_sig_body(p)).as_bytes()); + let better = match &best_prune { + None => true, + Some((s, h, _)) => rank > (*s, *h), + }; + if better { + best_prune = Some((rank.0, rank.1, p.clone())); + } + } + } + parsed.push(st); + } + let prune = best_prune.map(|(_, _, p)| p); + + let mut by_id: BTreeMap<[u8; 16], (Envelope, [u8; 32])> = BTreeMap::new(); + for st in &parsed { + for e in &st.envelopes { + if validate_envelope(owner, e).is_err() { + continue; + } + if let Some(p) = &prune { + if p.removed_ids.contains(&e.envelope_id) || e.expires_at <= p.floor_expiry { + continue; + } + } + let h = *blake3::hash(&bincode::serialize(e).unwrap()).as_bytes(); + match by_id.get(&e.envelope_id) { + Some((_, existing_h)) if existing_h <= &h => {} + _ => { + by_id.insert(e.envelope_id, (e.clone(), h)); + } + } + } + } + + let mut all: Vec = by_id.into_values().map(|(e, _)| e).collect(); + all.sort_by_key(|e| (e.created_at, e.envelope_id)); + let mut per_sender: BTreeMap<[u8; 32], Vec> = BTreeMap::new(); + let mut anon_pool: Vec = Vec::new(); + for e in all { + match &e.sender { + SenderClass::Known(k) => per_sender.entry(*k).or_default().push(e), + SenderClass::Anonymous => { + if anon_pool.len() < ANON_POOL_CAP { + anon_pool.push(e); + } + } + } + } + let mut survivors: Vec = anon_pool; + for (_, mut list) in per_sender { + let keep_from = list.len().saturating_sub(PER_SENDER_CAP); + survivors.extend(list.drain(keep_from..)); + } + survivors.sort_by_key(|e| (e.created_at, e.envelope_id)); + survivors.truncate(MAX_ENVELOPES); + InboxState { + schema_version: SCHEMA_VERSION, + owner: *owner, + envelopes: survivors, + prune, + } +} + +// ---------------------------------------------------------------- descriptor + +#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)] +pub struct InboxDescriptor { + pub schema_version: u32, + pub owner: [u8; 32], + pub sequence: u64, + pub inbox_family: Vec, + pub box_public_key: [u8; 32], + pub box_key_id: u32, + pub max_envelope_bytes: u32, + pub admission_policy: Vec, + pub sig: Vec, +} + +#[derive(Serialize)] +struct DescSigBody<'a> { + schema_version: u32, + owner: &'a [u8; 32], + sequence: u64, + inbox_family: &'a [u8], + box_public_key: &'a [u8; 32], + box_key_id: u32, + max_envelope_bytes: u32, + admission_policy: &'a [String], +} + +pub fn desc_sig_body(d: &InboxDescriptor) -> Vec { + bincode::serialize(&DescSigBody { + schema_version: d.schema_version, + owner: &d.owner, + sequence: d.sequence, + inbox_family: &d.inbox_family, + box_public_key: &d.box_public_key, + box_key_id: d.box_key_id, + max_envelope_bytes: d.max_envelope_bytes, + admission_policy: &d.admission_policy, + }) + .expect("serializes") +} + +pub fn make_desc_params(owner: &[u8; 32]) -> Vec { + let mut p = Vec::with_capacity(DESC_PARAMS_FAMILY.len() + 32); + p.extend_from_slice(DESC_PARAMS_FAMILY); + p.extend_from_slice(owner); + p +} + +pub fn validate_descriptor(owner: &[u8; 32], bytes: &[u8]) -> Option { + if bytes.len() > 4096 { + return None; + } + let d: InboxDescriptor = bincode::deserialize(bytes).ok()?; + if d.schema_version != SCHEMA_VERSION || &d.owner != owner { + return None; + } + crate::verify_sig_in(DESC_DOMAIN, owner, &sign_payload(&desc_sig_body(&d)), &d.sig).then_some(d) +} + +#[cfg(test)] +mod tests { + use super::*; + use ed25519_dalek::{Signer, SigningKey}; + + fn sign(key: &SigningKey, payload: &[u8]) -> Vec { + key.sign(&crate::signable(ENVELOPE_DOMAIN, payload)).to_bytes().to_vec() + } + + #[test] + fn seal_open_merge_and_prune_hold_their_gate() { + let recipient = SigningKey::from_bytes(&[1; 32]); + let sender = SigningKey::from_bytes(&[2; 32]); + let owner = recipient.verifying_key().to_bytes(); + let box_secret = [7u8; 32]; + let box_pub = box_public(&box_secret); + + // a sealed, signed envelope opens with the right key and not another + let mut e = Envelope { + envelope_id: [3; 16], + recipient: owner, + sender: SenderClass::Known(sender.verifying_key().to_bytes()), + created_at: 100, + expires_at: 100 + 3600, + admission: vec![], + sealed: vec![], + sender_sig: vec![], + }; + e.sealed = seal(&box_pub, &e.envelope_id, &envelope_header_bytes(&e), b"hello", [9u8; 32]); + e.sender_sig = sign(&sender, &sign_payload(&envelope_header_bytes(&e))); + assert_eq!(validate_envelope(&owner, &e), Ok(())); + assert_eq!(open(&box_secret, &e).as_deref(), Some(&b"hello"[..])); + assert_eq!(open(&[8u8; 32], &e), None); + // a tampered header breaks both the signature and the AAD + let mut t = e.clone(); + t.expires_at += 1; + assert_eq!(validate_envelope(&owner, &t), Err(EnvelopeInvalid::BadSenderSig)); + assert_eq!(open(&box_secret, &t), None); + + // merge: an offer state with the envelope lands; a prune removes it for good + let offer = bincode::serialize(&InboxState { schema_version: SCHEMA_VERSION, owner, envelopes: vec![e.clone()], prune: None }).unwrap(); + let merged = merge_inbox(&owner, &[&offer]); + assert_eq!(merged.envelopes.len(), 1); + let mut prune = PruneRecord { seq: 1, removed_ids: vec![e.envelope_id], floor_expiry: 0, sig: vec![] }; + prune.sig = sign(&recipient, &sign_payload(&prune_sig_body(&prune))); + let pruned = bincode::serialize(&InboxState { schema_version: SCHEMA_VERSION, owner, envelopes: vec![], prune: Some(prune) }).unwrap(); + let after = merge_inbox(&owner, &[&offer, &pruned]); + assert!(after.envelopes.is_empty()); + assert_eq!(after.prune.as_ref().map(|p| p.seq), Some(1)); + // a forged prune has no authority + let mut forged = PruneRecord { seq: 5, removed_ids: vec![e.envelope_id], floor_expiry: 0, sig: vec![] }; + forged.sig = sign(&sender, &sign_payload(&prune_sig_body(&forged))); + let fb = bincode::serialize(&InboxState { schema_version: SCHEMA_VERSION, owner, envelopes: vec![], prune: Some(forged) }).unwrap(); + assert_eq!(merge_inbox(&owner, &[&offer, &fb]).envelopes.len(), 1); + + // descriptor round trip + let mut d = InboxDescriptor { schema_version: SCHEMA_VERSION, owner, sequence: 1, inbox_family: INBOX_PARAMS_FAMILY.to_vec(), box_public_key: box_pub, box_key_id: 1, max_envelope_bytes: MAX_CIPHERTEXT as u32, admission_policy: vec!["known-signed".into()], sig: vec![] }; + d.sig = sign(&recipient, &sign_payload(&desc_sig_body(&d))); + let db = bincode::serialize(&d).unwrap(); + assert_eq!(validate_descriptor(&owner, &db), Some(d)); + } +} diff --git a/crates/persona-state/src/lib.rs b/crates/persona-state/src/lib.rs index 9185139..be111cf 100644 --- a/crates/persona-state/src/lib.rs +++ b/crates/persona-state/src/lib.rs @@ -18,6 +18,7 @@ use serde::{Deserialize, Serialize}; pub mod slsk_link; pub mod friend; pub mod playlist; +pub mod inbox; pub const SCHEMA_VERSION: u32 = 1; pub const SIGN_DOMAIN: &str = "soulstream.profile/v1"; diff --git a/src-tauri/assets/inbox_contract.wasm b/src-tauri/assets/inbox_contract.wasm new file mode 100644 index 0000000000000000000000000000000000000000..7cfd1036af026b4a948b18b653ddf89ccac5ea1c GIT binary patch literal 245327 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 asks, `SSFRIEND1!` +//! PM wire: `SSFRIEND1?` asks, `SSFRIEND1!` //! accepts or revokes, `SSFRIEND1-` declines. An -//! incoming REQUEST is bound to its sender by the link handshake: the -//! request names a persona key, and the sender is asked (over PM, with a -//! fresh nonce) to prove that key is theirs before the request is shown. -//! That ask waits on a PM, so the pump hands friend messages to a task — -//! awaiting inline would block the very loop that delivers the answer. +//! incoming PM REQUEST is bound to its sender by the link handshake (the +//! request names a key; the sender proves it). An inbox request needs no +//! such step: the envelope header is signed by the same key the request +//! names. That link ask waits on a PM, so PM friend messages are handled +//! on their own task — awaiting inline would block the loop that delivers +//! the answer. use std::collections::BTreeMap; use std::path::PathBuf; @@ -26,6 +29,7 @@ use persona_state::slsk_link::normalize_username; use serde::{Deserialize, Serialize}; use tauri::{Emitter, Manager}; +use crate::inbox::{self, Cargo}; use crate::persona; use crate::slsk_link; use crate::state::AppState; @@ -33,13 +37,17 @@ use crate::state::AppState; const REQ_PREFIX: &str = "SSFRIEND1?"; const ASSERT_PREFIX: &str = "SSFRIEND1!"; const DECLINE_PREFIX: &str = "SSFRIEND1-"; -/// A request stays open this long. const REQUEST_TTL_SECS: u64 = 7 * 24 * 3600; pub const EVENT: &str = "community:friends"; +fn carry_pm() -> String { + "pm".into() +} + #[derive(Debug, Clone, Serialize, Deserialize)] struct Relationship { - /// Their Soulseek account as the server spelled it when it last spoke. + /// Their Soulseek account as the server spelled it — may be empty for a + /// relationship that only ever travelled the inbox. username: String, username_normalized: String, their_key: String, @@ -48,11 +56,13 @@ struct Relationship { request_from_me: bool, #[serde(default)] assertions: Vec, - /// Local-only stances the verifier has no signature for. #[serde(default)] declined_by_me: bool, #[serde(default)] declined_by_them: bool, + /// "inbox" | "pm" — how the last message travelled; replies follow it. + #[serde(default = "carry_pm")] + carry: String, created_at: u64, updated_at: u64, } @@ -63,7 +73,6 @@ struct Store { relationships: BTreeMap, } -/// What the UI sees: one row per relationship, status from the verifier. #[derive(Debug, Serialize)] pub struct RelationshipView { pub id: String, @@ -74,6 +83,7 @@ pub struct RelationshipView { /// friends | pending-out | pending-in | accepted-waiting | declined | /// revoked | expired | reacceptance-required pub state: String, + pub carry: String, pub since: u64, pub updated_at: u64, pub expires_at: u64, @@ -95,12 +105,7 @@ fn b58(bytes: &[u8]) -> String { bs58::encode(bytes).into_string() } fn key_of(b58s: &str) -> Result<[u8; 32], String> { - bs58::decode(b58s) - .into_vec() - .map_err(|e| format!("bad key: {e}"))? - .as_slice() - .try_into() - .map_err(|_| "key is not 32 bytes".to_string()) + inbox::key_of(b58s) } fn path(app: &tauri::AppHandle) -> Result { @@ -178,6 +183,7 @@ fn view_of(id: &str, r: &Relationship, now: u64) -> RelationshipView { persona_key: r.their_key.clone(), direction: if r.request_from_me { "out" } else { "in" }, state: state.to_string(), + carry: r.carry.clone(), since, updated_at: r.updated_at, expires_at: r.request.expires_at, @@ -192,6 +198,9 @@ async fn my_key(app: &tauri::AppHandle) -> Result<[u8; 32], String> { key_of(&info.public_key) } async fn send_pm(app: &tauri::AppHandle, to: &str, text: &str) -> Result<(), String> { + if to.is_empty() { + return Err("no Soulseek account is known for them".into()); + } let st = app.state::(); let guard = st.client.lock().await; guard @@ -211,21 +220,52 @@ fn decode Deserialize<'de>>(b64: &str) -> Option { bincode::deserialize(&bytes).ok() } +/// Deliver by the relationship's carry; an inbox that went unreachable +/// falls back to the PM carry when an account is known. +async fn deliver(app: &tauri::AppHandle, rel: &mut Relationship, cargo: Cargo, pm_text: String) -> Result<(), String> { + if rel.carry == "inbox" { + match key_of(&rel.their_key) { + Ok(k) => match inbox::send(app, &k, &cargo).await { + Ok(()) => return Ok(()), + Err(e) => log::info!("friends: inbox carry failed ({e}); trying the Soulseek carry"), + }, + Err(e) => return Err(e), + } + } + send_pm(app, &rel.username, &pm_text).await?; + rel.carry = "pm".into(); + Ok(()) +} + async fn sign_assertion(app: &tauri::AppHandle, mut a: fr::FriendAssertion) -> Result { let adapter = app.state::().freenet.clone(); a.sig = persona::sign(&adapter, fr::FRIEND_DOMAIN, fr::assertion_sign_payload(&a)).await?; Ok(a) } +fn assertion_for(rel: &Relationship, me: [u8; 32], their: [u8; 32], accepted: bool, now: u64) -> fr::FriendAssertion { + fr::FriendAssertion { + relationship_id: rel.request.relationship_id, + signer: me, + peer: their, + request_hash: fr::request_hash(&rel.request), + accepted, + seq: now, + sig: vec![], + } +} + // ---------------------------------------------------------------- outgoing -/// Ask `username` to be friends. Needs their verified link (the drawer's -/// "Ask for their SoulStream ID") — the request is addressed to a KEY. -pub async fn request(app: &tauri::AppHandle, username: &str) -> Result { +async fn start_request( + app: &tauri::AppHandle, + their: [u8; 32], + username: String, +) -> Result { let me = my_key(app).await?; - let link = slsk_link::known_link(app, username) - .ok_or("verify their SoulStream ID first (the drawer's Ask button)")?; - let their = key_of(&link.persona_key)?; + if their == me { + return Err("that is your own identity".into()); + } let now = now_secs(); let mut req = fr::FriendRequest { relationship_id: nonce16(), @@ -239,29 +279,47 @@ pub async fn request(app: &tauri::AppHandle, username: &str) -> Result().freenet.clone(); req.sig = persona::sign(&adapter, fr::FRIEND_DOMAIN, fr::request_sign_payload(&req)).await?; let id = b58(&req.relationship_id); - let rel = Relationship { - username: link.username.clone(), - username_normalized: link.username_normalized.clone(), - their_key: link.persona_key.clone(), + let mut rel = Relationship { + username_normalized: normalize_username(&username), + username, + their_key: b58(&their), my_key: b58(&me), request: req.clone(), request_from_me: true, assertions: vec![], declined_by_me: false, declined_by_them: false, + carry: if inbox::reachable(app, &their).await { "inbox".into() } else { "pm".into() }, created_at: now, updated_at: now, }; - send_pm(app, &link.username, &encode(REQ_PREFIX, &req)?).await?; + deliver(app, &mut rel, Cargo::FriendRequest(req.clone()), encode(REQ_PREFIX, &req)?).await?; let mut store = load(app); store.relationships.insert(id.clone(), rel); save(app, &store)?; - log::info!("friends: request sent to {}", link.username); - Ok(view_of(&id, &store.relationships[&id], now)) + let rel = &store.relationships[&id]; + log::info!("friends: request sent to {} via {}", if rel.username.is_empty() { &rel.their_key } else { &rel.username }, rel.carry); + Ok(view_of(&id, rel, now)) +} + +/// Ask a Soulseek account to be friends. Needs their verified link — the +/// request is addressed to a KEY. +pub async fn request(app: &tauri::AppHandle, username: &str) -> Result { + let link = slsk_link::known_link(app, username) + .ok_or("verify their SoulStream ID first (the drawer's Ask button)")?; + start_request(app, key_of(&link.persona_key)?, link.username.clone()).await +} + +/// Ask a SoulStream ID directly — only through their inbox. +pub async fn request_by_key(app: &tauri::AppHandle, persona_key: &str) -> Result { + let their = key_of(persona_key)?; + if !inbox::reachable(app, &their).await { + return Err("they have not published an inbox — reachable only through a Soulseek account".into()); + } + let username = slsk_link::username_for_key(app, persona_key).unwrap_or_default(); + start_request(app, their, username).await } -/// Accept an incoming request: sign our assertion, send it, remember it. -/// Friendship is still one-sided until their reciprocal assertion arrives. pub async fn accept(app: &tauri::AppHandle, id: &str) -> Result { let me = my_key(app).await?; let mut store = load(app); @@ -271,20 +329,8 @@ pub async fn accept(app: &tauri::AppHandle, id: &str) -> Result Result Result Vec { // ---------------------------------------------------------------- incoming -async fn on_request(app: tauri::AppHandle, from: String, req: fr::FriendRequest) { +/// Who a message came from, as far as its carry can vouch. +enum From { + /// A Soulseek account the server attributed. + Pm(String), + /// A persona key that signed the envelope header. + Inbox([u8; 32]), +} + +async fn store_request(app: &tauri::AppHandle, from: From, req: fr::FriendRequest) { if !fr::verify_request(&req) { - log::warn!("friends: request from {from} does not verify"); + log::warn!("friends: a request does not verify"); return; } - let Ok(me) = my_key(&app).await else { - log::debug!("friends: request from {from}, but no persona here to receive it"); + let Ok(me) = my_key(app).await else { + log::debug!("friends: a request arrived, but no persona is here to receive it"); return; }; if req.recipient != me { - log::debug!("friends: request from {from} is addressed to another persona"); return; } let now = now_secs(); if now > req.expires_at { return; } - // The request names a key; the sender must prove it is theirs. - let bound = match slsk_link::known_link(&app, &from) { - Some(l) if l.persona_key == b58(&req.sender) => Some(l), - _ => match slsk_link::ask(&app, &from).await { - Ok(l) if l.persona_key == b58(&req.sender) => { - slsk_link::remember(&app, l.clone()); - Some(l) + // Bind the request's key to whoever sent it. + let (username, carry) = match from { + From::Inbox(sender) => { + if sender != req.sender { + log::warn!("friends: an inbox request names a key other than its envelope's signer"); + return; } - Ok(_) => { - log::warn!("friends: {from} proved a different key than the request names"); - None - } - Err(e) => { - log::warn!("friends: could not bind {from} to the request's key: {e}"); - None - } - }, + (slsk_link::username_for_key(app, &b58(&sender)).unwrap_or_default(), "inbox") + } + From::Pm(from) => { + let bound = match slsk_link::known_link(app, &from) { + Some(l) if l.persona_key == b58(&req.sender) => Some(l), + _ => match slsk_link::ask(app, &from).await { + Ok(l) if l.persona_key == b58(&req.sender) => { + slsk_link::remember(app, l.clone()); + Some(l) + } + Ok(_) => { + log::warn!("friends: {from} proved a different key than the request names"); + None + } + Err(e) => { + log::warn!("friends: could not bind {from} to the request's key: {e}"); + None + } + }, + }; + let Some(link) = bound else { return }; + (link.username, "pm") + } }; - let Some(link) = bound else { return }; let id = b58(&req.relationship_id); - let mut store = load(&app); + let mut store = load(app); if store.relationships.contains_key(&id) { return; } + let who = if username.is_empty() { b58(&req.sender) } else { username.clone() }; store.relationships.insert( id, Relationship { - username: link.username, - username_normalized: link.username_normalized, - their_key: link.persona_key, + username_normalized: normalize_username(&username), + username, + their_key: b58(&req.sender), my_key: b58(&me), request: req, request_from_me: false, assertions: vec![], declined_by_me: false, declined_by_them: false, + carry: carry.into(), created_at: now, updated_at: now, }, ); - if let Err(e) = save(&app, &store) { - log::warn!("friends: could not store the request from {from}: {e}"); + if let Err(e) = save(app, &store) { + log::warn!("friends: could not store the request from {who}: {e}"); } else { - log::info!("friends: request from {from} verified and waiting"); + log::info!("friends: request from {who} verified and waiting (via {carry})"); } } -async fn on_assertion(app: tauri::AppHandle, from: String, a: fr::FriendAssertion) { +async fn apply_assertion(app: &tauri::AppHandle, from: From, a: fr::FriendAssertion) { if !fr::verify_assertion(&a) { - log::warn!("friends: assertion from {from} does not verify"); + log::warn!("friends: an assertion does not verify"); return; } let id = b58(&a.relationship_id); - let mut store = load(&app); + let mut store = load(app); let Some(rel) = store.relationships.get_mut(&id) else { - log::debug!("friends: assertion from {from} for an unknown relationship"); + log::debug!("friends: assertion for an unknown relationship"); return; }; - if normalize_username(&from) != rel.username_normalized + let sender_ok = match &from { + From::Pm(u) => normalize_username(u) == rel.username_normalized, + From::Inbox(k) => b58(k) == rel.their_key, + }; + if !sender_ok || b58(&a.signer) != rel.their_key || b58(&a.peer) != rel.my_key || a.request_hash != fr::request_hash(&rel.request) { - log::warn!("friends: assertion from {from} does not belong to its relationship"); + log::warn!("friends: an assertion does not belong to its relationship"); return; } if rel @@ -447,27 +506,17 @@ async fn on_assertion(app: tauri::AppHandle, from: String, a: fr::FriendAssertio let now = now_secs(); rel.assertions.push(a.clone()); rel.updated_at = now; + if let From::Inbox(_) = from { + rel.carry = "inbox".into(); + } // Their acceptance of OUR request completes with our own assertion. let mine_exists = rel.assertions.iter().any(|x| b58(&x.signer) == rel.my_key); if a.accepted && rel.request_from_me && !mine_exists { if let (Ok(me), Ok(their)) = (key_of(&rel.my_key), key_of(&rel.their_key)) { - match sign_assertion( - &app, - fr::FriendAssertion { - relationship_id: rel.request.relationship_id, - signer: me, - peer: their, - request_hash: fr::request_hash(&rel.request), - accepted: true, - seq: now, - sig: vec![], - }, - ) - .await - { + match sign_assertion(app, assertion_for(rel, me, their, true, now)).await { Ok(mine) => { if let Ok(text) = encode(ASSERT_PREFIX, &mine) { - let _ = send_pm(&app, &rel.username, &text).await; + let _ = deliver(app, rel, Cargo::FriendAssertion(mine.clone()), text).await; } rel.assertions.push(mine); } @@ -476,17 +525,22 @@ async fn on_assertion(app: tauri::AppHandle, from: String, a: fr::FriendAssertio } } let state = view_of(&id, rel, now).state; - if let Err(e) = save(&app, &store) { - log::warn!("friends: could not store the assertion from {from}: {e}"); + let who = if rel.username.is_empty() { rel.their_key.clone() } else { rel.username.clone() }; + if let Err(e) = save(app, &store) { + log::warn!("friends: could not store an assertion: {e}"); } else { - log::info!("friends: {from} → {state}"); + log::info!("friends: {who} → {state}"); } } -fn on_decline(app: &tauri::AppHandle, from: &str, id: &str) { +fn apply_decline(app: &tauri::AppHandle, from: From, id: &str) { let mut store = load(app); let Some(rel) = store.relationships.get_mut(id) else { return }; - if normalize_username(from) != rel.username_normalized || !rel.request_from_me { + let sender_ok = match &from { + From::Pm(u) => normalize_username(u) == rel.username_normalized, + From::Inbox(k) => b58(k) == rel.their_key, + }; + if !sender_ok || !rel.request_from_me { return; } rel.declined_by_them = true; @@ -494,6 +548,17 @@ fn on_decline(app: &tauri::AppHandle, from: &str, id: &str) { let _ = save(app, &store); } +/// Sealed cargo from inbox.rs: the envelope's signer is the sender. +pub(crate) async fn on_inbox_request(app: &tauri::AppHandle, sender: [u8; 32], req: fr::FriendRequest) { + store_request(app, From::Inbox(sender), req).await; +} +pub(crate) async fn on_inbox_assertion(app: &tauri::AppHandle, sender: [u8; 32], a: fr::FriendAssertion) { + apply_assertion(app, From::Inbox(sender), a).await; +} +pub(crate) fn on_inbox_decline(app: &tauri::AppHandle, sender: [u8; 32], id: [u8; 16]) { + apply_decline(app, From::Inbox(sender), &b58(&id)); +} + /// The event pump hands every private message here after the link proof. /// True means it was ours and must not surface in the Inbox. Requests and /// assertions are handled on their own task (see the module note). @@ -501,18 +566,20 @@ pub fn intercept_pm(app: &tauri::AppHandle, from: &str, message: &str) -> bool { let msg = message.trim(); if let Some(rest) = msg.strip_prefix(REQ_PREFIX) { if let Some(req) = decode::(rest) { - tauri::async_runtime::spawn(on_request(app.clone(), from.to_string(), req)); + let (app, from) = (app.clone(), from.to_string()); + tauri::async_runtime::spawn(async move { store_request(&app, From::Pm(from), req).await }); } return true; } if let Some(rest) = msg.strip_prefix(ASSERT_PREFIX) { if let Some(a) = decode::(rest) { - tauri::async_runtime::spawn(on_assertion(app.clone(), from.to_string(), a)); + let (app, from) = (app.clone(), from.to_string()); + tauri::async_runtime::spawn(async move { apply_assertion(&app, From::Pm(from), a).await }); } return true; } if let Some(rest) = msg.strip_prefix(DECLINE_PREFIX) { - on_decline(app, from, rest.trim()); + apply_decline(app, From::Pm(from.to_string()), rest.trim()); return true; } false @@ -529,6 +596,10 @@ pub async fn friend_request(app: tauri::AppHandle, username: String) -> Result Result { + request_by_key(&app, &persona_key).await +} +#[tauri::command] pub async fn friend_accept(app: tauri::AppHandle, id: String) -> Result { accept(&app, &id).await } diff --git a/src-tauri/src/inbox.rs b/src-tauri/src/inbox.rs new file mode 100644 index 0000000..77a294d --- /dev/null +++ b/src-tauri/src/inbox.rs @@ -0,0 +1,443 @@ +//! The encrypted inbox (F5 → the app): the second carry for everything the +//! friend and share handshakes send. A persona that has published an +//! InboxDescriptor can be written to by anyone who can resolve it: the +//! sender seals the cargo to the recipient's box key, signs the envelope +//! header with its persona key, and OFFERS the envelope to the recipient's +//! inbox contract, whose merge admits, dedups and caps it. The recipient +//! reads its own inbox, opens what it can, acts on it, and prunes what it +//! handled with an owner-signed tombstone record. +//! +//! Custody, for now: the X25519 box secret lives beside the node in this +//! device's app folder (`inbox-box.key`). The design wants it in the +//! identity delegate — that is the next delegate generation, a migration +//! event — so a persona restored elsewhere from the recovery file has to +//! publish a fresh box key, and mail sealed to the old one is unreadable. +//! The UI says so. +//! +//! Adapter rules from F5 apply verbatim: read before the first write to a +//! contract this node never held (`get_then_update`), read-and-bump the +//! descriptor and prune sequences, and an unresolvable descriptor means +//! "unreachable through Freenet" — never a guess. + +use std::collections::{BTreeSet, HashMap}; +use std::path::PathBuf; +use std::sync::{Mutex, OnceLock}; +use std::time::{Duration, Instant, SystemTime, UNIX_EPOCH}; + +use freenet_adapter::FreenetAdapter; +use persona_state::friend as fr; +use persona_state::inbox as ib; +use serde::{Deserialize, Serialize}; +use tauri::{Emitter, Manager}; + +use crate::persona; +use crate::state::AppState; + +const INBOX_WASM: &[u8] = include_bytes!("../assets/inbox_contract.wasm"); +const DESC_WASM: &[u8] = include_bytes!("../assets/inbox_desc_contract.wasm"); +pub const EVENT: &str = "community:inbox"; +/// How long an envelope we send stays valid. +const ENVELOPE_TTL_SECS: u64 = 7 * 24 * 3600; +/// A descriptor lookup that found nothing is not repeated for this long. +const DESC_CACHE_TTL: Duration = Duration::from_secs(600); + +/// What travels sealed inside an envelope: the same things the PM carry +/// moves in the clear. Bincode variant order is the wire — append only. +#[derive(Debug, Clone, Serialize, Deserialize)] +pub enum Cargo { + FriendRequest(fr::FriendRequest), + FriendAssertion(fr::FriendAssertion), + FriendDecline([u8; 16]), + Share(ShareCargo), +} + +#[derive(Debug, Clone, Serialize, Deserialize)] +pub struct ShareCargo { + pub owner: [u8; 32], + pub playlist_uuid: [u8; 16], + pub name: String, + pub entry_count: u32, +} + +#[derive(Default, Serialize, Deserialize)] +struct Ledger { + /// Sequence of the descriptor we last published (0 = never). + #[serde(default)] + desc_seq: u64, + #[serde(default)] + box_key_id: u32, + /// Envelope ids already acted on (b58) — pruned on the next check. + #[serde(default)] + handled: Vec, + #[serde(default)] + prune_seq: u64, + #[serde(default)] + last_check: u64, + #[serde(default)] + quarantined: u64, +} + +#[derive(Debug, Serialize)] +pub struct InboxStatus { + pub published: bool, + pub descriptor_seq: u64, + pub box_key_id: u32, + pub last_check: u64, + pub handled_count: usize, + pub quarantined: u64, +} + +fn now_secs() -> u64 { + SystemTime::now() + .duration_since(UNIX_EPOCH) + .map(|d| d.as_secs()) + .unwrap_or(0) +} +fn rand32() -> [u8; 32] { + use rand::RngCore; + let mut n = [0u8; 32]; + rand::thread_rng().fill_bytes(&mut n); + n +} +fn rand16() -> [u8; 16] { + use rand::RngCore; + let mut n = [0u8; 16]; + rand::thread_rng().fill_bytes(&mut n); + n +} +fn b58(bytes: &[u8]) -> String { + bs58::encode(bytes).into_string() +} +pub(crate) fn key_of(b58s: &str) -> Result<[u8; 32], String> { + bs58::decode(b58s) + .into_vec() + .map_err(|e| format!("bad key: {e}"))? + .as_slice() + .try_into() + .map_err(|_| "key is not 32 bytes".to_string()) +} + +fn dir(app: &tauri::AppHandle) -> Result { + Ok(app + .path() + .app_data_dir() + .map_err(|e| e.to_string())? + .join("freenet")) +} +fn load(app: &tauri::AppHandle) -> Ledger { + dir(app) + .ok() + .and_then(|d| std::fs::read(d.join("inbox-ledger.json")).ok()) + .and_then(|b| serde_json::from_slice(&b).ok()) + .unwrap_or_default() +} +fn save(app: &tauri::AppHandle, l: &Ledger) -> Result<(), String> { + let d = dir(app)?; + std::fs::create_dir_all(&d).map_err(|e| e.to_string())?; + std::fs::write(d.join("inbox-ledger.json"), serde_json::to_vec_pretty(l).map_err(|e| e.to_string())?) + .map_err(|e| e.to_string()) +} + +/// The box secret, minted on first use. 32 raw bytes in the app folder — +/// see the custody note above. +fn box_secret(app: &tauri::AppHandle, mint: bool) -> Result, String> { + let p = dir(app)?.join("inbox-box.key"); + if let Ok(b) = std::fs::read(&p) { + if b.len() == 32 { + return Ok(Some(b.as_slice().try_into().unwrap())); + } + } + if !mint { + return Ok(None); + } + let s = rand32(); + std::fs::create_dir_all(p.parent().unwrap()).map_err(|e| e.to_string())?; + std::fs::write(&p, s).map_err(|e| format!("could not keep the box key: {e}"))?; + Ok(Some(s)) +} + +async fn own_key(app: &tauri::AppHandle) -> Result<[u8; 32], String> { + let adapter = app.state::().freenet.clone(); + let info = persona::current(&adapter) + .await? + .ok_or("create a SoulStream identity first")?; + key_of(&info.public_key) +} + +pub fn status(app: &tauri::AppHandle) -> InboxStatus { + let l = load(app); + InboxStatus { + published: l.desc_seq > 0, + descriptor_seq: l.desc_seq, + box_key_id: l.box_key_id, + last_check: l.last_check, + handled_count: l.handled.len(), + quarantined: l.quarantined, + } +} + +// ---------------------------------------------------------------- descriptor + +/// Publish (or re-publish) how to reach this persona. Minting the box key +/// and publishing the descriptor is what makes the inbox exist. +pub async fn publish(app: &tauri::AppHandle) -> Result { + let adapter = app.state::().freenet.clone(); + let owner = own_key(app).await?; + let secret = box_secret(app, true)?.expect("minted"); + let mut l = load(app); + let first = l.desc_seq == 0; + let seq = l.desc_seq + 1; + let key_id = if l.box_key_id == 0 { 1 } else { l.box_key_id }; + let mut d = ib::InboxDescriptor { + schema_version: ib::SCHEMA_VERSION, + owner, + sequence: seq, + inbox_family: ib::INBOX_PARAMS_FAMILY.to_vec(), + box_public_key: ib::box_public(&secret), + box_key_id: key_id, + max_envelope_bytes: ib::MAX_CIPHERTEXT as u32, + admission_policy: vec!["known-signed".into()], + sig: vec![], + }; + d.sig = persona::sign(&adapter, ib::DESC_DOMAIN, ib::sign_payload(&ib::desc_sig_body(&d))).await?; + let bytes = bincode::serialize(&d).map_err(|e| e.to_string())?; + let params = ib::make_desc_params(&owner); + if first { + adapter + .contract_put(DESC_WASM.to_vec(), ¶ms, bytes, false) + .await + .map(|_| ()) + } else { + adapter.contract_update(DESC_WASM.to_vec(), ¶ms, bytes).await.map(|_| ()) + } + .map_err(|e| e.to_string())?; + l.desc_seq = seq; + l.box_key_id = key_id; + save(app, &l)?; + // Our own inbox contract must exist for anyone to write into it. + let empty = bincode::serialize(&ib::InboxState { + schema_version: ib::SCHEMA_VERSION, + owner, + envelopes: vec![], + prune: None, + }) + .map_err(|e| e.to_string())?; + let _ = adapter + .contract_put(INBOX_WASM.to_vec(), &ib::make_inbox_params(&owner), empty, false) + .await; + log::info!("inbox: descriptor published (seq {seq}, box key {key_id})"); + Ok(status(app)) +} + +struct DescCache { + at: Instant, + desc: Option, +} +static DESC_CACHE: OnceLock>> = OnceLock::new(); + +/// Resolve someone's descriptor through the network. None = unreachable +/// through Freenet (no descriptor, or one that does not verify). +pub async fn resolve(app: &tauri::AppHandle, key: &[u8; 32]) -> Option { + let cache = DESC_CACHE.get_or_init(Default::default); + if let Some(c) = cache.lock().unwrap().get(key) { + if c.at.elapsed() < DESC_CACHE_TTL { + return c.desc.clone(); + } + } + let adapter = app.state::().freenet.clone(); + let ids = FreenetAdapter::contract_ids(DESC_WASM.to_vec(), &ib::make_desc_params(key)); + let desc = match adapter.contract_get(&ids.instance, false).await { + Ok(bytes) => ib::validate_descriptor(key, &bytes), + Err(_) => None, + }; + cache + .lock() + .unwrap() + .insert(*key, DescCache { at: Instant::now(), desc: desc.clone() }); + desc +} + +/// True when we can reach `key` through Freenet right now. +pub async fn reachable(app: &tauri::AppHandle, key: &[u8; 32]) -> bool { + resolve(app, key).await.is_some() +} + +// ---------------------------------------------------------------- send + +/// Seal cargo to a persona and offer it to their inbox. Errors when they +/// have no descriptor — the caller falls back to the Soulseek carry. +pub async fn send(app: &tauri::AppHandle, to: &[u8; 32], cargo: &Cargo) -> Result<(), String> { + let desc = resolve(app, to) + .await + .ok_or("they have not published an inbox — unreachable through Freenet")?; + let adapter = app.state::().freenet.clone(); + let me = own_key(app).await?; + let payload = bincode::serialize(cargo).map_err(|e| e.to_string())?; + if payload.len() > desc.max_envelope_bytes as usize { + return Err("cargo is over their envelope cap".into()); + } + let now = now_secs(); + let mut e = ib::Envelope { + envelope_id: rand16(), + recipient: *to, + sender: ib::SenderClass::Known(me), + created_at: now, + expires_at: now + ENVELOPE_TTL_SECS, + admission: vec![], + sealed: vec![], + sender_sig: vec![], + }; + let header = ib::envelope_header_bytes(&e); + e.sealed = ib::seal(&desc.box_public_key, &e.envelope_id, &header, &payload, rand32()); + e.sender_sig = persona::sign(&adapter, ib::ENVELOPE_DOMAIN, ib::sign_payload(&header)).await?; + let offer = bincode::serialize(&ib::InboxState { + schema_version: ib::SCHEMA_VERSION, + owner: *to, + envelopes: vec![e], + prune: None, + }) + .map_err(|e| e.to_string())?; + adapter + .get_then_update(INBOX_WASM.to_vec(), &ib::make_inbox_params(to), offer) + .await + .map_err(|e| e.to_string())?; + log::info!("inbox: sealed cargo offered to {}", b58(to)); + Ok(()) +} + +// ---------------------------------------------------------------- receive + +/// What one check found. +#[derive(Debug, Serialize)] +pub struct CheckResult { + pub new_items: usize, + pub quarantined: usize, + pub pruned: usize, +} + +/// Read our inbox, open what we can, act on it, prune what we handled. +pub async fn check(app: &tauri::AppHandle) -> Result { + let adapter = app.state::().freenet.clone(); + let owner = own_key(app).await?; + let Some(secret) = box_secret(app, false)? else { + return Err("no inbox published yet".into()); + }; + let ids = FreenetAdapter::contract_ids(INBOX_WASM.to_vec(), &ib::make_inbox_params(&owner)); + let bytes = match adapter.contract_get(&ids.instance, false).await { + Ok(b) => b, + Err(e) if e.to_string().contains("not found") => Vec::new(), + Err(e) => return Err(e.to_string()), + }; + let state = ib::merge_inbox(&owner, &[&bytes]); + let mut l = load(app); + let handled: BTreeSet = l.handled.iter().cloned().collect(); + let mut newly: Vec<[u8; 16]> = Vec::new(); + let mut new_items = 0usize; + let mut quarantined = 0usize; + for e in &state.envelopes { + let id = b58(&e.envelope_id); + if handled.contains(&id) { + continue; + } + let ib::SenderClass::Known(sender) = e.sender else { + // Anonymous admission is not offered by our descriptor; anything + // that arrives that way is dropped. + newly.push(e.envelope_id); + quarantined += 1; + continue; + }; + match ib::open(&secret, e).and_then(|b| bincode::deserialize::(&b).ok()) { + Some(cargo) => { + dispatch(app, sender, cargo).await; + new_items += 1; + } + None => quarantined += 1, + } + newly.push(e.envelope_id); + } + let pruned = newly.len(); + if !newly.is_empty() { + // Read-and-bump: the record's seq must beat whatever the network holds. + let seq = state.prune.as_ref().map(|p| p.seq).unwrap_or(0).max(l.prune_seq) + 1; + let mut ids_all: Vec<[u8; 16]> = state + .prune + .as_ref() + .map(|p| p.removed_ids.clone()) + .unwrap_or_default(); + ids_all.extend(newly.iter().copied()); + if ids_all.len() > ib::MAX_TOMBSTONES { + ids_all.drain(..ids_all.len() - ib::MAX_TOMBSTONES); + } + let mut rec = ib::PruneRecord { + seq, + removed_ids: ids_all, + floor_expiry: now_secs().saturating_sub(1), + sig: vec![], + }; + rec.sig = persona::sign(&adapter, ib::ENVELOPE_DOMAIN, ib::sign_payload(&ib::prune_sig_body(&rec))).await?; + let st = bincode::serialize(&ib::InboxState { + schema_version: ib::SCHEMA_VERSION, + owner, + envelopes: vec![], + prune: Some(rec), + }) + .map_err(|e| e.to_string())?; + if let Err(e) = adapter + .get_then_update(INBOX_WASM.to_vec(), &ib::make_inbox_params(&owner), st) + .await + { + log::warn!("inbox: prune not applied ({e}) — handled ids stay in the ledger"); + } else { + l.prune_seq = seq; + } + for id in &newly { + l.handled.push(b58(id)); + } + if l.handled.len() > 2048 { + l.handled.drain(..l.handled.len() - 2048); + } + } + l.last_check = now_secs(); + l.quarantined += quarantined as u64; + save(app, &l)?; + let _ = app.emit(EVENT, new_items); + Ok(CheckResult { new_items, quarantined, pruned }) +} + +async fn dispatch(app: &tauri::AppHandle, sender: [u8; 32], cargo: Cargo) { + match cargo { + Cargo::FriendRequest(r) => crate::friends::on_inbox_request(app, sender, r).await, + Cargo::FriendAssertion(a) => crate::friends::on_inbox_assertion(app, sender, a).await, + Cargo::FriendDecline(id) => crate::friends::on_inbox_decline(app, sender, id), + Cargo::Share(s) => crate::shared_playlists::on_inbox_share(app, sender, s), + } +} + +// ---------------------------------------------------------------- commands + +#[tauri::command] +pub fn inbox_status(app: tauri::AppHandle) -> InboxStatus { + status(&app) +} +#[tauri::command] +pub async fn inbox_publish(app: tauri::AppHandle) -> Result { + publish(&app).await +} +#[tauri::command] +pub async fn inbox_check(app: tauri::AppHandle) -> Result { + check(&app).await +} + +#[cfg(test)] +mod tests { + use super::*; + + #[test] + fn contract_generations_are_pinned() { + let owner = [7u8; 32]; + let inbox = FreenetAdapter::contract_ids(INBOX_WASM.to_vec(), &ib::make_inbox_params(&owner)); + let desc = FreenetAdapter::contract_ids(DESC_WASM.to_vec(), &ib::make_desc_params(&owner)); + assert_eq!(inbox.code_hash, "UjK4sLZqGSE2qEXwQYMvNFsTiuLSYjMJuwzVbhAtXKR"); + assert_eq!(desc.code_hash, "B4A2nMJgSKzgo72gaDJyTpFNTmjBynLFga3EiNoSVstv"); + } +} diff --git a/src-tauri/src/lib.rs b/src-tauri/src/lib.rs index c6b99db..5939d85 100644 --- a/src-tauri/src/lib.rs +++ b/src-tauri/src/lib.rs @@ -8,6 +8,7 @@ mod friends; mod persona; mod hero_crop; mod import; +mod inbox; mod hero_detector; mod loudness; mod lyric_align; @@ -133,6 +134,7 @@ pub fn run() { slsk_link::slsk_link_forget, friends::friends_list, friends::friend_request, + friends::friend_request_by_key, friends::friend_accept, friends::friend_decline, friends::friend_remove, @@ -145,6 +147,9 @@ pub fn run() { shared_playlists::share_send, shared_playlists::shares_inbox, shared_playlists::share_dismiss, + inbox::inbox_status, + inbox::inbox_publish, + inbox::inbox_check, commands::buddy_list, commands::buddy_add, commands::buddy_remove, diff --git a/src-tauri/src/shared_playlists.rs b/src-tauri/src/shared_playlists.rs index d345335..29954fd 100644 --- a/src-tauri/src/shared_playlists.rs +++ b/src-tauri/src/shared_playlists.rs @@ -28,6 +28,7 @@ use persona_state::slsk_link::normalize_username; use serde::{Deserialize, Serialize}; use tauri::{Emitter, Manager, State}; +use crate::inbox::{self, Cargo, ShareCargo}; use crate::persona; use crate::pipeline::LibraryState; use crate::playlist_formats::{ParsedEntry, ParsedPlaylist}; @@ -59,7 +60,14 @@ pub struct Published { #[derive(Debug, Clone, Serialize, Deserialize)] pub struct ShareCard { pub id: String, + /// Empty when it arrived sealed from a persona this device has no + /// Soulseek account for; `from_key` is then the only name. pub from_username: String, + #[serde(default)] + pub from_key: String, + /// "pm" | "inbox" — how it arrived. + #[serde(default = "carry_pm")] + pub carry: String, pub owner_key: String, pub playlist_uuid: String, pub name: String, @@ -67,6 +75,10 @@ pub struct ShareCard { pub received_at: u64, } +fn carry_pm() -> String { + "pm".into() +} + #[derive(Default, Serialize, Deserialize)] struct Ledger { #[serde(default)] @@ -452,6 +464,24 @@ pub async fn send(app: &tauri::AppHandle, username: &str, playlist_id: i64) -> R name: rec.name.clone(), entry_count: rec.entry_count, }; + // Sealed through their inbox when they have one; the Soulseek carry otherwise. + if let Some(link) = crate::slsk_link::known_link(app, username) { + if let Ok(their) = bytes32(&link.persona_key) { + let cargo = Cargo::Share(ShareCargo { + owner, + playlist_uuid: r.playlist_uuid, + name: r.name.clone(), + entry_count: r.entry_count, + }); + match inbox::send(app, &their, &cargo).await { + Ok(()) => { + log::info!("shared playlists: sent {:?} to {username} via inbox", rec.name); + return Ok(()); + } + Err(e) => log::info!("shared playlists: inbox carry failed ({e}); trying the Soulseek carry"), + } + } + } use base64::Engine; let bytes = bincode::serialize(&r).map_err(|e| e.to_string())?; let text = format!("{SHARE_PREFIX}{}", base64::engine::general_purpose::STANDARD.encode(bytes)); @@ -460,6 +490,38 @@ pub async fn send(app: &tauri::AppHandle, username: &str, playlist_id: i64) -> R Ok(()) } +fn keep_card(app: &tauri::AppHandle, card: ShareCard) { + let who = if card.from_username.is_empty() { card.from_key.clone() } else { card.from_username.clone() }; + let mut ledger = load(app); + ledger.inbox.retain(|c| c.id != card.id); + ledger.inbox.push(card); + if let Err(e) = save(app, &ledger) { + log::warn!("shared playlists: could not keep the share from {who}: {e}"); + } else { + log::info!("shared playlists: share received from {who}"); + } +} + +/// Sealed cargo from inbox.rs: the envelope's signer is the sender. +pub(crate) fn on_inbox_share(app: &tauri::AppHandle, sender: [u8; 32], s: ShareCargo) { + let from_key = b58(&sender); + let from_username = crate::slsk_link::username_for_key(app, &from_key).unwrap_or_default(); + keep_card( + app, + ShareCard { + id: format!("{}:{}:{}", from_key, b58(&s.owner), b58(&s.playlist_uuid)), + from_username, + from_key, + carry: "inbox".into(), + owner_key: b58(&s.owner), + playlist_uuid: b58(&s.playlist_uuid), + name: cap(&s.name, pl::MAX_NAME_BYTES), + entry_count: s.entry_count, + received_at: now_secs(), + }, + ); +} + /// The event pump hands private messages here after the link and friend /// handshakes. True means it was a share reference, now a card in the Inbox. pub fn intercept_pm(app: &tauri::AppHandle, from: &str, message: &str) -> bool { @@ -467,23 +529,20 @@ pub fn intercept_pm(app: &tauri::AppHandle, from: &str, message: &str) -> bool { use base64::Engine; let Ok(bytes) = base64::engine::general_purpose::STANDARD.decode(rest.trim()) else { return true }; let Ok(r) = bincode::deserialize::(&bytes) else { return true }; - let card = ShareCard { - id: format!("{}:{}:{}", normalize_username(from), b58(&r.owner), b58(&r.playlist_uuid)), - from_username: from.to_string(), - owner_key: b58(&r.owner), - playlist_uuid: b58(&r.playlist_uuid), - name: cap(&r.name, pl::MAX_NAME_BYTES), - entry_count: r.entry_count, - received_at: now_secs(), - }; - let mut ledger = load(app); - ledger.inbox.retain(|c| c.id != card.id); - ledger.inbox.push(card); - if let Err(e) = save(app, &ledger) { - log::warn!("shared playlists: could not keep the share from {from}: {e}"); - } else { - log::info!("shared playlists: share received from {from}"); - } + keep_card( + app, + ShareCard { + id: format!("{}:{}:{}", normalize_username(from), b58(&r.owner), b58(&r.playlist_uuid)), + from_username: from.to_string(), + from_key: String::new(), + carry: "pm".into(), + owner_key: b58(&r.owner), + playlist_uuid: b58(&r.playlist_uuid), + name: cap(&r.name, pl::MAX_NAME_BYTES), + entry_count: r.entry_count, + received_at: now_secs(), + }, + ); true } diff --git a/src-tauri/src/slsk_link.rs b/src-tauri/src/slsk_link.rs index 1a85598..52b6f46 100644 --- a/src-tauri/src/slsk_link.rs +++ b/src-tauri/src/slsk_link.rs @@ -293,6 +293,22 @@ pub(crate) fn remember(app: &tauri::AppHandle, link: KnownLink) { let _ = save(app, &links); } +/// The Soulseek account a verified persona key belongs to, if this device +/// verified one (our own included). +pub(crate) fn username_for_key(app: &tauri::AppHandle, persona_key: &str) -> Option { + let links = load(app); + if let Some(o) = &links.own { + if o.persona_key == persona_key { + return Some(o.username.clone()); + } + } + links + .others + .values() + .find(|l| l.persona_key == persona_key) + .map(|l| l.username.clone()) +} + // ---------------------------------------------------------------- commands #[tauri::command] diff --git a/src/lib/api.js b/src/lib/api.js index b0f2aa8..40a27d8 100644 --- a/src/lib/api.js +++ b/src/lib/api.js @@ -158,6 +158,7 @@ export const slskLinkCheck = (username) => invoke("slsk_link_check", { username export const slskLinkForget = (username) => invoke("slsk_link_forget", { username }); export const friendsList = () => invoke("friends_list"); export const friendRequest = (username) => invoke("friend_request", { username }); +export const friendRequestByKey = (personaKey) => invoke("friend_request_by_key", { personaKey }); export const friendAccept = (id) => invoke("friend_accept", { id }); export const friendDecline = (id) => invoke("friend_decline", { id }); export const friendRemove = (id) => invoke("friend_remove", { id }); @@ -170,6 +171,9 @@ export const sharedPlaylistImport = (owner, uuid) => invoke("shared_playlist_imp export const shareSend = (username, playlistId) => invoke("share_send", { username, playlistId }); export const sharesInbox = () => invoke("shares_inbox"); export const shareDismiss = (id) => invoke("share_dismiss", { id }); +export const inboxStatus = () => invoke("inbox_status"); +export const inboxPublish = () => invoke("inbox_publish"); +export const inboxCheck = () => invoke("inbox_check"); export const buddyList = () => invoke("buddy_list"); export const buddyAdd = (username) => invoke("buddy_add", { username }); export const buddyRemove = (username) => invoke("buddy_remove", { username }); diff --git a/src/lib/community.svelte.js b/src/lib/community.svelte.js index 7bfe4bc..13b6241 100644 --- a/src/lib/community.svelte.js +++ b/src/lib/community.svelte.js @@ -71,6 +71,10 @@ export const community = $state({ sharePreviews: {}, /** shared_playlists_mine: what this device has published. */ published: [], + /** inbox_status: the encrypted inbox's state on this device. */ + inbox: null, + /** What the last check found ({new_items, quarantined, pruned}). */ + inboxLast: null, /** persona key → ProfileView | {none} | {error} | {pending}: other * people's signed profiles, read once per session when surfaced. */ remoteProfiles: {}, @@ -323,7 +327,7 @@ export async function initCommunity() { if (p.status === 1 || p.status === 2) noteSeen(p.username); }); } - await Promise.all([refreshFreenet(), loadContacts(), refreshLinks(), refreshFriends(), refreshShares(), refreshPublished()]); + await Promise.all([refreshFreenet(), loadContacts(), refreshLinks(), refreshFriends(), refreshShares(), refreshPublished(), refreshInbox()]); await refreshPersona(); } @@ -489,7 +493,33 @@ export const shareImport = (card) => }); +// ---- the encrypted inbox -------------------------------------------------------------- +export async function refreshInbox() { + try { + community.inbox = await api.inboxStatus(); + } catch { + // stays as it was + } +} +export const publishInbox = () => + run("inbox", async () => { + community.inbox = await api.inboxPublish(); + }); +/** Read our inbox through the node, act on sealed cargo, prune it. */ +export const checkInbox = () => + run("inboxcheck", async () => { + community.inboxLast = await api.inboxCheck(); + await Promise.all([refreshInbox(), refreshFriends(), refreshShares()]); + return community.inboxLast; + }); +export const friendRequestByKey = (personaKey) => friendAction("friend:" + personaKey, () => api.friendRequestByKey(personaKey)); +export const friendshipForKey = (key) => { + const mine = community.friends.filter((f) => f.persona_key === key); + return mine.find((f) => f.state === "friends") ?? mine[0] ?? null; +}; + + // Dev handle beside `__soulstream` (state.svelte.js): probes reach the store // through this, never through a bare import (which would be a second copy). if (import.meta.env.DEV) globalThis.__community = community; -if (import.meta.env.DEV) globalThis.__communityActions = { friendRequest, friendAccept, friendDecline, friendRemove, friendForget, checkLink, refreshFriends, sharedPublish, sharedWithdraw, shareSend, sharePreview, shareImport, refreshShares, refreshPublished }; +if (import.meta.env.DEV) globalThis.__communityActions = { friendRequest, friendRequestByKey, friendAccept, friendDecline, friendRemove, friendForget, checkLink, refreshFriends, sharedPublish, sharedWithdraw, shareSend, sharePreview, shareImport, refreshShares, refreshPublished, publishInbox, checkInbox, refreshInbox }; diff --git a/src/views/Community.svelte b/src/views/Community.svelte index a71e6a1..2cee5f8 100644 --- a/src/views/Community.svelte +++ b/src/views/Community.svelte @@ -77,6 +77,9 @@ shareDismiss, sharedPublish, sharedWithdraw, + publishInbox, + checkInbox, + friendRequestByKey, } from "../lib/community.svelte.js"; onMount(() => { @@ -432,11 +435,24 @@ const id = await shareImport(card); if (id) goToView("playlist", { playlistId: id, label: card.name }); } + // The inbox is polled while this page is open and the node is up: on + // arrival and every 90 s. Sealed cargo becomes friend requests and share + // cards through the same stores the PM carry feeds. + $effect(() => { + if (!nodeUp || !key || !community.inbox?.published) return; + untrack(() => void checkInbox()); + const t = setInterval(() => void checkInbox(), 90_000); + return () => clearInterval(t); + }); + let addKey = $state(""); const isMe = (u) => !!me && (u ?? "").trim().toLowerCase() === me.trim().toLowerCase(); $effect(() => { const lk = drawerLink; if (lk) untrack(() => loadRemoteProfile(lk.persona_key)); }); + $effect(() => { + for (const f of pendingIn()) if (!f.username) untrack(() => loadRemoteProfile(f.persona_key)); + }); // Discover's similar-users shelf asks the server once per session. $effect(() => { if (community.section === "discover" && online) untrack(() => loadSimilar()); @@ -564,9 +580,9 @@
-
{display(f.username)} wants to be friends
-
{f.username} · SoulStream ID {fpShort(f.persona_key)} · asked {fmtWhen(f.updated_at * 1000)}
-
SoulStreamsigned request · their ID proven over Soulseek·open until {fmtWhen(f.expires_at * 1000)}
+
{f.username ? display(f.username) : community.remoteProfiles[f.persona_key]?.display_name || `SoulStream ID ${fpShort(f.persona_key)}`} wants to be friends
+
{f.username ? `${f.username} · ` : ""}SoulStream ID {fpShort(f.persona_key)} · asked {fmtWhen(f.updated_at * 1000)}
+
SoulStream{f.carry === "inbox" ? "sealed · via your encrypted inbox · signed by their key" : "signed request · their ID proven over Soulseek"}·open until {fmtWhen(f.expires_at * 1000)}
@@ -587,10 +603,11 @@
{c.name}
-
{c.entry_count} {c.entry_count === 1 ? "track" : "tracks"} · playlist · shared by {fmtWhen(c.received_at * 1000)}
+
{c.entry_count} {c.entry_count === 1 ? "track" : "tracks"} · playlist · shared by {#if c.from_username}{:else}SoulStream ID {fpShort(c.from_key)}{/if} {fmtWhen(c.received_at * 1000)}
SoulStream signed by {fpShort(c.owner_key)} + {#if c.carry === "inbox"}· sealed · via your encrypted inbox{/if} {#if pv && !pv.pending && !pv.error && !pv.withdrawn}·verified · revision {pv.revision_seq}{/if} {#if pv?.withdrawn}·withdrawn by the owner{/if} {#if pv?.error}·{pv.error}{/if} @@ -837,6 +854,10 @@ +
{ e.preventDefault(); const k = addKey.trim(); if (k) { void friendRequestByKey(k); addKey = ""; } }}> +
+ +
{ e.preventDefault(); void addContact(); }}>
@@ -1237,6 +1258,18 @@ Load remote profile images verified, resized, cached by hash + {#if key} +
+ {#if community.inbox?.published} + encrypted inbox · key {community.inbox.box_key_id} + + {community.inbox.last_check ? `checked ${fmtWhen(community.inbox.last_check * 1000)} · ` : ""}friend requests and shares arrive sealed to a key kept on this device; a persona restored elsewhere publishes a new one + {:else} + + lets other SoulStream users send you friend requests and shares sealed, without Soulseek in between + {/if} +
+ {/if} {/if}