Add server-side moderation service with report submission, user banning/unbanning, and admin listing endpoints. Add client-side user blocking with message filtering in ConversationStore. Server: - ModerationService domain logic (report, ban, unban, list) - Storage trait methods + FileBackedStore + SqlStore implementations - SQL migration 012_moderation.sql (reports + bans tables) - Error codes E031-E033 for moderation - Domain types for all moderation request/response pairs - 10 new tests (6 domain + 4 storage) SDK: - blocked_users table in ConversationStore - block_user, unblock_user, is_blocked, list_blocked methods - load_recent_messages_filtered excludes blocked senders - QpqClient moderation convenience methods - 4 new tests for block/unblock/filter
47 lines
2.1 KiB
Rust
47 lines
2.1 KiB
Rust
//! Structured error codes for server RPC responses.
|
||
//!
|
||
//! Every `capnp::Error::failed()` message is prefixed with a stable code
|
||
//! (E001–E020) so clients can match on the code without parsing free-text.
|
||
|
||
pub const E001_BAD_AUTH_VERSION: &str = "E001";
|
||
pub const E002_EMPTY_TOKEN: &str = "E002";
|
||
pub const E003_INVALID_TOKEN: &str = "E003";
|
||
pub const E004_IDENTITY_KEY_LENGTH: &str = "E004";
|
||
pub const E005_PAYLOAD_EMPTY: &str = "E005";
|
||
pub const E006_PAYLOAD_TOO_LARGE: &str = "E006";
|
||
pub const E007_PACKAGE_EMPTY: &str = "E007";
|
||
pub const E008_PACKAGE_TOO_LARGE: &str = "E008";
|
||
pub const E009_STORAGE_ERROR: &str = "E009";
|
||
pub const E010_OPAQUE_ERROR: &str = "E010";
|
||
pub const E011_USERNAME_EMPTY: &str = "E011";
|
||
pub const E012_WIRE_VERSION: &str = "E012";
|
||
pub const E013_HYBRID_KEY_EMPTY: &str = "E013";
|
||
pub const E014_RATE_LIMITED: &str = "E014";
|
||
pub const E015_QUEUE_FULL: &str = "E015";
|
||
pub const E016_IDENTITY_MISMATCH: &str = "E016";
|
||
pub const E017_SESSION_EXPIRED: &str = "E017";
|
||
pub const E018_USER_EXISTS: &str = "E018";
|
||
pub const E019_NO_PENDING_LOGIN: &str = "E019";
|
||
pub const E020_BAD_PARAMS: &str = "E020";
|
||
pub const E021_CIPHERSUITE_NOT_ALLOWED: &str = "E021";
|
||
pub const E022_CHANNEL_ACCESS_DENIED: &str = "E022";
|
||
pub const E023_CHANNEL_NOT_FOUND: &str = "E023";
|
||
pub const E024_BLOB_TOO_LARGE: &str = "E024";
|
||
pub const E025_BLOB_HASH_LENGTH: &str = "E025";
|
||
pub const E026_BLOB_HASH_MISMATCH: &str = "E026";
|
||
pub const E027_BLOB_NOT_FOUND: &str = "E027";
|
||
pub const E028_ACCOUNT_DELETION_FAILED: &str = "E028";
|
||
pub const E029_DEVICE_LIMIT: &str = "E029";
|
||
pub const E030_DEVICE_NOT_FOUND: &str = "E030";
|
||
#[allow(dead_code)] // used by v2 RPC moderation handlers
|
||
pub const E031_USER_BANNED: &str = "E031";
|
||
#[allow(dead_code)] // used by v2 RPC moderation handlers
|
||
pub const E032_REPORT_EMPTY: &str = "E032";
|
||
#[allow(dead_code)] // used by v2 RPC moderation handlers
|
||
pub const E033_ADMIN_REQUIRED: &str = "E033";
|
||
|
||
/// Build a `capnp::Error::failed()` with the structured code prefix.
|
||
pub fn coded_error(code: &str, msg: impl std::fmt::Display) -> capnp::Error {
|
||
capnp::Error::failed(format!("{code}: {msg}"))
|
||
}
|