Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 1 addition & 3 deletions deltachat-ffi/deltachat.h
Original file line number Diff line number Diff line change
Expand Up @@ -6560,9 +6560,7 @@ void dc_event_unref(dc_event_t* event);
* generated by dc_get_securejoin_qr().
*
* @param data1 (int) The ID of the contact that wants to join.
* @param data2 (int) The progress as:
* 0=Error.
* 1000=Protocol finished for this contact.
* @param data2 (int) The progress, always 1000.
*/
#define DC_EVENT_SECUREJOIN_INVITER_PROGRESS 2060

Expand Down
12 changes: 7 additions & 5 deletions deltachat-jsonrpc/src/api/types/events.rs
Original file line number Diff line number Diff line change
Expand Up @@ -294,8 +294,8 @@ pub enum EventType {
#[serde(rename_all = "camelCase")]
ImexFileWritten { path: String },

/// Progress information of a secure-join handshake from the view of the inviter
/// (Alice, the person who shows the QR code).
/// Progress event sent when SecureJoin protocol has finished
/// from the view of the inviter (Alice, the person who shows the QR code).
///
/// These events are typically sent after a joiner has scanned the QR code
/// generated by getChatSecurejoinQrCodeSvg().
Expand All @@ -308,10 +308,10 @@ pub enum EventType {
/// This can take the same values
/// as `BasicChat.chatType` ([`crate::api::types::chat::BasicChat::chat_type`]).
chat_type: u32,
/// ID of the chat in case of success.
chat_id: u32,

/// Progress as:
/// 0=Error.
/// 1000=Protocol finished for this contact.
/// Progress, always 1000.
progress: usize,
},

Expand Down Expand Up @@ -558,10 +558,12 @@ impl From<CoreEventType> for EventType {
CoreEventType::SecurejoinInviterProgress {
contact_id,
chat_type,
chat_id,
progress,
} => SecurejoinInviterProgress {
contact_id: contact_id.to_u32(),
chat_type: chat_type.to_u32().unwrap_or(0),
chat_id: chat_id.to_u32(),
progress,
},
CoreEventType::SecurejoinJoinerProgress {
Expand Down
9 changes: 4 additions & 5 deletions src/events/payload.rs
Original file line number Diff line number Diff line change
Expand Up @@ -273,14 +273,13 @@ pub enum EventType {
/// ID of the contact that wants to join.
contact_id: ContactId,

/// ID of the chat in case of success.
chat_id: ChatId,

/// The type of the joined chat.
chat_type: Chattype,

/// Progress as:
/// 300=vg-/vc-request received, typically shown as "bob@addr joins".
/// 600=vg-/vc-request-with-auth received and verified, typically shown as "bob@addr verified".
/// 800=contact added to chat, shown as "bob@addr securely joined GROUP". Only for the verified-group-protocol.
/// 1000=Protocol finished for this contact.
/// Progress, always 1000.
progress: usize,
},

Expand Down
29 changes: 18 additions & 11 deletions src/securejoin.rs
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,6 @@ use crate::events::EventType;
use crate::headerdef::HeaderDef;
use crate::key::{DcKey, Fingerprint, load_self_public_key};
use crate::log::{error, info, warn};
use crate::logged_debug_assert;
use crate::message::{Message, Viewtype};
use crate::mimeparser::{MimeMessage, SystemMessage};
use crate::param::Param;
Expand All @@ -35,22 +34,20 @@ use crate::token::Namespace;
fn inviter_progress(
context: &Context,
contact_id: ContactId,
chat_id: ChatId,
is_group: bool,
progress: usize,
) -> Result<()> {
logged_debug_assert!(
context,
progress == 0 || progress == 1000,
"inviter_progress: contact {contact_id}, progress={progress}, but value is not 0 (error) or 1000 (success)."
);
let chat_type = if is_group {
Chattype::Group
} else {
Chattype::Single
};

// No other values are used.
let progress = 1000;
context.emit_event(EventType::SecurejoinInviterProgress {
contact_id,
chat_id,
chat_type,
progress,
});
Expand Down Expand Up @@ -427,16 +424,17 @@ pub(crate) async fn handle_securejoin_handshake(
chat::add_contact_to_chat_ex(context, Nosync, group_chat_id, contact_id, true)
.await?;
let is_group = true;
inviter_progress(context, contact_id, is_group, 1000)?;
inviter_progress(context, contact_id, group_chat_id, is_group)?;
// IMAP-delete the message to avoid handling it by another device and adding the
// member twice. Another device will know the member's key from Autocrypt-Gossip.
Ok(HandshakeMessage::Done)
} else {
let chat_id = info_chat_id(context, contact_id).await?;
// Setup verified contact.
secure_connection_established(
context,
contact_id,
info_chat_id(context, contact_id).await?,
chat_id,
mime_message.timestamp_sent,
)
.await?;
Expand All @@ -445,7 +443,7 @@ pub(crate) async fn handle_securejoin_handshake(
.context("failed sending vc-contact-confirm message")?;

let is_group = false;
inviter_progress(context, contact_id, is_group, 1000)?;
inviter_progress(context, contact_id, chat_id, is_group)?;
Ok(HandshakeMessage::Ignore) // "Done" would delete the message and break multi-device (the key from Autocrypt-header is needed)
}
}
Expand Down Expand Up @@ -568,7 +566,16 @@ pub(crate) async fn observe_securejoin_on_other_device(
let is_group = mime_message
.get_header(HeaderDef::ChatGroupMemberAdded)
.is_some();
inviter_progress(context, contact_id, is_group, 1000)?;

// We don't know the chat ID
// as we may not know about the group yet.
//
// Event is mostly used for bots
// which only have a single device
// and tests which don't care about the chat ID,
// so we pass invalid chat ID here.
let chat_id = ChatId::new(0);
Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is a bit hacky, but I did not want to change the tests that depend on having this event on a second device. Actual users of this event should not be affected.

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It's better to add another event for ChatGroupMemberAdded messages in the future, which should be emitted from receive_imf where we know the chat id as well. For SecurejoinInviterProgress, zero chat id is fine i think

inviter_progress(context, contact_id, chat_id, is_group)?;
}

if step == "vg-request-with-auth" || step == "vc-request-with-auth" {
Expand Down
3 changes: 3 additions & 0 deletions src/securejoin/securejoin_tests.rs
Original file line number Diff line number Diff line change
Expand Up @@ -380,6 +380,7 @@ async fn test_setup_contact_bob_knows_alice() -> Result<()> {
contact_id,
chat_type,
progress,
..
} => {
assert_eq!(contact_id, contact_bob.id);
assert_eq!(chat_type, Chattype::Single);
Expand Down Expand Up @@ -552,10 +553,12 @@ async fn test_secure_join() -> Result<()> {
EventType::SecurejoinInviterProgress {
contact_id,
chat_type,
chat_id,
progress,
} => {
assert_eq!(contact_id, contact_bob.id);
assert_eq!(chat_type, Chattype::Group);
assert_eq!(chat_id, alice_chatid);
assert_eq!(progress, 1000);
}
_ => unreachable!(),
Expand Down
Loading