doc: add and sync code docs from OAPI

This commit is contained in:
oxalica 2024-10-17 07:30:33 -04:00
parent 71c5f038fa
commit ee85112fb6
4 changed files with 31 additions and 2 deletions

View file

@ -10,12 +10,16 @@ use ed25519_dalek::{
use rand::RngCore; use rand::RngCore;
use serde::{Deserialize, Serialize}; use serde::{Deserialize, Serialize};
/// User pubkey pair to uniquely identity a user.
#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)] #[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
pub struct UserKey { pub struct UserKey {
/// The identity key (`id_key`).
pub id_key: PubKey, pub id_key: PubKey,
/// The action key (`act_key`).
pub act_key: PubKey, pub act_key: PubKey,
} }
/// Raw Ed25519 public key, serialized in hex-encoded string.
#[derive(Clone, PartialEq, Eq, Serialize, Deserialize)] #[derive(Clone, PartialEq, Eq, Serialize, Deserialize)]
#[serde(transparent)] #[serde(transparent)]
pub struct PubKey(#[serde(with = "hex::serde")] pub [u8; PUBLIC_KEY_LENGTH]); pub struct PubKey(#[serde(with = "hex::serde")] pub [u8; PUBLIC_KEY_LENGTH]);

View file

@ -21,6 +21,7 @@ pub struct UserIdentityDesc {
pub profile: Signed<UserProfile>, pub profile: Signed<UserProfile>,
} }
/// Error on verifying [`UserIdentityDesc`].
#[derive(Debug, Error)] #[derive(Debug, Error)]
#[error(transparent)] #[error(transparent)]
pub struct VerifyError(#[from] VerifyErrorImpl); pub struct VerifyError(#[from] VerifyErrorImpl);
@ -44,6 +45,7 @@ enum VerifyErrorImpl {
} }
impl UserIdentityDesc { impl UserIdentityDesc {
/// The relative path from domain to the well-known identity description file.
pub const WELL_KNOWN_PATH: &str = "/.well-known/blah/identity.json"; pub const WELL_KNOWN_PATH: &str = "/.well-known/blah/identity.json";
/// Validate signatures of the identity description at given time. /// Validate signatures of the identity description at given time.
@ -89,21 +91,33 @@ impl UserIdentityDesc {
} }
} }
/// Description of an action key.
#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)] #[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
#[serde(tag = "typ", rename = "user_act_key")] #[serde(tag = "typ", rename = "user_act_key")]
pub struct UserActKeyDesc { pub struct UserActKeyDesc {
/// Per-device action key for signing msgs.
pub act_key: PubKey, pub act_key: PubKey,
/// The UNIX timestamp of expire time.
pub expire_time: u64, pub expire_time: u64,
/// User-provided arbitrary comment string.
pub comment: String, pub comment: String,
} }
/// User profile describing their non-cryptographic metadata.
#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)] #[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
#[serde(tag = "typ", rename = "user_profile")] #[serde(tag = "typ", rename = "user_profile")]
pub struct UserProfile { pub struct UserProfile {
/// Preferred chat servers ordered by decreasing preference, for starting private chats.
pub preferred_chat_server_urls: Vec<Url>, pub preferred_chat_server_urls: Vec<Url>,
/// Allowed identity URLs (`id_url`) where this profile should be retrieved on.
pub id_urls: Vec<IdUrl>, pub id_urls: Vec<IdUrl>,
} }
/// Identity URL.
///
/// In short, it must be a valid URL in format `https?://some.domain.name(:\d+)?/`.
/// Servers may pose additional requirement including: requiring HTTPS, rejecting ports,
/// rejecting `localhost` or local hostnames, and etc.
#[derive(Debug, Clone, PartialEq, Eq, Deserialize)] #[derive(Debug, Clone, PartialEq, Eq, Deserialize)]
#[serde(try_from = "Url")] #[serde(try_from = "Url")]
pub struct IdUrl(Url); pub struct IdUrl(Url);
@ -128,6 +142,7 @@ impl IdUrl {
/// which is 64. Adding the schema and port, it should still be below 80. /// which is 64. Adding the schema and port, it should still be below 80.
/// ///
/// Ref: <https://www.rfc-editor.org/rfc/rfc3280> /// Ref: <https://www.rfc-editor.org/rfc/rfc3280>
// TODO: IPFS URLs can be extensively long, should we keep this limit?
pub const MAX_LEN: usize = 80; pub const MAX_LEN: usize = 80;
} }
@ -139,6 +154,7 @@ impl ops::Deref for IdUrl {
} }
} }
/// Error on validating [`IdUrl`].
#[derive(Debug, Clone, PartialEq, Eq, Error)] #[derive(Debug, Clone, PartialEq, Eq, Error)]
#[non_exhaustive] #[non_exhaustive]
pub enum IdUrlError { pub enum IdUrlError {

View file

@ -55,9 +55,15 @@ impl<T> WithMsgId<T> {
#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)] #[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
#[serde(tag = "typ", rename = "user_register")] #[serde(tag = "typ", rename = "user_register")]
pub struct UserRegisterPayload { pub struct UserRegisterPayload {
/// The normalized server URL to register on.
/// It must matches chat server's base_url.
pub server_url: Url, pub server_url: Url,
/// The normalized identity URL.
/// It should be in form `https://<domain>/`.
pub id_url: IdUrl, pub id_url: IdUrl,
/// Hex encoded user primary key (`id_key`).
pub id_key: PubKey, pub id_key: PubKey,
/// Server specific register challenge.
#[serde(default, skip_serializing_if = "Option::is_none")] #[serde(default, skip_serializing_if = "Option::is_none")]
pub challenge: Option<UserRegisterChallengeResponse>, pub challenge: Option<UserRegisterChallengeResponse>,
} }
@ -68,7 +74,10 @@ pub struct UserRegisterPayload {
pub enum UserRegisterChallengeResponse { pub enum UserRegisterChallengeResponse {
/// Proof of work challenge containing the same nonce from server challenge request. /// Proof of work challenge containing the same nonce from server challenge request.
/// The whole msg signee hash should have enough prefix zero bits. /// The whole msg signee hash should have enough prefix zero bits.
Pow { nonce: u32 }, Pow {
/// The challenge nonce retrieved from a recent GET response of `/_blah/user/me`.
nonce: u32,
},
} }
// FIXME: `deny_unknown_fields` breaks this. // FIXME: `deny_unknown_fields` breaks this.

View file

@ -128,7 +128,7 @@ pub struct RoomMetadata {
/// Response to list room msgs. /// Response to list room msgs.
#[derive(Debug, Default, Clone, PartialEq, Eq, Serialize, Deserialize)] #[derive(Debug, Default, Clone, PartialEq, Eq, Serialize, Deserialize)]
pub struct RoomMsgs { pub struct RoomMsgs {
/// Result list of msgs. /// Result list of msgs ordered in reverse of server-received time.
pub msgs: Vec<SignedChatMsgWithId>, pub msgs: Vec<SignedChatMsgWithId>,
/// The skip-token to fetch the next page. /// The skip-token to fetch the next page.
#[serde(skip_serializing_if = "Option::is_none")] #[serde(skip_serializing_if = "Option::is_none")]