Skip to main content

DehydratedDevices

Struct DehydratedDevices 

Source
pub struct DehydratedDevices { /* private fields */ }
Available on crate feature e2e-encryption only.
Expand description

High-level handle returned by Encryption::dehydrated_devices.

Implementations§

Source§

impl DehydratedDevices

Source

pub fn state_stream( &self, ) -> impl Stream<Item = Result<DehydratedDeviceEvent, BroadcastStreamRecvError>> + use<>

Subscribe to the stream of DehydratedDeviceEvents.

Each call returns a fresh stream. If a subscriber is slow enough to fall behind the channel’s buffer, it receives a BroadcastStreamRecvError reporting the number of skipped events and the stream continues from the most recent event.

§Example
let dehydrated = client.encryption().dehydrated_devices();
let mut stream = dehydrated.state_stream();
while let Some(Ok(event)) = stream.next().await {
    println!("dehydrated devices: {event:?}");
}
Source

pub async fn is_supported(&self) -> Result<bool, DehydratedDeviceError>

Return whether the homeserver advertises dehydrated-device support.

Probes by issuing GET /dehydrated_device and inspecting the errcode of the response:

  • M_UNRECOGNIZED means the server does not understand the endpoint.
  • M_NOT_FOUND or a successful response means the server understands the endpoint (whether or not the user currently has a dehydrated device on file).

Any other transport or API failure is propagated.

Source

pub async fn create( &self, display_name: Option<&str>, pickle_key: &DehydratedDeviceKey, ) -> Result<OwnedDeviceId, DehydratedDeviceError>

Create a fresh dehydrated device and upload it to the homeserver.

The pickle key is used by vodozemac to encrypt the private parts of the device. The application is responsible for safely storing the pickle key (typically in Secret Storage so future sessions can rehydrate the device).

§Arguments
  • display_name - Optional human-readable name uploaded as the dehydrated device’s initial_device_display_name. Defaults to "Dehydrated device".
  • pickle_key - 32-byte key used to encrypt the dehydrated device.
§Example
let pickle_key = DehydratedDeviceKey::new();
let device_id = client
    .encryption()
    .dehydrated_devices()
    .create(Some("Offline catcher"), &pickle_key)
    .await?;
println!("Uploaded dehydrated device {device_id}");
Source

pub async fn rehydrate( &self, pickle_key: &DehydratedDeviceKey, ) -> Result<bool, DehydratedDeviceError>

Rehydrate the dehydrated device currently on the server, if any.

Downloads the dehydrated device, decrypts it with pickle_key, drains all queued to-device events to import their room keys, and finally deletes the device from the server.

Returns Ok(false) if the server reports no dehydrated device (M_NOT_FOUND) or does not implement the endpoint (M_UNRECOGNIZED). Returns Ok(true) once the rehydration cycle has completed end to end.

If the drain stops defensively before the server’s queue is exhausted, the device is left on the server and DehydratedDeviceError::DrainTruncated is returned. Calling this method again restarts the drain from the beginning of the queue; room keys imported by the earlier attempt import idempotently.

§Example
let rehydrated =
    client.encryption().dehydrated_devices().rehydrate(&pickle_key).await?;
if rehydrated {
    println!("Caught up on offline room keys");
}
Source

pub async fn is_key_stored( &self, secret_store: &SecretStore, ) -> Result<bool, DehydratedDeviceError>

Return whether the pickle key is stored in the given Secret Storage.

The key is looked up by the account-data event type org.matrix.msc3814 (the unstable name reserved by MSC3814).

§Example
let stored =
    client.encryption().dehydrated_devices().is_key_stored(&store).await?;
Source

pub async fn reset_key( &self, secret_store: &SecretStore, ) -> Result<DehydratedDeviceKey, DehydratedDeviceError>

Generate a new random pickle key, persist it in Secret Storage, and cache it in the local crypto store.

The previous key (if any) is overwritten in both places. Any dehydrated device that was encrypted with the previous key becomes unrehydratable until rotated.

