v0.3.5: Private blob encryption, blob prefetch, intent-based filtering, crypto refactoring
Private blob encryption:
- Encrypted posts (Friends/Circle/Direct) now encrypt attachment blobs with same CEK
- Public blobs unchanged, CID computed on ciphertext for private
- decrypt_blob_for_post/get_blob_for_post for transparent decryption on retrieval
Blob prefetch:
- Pull cycle and sync_with eagerly fetch missing blobs after post sync
- prefetch_blobs_from_peer scans for missing attachments, fetches via fallback chain
- Runs outside conn_mgr lock at Node level
Crypto refactoring:
- Extracted: encrypt/decrypt_bytes_with_cek, wrap/unwrap_cek_for_recipients
- unwrap_cek_for_recipient, unwrap_group_cek, random_cek
- encrypt_post_with_cek, encrypt_post_for_group_with_cek variants
- All existing functions refactored to delegate, 19 crypto tests pass
Intent-based filtering:
- intent_kind field on PostDto ("public"/"friends"/"circle"/"direct"/"unknown")
- Feed/MyPosts filter on intentKind !== 'direct' instead of visibility
- Messages filter with backward-compatible fallback for pre-intent posts
- get_post_intent storage method
IPC updates:
- resolve_blob_data helper using get_blob_for_post with network fallback
- sanitize_download_filename prevents path traversal
- get_blob_path accepts optional post_id_hex
Website:
- Mobile hamburger nav on all pages
- Mesh/Non-mesh N1 labels in network diagnostics
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
parent
0abc244ee9
commit
a41b11c0b8
14 changed files with 562 additions and 325 deletions
|
|
@ -644,6 +644,23 @@ impl Storage {
|
|||
}
|
||||
}
|
||||
|
||||
/// Get the visibility intent for a post (if stored).
|
||||
pub fn get_post_intent(&self, id: &PostId) -> anyhow::Result<Option<VisibilityIntent>> {
|
||||
let mut stmt = self.conn.prepare(
|
||||
"SELECT visibility_intent FROM posts WHERE id = ?1",
|
||||
)?;
|
||||
let mut rows = stmt.query(params![id.as_slice()])?;
|
||||
if let Some(row) = rows.next()? {
|
||||
let intent_json: Option<String> = row.get(0)?;
|
||||
match intent_json {
|
||||
Some(json) => Ok(serde_json::from_str(&json).ok()),
|
||||
None => Ok(None),
|
||||
}
|
||||
} else {
|
||||
Ok(None)
|
||||
}
|
||||
}
|
||||
|
||||
pub fn list_post_ids(&self) -> anyhow::Result<Vec<PostId>> {
|
||||
let mut stmt = self.conn.prepare("SELECT id FROM posts")?;
|
||||
let rows = stmt.query_map([], |row| {
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue