feat: GuiPresence (chat-service presence backend, gateway route, mod module); restore TODO history

This commit is contained in:
loki5512344 2026-10-02 13:41:49 +02:00
parent 8d9a2ad0d6
commit e82efb74e7
Signed by: boba
GPG key ID: 253067914055423B
44 changed files with 2202 additions and 19 deletions

View file

@ -0,0 +1,46 @@
//! Validation of the opaque GUI payload and server key. The payload is a
//! base64 string produced by the mod (header + up to 8 cursor samples); the
//! service never decodes it, it only bounds what it stores and relays.
/// Header (4 bytes) + 8 samples x 4 bytes = 36 bytes = 48 base64 characters.
pub const MAX_PAYLOAD_CHARS: usize = 48;
pub const MAX_SERVER_CHARS: usize = 64;
pub const MAX_WANT: usize = 40;
pub fn valid_payload(s: &str) -> bool {
!s.is_empty()
&& s.len() <= MAX_PAYLOAD_CHARS
&& s.bytes().all(|b| b.is_ascii_alphanumeric() || matches!(b, b'+' | b'/' | b'='))
}
/// Normalised server key: trimmed, lower-case, no control characters, bounded.
pub fn normalize_server(s: &str) -> Option<String> {
let s = s.trim().to_ascii_lowercase();
if s.is_empty() || s.chars().count() > MAX_SERVER_CHARS || s.chars().any(|c| c.is_control()) {
return None;
}
Some(s)
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn payload_charset_and_length() {
assert!(valid_payload("AQEAAAA="));
assert!(!valid_payload(""));
assert!(!valid_payload("has space"));
assert!(!valid_payload("<script>"));
assert!(!valid_payload(&"A".repeat(MAX_PAYLOAD_CHARS + 1)));
assert!(valid_payload(&"A".repeat(MAX_PAYLOAD_CHARS)));
}
#[test]
fn server_is_normalised() {
assert_eq!(normalize_server(" Play.Example.COM ").as_deref(), Some("play.example.com"));
assert_eq!(normalize_server(""), None);
assert_eq!(normalize_server("a\nb"), None);
assert_eq!(normalize_server(&"x".repeat(65)), None);
}
}