Skip to main content

tsafe_collab/
types.rs

1use chrono::{DateTime, Utc};
2use serde::{Deserialize, Serialize};
3
4/// A member of a team, identified by their age X25519 public key.
5#[derive(Debug, Clone, Serialize, Deserialize)]
6pub struct MemberEntry {
7    /// The age X25519 bech32 public key for this member.
8    pub pubkey: String,
9    /// UTC timestamp when this member joined the team.
10    pub joined_at: DateTime<Utc>,
11}
12
13/// An age-encrypted DEK envelope.  The server stores and returns this blob
14/// opaquely — it cannot decrypt it because it holds no private key material.
15///
16/// JSON schema: `tsafe/collab-dek/v1`
17///
18/// ```json
19/// {
20///   "schema": "tsafe/collab-dek/v1",
21///   "team_id": "<uuid>",
22///   "recipient_pubkey": "<age X25519 bech32 pubkey>",
23///   "age_ciphertext_b64": "<base64(age-armored ciphertext of 32-byte DEK)>",
24///   "delivered_at": "<ISO-8601 UTC>"
25/// }
26/// ```
27#[derive(Debug, Clone, Serialize, Deserialize)]
28pub struct DekEnvelope {
29    /// Always `"tsafe/collab-dek/v1"`.
30    pub schema: String,
31    /// The team this envelope belongs to.
32    pub team_id: String,
33    /// The age bech32 public key of the intended recipient.
34    pub recipient_pubkey: String,
35    /// Base64-encoded age-armored ciphertext of the 32-byte DEK, encrypted to
36    /// `recipient_pubkey`.  The server never decrypts this.
37    pub age_ciphertext_b64: String,
38    /// UTC timestamp when the envelope was delivered to the server.
39    pub delivered_at: DateTime<Utc>,
40}
41
42impl DekEnvelope {
43    /// Canonical schema identifier for envelope v1.
44    pub const SCHEMA: &'static str = "tsafe/collab-dek/v1";
45}
46
47/// An opaque invite token produced by `CollabRemote::create_invite`.
48///
49/// The token carries the team ID and the invitee's expected public key so that
50/// the confirm step can enforce the TOFU binding (ADR-028).
51#[derive(Debug, Clone, Serialize, Deserialize)]
52pub struct InviteToken {
53    /// Unique token string delivered to the invitee out-of-band.
54    pub token: String,
55    /// Team the invite is for.
56    pub team_id: String,
57    /// The age public key the invite was bound to.
58    pub bound_pubkey: String,
59}
60
61/// Server-side record for a pending invite.
62#[derive(Debug, Clone, Serialize, Deserialize)]
63pub struct InviteRecord {
64    /// The unique token string.
65    pub token: String,
66    /// Team the invite targets.
67    pub team_id: String,
68    /// The age public key of the intended invitee, bound at creation time.
69    pub invitee_pubkey: String,
70    /// UTC timestamp when the invite expires.
71    pub expires_at: DateTime<Utc>,
72}