1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192
//! `POST /_matrix/identity/*/store-invite`
//!
//! Store pending invitations to a user's third-party ID.
pub mod v2 {
//! `/v2/` ([spec])
//!
//! [spec]: https://spec.matrix.org/latest/identity-service-api/#post_matrixidentityv2store-invite
use ruma_common::{
api::{request, response, Metadata},
metadata,
room::RoomType,
thirdparty::Medium,
OwnedMxcUri, OwnedRoomAliasId, OwnedRoomId, OwnedUserId,
};
use serde::{ser::SerializeSeq, Deserialize, Serialize};
const METADATA: Metadata = metadata! {
method: POST,
rate_limited: false,
authentication: AccessToken,
history: {
1.0 => "/_matrix/identity/v2/store-invite",
}
};
/// Request type for the `store_invitation` endpoint.
#[request]
pub struct Request {
/// The type of the third party identifier for the invited user.
///
/// Currently, only `Medium::Email` is supported.
pub medium: Medium,
/// The email address of the invited user.
pub address: String,
/// The Matrix room ID to which the user is invited.
pub room_id: OwnedRoomId,
/// The Matrix user ID of the inviting user.
pub sender: OwnedUserId,
/// The Matrix room alias for the room to which the user is invited.
///
/// This should be retrieved from the `m.room.canonical` state event.
#[serde(skip_serializing_if = "Option::is_none")]
pub room_alias: Option<OwnedRoomAliasId>,
/// The Content URI for the room to which the user is invited.
///
/// This should be retrieved from the `m.room.avatar` state event.
#[serde(skip_serializing_if = "Option::is_none")]
pub room_avatar_url: Option<OwnedMxcUri>,
/// The `join_rule` for the room to which the user is invited.
///
/// This should be retrieved from the `m.room.join_rules` state event.
#[serde(skip_serializing_if = "Option::is_none")]
pub room_join_rules: Option<String>,
/// The name of the room to which the user is invited.
///
/// This should be retrieved from the `m.room.name` state event.
#[serde(skip_serializing_if = "Option::is_none")]
pub room_name: Option<String>,
/// The type of the room to which the user is invited.
///
/// This should be retrieved from the `m.room.create` state event.
#[serde(skip_serializing_if = "Option::is_none")]
pub room_type: Option<RoomType>,
/// The display name of the user ID initiating the invite.
#[serde(skip_serializing_if = "Option::is_none")]
pub sender_display_name: Option<String>,
/// The Content URI for the avater of the user ID initiating the invite.
#[serde(skip_serializing_if = "Option::is_none")]
pub sender_avatar_url: Option<OwnedMxcUri>,
}
/// Response type for the `store_invitation` endpoint.
#[response]
pub struct Response {
/// The generated token.
///
/// Must be a string consisting of the characters `[0-9a-zA-Z.=_-]`. Its length must not
/// exceed 255 characters and it must not be empty.
pub token: String,
/// A list of [server's long-term public key, generated ephemeral public key].
pub public_keys: PublicKeys,
/// The generated (redacted) display_name.
///
/// An example is `f...@b...`.
pub display_name: String,
}
impl Request {
/// Creates a new `Request with the given medium, email address, room ID and sender.
pub fn new(
medium: Medium,
address: String,
room_id: OwnedRoomId,
sender: OwnedUserId,
) -> Self {
Self {
medium,
address,
room_id,
sender,
room_alias: None,
room_avatar_url: None,
room_join_rules: None,
room_name: None,
room_type: None,
sender_display_name: None,
sender_avatar_url: None,
}
}
/// Creates a new `Request` with the given email address, room ID and sender.
pub fn email(address: String, room_id: OwnedRoomId, sender: OwnedUserId) -> Self {
Self::new(Medium::Email, address, room_id, sender)
}
}
impl Response {
/// Creates a new `Response` with the given token, public keys and display name.
pub fn new(token: String, public_keys: PublicKeys, display_name: String) -> Self {
Self { token, public_keys, display_name }
}
}
/// The server's long-term public key and generated ephemeral public key.
#[derive(Debug, Clone)]
#[allow(clippy::exhaustive_structs)]
pub struct PublicKeys {
/// The server's long-term public key.
pub server_key: PublicKey,
/// The generated ephemeral public key.
pub ephemeral_key: PublicKey,
}
impl<'de> Deserialize<'de> for PublicKeys {
fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
where
D: serde::Deserializer<'de>,
{
let [server_key, ephemeral_key] = <[PublicKey; 2]>::deserialize(deserializer)?;
Ok(Self { server_key, ephemeral_key })
}
}
impl Serialize for PublicKeys {
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
where
S: serde::Serializer,
{
let mut seq = serializer.serialize_seq(Some(2))?;
seq.serialize_element(&self.server_key)?;
seq.serialize_element(&self.ephemeral_key)?;
seq.end()
}
}
/// A server's long-term or ephemeral public key.
#[derive(Clone, Debug, Serialize, Deserialize)]
#[non_exhaustive]
pub struct PublicKey {
/// The public key, encoded using [unpadded Base64](https://spec.matrix.org/latest/appendices/#unpadded-base64).
pub public_key: String,
/// The URI of an endpoint where the validity of this key can be checked by passing it as a
/// `public_key` query parameter.
pub key_validity_url: String,
}
impl PublicKey {
/// Constructs a new `PublicKey` with the given encoded public key and key validity URL.
pub fn new(public_key: String, key_validity_url: String) -> Self {
Self { public_key, key_validity_url }
}
}
}