@@ -11,11 +11,12 @@ use crate::contact::Contact;
11
11
use crate :: context:: Context ;
12
12
use crate :: dc_tools:: time;
13
13
use crate :: events:: EventType ;
14
+ use crate :: mimeparser:: MimeMessage ;
14
15
use crate :: { chat, stock_str} ;
15
16
16
17
use super :: bobstate:: { BobHandshakeStage , BobState } ;
17
18
use super :: qrinvite:: QrInvite ;
18
- use super :: JoinError ;
19
+ use super :: { HandshakeMessage , JoinError } ;
19
20
20
21
/// Starts the securejoin protocol with the QR `invite`.
21
22
///
@@ -29,7 +30,10 @@ use super::JoinError;
29
30
///
30
31
/// The [`ChatId`] of the created chat is returned, for a SetupContact QR this is the 1:1
31
32
/// chat with Alice, for a SecureJoin QR this is the group chat.
32
- pub async fn start_protocol ( context : & Context , invite : QrInvite ) -> Result < ChatId , JoinError > {
33
+ pub ( super ) async fn start_protocol (
34
+ context : & Context ,
35
+ invite : QrInvite ,
36
+ ) -> Result < ChatId , JoinError > {
33
37
// A 1:1 chat is needed to send messages to Alice. When joining a group this chat is
34
38
// hidden, if a user starts sending messages in it it will be unhidden in
35
39
// dc_receive_imf.
@@ -46,7 +50,7 @@ pub async fn start_protocol(context: &Context, invite: QrInvite) -> Result<ChatI
46
50
BobState :: start_protocol ( context, invite. clone ( ) , chat_id) . await ?;
47
51
for state in aborted_states {
48
52
error ! ( context, "Aborting previously unfinished QR Join process." ) ;
49
- state. notify_aborted ( context) . await ?;
53
+ state. notify_aborted ( context, "new QR scanned" ) . await ?;
50
54
state. emit_progress ( context, JoinerProgress :: Error ) ;
51
55
}
52
56
if matches ! ( stage, BobHandshakeStage :: RequestWithAuthSent ) {
@@ -74,8 +78,47 @@ pub async fn start_protocol(context: &Context, invite: QrInvite) -> Result<ChatI
74
78
}
75
79
}
76
80
81
+ /// Handles `vc-auth-required` and `vg-auth-required` handshake messages.
82
+ ///
83
+ /// # Bob - the joiner's side
84
+ /// ## Step 4 in the "Setup Contact protocol"
85
+ pub ( super ) async fn handle_auth_required (
86
+ context : & Context ,
87
+ message : & MimeMessage ,
88
+ ) -> Result < HandshakeMessage > {
89
+ match BobState :: from_db ( & context. sql ) . await ? {
90
+ Some ( mut bobstate) => match bobstate. handle_message ( context, message) . await ? {
91
+ Some ( BobHandshakeStage :: Terminated ( why) ) => {
92
+ bobstate. notify_aborted ( context, why) . await ?;
93
+ Ok ( HandshakeMessage :: Done )
94
+ }
95
+ Some ( _stage) => {
96
+ if bobstate. is_join_group ( ) {
97
+ // The message reads "Alice replied, waiting to be added to the group…",
98
+ // so only show it on secure-join and not on setup-contact.
99
+ let contact_id = bobstate. invite ( ) . contact_id ( ) ;
100
+ let msg = stock_str:: secure_join_replies ( context, contact_id) . await ;
101
+ let chat_id = bobstate. joining_chat_id ( context) . await ?;
102
+ chat:: add_info_msg ( context, chat_id, msg, time ( ) ) . await ?;
103
+ }
104
+ bobstate. emit_progress ( context, JoinerProgress :: RequestWithAuthSent ) ;
105
+ Ok ( HandshakeMessage :: Done )
106
+ }
107
+ None => Ok ( HandshakeMessage :: Ignore ) ,
108
+ } ,
109
+ None => Ok ( HandshakeMessage :: Ignore ) ,
110
+ }
111
+ }
112
+
77
113
/// Private implementations for user interactions about this [`BobState`].
78
114
impl BobState {
115
+ fn is_join_group ( & self ) -> bool {
116
+ match self . invite ( ) {
117
+ QrInvite :: Contact { .. } => false ,
118
+ QrInvite :: Group { .. } => true ,
119
+ }
120
+ }
121
+
79
122
fn emit_progress ( & self , context : & Context , progress : JoinerProgress ) {
80
123
let contact_id = self . invite ( ) . contact_id ( ) ;
81
124
context. emit_event ( EventType :: SecurejoinJoinerProgress {
@@ -122,15 +165,21 @@ impl BobState {
122
165
}
123
166
}
124
167
125
- async fn notify_aborted ( & self , context : & Context ) -> Result < ( ) > {
168
+ /// Notifies the user that the SecureJoin was aborted.
169
+ ///
170
+ /// This creates and info message in the chat being joined.
171
+ async fn notify_aborted ( & self , context : & Context , why : & str ) -> Result < ( ) > {
126
172
let contact_addr = match Contact :: get_by_id ( context, self . invite ( ) . contact_id ( ) ) . await {
127
173
Ok ( ref contact) => contact. get_addr ( ) . to_string ( ) ,
128
174
Err ( _) => "?" . to_string ( ) ,
129
175
} ;
130
- // TODO: custom stock string?
131
176
let msg = stock_str:: contact_not_verified ( context, contact_addr) . await ;
132
177
let chat_id = self . joining_chat_id ( context) . await ?;
133
178
chat:: add_info_msg ( context, chat_id, & msg, time ( ) ) . await ?;
179
+ warn ! (
180
+ context,
181
+ "StockMessage::ContactNotVerified posted to joining chat ({})" , why
182
+ ) ;
134
183
Ok ( ( ) )
135
184
}
136
185
}
0 commit comments