ap_proxy_protocol/messages.rs
1//! Protocol message types for client-proxy communication.
2//!
3//! This module defines the message types used in the three-phase protocol:
4//!
5//! # Message Flow
6//!
7//! ## Phase 1: Authentication
8//! 1. Server → Client: [`Messages::AuthChallenge`] - Random challenge for the client to sign
9//! 2. Client → Server: [`Messages::AuthResponse`] - Client's identity and signature
10//!
11//! ## Phase 2: Rendezvous (Optional)
12//! 3. Client → Server: [`Messages::GetRendevouz`] - Request a temporary code
13//! 4. Server → Client: [`Messages::RendevouzInfo`] - The generated code (e.g., "ABC-DEF-GHI")
14//! 5. Client → Server: [`Messages::GetIdentity`] - Look up identity by code
15//! 6. Server → Client: [`Messages::IdentityInfo`] - The identity associated with the code
16//!
17//! ## Phase 3: Messaging
18//! 7. Client → Server: [`Messages::Send`] - Client sends message (destination + payload only)
19//! 8. Server → Client: [`Messages::Send`] - Server forwards with validated source added
20//!
21//! All messages are serialized as JSON over WebSocket connections.
22
23use crate::{
24 auth::{Challenge, ChallengeResponse, Identity, IdentityFingerprint},
25 rendevouz::RendevouzCode,
26};
27use serde::{Deserialize, Serialize};
28
29/// Protocol messages exchanged between clients and the proxy server.
30///
31/// Messages flow through three distinct phases: authentication, optional rendezvous
32/// for peer discovery, and message routing between authenticated clients.
33#[derive(Debug, Clone, Serialize, Deserialize)]
34pub enum Messages {
35 /// Server sends a random challenge to a newly connected client.
36 ///
37 /// The client must sign this challenge with its private key to authenticate.
38 /// Sent immediately after WebSocket connection establishment.
39 AuthChallenge(Challenge),
40
41 /// Client responds to authentication challenge with identity and signature.
42 ///
43 /// Contains the client's public [`Identity`] and a [`ChallengeResponse`] (signature).
44 /// The server verifies the signature to authenticate the client.
45 AuthResponse(Identity, ChallengeResponse),
46
47 /// Client requests a temporary rendezvous code.
48 ///
49 /// The server will generate a unique code (format: "ABC-DEF-GHI") and send it back
50 /// via [`Messages::RendevouzInfo`]. The code expires after 5 minutes.
51 GetRendevouz,
52
53 /// Server responds with the generated rendezvous code.
54 ///
55 /// The code can be shared with other clients to enable them to discover
56 /// this client's identity via [`Messages::GetIdentity`].
57 RendevouzInfo(RendevouzCode),
58
59 /// Client looks up an identity using a rendezvous code.
60 ///
61 /// If the code is valid and hasn't expired, the server responds with
62 /// [`Messages::IdentityInfo`]. Codes are single-use and deleted after lookup.
63 GetIdentity(RendevouzCode),
64
65 /// Server responds with the identity associated with a rendezvous code.
66 ///
67 /// Contains both the [`IdentityFingerprint`] (SHA256 hash) and full [`Identity`]
68 /// (public key). After sending this, the rendezvous code is deleted.
69 IdentityInfo {
70 /// SHA256 fingerprint of the identity's public key
71 fingerprint: IdentityFingerprint,
72 /// The full public identity (MlDsa65 public key)
73 identity: Identity,
74 },
75
76 /// A message routed from one client to another through the proxy.
77 ///
78 /// When sent by clients, only contains destination and payload. The source is
79 /// automatically set by the proxy based on the authenticated identity.
80 /// When forwarded to recipients, includes the validated source fingerprint.
81 Send {
82 /// The authenticated sender's fingerprint (added by proxy)
83 #[serde(skip_serializing_if = "Option::is_none")]
84 source: Option<IdentityFingerprint>,
85 /// The recipient's fingerprint
86 destination: IdentityFingerprint,
87 /// Arbitrary payload data (should be encrypted by clients)
88 payload: Vec<u8>,
89 },
90}