§Example
let fresh_key =
    client.encryption().dehydrated_devices().reset_key(&store).await?;
Source

pub fn start<'a>( &'a self, secret_store: &'a SecretStore, ) -> StartDehydration<'a>

Start using dehydrated devices for this client.

Returns a StartDehydration future. Await it directly for the default behavior, or configure it first with StartDehydration::create_new_key, StartDehydration::skip_rehydration, and StartDehydration::only_if_key_cached.

The caller is expected to have unlocked Secret Storage and bootstrapped cross-signing before this call; otherwise the underlying account-data reads and writes will fail mid-flight.

Awaiting the future performs the following steps:

  1. If StartDehydration::only_if_key_cached was set, return early when no pickle key is cached locally.
  2. Stop any previously scheduled rotation.
  3. Unless StartDehydration::skip_rehydration was set, attempt to rehydrate the existing dehydrated device. Failures are logged and emitted as DehydratedDeviceEvent::RehydrationError but do not abort the start.
  4. If StartDehydration::create_new_key was set and the rehydration step succeeded (or was skipped), replace the pickle key in Secret Storage with a fresh random one. A failed rehydration suppresses the reset so the stored key can still recover the existing dehydrated device on another client.
  5. Create a new dehydrated device now and schedule rotation once a week.

The rotation task resolves the pickle key from the local crypto store on each tick. The local cache is the only key source available to the task because reopening Secret Storage requires the recovery key, which is not retained. Per-tick failures emit DehydratedDeviceEvent::RotationError without aborting the schedule.

§Example
client.encryption().dehydrated_devices().start(&store).await?;
Source

pub fn stop(&self)

Stop the scheduled dehydrated-device rotation, if any.

Has no effect when no rotation is scheduled. Existing dehydrated devices on the server are left in place; pair with Self::delete to clean those up.

Source

pub async fn delete(&self) -> Result<(), DehydratedDeviceError>

Delete the current dehydrated device, if one exists.

Also stops any scheduled rotation, so the next tick will not immediately recreate the device the caller just asked to remove.

Returns Ok(()) silently if no dehydrated device is on the server or the server does not implement the endpoint.

§Example
client.encryption().dehydrated_devices().delete().await?;

Trait Implementations§

Source§

impl Clone for DehydratedDevices

Source§

fn clone(&self) -> DehydratedDevices

Returns a duplicate of the value. Read more
1.0.0 (const: unstable) · Source§

fn clone_from(&mut self, source: &Self)

Performs copy-assignment from source. Read more
Source§

impl Debug for DehydratedDevices

Source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result

Formats the value using the given formatter. Read more

Auto Trait Implementations§

Blanket Implementations§

Source§

impl<T> Any for T
where T: 'static + ?Sized,

Source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
Source§

impl<T> Any for T
where T: Any,

Source§

impl<T> AsyncTraitDeps for T

Source§

impl<T> Borrow<T> for T
where T: ?Sized,

Source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
Source§

impl<T> BorrowMut<T> for T
where T: ?Sized,

Source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
Source§

impl<T> CloneAny for T
where T: Any + Clone,

Source§

impl<T> CloneAnySend for T
where T: Any + Send + Clone,

Source§

impl<T> CloneAnySendSync for T
where T: Any + Send + Sync + Clone,

Source§

impl<T> CloneAnySync for T
where T: Any + Sync + Clone,

Source§

impl<T> CloneToUninit for T
where T: Clone,

Source§

unsafe fn clone_to_uninit(&self, dest: *mut u8)

🔬This is a nightly-only experimental API. (clone_to_uninit)
Performs copy-assignment from self to dest. Read more
§

impl<T> CompatExt for T

§

fn compat(self) -> Compat<T>
where T: Sized,

Applies the [Compat] adapter by value. Read more
§

fn compat_ref(&self) -> Compat<&T>

Applies the [Compat] adapter by shared reference. Read more
§

fn compat_mut(&mut self) -> Compat<&mut T>

Applies the [Compat] adapter by mutable reference. Read more
Source§

impl<T> Downcast for T
where T: Any,

Source§

