mirror of
https://github.com/chatmail/core.git
synced 2026-05-08 17:36:29 +03:00
Fix multidevice
This commit is contained in:
33
src/chat.rs
33
src/chat.rs
@@ -3685,7 +3685,8 @@ pub async fn create_group_chat(
|
|||||||
/// Returns the created chat's id.
|
/// Returns the created chat's id.
|
||||||
pub async fn create_broadcast(context: &Context, chat_name: String) -> Result<ChatId> {
|
pub async fn create_broadcast(context: &Context, chat_name: String) -> Result<ChatId> {
|
||||||
let grpid = create_id();
|
let grpid = create_id();
|
||||||
create_broadcast_ex(context, Sync, grpid, chat_name).await
|
let secret = create_broadcast_shared_secret();
|
||||||
|
create_broadcast_ex(context, Sync, grpid, chat_name, secret).await
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(crate) async fn create_broadcast_ex(
|
pub(crate) async fn create_broadcast_ex(
|
||||||
@@ -3693,6 +3694,7 @@ pub(crate) async fn create_broadcast_ex(
|
|||||||
sync: sync::Sync,
|
sync: sync::Sync,
|
||||||
grpid: String,
|
grpid: String,
|
||||||
chat_name: String,
|
chat_name: String,
|
||||||
|
secret: String,
|
||||||
) -> Result<ChatId> {
|
) -> Result<ChatId> {
|
||||||
let row_id = {
|
let row_id = {
|
||||||
let chat_name = &chat_name;
|
let chat_name = &chat_name;
|
||||||
@@ -3712,7 +3714,7 @@ pub(crate) async fn create_broadcast_ex(
|
|||||||
}
|
}
|
||||||
let mut param = Params::new();
|
let mut param = Params::new();
|
||||||
// param.set(Param::Unpromoted, 1); // TODO broadcasts will just never be unpromoted for now
|
// param.set(Param::Unpromoted, 1); // TODO broadcasts will just never be unpromoted for now
|
||||||
param.set(Param::SymmetricKey, create_broadcast_shared_secret());
|
param.set(Param::SymmetricKey, &secret);
|
||||||
t.execute(
|
t.execute(
|
||||||
"INSERT INTO chats \
|
"INSERT INTO chats \
|
||||||
(type, name, grpid, param, created_timestamp) \
|
(type, name, grpid, param, created_timestamp) \
|
||||||
@@ -3725,6 +3727,13 @@ pub(crate) async fn create_broadcast_ex(
|
|||||||
create_smeared_timestamp(context),
|
create_smeared_timestamp(context),
|
||||||
),
|
),
|
||||||
)?;
|
)?;
|
||||||
|
let chat_id = t.last_insert_rowid();
|
||||||
|
// TODO code duplication of `INSERT INTO broadcasts_shared_secrets`
|
||||||
|
t.execute(
|
||||||
|
"INSERT INTO broadcasts_shared_secrets (chat_id, secret) VALUES (?, ?)
|
||||||
|
ON CONFLICT(chat_id) DO UPDATE SET secret=excluded.chat_id",
|
||||||
|
(chat_id, &secret),
|
||||||
|
)?;
|
||||||
Ok(t.last_insert_rowid().try_into()?)
|
Ok(t.last_insert_rowid().try_into()?)
|
||||||
};
|
};
|
||||||
context.sql.transaction(trans_fn).await?
|
context.sql.transaction(trans_fn).await?
|
||||||
@@ -3736,7 +3745,7 @@ pub(crate) async fn create_broadcast_ex(
|
|||||||
|
|
||||||
if sync.into() {
|
if sync.into() {
|
||||||
let id = SyncId::Grpid(grpid);
|
let id = SyncId::Grpid(grpid);
|
||||||
let action = SyncAction::CreateBroadcast(chat_name);
|
let action = SyncAction::CreateBroadcast { chat_name, secret };
|
||||||
self::sync(context, id, action).await.log_err(context).ok();
|
self::sync(context, id, action).await.log_err(context).ok();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -4952,7 +4961,10 @@ pub(crate) enum SyncAction {
|
|||||||
SetVisibility(ChatVisibility),
|
SetVisibility(ChatVisibility),
|
||||||
SetMuted(MuteDuration),
|
SetMuted(MuteDuration),
|
||||||
/// Create broadcast channel with the given name.
|
/// Create broadcast channel with the given name.
|
||||||
CreateBroadcast(String),
|
CreateBroadcast {
|
||||||
|
chat_name: String,
|
||||||
|
secret: String,
|
||||||
|
},
|
||||||
Rename(String),
|
Rename(String),
|
||||||
/// Set chat contacts by their addresses.
|
/// Set chat contacts by their addresses.
|
||||||
SetContacts(Vec<String>),
|
SetContacts(Vec<String>),
|
||||||
@@ -5015,8 +5027,15 @@ impl Context {
|
|||||||
.id
|
.id
|
||||||
}
|
}
|
||||||
SyncId::Grpid(grpid) => {
|
SyncId::Grpid(grpid) => {
|
||||||
if let SyncAction::CreateBroadcast(name) = action {
|
if let SyncAction::CreateBroadcast { chat_name, secret } = action {
|
||||||
create_broadcast_ex(self, Nosync, grpid.clone(), name.clone()).await?;
|
create_broadcast_ex(
|
||||||
|
self,
|
||||||
|
Nosync,
|
||||||
|
grpid.clone(),
|
||||||
|
chat_name.clone(),
|
||||||
|
secret.to_string(),
|
||||||
|
)
|
||||||
|
.await?;
|
||||||
return Ok(());
|
return Ok(());
|
||||||
}
|
}
|
||||||
get_chat_id_by_grpid(self, grpid)
|
get_chat_id_by_grpid(self, grpid)
|
||||||
@@ -5039,7 +5058,7 @@ impl Context {
|
|||||||
SyncAction::Accept => chat_id.accept_ex(self, Nosync).await,
|
SyncAction::Accept => chat_id.accept_ex(self, Nosync).await,
|
||||||
SyncAction::SetVisibility(v) => chat_id.set_visibility_ex(self, Nosync, *v).await,
|
SyncAction::SetVisibility(v) => chat_id.set_visibility_ex(self, Nosync, *v).await,
|
||||||
SyncAction::SetMuted(duration) => set_muted_ex(self, Nosync, chat_id, *duration).await,
|
SyncAction::SetMuted(duration) => set_muted_ex(self, Nosync, chat_id, *duration).await,
|
||||||
SyncAction::CreateBroadcast(_) => {
|
SyncAction::CreateBroadcast { .. } => {
|
||||||
Err(anyhow!("sync_alter_chat({id:?}, {action:?}): Bad request."))
|
Err(anyhow!("sync_alter_chat({id:?}, {action:?}): Bad request."))
|
||||||
}
|
}
|
||||||
SyncAction::Rename(to) => rename_ex(self, Nosync, chat_id, to).await,
|
SyncAction::Rename(to) => rename_ex(self, Nosync, chat_id, to).await,
|
||||||
|
|||||||
@@ -3827,12 +3827,25 @@ async fn test_sync_name() -> Result<()> {
|
|||||||
let a0_broadcast_id = create_broadcast(alice0, "Channel".to_string()).await?;
|
let a0_broadcast_id = create_broadcast(alice0, "Channel".to_string()).await?;
|
||||||
sync(alice0, alice1).await;
|
sync(alice0, alice1).await;
|
||||||
let a0_broadcast_chat = Chat::load_from_db(alice0, a0_broadcast_id).await?;
|
let a0_broadcast_chat = Chat::load_from_db(alice0, a0_broadcast_id).await?;
|
||||||
|
|
||||||
set_chat_name(alice0, a0_broadcast_id, "Broadcast channel 42").await?;
|
set_chat_name(alice0, a0_broadcast_id, "Broadcast channel 42").await?;
|
||||||
sync(alice0, alice1).await;
|
//sync(alice0, alice1).await; // crash
|
||||||
|
|
||||||
|
let sent = alice0.pop_sent_msg().await;
|
||||||
|
let rcvd = alice1.recv_msg(&sent).await;
|
||||||
|
assert_eq!(rcvd.from_id, ContactId::SELF);
|
||||||
|
assert_eq!(rcvd.to_id, ContactId::SELF);
|
||||||
|
assert_eq!(
|
||||||
|
rcvd.text,
|
||||||
|
"You changed group name from \"Channel\" to \"Broadcast channel 42\"."
|
||||||
|
);
|
||||||
|
assert_eq!(rcvd.param.get_cmd(), SystemMessage::GroupNameChanged);
|
||||||
let a1_broadcast_id = get_chat_id_by_grpid(alice1, &a0_broadcast_chat.grpid)
|
let a1_broadcast_id = get_chat_id_by_grpid(alice1, &a0_broadcast_chat.grpid)
|
||||||
.await?
|
.await?
|
||||||
.unwrap()
|
.unwrap()
|
||||||
.0;
|
.0;
|
||||||
|
assert_eq!(rcvd.chat_id, a1_broadcast_id);
|
||||||
|
|
||||||
let a1_broadcast_chat = Chat::load_from_db(alice1, a1_broadcast_id).await?;
|
let a1_broadcast_chat = Chat::load_from_db(alice1, a1_broadcast_id).await?;
|
||||||
assert_eq!(a1_broadcast_chat.get_type(), Chattype::OutBroadcast);
|
assert_eq!(a1_broadcast_chat.get_type(), Chattype::OutBroadcast);
|
||||||
assert_eq!(a1_broadcast_chat.get_name(), "Broadcast channel 42");
|
assert_eq!(a1_broadcast_chat.get_name(), "Broadcast channel 42");
|
||||||
|
|||||||
@@ -174,7 +174,7 @@ pub enum Param {
|
|||||||
/// and for messages adding members to such a chat.
|
/// and for messages adding members to such a chat.
|
||||||
/// The symmetric key shared among all chat participants,
|
/// The symmetric key shared among all chat participants,
|
||||||
/// used to encrypt and decrypt messages.
|
/// used to encrypt and decrypt messages.
|
||||||
SymmetricKey = b'z',
|
SymmetricKey = b'z', // TODO remove this again
|
||||||
|
|
||||||
/// For Contacts: If this is the List-Post address of a mailing list, contains
|
/// For Contacts: If this is the List-Post address of a mailing list, contains
|
||||||
/// the List-Id of the mailing list (which is also used as the group id of the chat).
|
/// the List-Id of the mailing list (which is also used as the group id of the chat).
|
||||||
|
|||||||
@@ -1540,10 +1540,25 @@ async fn do_chat_assignment(
|
|||||||
if let Some((id, ..)) = chat::get_chat_id_by_grpid(context, &listid).await?
|
if let Some((id, ..)) = chat::get_chat_id_by_grpid(context, &listid).await?
|
||||||
{
|
{
|
||||||
id
|
id
|
||||||
} else {
|
} else if let Some(secret) =
|
||||||
|
mime_parser.get_header(HeaderDef::ChatBroadcastSecret)
|
||||||
|
{
|
||||||
let name =
|
let name =
|
||||||
compute_mailinglist_name(mailinglist_header, &listid, mime_parser);
|
compute_mailinglist_name(mailinglist_header, &listid, mime_parser);
|
||||||
chat::create_broadcast_ex(context, Nosync, listid, name).await?
|
chat::create_broadcast_ex(
|
||||||
|
context,
|
||||||
|
Nosync,
|
||||||
|
listid,
|
||||||
|
name,
|
||||||
|
secret.to_string(),
|
||||||
|
)
|
||||||
|
.await?
|
||||||
|
} else {
|
||||||
|
warn!(
|
||||||
|
context,
|
||||||
|
"Unknown shared secret for outgoing broadcast (TRASH)"
|
||||||
|
);
|
||||||
|
DC_CHAT_ID_TRASH
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
@@ -3450,8 +3465,22 @@ async fn apply_out_broadcast_changes(
|
|||||||
chat: &mut Chat,
|
chat: &mut Chat,
|
||||||
from_id: ContactId,
|
from_id: ContactId,
|
||||||
) -> Result<GroupChangesInfo> {
|
) -> Result<GroupChangesInfo> {
|
||||||
|
// TODO code duplication with apply_in_broadcast_changes()
|
||||||
ensure!(chat.typ == Chattype::OutBroadcast);
|
ensure!(chat.typ == Chattype::OutBroadcast);
|
||||||
|
|
||||||
|
let mut send_event_chat_modified = false;
|
||||||
|
let mut better_msg = None;
|
||||||
|
|
||||||
|
apply_chat_name_and_avatar_changes(
|
||||||
|
context,
|
||||||
|
mime_parser,
|
||||||
|
from_id,
|
||||||
|
chat,
|
||||||
|
&mut send_event_chat_modified,
|
||||||
|
&mut better_msg,
|
||||||
|
)
|
||||||
|
.await?;
|
||||||
|
|
||||||
if let Some(_removed_addr) = mime_parser.get_header(HeaderDef::ChatGroupMemberRemoved) {
|
if let Some(_removed_addr) = mime_parser.get_header(HeaderDef::ChatGroupMemberRemoved) {
|
||||||
// The sender of the message left the broadcast channel
|
// The sender of the message left the broadcast channel
|
||||||
remove_from_chat_contacts_table(context, chat.id, from_id).await?;
|
remove_from_chat_contacts_table(context, chat.id, from_id).await?;
|
||||||
@@ -3464,7 +3493,16 @@ async fn apply_out_broadcast_changes(
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
Ok(GroupChangesInfo::default())
|
if send_event_chat_modified {
|
||||||
|
context.emit_event(EventType::ChatModified(chat.id));
|
||||||
|
chatlist_events::emit_chatlist_item_changed(context, chat.id);
|
||||||
|
}
|
||||||
|
Ok(GroupChangesInfo {
|
||||||
|
better_msg,
|
||||||
|
added_removed_id: None,
|
||||||
|
silent: false,
|
||||||
|
extra_msgs: vec![],
|
||||||
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
async fn apply_in_broadcast_changes(
|
async fn apply_in_broadcast_changes(
|
||||||
|
|||||||
Reference in New Issue
Block a user