mirror of
https://github.com/matrix-org/matrix-rust-sdk.git
synced 2026-02-13 17:12:19 -05:00
feat(client): make it possible to subscribe to key upload errors (#6135)
Signed-off-by: Johannes Marbach <n0-0ne+github@mailbox.org>
This commit is contained in:
@@ -31,6 +31,9 @@ All notable changes to this project will be documented in this file.
|
||||
|
||||
### Features
|
||||
|
||||
- Add `Client::subscribe_to_duplicate_key_upload_errors` for listening to duplicate key
|
||||
upload errors from `/keys/upload`.
|
||||
([#6135](https://github.com/matrix-org/matrix-rust-sdk/pull/6135/))
|
||||
- Add `NotificationItem::raw_event` to get the raw event content of the event that triggered the notification, which can be useful for debugging and to support clients that want to implement custom handling for certain notifications. ([#6122](https://github.com/matrix-org/matrix-rust-sdk/pull/6122))
|
||||
- [**breaking**] Extend `TimelineFocus::Event` to allow marking the target
|
||||
event as the root of a thread.
|
||||
|
||||
@@ -237,6 +237,32 @@ pub trait AccountDataListener: SyncOutsideWasm + SendOutsideWasm {
|
||||
fn on_change(&self, event: AccountDataEvent);
|
||||
}
|
||||
|
||||
/// A listener for duplicate key upload errors triggered by requests to
|
||||
/// /keys/upload.
|
||||
#[matrix_sdk_ffi_macros::export(callback_interface)]
|
||||
pub trait DuplicateKeyUploadErrorListener: SyncOutsideWasm + SendOutsideWasm {
|
||||
/// Called once when uploading keys fails.
|
||||
fn on_duplicate_key_upload_error(&self, message: Option<DuplicateOneTimeKeyErrorMessage>);
|
||||
}
|
||||
|
||||
/// Information about the old and new key that caused a duplicate key upload
|
||||
/// error in /keys/upload.
|
||||
#[derive(uniffi::Record)]
|
||||
pub struct DuplicateOneTimeKeyErrorMessage {
|
||||
/// The previously uploaded one-time key, encoded as unpadded base64.
|
||||
pub old_key: String,
|
||||
/// The one-time key we attempted to upload, encoded as unpadded base64
|
||||
pub new_key: String,
|
||||
}
|
||||
|
||||
impl From<matrix_sdk::encryption::DuplicateOneTimeKeyErrorMessage>
|
||||
for DuplicateOneTimeKeyErrorMessage
|
||||
{
|
||||
fn from(value: matrix_sdk::encryption::DuplicateOneTimeKeyErrorMessage) -> Self {
|
||||
Self { old_key: value.old_key.to_base64(), new_key: value.new_key.to_base64() }
|
||||
}
|
||||
}
|
||||
|
||||
/// A listener for changes of room account data events.
|
||||
#[matrix_sdk_ffi_macros::export(callback_interface)]
|
||||
pub trait RoomAccountDataListener: SyncOutsideWasm + SendOutsideWasm {
|
||||
@@ -748,6 +774,28 @@ impl Client {
|
||||
})))
|
||||
}
|
||||
|
||||
/// Subscribe to duplicate key upload errors triggered by requests to
|
||||
/// /keys/upload.
|
||||
pub fn subscribe_to_duplicate_key_upload_errors(
|
||||
&self,
|
||||
listener: Box<dyn DuplicateKeyUploadErrorListener>,
|
||||
) -> Arc<TaskHandle> {
|
||||
let mut subscriber = self.inner.subscribe_to_duplicate_key_upload_errors();
|
||||
|
||||
Arc::new(TaskHandle::new(get_runtime_handle().spawn(async move {
|
||||
loop {
|
||||
match subscriber.recv().await {
|
||||
Ok(message) => {
|
||||
listener.on_duplicate_key_upload_error(message.map(|m| m.into()))
|
||||
}
|
||||
Err(err) => {
|
||||
error!("error when listening to key upload errors: {err}");
|
||||
}
|
||||
}
|
||||
}
|
||||
})))
|
||||
}
|
||||
|
||||
/// Subscribe to updates of global account data events.
|
||||
///
|
||||
/// Be careful that only the most recent value can be observed. Subscribers
|
||||
|
||||
@@ -8,6 +8,9 @@ All notable changes to this project will be documented in this file.
|
||||
|
||||
### Features
|
||||
|
||||
- Add `Client::subscribe_to_duplicate_key_upload_errors` for listening to duplicate key
|
||||
upload errors from `/keys/upload`.
|
||||
([#6135](https://github.com/matrix-org/matrix-rust-sdk/pull/6135/))
|
||||
- Add `Room::pin_event` and `Room::unpin_event`, which allow pinning and unpinning events from a
|
||||
room. These were extracted from the `matrix_sdk_ui` crate, with no changes in functionality.
|
||||
([#6106](https://github.com/matrix-org/matrix-rust-sdk/pull/6106))
|
||||
|
||||
@@ -119,7 +119,10 @@ use crate::{
|
||||
#[cfg(feature = "e2e-encryption")]
|
||||
use crate::{
|
||||
cross_process_lock::CrossProcessLock,
|
||||
encryption::{Encryption, EncryptionData, EncryptionSettings, VerificationState},
|
||||
encryption::{
|
||||
DuplicateOneTimeKeyErrorMessage, Encryption, EncryptionData, EncryptionSettings,
|
||||
VerificationState,
|
||||
},
|
||||
};
|
||||
|
||||
mod builder;
|
||||
@@ -387,6 +390,12 @@ pub(crate) struct ClientInner {
|
||||
|
||||
/// A monitor for background tasks spawned by the client.
|
||||
pub(crate) task_monitor: TaskMonitor,
|
||||
|
||||
/// A sender to notify subscribers about duplicate key upload errors
|
||||
/// triggered by requests to /keys/upload.
|
||||
#[cfg(feature = "e2e-encryption")]
|
||||
pub(crate) duplicate_key_upload_error_sender:
|
||||
broadcast::Sender<Option<DuplicateOneTimeKeyErrorMessage>>,
|
||||
}
|
||||
|
||||
impl ClientInner {
|
||||
@@ -454,6 +463,8 @@ impl ClientInner {
|
||||
search_index: search_index_handler,
|
||||
thread_subscription_catchup,
|
||||
task_monitor: TaskMonitor::new(),
|
||||
#[cfg(feature = "e2e-encryption")]
|
||||
duplicate_key_upload_error_sender: broadcast::channel(1).0,
|
||||
};
|
||||
|
||||
#[allow(clippy::let_and_return)]
|
||||
@@ -3320,6 +3331,15 @@ impl Client {
|
||||
pub fn task_monitor(&self) -> &TaskMonitor {
|
||||
&self.inner.task_monitor
|
||||
}
|
||||
|
||||
/// Add a subscriber for duplicate key upload error notifications triggered
|
||||
/// by requests to /keys/upload.
|
||||
#[cfg(feature = "e2e-encryption")]
|
||||
pub fn subscribe_to_duplicate_key_upload_errors(
|
||||
&self,
|
||||
) -> broadcast::Receiver<Option<DuplicateOneTimeKeyErrorMessage>> {
|
||||
self.inner.duplicate_key_upload_error_sender.subscribe()
|
||||
}
|
||||
}
|
||||
|
||||
/// Contains the disk size of the different stores, if known. It won't be
|
||||
|
||||
@@ -368,12 +368,12 @@ impl OAuthCrossSigningResetInfo {
|
||||
|
||||
/// A struct that helps to parse the custom error message Synapse posts if a
|
||||
/// duplicate one-time key is uploaded.
|
||||
#[derive(Debug)]
|
||||
struct DuplicateOneTimeKeyErrorMessage {
|
||||
#[derive(Clone, Debug)]
|
||||
pub struct DuplicateOneTimeKeyErrorMessage {
|
||||
/// The previously uploaded one-time key.
|
||||
old_key: Curve25519PublicKey,
|
||||
pub old_key: Curve25519PublicKey,
|
||||
/// The one-time key we're attempting to upload right now.
|
||||
new_key: Curve25519PublicKey,
|
||||
pub new_key: Curve25519PublicKey,
|
||||
}
|
||||
|
||||
impl FromStr for DuplicateOneTimeKeyErrorMessage {
|
||||
@@ -678,9 +678,10 @@ impl Client {
|
||||
.is_some();
|
||||
|
||||
if message.starts_with("One time key") && !already_reported {
|
||||
if let Ok(message) =
|
||||
DuplicateOneTimeKeyErrorMessage::from_str(message)
|
||||
{
|
||||
let error_message =
|
||||
DuplicateOneTimeKeyErrorMessage::from_str(message);
|
||||
|
||||
if let Ok(message) = &error_message {
|
||||
error!(
|
||||
sentry = true,
|
||||
old_key = %message.old_key,
|
||||
@@ -700,6 +701,17 @@ impl Client {
|
||||
StateStoreDataValue::OneTimeKeyAlreadyUploaded,
|
||||
)
|
||||
.await?;
|
||||
|
||||
if let Err(e) = self
|
||||
.inner
|
||||
.duplicate_key_upload_error_sender
|
||||
.send(error_message.ok())
|
||||
{
|
||||
error!(
|
||||
"Failed to dispatch duplicate key upload error notification: {}",
|
||||
e
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user