Prepares a message to be sent out. Returns row ids of the `smtp` table.
(
context: &Context,
chat_id: ChatId,
msg: &mut Message,
)
| 2659 | /// |
| 2660 | /// Returns row ids of the `smtp` table. |
| 2661 | async fn prepare_send_msg( |
| 2662 | context: &Context, |
| 2663 | chat_id: ChatId, |
| 2664 | msg: &mut Message, |
| 2665 | ) -> Result<Vec<i64>> { |
| 2666 | let mut chat = Chat::load_from_db(context, chat_id).await?; |
| 2667 | |
| 2668 | let skip_fn = |reason: &CantSendReason| match reason { |
| 2669 | CantSendReason::ContactRequest => { |
| 2670 | // Allow securejoin messages, they are supposed to repair the verification. |
| 2671 | // If the chat is a contact request, let the user accept it later. |
| 2672 | msg.param.get_cmd() == SystemMessage::SecurejoinMessage |
| 2673 | } |
| 2674 | // Allow to send "Member removed" messages so we can leave the group/broadcast. |
| 2675 | // Necessary checks should be made anyway before removing contact |
| 2676 | // from the chat. |
| 2677 | CantSendReason::NotAMember => msg.param.get_cmd() == SystemMessage::MemberRemovedFromGroup, |
| 2678 | CantSendReason::InBroadcast => { |
| 2679 | matches!( |
| 2680 | msg.param.get_cmd(), |
| 2681 | SystemMessage::MemberRemovedFromGroup | SystemMessage::SecurejoinMessage |
| 2682 | ) |
| 2683 | } |
| 2684 | CantSendReason::MissingKey => msg |
| 2685 | .param |
| 2686 | .get_bool(Param::ForcePlaintext) |
| 2687 | .unwrap_or_default(), |
| 2688 | _ => false, |
| 2689 | }; |
| 2690 | if let Some(reason) = chat.why_cant_send_ex(context, &skip_fn).await? { |
| 2691 | bail!("Cannot send to {chat_id}: {reason}"); |
| 2692 | } |
| 2693 | |
| 2694 | // Check a quote reply is not leaking data from other chats. |
| 2695 | // This is meant as a last line of defence, the UI should check that before as well. |
| 2696 | // (We allow Chattype::Single in general for "Reply Privately"; |
| 2697 | // checking for exact contact_id will produce false positives when ppl just left the group) |
| 2698 | if chat.typ != Chattype::Single |
| 2699 | && !context.get_config_bool(Config::Bot).await? |
| 2700 | && let Some(quoted_message) = msg.quoted_message(context).await? |
| 2701 | && quoted_message.chat_id != chat_id |
| 2702 | { |
| 2703 | bail!( |
| 2704 | "Quote of message from {} cannot be sent to {chat_id}", |
| 2705 | quoted_message.chat_id |
| 2706 | ); |
| 2707 | } |
| 2708 | |
| 2709 | // check current MessageState for drafts (to keep msg_id) ... |
| 2710 | let update_msg_id = if msg.state == MessageState::OutDraft { |
| 2711 | msg.hidden = false; |
| 2712 | if !msg.id.is_special() && msg.chat_id == chat_id { |
| 2713 | Some(msg.id) |
| 2714 | } else { |
| 2715 | None |
| 2716 | } |
| 2717 | } else { |
| 2718 | None |
no test coverage detected