Skip to content

Commit e4e7a36

Browse files
committed
feat: Sync Alice's verification on Bob's side
1 parent 3c3e1ae commit e4e7a36

File tree

5 files changed

+51
-32
lines changed

5 files changed

+51
-32
lines changed

src/chat.rs

Lines changed: 17 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -5089,10 +5089,8 @@ pub(crate) enum SyncAction {
50895089
chat_name: String,
50905090
shared_secret: String,
50915091
},
5092-
CreateInBroadcast {
5093-
chat_name: String,
5094-
shared_secret: String,
5095-
},
5092+
/// Mark the contact with the given fingerprint as verified by self.
5093+
MarkVerified,
50965094
Rename(String),
50975095
/// Set chat contacts by their addresses.
50985096
SetContacts(Vec<String>),
@@ -5148,6 +5146,14 @@ impl Context {
51485146
SyncAction::Unblock => {
51495147
return contact::set_blocked(self, Nosync, contact_id, false).await;
51505148
}
5149+
SyncAction::MarkVerified => {
5150+
return contact::mark_contact_id_as_verified(
5151+
self,
5152+
contact_id,
5153+
ContactId::SELF,
5154+
)
5155+
.await;
5156+
}
51515157
_ => (),
51525158
}
51535159
ChatIdBlocked::get_for_contact(self, contact_id, Blocked::Request)
@@ -5179,8 +5185,9 @@ impl Context {
51795185
SyncAction::Accept => chat_id.accept_ex(self, Nosync).await,
51805186
SyncAction::SetVisibility(v) => chat_id.set_visibility_ex(self, Nosync, *v).await,
51815187
SyncAction::SetMuted(duration) => set_muted_ex(self, Nosync, chat_id, *duration).await,
5182-
SyncAction::CreateOutBroadcast { .. } | SyncAction::CreateInBroadcast { .. } => {
5183-
// Create action should have been handled by handle_sync_create_chat() already
5188+
SyncAction::CreateOutBroadcast { .. } | SyncAction::MarkVerified => {
5189+
// Create action should have been handled by handle_sync_create_chat() already.
5190+
// MarkVerified action should have been handled by mark_contact_id_as_verified() already.
51845191
Err(anyhow!("sync_alter_chat({id:?}, {action:?}): Bad request."))
51855192
}
51865193
SyncAction::Rename(to) => rename_ex(self, Nosync, chat_id, to).await,
@@ -5193,7 +5200,7 @@ impl Context {
51935200
}
51945201

51955202
async fn handle_sync_create_chat(&self, action: &SyncAction, grpid: &str) -> Result<bool> {
5196-
Ok(match action {
5203+
match action {
51975204
SyncAction::CreateOutBroadcast {
51985205
chat_name,
51995206
shared_secret,
@@ -5206,29 +5213,10 @@ impl Context {
52065213
shared_secret.to_string(),
52075214
)
52085215
.await?;
5209-
return Ok(true);
5210-
}
5211-
SyncAction::CreateInBroadcast {
5212-
chat_name,
5213-
shared_secret,
5214-
} => {
5215-
let chat_id = ChatId::create_multiuser_record(
5216-
self,
5217-
Chattype::InBroadcast,
5218-
grpid,
5219-
chat_name,
5220-
Blocked::Not,
5221-
ProtectionStatus::Unprotected,
5222-
None,
5223-
smeared_time(self),
5224-
)
5225-
.await?;
5226-
save_broadcast_shared_secret(self, chat_id, shared_secret).await?;
5227-
5228-
return Ok(true);
5216+
Ok(true)
52295217
}
5230-
_ => false,
5231-
})
5218+
_ => Ok(false),
5219+
}
52325220
}
52335221

52345222
/// Emits the appropriate `MsgsChanged` event. Should be called if the number of unnoticed

src/chat/chat_tests.rs

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3119,8 +3119,19 @@ async fn test_leave_broadcast_multidevice() -> Result<()> {
31193119
alice.recv_msg_trash(&request).await;
31203120
let answer = alice.pop_sent_msg().await;
31213121
bob0.recv_msg(&answer).await;
3122+
3123+
// Sync Bob's verification of Alice:
3124+
sync(bob0, bob1).await;
3125+
// TODO uncommenting the next line creates a message "Can't decrypt outgoing messages, probably you're using DC on multiple devices without transferring your key"
3126+
// bob1.recv_msg(&request).await;
31223127
bob1.recv_msg(&answer).await;
31233128

3129+
// The 1:1 chat should not be visible to the user on any of the devices.
3130+
// The contact should be marked as verified.
3131+
check_direct_chat_is_hidden_and_contact_is_verified(alice, bob0).await;
3132+
check_direct_chat_is_hidden_and_contact_is_verified(bob0, alice).await;
3133+
check_direct_chat_is_hidden_and_contact_is_verified(bob1, alice).await;
3134+
31243135
tcm.section("Alice sends first message to broadcast.");
31253136
let sent_msg = alice.send_text(alice_chat_id, "Hello!").await;
31263137
let bob0_hello = bob0.recv_msg(&sent_msg).await;
@@ -3151,6 +3162,20 @@ async fn test_leave_broadcast_multidevice() -> Result<()> {
31513162
Ok(())
31523163
}
31533164

3165+
async fn check_direct_chat_is_hidden_and_contact_is_verified(
3166+
t: &TestContext,
3167+
contact: &TestContext,
3168+
) {
3169+
let contact = t.add_or_lookup_contact_no_key(contact).await;
3170+
if let Some(direct_chat) = ChatIdBlocked::lookup_by_contact(t, contact.id)
3171+
.await
3172+
.unwrap()
3173+
{
3174+
assert_eq!(direct_chat.blocked, Blocked::Yes);
3175+
}
3176+
assert!(contact.is_verified(t).await.unwrap());
3177+
}
3178+
31543179
/// Test that only the owner of the broadcast channel
31553180
/// can send messages into the chat.
31563181
///

src/receive_imf.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3531,6 +3531,7 @@ async fn apply_out_broadcast_changes(
35313531
} else if let Some(added_addr) = mime_parser.get_header(HeaderDef::ChatGroupMemberAdded) {
35323532
// TODO this block can be removed,
35333533
// now that all of Alice's devices get to know about Bob joining via Bob's QR message.
3534+
// TODO test if this creates some problems with duplicate member-added messages on Alice's device
35343535
let contact = lookup_key_contact_by_address(context, added_addr, None).await?;
35353536
if let Some(contact) = contact {
35363537
better_msg.get_or_insert(

src/securejoin.rs

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -594,8 +594,6 @@ pub(crate) async fn observe_securejoin_on_other_device(
594594
inviter_progress(context, contact_id, 1000);
595595
}
596596

597-
// TODO not sure if I should add vb-request-with-auth here
598-
// Actually, I'm not even sure why vg-request-with-auth is here - why do we create a 1:1 chat??
599597
if step == "vg-request-with-auth" || step == "vc-request-with-auth" {
600598
// This actually reflects what happens on the first device (which does the secure
601599
// join) and causes a subsequent "vg-member-added" message to create an unblocked

src/securejoin/bob.rs

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ use crate::contact::Origin;
1010
use crate::context::Context;
1111
use crate::events::EventType;
1212
use crate::key::self_fingerprint;
13-
use crate::log::info;
13+
use crate::log::{LogExt as _, info};
1414
use crate::message::{Message, Viewtype};
1515
use crate::mimeparser::{MimeMessage, SystemMessage};
1616
use crate::param::Param;
@@ -81,6 +81,13 @@ pub(super) async fn start_protocol(context: &Context, invite: QrInvite) -> Resul
8181
contact_id: invite.contact_id(),
8282
progress: JoinerProgress::RequestWithAuthSent.to_usize(),
8383
});
84+
85+
// Our second device won't be able to decrypt the outgoing message
86+
// because it will be symmetrically encrypted with the AUTH token.
87+
// So, we need to send a sync message:
88+
let id = chat::SyncId::ContactFingerprint(invite.fingerprint().hex());
89+
let action = chat::SyncAction::MarkVerified;
90+
chat::sync(context, id, action).await.log_err(context).ok();
8491
} else {
8592
// Start the version 1 protocol and initialise the state.
8693
let has_key = context

0 commit comments

Comments
 (0)