Skip to main content

auths_pairing_protocol/
types.rs

1use base64::{Engine, engine::general_purpose::URL_SAFE_NO_PAD};
2use serde::{Deserialize, Serialize};
3
4/// A base64url-encoded (no padding) byte string.
5#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
6#[cfg_attr(feature = "schema", derive(schemars::JsonSchema))]
7#[serde(transparent)]
8pub struct Base64UrlEncoded(String);
9
10impl Base64UrlEncoded {
11    pub fn from_raw(s: String) -> Self {
12        Self(s)
13    }
14
15    pub fn encode(bytes: &[u8]) -> Self {
16        Self(URL_SAFE_NO_PAD.encode(bytes))
17    }
18
19    pub fn decode(&self) -> Result<Vec<u8>, base64::DecodeError> {
20        URL_SAFE_NO_PAD.decode(&self.0)
21    }
22
23    pub fn as_str(&self) -> &str {
24        &self.0
25    }
26}
27
28impl std::ops::Deref for Base64UrlEncoded {
29    type Target = str;
30    fn deref(&self) -> &str {
31        &self.0
32    }
33}
34
35impl std::fmt::Display for Base64UrlEncoded {
36    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
37        f.write_str(&self.0)
38    }
39}
40
41/// Session status.
42#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)]
43#[cfg_attr(feature = "schema", derive(schemars::JsonSchema))]
44#[serde(rename_all = "lowercase")]
45pub enum SessionStatus {
46    Pending,
47    Responded,
48    Confirmed,
49    Aborted,
50    Completed,
51    Cancelled,
52    Expired,
53}
54
55/// Request to create a new pairing session.
56#[derive(Debug, Clone, Serialize, Deserialize)]
57#[cfg_attr(feature = "schema", derive(schemars::JsonSchema))]
58pub struct CreateSessionRequest {
59    pub session_id: String,
60    pub controller_did: String,
61    pub ephemeral_pubkey: Base64UrlEncoded,
62    pub short_code: String,
63    #[serde(default)]
64    pub capabilities: Vec<String>,
65    pub expires_at: i64,
66}
67
68/// Response to session creation.
69#[derive(Debug, Serialize, Deserialize)]
70#[cfg_attr(feature = "schema", derive(schemars::JsonSchema))]
71pub struct CreateSessionResponse {
72    pub session_id: String,
73    pub status: SessionStatus,
74    pub short_code: String,
75    pub uri: String,
76    pub ttl_seconds: u64,
77}
78
79/// Request to submit a pairing response.
80#[derive(Debug, Clone, Serialize, Deserialize)]
81#[cfg_attr(feature = "schema", derive(schemars::JsonSchema))]
82pub struct SubmitResponseRequest {
83    pub device_x25519_pubkey: Base64UrlEncoded,
84    pub device_signing_pubkey: Base64UrlEncoded,
85    /// Responder's DID string (e.g. `did:key:z6Mk...`).
86    pub device_did: String,
87    pub signature: Base64UrlEncoded,
88    #[serde(skip_serializing_if = "Option::is_none")]
89    pub device_name: Option<String>,
90}
91
92/// Response when getting session status.
93#[derive(Debug, Serialize, Deserialize)]
94#[cfg_attr(feature = "schema", derive(schemars::JsonSchema))]
95pub struct GetSessionResponse {
96    pub session_id: String,
97    pub status: SessionStatus,
98    pub ttl_seconds: u64,
99    #[serde(skip_serializing_if = "Option::is_none")]
100    pub token: Option<CreateSessionRequest>,
101    #[serde(skip_serializing_if = "Option::is_none")]
102    pub response: Option<SubmitResponseRequest>,
103}
104
105/// Response for successful operations.
106#[derive(Debug, Serialize, Deserialize)]
107#[cfg_attr(feature = "schema", derive(schemars::JsonSchema))]
108pub struct SuccessResponse {
109    pub success: bool,
110    pub message: String,
111}
112
113/// Request to submit a SAS confirmation (or abort).
114#[derive(Debug, Clone, Serialize, Deserialize)]
115#[cfg_attr(feature = "schema", derive(schemars::JsonSchema))]
116pub struct SubmitConfirmationRequest {
117    #[serde(skip_serializing_if = "Option::is_none")]
118    pub encrypted_attestation: Option<String>,
119    #[serde(default)]
120    pub aborted: bool,
121}
122
123/// Response when polling for confirmation.
124#[derive(Debug, Serialize, Deserialize)]
125#[cfg_attr(feature = "schema", derive(schemars::JsonSchema))]
126pub struct GetConfirmationResponse {
127    #[serde(skip_serializing_if = "Option::is_none")]
128    pub encrypted_attestation: Option<String>,
129    #[serde(default)]
130    pub aborted: bool,
131}