@@ -203,6 +203,23 @@ impl From<PushFormat> for RumaPushFormat {
203203 }
204204}
205205
206+ #[ derive( uniffi:: Object ) ]
207+ pub struct SecretsBundle {
208+ inner : matrix_sdk_base:: crypto:: types:: SecretsBundle ,
209+ }
210+
211+ impl SecretsBundle {
212+ pub fn bundle_from_str ( bundle : & str ) -> Result < Arc < Self > , ClientError > {
213+ let bundle = serde_json:: from_str ( bundle) ?;
214+
215+ Ok ( Self { inner : bundle } . into ( ) )
216+ }
217+
218+ pub fn from_database ( database_path : & str ) -> Result < Arc < Self > , ClientError > {
219+ todo ! ( )
220+ }
221+ }
222+
206223#[ matrix_sdk_ffi_macros:: export( callback_interface) ]
207224pub trait ClientDelegate : SyncOutsideWasm + SendOutsideWasm {
208225 /// A callback invoked whenever the SDK runs into an unknown token error.
@@ -418,6 +435,24 @@ impl Client {
418435
419436 Ok ( client)
420437 }
438+
439+ pub ( crate ) async fn import_secrets_bundle (
440+ & self ,
441+ secrets_bundle : & SecretsBundle ,
442+ ) -> Result < ( ) , ClientError > {
443+ self . inner
444+ . encryption ( )
445+ . import_secrets_bundle ( & secrets_bundle. inner )
446+ . await
447+ . map_err ( |e| ClientError :: from_err ( e) ) ?;
448+
449+ // Upload the device keys, this will ensure that other devices see us as a fully
450+ // verified device ass soon as this method returns.
451+ self . inner . encryption ( ) . ensure_device_keys_upload ( ) . await ?;
452+ self . inner . encryption ( ) . wait_for_e2ee_initialization_tasks ( ) . await ;
453+
454+ Ok ( ( ) )
455+ }
421456}
422457
423458#[ matrix_sdk_ffi_macros:: export]
@@ -486,15 +521,24 @@ impl Client {
486521 password : String ,
487522 initial_device_name : Option < String > ,
488523 device_id : Option < String > ,
524+ secrets_bundle : Option < Arc < SecretsBundle > > ,
489525 ) -> Result < ( ) , ClientError > {
490526 let mut builder = self . inner . matrix_auth ( ) . login_username ( & username, & password) ;
527+
491528 if let Some ( initial_device_name) = initial_device_name. as_ref ( ) {
492529 builder = builder. initial_device_display_name ( initial_device_name) ;
493530 }
531+
494532 if let Some ( device_id) = device_id. as_ref ( ) {
495533 builder = builder. device_id ( device_id) ;
496534 }
535+
497536 builder. send ( ) . await ?;
537+
538+ if let Some ( bundle) = secrets_bundle {
539+ self . import_secrets_bundle ( & bundle) . await ?;
540+ }
541+
498542 Ok ( ( ) )
499543 }
500544
@@ -506,6 +550,7 @@ impl Client {
506550 jwt : String ,
507551 initial_device_name : Option < String > ,
508552 device_id : Option < String > ,
553+ secrets_bundle : Option < Arc < SecretsBundle > > ,
509554 ) -> Result < ( ) , ClientError > {
510555 let data = json ! ( { "token" : jwt } ) . as_object ( ) . unwrap ( ) . clone ( ) ;
511556
@@ -520,6 +565,11 @@ impl Client {
520565 }
521566
522567 builder. send ( ) . await ?;
568+
569+ if let Some ( bundle) = secrets_bundle {
570+ self . import_secrets_bundle ( & bundle) . await ?;
571+ }
572+
523573 Ok ( ( ) )
524574 }
525575
@@ -530,6 +580,7 @@ impl Client {
530580 password : String ,
531581 initial_device_name : Option < String > ,
532582 device_id : Option < String > ,
583+ secrets_bundle : Option < Arc < SecretsBundle > > ,
533584 ) -> Result < ( ) , ClientError > {
534585 let mut builder = self
535586 . inner
@@ -546,6 +597,10 @@ impl Client {
546597
547598 builder. send ( ) . await ?;
548599
600+ if let Some ( bundle) = secrets_bundle {
601+ self . import_secrets_bundle ( & bundle) . await ?;
602+ }
603+
549604 Ok ( ( ) )
550605 }
551606
@@ -637,7 +692,11 @@ impl Client {
637692 }
638693
639694 /// Completes the OIDC login process.
640- pub async fn login_with_oidc_callback ( & self , callback_url : String ) -> Result < ( ) , OidcError > {
695+ pub async fn login_with_oidc_callback (
696+ & self ,
697+ callback_url : String ,
698+ secrets_bundle : Option < Arc < SecretsBundle > > ,
699+ ) -> Result < ( ) , OidcError > {
641700 let url = Url :: parse ( & callback_url) . or ( Err ( OidcError :: CallbackUrlInvalid ) ) ?;
642701
643702 self . inner . oauth ( ) . finish_login ( url. into ( ) ) . await ?;
0 commit comments