feat: Sprint 1 — production hardening, TLS lifecycle, CI coverage, lint cleanup
- Fix 3 client panics: replace .unwrap()/.expect() with proper error handling in rpc.rs (AUTH_CONTEXT lock), repl.rs (pending_member), and retry.rs (last_err) - Add --danger-accept-invalid-certs flag with InsecureServerCertVerifier for development TLS bypass, plus mdBook TLS documentation - Add CI coverage job (cargo-tarpaulin) and Docker build validation to GitHub Actions workflow, plus README CI badge - Add [workspace.lints] config, fix 46 clippy warnings across 8 crates, zero warnings on all buildable crates - Update Dockerfile for all 11 workspace members
This commit is contained in:
@@ -147,6 +147,7 @@ pub trait Store: Send + Sync {
|
||||
fn create_channel(&self, member_a: &[u8], member_b: &[u8]) -> Result<(Vec<u8>, bool), StorageError>;
|
||||
|
||||
/// Get the two members of a channel by channel_id (16 bytes). Returns (member_a, member_b) in sorted order.
|
||||
#[allow(clippy::type_complexity)]
|
||||
fn get_channel_members(&self, channel_id: &[u8]) -> Result<Option<(Vec<u8>, Vec<u8>)>, StorageError>;
|
||||
|
||||
// ── Federation ──────────────────────────────────────────────────────────
|
||||
@@ -232,6 +233,7 @@ pub struct FileBackedStore {
|
||||
channels_path: PathBuf,
|
||||
key_packages: Mutex<HashMap<Vec<u8>, VecDeque<Vec<u8>>>>,
|
||||
deliveries: Mutex<QueueMapV3>,
|
||||
#[allow(clippy::type_complexity)]
|
||||
channels: Mutex<HashMap<Vec<u8>, (Vec<u8>, Vec<u8>)>>,
|
||||
hybrid_keys: Mutex<HashMap<Vec<u8>, Vec<u8>>>,
|
||||
users: Mutex<HashMap<String, Vec<u8>>>,
|
||||
@@ -282,6 +284,7 @@ impl FileBackedStore {
|
||||
})
|
||||
}
|
||||
|
||||
#[allow(clippy::type_complexity)]
|
||||
fn load_channels(
|
||||
path: &Path,
|
||||
) -> Result<HashMap<Vec<u8>, (Vec<u8>, Vec<u8>)>, StorageError> {
|
||||
@@ -435,13 +438,13 @@ impl Store for FileBackedStore {
|
||||
map.entry(identity_key.to_vec())
|
||||
.or_default()
|
||||
.push_back(package);
|
||||
self.flush_kp_map(&self.kp_path, &*map)
|
||||
self.flush_kp_map(&self.kp_path, &map)
|
||||
}
|
||||
|
||||
fn fetch_key_package(&self, identity_key: &[u8]) -> Result<Option<Vec<u8>>, StorageError> {
|
||||
let mut map = lock(&self.key_packages)?;
|
||||
let package = map.get_mut(identity_key).and_then(|q| q.pop_front());
|
||||
self.flush_kp_map(&self.kp_path, &*map)?;
|
||||
self.flush_kp_map(&self.kp_path, &map)?;
|
||||
Ok(package)
|
||||
}
|
||||
|
||||
@@ -460,7 +463,7 @@ impl Store for FileBackedStore {
|
||||
let seq = *entry;
|
||||
*entry = seq + 1;
|
||||
inner.map.entry(key).or_default().push_back(SeqEntry { seq, data: payload });
|
||||
self.flush_delivery_map(&self.ds_path, &*inner)?;
|
||||
self.flush_delivery_map(&self.ds_path, &inner)?;
|
||||
Ok(seq)
|
||||
}
|
||||
|
||||
@@ -479,7 +482,7 @@ impl Store for FileBackedStore {
|
||||
.get_mut(&key)
|
||||
.map(|q| q.drain(..).map(|e| (e.seq, e.data)).collect())
|
||||
.unwrap_or_default();
|
||||
self.flush_delivery_map(&self.ds_path, &*inner)?;
|
||||
self.flush_delivery_map(&self.ds_path, &inner)?;
|
||||
Ok(messages)
|
||||
}
|
||||
|
||||
@@ -502,7 +505,7 @@ impl Store for FileBackedStore {
|
||||
q.drain(..count).map(|e| (e.seq, e.data)).collect()
|
||||
})
|
||||
.unwrap_or_default();
|
||||
self.flush_delivery_map(&self.ds_path, &*inner)?;
|
||||
self.flush_delivery_map(&self.ds_path, &inner)?;
|
||||
Ok(messages)
|
||||
}
|
||||
|
||||
@@ -527,7 +530,7 @@ impl Store for FileBackedStore {
|
||||
) -> Result<(), StorageError> {
|
||||
let mut map = lock(&self.hybrid_keys)?;
|
||||
map.insert(identity_key.to_vec(), hybrid_pk);
|
||||
self.flush_hybrid_keys(&self.hk_path, &*map)
|
||||
self.flush_hybrid_keys(&self.hk_path, &map)
|
||||
}
|
||||
|
||||
fn fetch_hybrid_key(&self, identity_key: &[u8]) -> Result<Option<Vec<u8>>, StorageError> {
|
||||
@@ -615,7 +618,7 @@ impl Store for FileBackedStore {
|
||||
v.insert(record);
|
||||
}
|
||||
}
|
||||
self.flush_users(&self.users_path, &*map)
|
||||
self.flush_users(&self.users_path, &map)
|
||||
}
|
||||
|
||||
fn get_user_record(&self, username: &str) -> Result<Option<Vec<u8>>, StorageError> {
|
||||
@@ -635,7 +638,7 @@ impl Store for FileBackedStore {
|
||||
) -> Result<(), StorageError> {
|
||||
let mut map = lock(&self.identity_keys)?;
|
||||
map.insert(username.to_string(), identity_key);
|
||||
self.flush_map_string_bytes(&self.identity_keys_path, &*map)
|
||||
self.flush_map_string_bytes(&self.identity_keys_path, &map)
|
||||
}
|
||||
|
||||
fn get_user_identity_key(&self, username: &str) -> Result<Option<Vec<u8>>, StorageError> {
|
||||
@@ -697,7 +700,7 @@ impl Store for FileBackedStore {
|
||||
} else {
|
||||
0
|
||||
};
|
||||
self.flush_delivery_map(&self.ds_path, &*inner)?;
|
||||
self.flush_delivery_map(&self.ds_path, &inner)?;
|
||||
Ok(removed)
|
||||
}
|
||||
|
||||
@@ -730,7 +733,7 @@ impl Store for FileBackedStore {
|
||||
rand::thread_rng().fill_bytes(&mut channel_id);
|
||||
let channel_id = channel_id.to_vec();
|
||||
map.insert(channel_id.clone(), (a, b));
|
||||
self.flush_channels(&self.channels_path, &*map)?;
|
||||
self.flush_channels(&self.channels_path, &map)?;
|
||||
Ok((channel_id, true))
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user