fn into_any(self: Box<T>) -> Box<dyn Any>

Converts Box<dyn Trait> (where Trait: Downcast) to Box<dyn Any>, which can then be downcast into Box<dyn ConcreteType> where ConcreteType implements Trait.
Source§

fn into_any_rc(self: Rc<T>) -> Rc<dyn Any>

Converts Rc<Trait> (where Trait: Downcast) to Rc<Any>, which can then be further downcast into Rc<ConcreteType> where ConcreteType implements Trait.
Source§

fn as_any(&self) -> &(dyn Any + 'static)

Converts &Trait (where Trait: Downcast) to &Any. This is needed since Rust cannot generate &Any’s vtable from &Trait’s.
Source§

fn as_any_mut(&mut self) -> &mut (dyn Any + 'static)

Converts &mut Trait (where Trait: Downcast) to &Any. This is needed since Rust cannot generate &mut Any’s vtable from &mut Trait’s.
Source§

impl<T> DowncastSend for T
where T: Any + Send,

Source§

fn into_any_send(self: Box<T>) -> Box<dyn Any + Send>

Converts Box<Trait> (where Trait: DowncastSend) to Box<dyn Any + Send>, which can then be downcast into Box<ConcreteType> where ConcreteType implements Trait.
Source§

impl<T> DowncastSync for T
where T: Any + Send + Sync,

Source§

fn into_any_sync(self: Box<T>) -> Box<dyn Any + Sync + Send>

Converts Box<Trait> (where Trait: DowncastSync) to Box<dyn Any + Send + Sync>, which can then be downcast into Box<ConcreteType> where ConcreteType implements Trait.
Source§

fn into_any_arc(self: Arc<T>) -> Arc<dyn Any + Sync + Send>

Converts Arc<Trait> (where Trait: DowncastSync) to Arc<Any>, which can then be downcast into Arc<ConcreteType> where ConcreteType implements Trait.
Source§

impl<T> DropFlavorWrapper<T> for T

Source§

type Flavor = MayDrop

The DropFlavor that wraps T into Self
Source§

impl<T> ErasedDestructor for T
where T: 'static,

Source§

impl<T> From<T> for T

Source§

fn from(t: T) -> T

Returns the argument unchanged.

Source§

impl<T> FromRef<T> for T
where T: Clone,

Source§

fn from_ref(input: &T) -> T

Converts to this type from a reference to the input type.
Source§

impl<T> Fruit for T
where T: Send + Downcast,

§

impl<T, UT> HandleAlloc<UT> for T
where T: Send + Sync,

§

fn new_handle(value: Arc<T>) -> Handle

Create a new handle for an Arc value Read more
§

unsafe fn clone_handle(handle: Handle) -> Handle

Clone a handle Read more
§

unsafe fn consume_handle(handle: Handle) -> Arc<T>

Consume a handle, getting back the initial Arc<> Read more
§

unsafe fn get_arc(handle: Handle) -> Arc<Self>

Get a clone of the Arc<> using a “borrowed” handle. Read more
Source§

impl<T, W> HasTypeWitness<W> for T
where W: MakeTypeWitness<Arg = T>, T: ?Sized,

Source§

const WITNESS: W = W::MAKE

A constant of the type witness
Source§

impl<T> Identity for T
where T: ?Sized,

Source§

const TYPE_EQ: TypeEq<T, <T as Identity>::Type> = TypeEq::NEW

Proof that Self is the same type as Self::Type, provides methods for casting between Self and Self::Type.
Source§

type Type = T

The same type as Self, used to emulate type equality bounds (T == U) with associated type equality constraints (T: Identity<Type = U>).
Source§

impl<T> Instrument for T

Source§

fn instrument(self, span: Span) -> Instrumented<Self>

Instruments this type with the provided Span, returning an Instrumented wrapper. Read more
Source§

fn in_current_span(self) -> Instrumented<Self>

Instruments this type with the current Span, returning an Instrumented wrapper. Read more
Source§

impl<T, U> Into<U> for T
where U: From<T>,

Source§

fn into(self) -> U

Calls U::from(self).

That is, this conversion is whatever the implementation of From<T> for U chooses to do.

Source§

impl<T> IntoEither for T

Source§

fn into_either(self, into_left: bool) -> Either<Self, Self>

Converts self into a Left variant of Either<Self, Self> if into_left is true. Converts self into a Right variant of Either<Self, Self> otherwise. Read more
Source§

fn into_either_with<F>(self, into_left: F) -> Either<Self, Self>
where F: FnOnce(&Self) -> bool,

Converts self into a Left variant of Either<Self, Self> if into_left(&self) returns true. Converts self into a Right variant of Either<Self, Self> otherwise. Read more
§

impl<T> JsonCastable<CanonicalJsonValue> for T

§

impl<T> JsonCastable<Value> for T

Source§

impl<T> MaybeSendSync for T

Source§

impl<T> Pointable for T

Source§

const ALIGN: usize

The alignment of pointer.
Source§

type Init = T

The type for initializers.
Source§

unsafe fn init(init: <T as Pointable>::Init) -> usize

Initializes a with the given initializer. Read more
Source§

unsafe fn deref<'a>(ptr: usize) -> &'a T

Dereferences the given pointer. Read more
Source§

unsafe fn deref_mut<'a>(ptr: usize) -> &'a mut T

Mutably dereferences the given pointer. Read more
Source§

unsafe fn drop(ptr: usize)

Drops the object pointed to by the given pointer. Read more
Source§

impl<T> PolicyExt for T
where T: ?Sized,

Source§

fn and<P, B, E>(self, other: P) -> And<T, P>
where T: Sized + Policy<B, E>, P: Policy<B, E>,

Create a new Policy that returns Action::Follow only if self and other return Action::Follow. Read more
Source§

fn or<P, B, E>(self, other: P) -> Or<T, P>
where T: Sized + Policy<B, E>, P: Policy<B, E>,

Create a new Policy that returns Action::Follow if either self or other returns Action::Follow. Read more
Source§

impl<T> Same for T

Source§

type Output = T

Should always be Self
Source§

impl<T> SendOutsideWasm for T
where T: Send,

Source§

impl<T> SyncOutsideWasm for T
where T: Sync,

Source§

impl<T> ToOwned for T
where T: Clone,

Source§

type Owned = T

The resulting type after obtaining ownership.
Source§

fn to_owned(&self) -> T

Creates owned data from borrowed data, usually by cloning. Read more
Source§

fn clone_into(&self, target: &mut T)

Uses borrowed data to replace owned data, usually by cloning. Read more
Source§

impl<T, U> TryFrom<U> for T
where U: Into<T>,

Source§

type Error = Infallible

The type returned in the event of a conversion error.
Source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
Source§

impl<T, U> TryInto<U> for T
where U: TryFrom<T>,

Source§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
Source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.
Source§

impl<S, T> Upcast<T> for S
where T: UpcastFrom<S> + ?Sized, S: ?Sized,

Source§

fn upcast(&self) -> &T
where Self: ErasableGeneric, T: Sized + ErasableGeneric<Repr = Self::Repr>,

Perform a zero-cost type-safe upcast to a wider ref type within the Wasm bindgen generics type system. Read more
Source§

fn upcast_into(self) -> T
where Self: Sized + ErasableGeneric, T: Sized + ErasableGeneric<Repr = Self::Repr>,

Perform a zero-cost type-safe upcast to a wider type within the Wasm bindgen generics type system. Read more
Source§

impl<V, T> VZip<V> for T
where V: MultiLane<T>,

Source§

fn vzip(self) -> V

Source§

impl<T> WithSubscriber for T

Source§

fn with_subscriber<S>(self, subscriber: S) -> WithDispatch<Self>
where S: Into<Dispatch>,

Attaches the provided Subscriber to this type, returning a WithDispatch wrapper. Read more
Source§

fn with_current_subscriber(self) -> WithDispatch<Self>

Attaches the current default Subscriber to this type, returning a WithDispatch wrapper. Read more