diff --git a/crates/ruma-client-api/src/r0/keys/upload_keys.rs b/crates/ruma-client-api/src/r0/keys/upload_keys.rs index e35e09d59b..45e97f602d 100644 --- a/crates/ruma-client-api/src/r0/keys/upload_keys.rs +++ b/crates/ruma-client-api/src/r0/keys/upload_keys.rs @@ -29,6 +29,11 @@ ruma_api! { /// One-time public keys for "pre-key" messages. #[serde(skip_serializing_if = "Option::is_none")] pub one_time_keys: Option, Raw>>, + + /// Fallback public keys for "pre-key" messages. + #[cfg(feature = "unstable-pre-spec")] + #[serde(skip_serializing_if = "Option::is_none", rename = "org.matrix.msc2732.fallback_keys")] + pub fallback_keys: Option, Raw>>, } response: { diff --git a/crates/ruma-client-api/src/r0/sync/sync_events.rs b/crates/ruma-client-api/src/r0/sync/sync_events.rs index 37b58b1118..51fdb1122c 100644 --- a/crates/ruma-client-api/src/r0/sync/sync_events.rs +++ b/crates/ruma-client-api/src/r0/sync/sync_events.rs @@ -93,6 +93,15 @@ ruma_api! { /// currently held on the server for a device. #[serde(default, skip_serializing_if = "BTreeMap::is_empty")] pub device_one_time_keys_count: BTreeMap, + + /// For each key algorithm, the number of unclaimed one-time keys + /// currently held on the server for a device. + /// + /// The presence of this field indicates that the server supports + /// fallback keys. + #[cfg(feature = "unstable-pre-spec")] + #[serde(rename = "org.matrix.msc2732.device_unused_fallback_key_types")] + pub device_unused_fallback_key_types: Option>, } error: crate::Error @@ -116,6 +125,8 @@ impl Response { to_device: Default::default(), device_lists: Default::default(), device_one_time_keys_count: BTreeMap::new(), + #[cfg(feature = "unstable-pre-spec")] + device_unused_fallback_key_types: None, } } } diff --git a/crates/ruma-common/src/encryption.rs b/crates/ruma-common/src/encryption.rs index 14c5028fa1..1ce1ee2bea 100644 --- a/crates/ruma-common/src/encryption.rs +++ b/crates/ruma-common/src/encryption.rs @@ -83,12 +83,28 @@ pub struct SignedKey { /// Signatures for the key object. pub signatures: SignedKeySignatures, + + /// Is this key considered to be a fallback key, defaults to false. + #[cfg(feature = "unstable-pre-spec")] + #[serde(default, skip_serializing_if = "ruma_serde::is_default")] + pub fallback: bool, } impl SignedKey { /// Creates a new `SignedKey` with the given key and signatures. pub fn new(key: String, signatures: SignedKeySignatures) -> Self { - Self { key, signatures } + Self { + key, + signatures, + #[cfg(feature = "unstable-pre-spec")] + fallback: false, + } + } + + /// Creates a new fallback `SignedKey` with the given key and signatures. + #[cfg(feature = "unstable-pre-spec")] + pub fn new_fallback(key: String, signatures: SignedKeySignatures) -> Self { + Self { key, signatures, fallback: true } } }