Commit Graph

72 Commits

Author SHA1 Message Date
link2xt
25750de4e1 feat: send sync messages over SMTP and do not move them to mvbox 2025-12-26 10:58:33 +00:00
link2xt
f7ae2abe52 feat: synchronize transports via sync messages 2025-12-04 14:40:36 +00:00
link2xt
22ebd6436f feat: default bcc_self to 0 for new accounts 2025-11-16 10:00:00 +00:00
link2xt
cf5b145ce0 refactor: remove unused imports 2025-11-07 17:31:34 +00:00
link2xt
9c2a13b88e refactor(sql): do not expose rusqlite Error type in query_map methods
We use query_and_then() instead of query_map() function now.
The difference is that row processing function
returns anyhow::Result, so simple fallible processing
like JSON parsing can be done inside of it
when calling query_map_vec() and query_map_collect()
without having to resort to query_map()
and iterating over all rows again afterwards.
2025-11-03 23:08:56 +00:00
link2xt
2f2a147efb feat: move the messages only from INBOX and Spam folders
We do not try to delete resent messages
anymore. Previously resent messages
were distinguised by having duplicate Message-ID,
but future Date, but now we need to download
the message before we even see the Date.
We now move the message to the destination folder
but do not fetch it.

It may not be a good idea to delete
the duplicate in multi-device setups anyway,
because the device which has a message
may delete the duplicate of a message
the other device missed.

To avoid triggering IMAP busy move loop
described in the comments
we now only move the messages
from INBOX and Spam folders.
2025-10-23 15:29:14 +00:00
iequidoo
fc81cef113 refactor: Rename chat::create_group_chat() to create_group()
If we use modules (which are actually namespaces), we can use shorter names. Another approach is to
only use modules for internal code incapsulation and use full names like deltachat-ffi does.
2025-10-20 04:19:22 -03:00
link2xt
afc74b0829 fix: do not allow sync item timestamps to be in the future 2025-10-19 11:35:10 +00:00
link2xt
498a831873 api!: remove APIs to create protected chats
Create unprotected group in test_create_protected_grp_multidev
The test is renamed accordingly.

SystemMessage::ChatE2ee is added in encrypted groups
regardless of whether they are protected or not.
Previously new encrypted unprotected groups
had no message saying that messages are end-to-end encrypted
at all.
2025-10-19 11:35:09 +00:00
link2xt
eea848f72b fix: don't ignore QR token timestamp from sync messages 2025-10-19 11:35:09 +00:00
link2xt
307a2eb6ec feat: withdraw all QR codes when one is withdrawn
This is a preparation for expiring authentication tokens.

If we make authentication token expire,
we need to generate new authentication tokens each time
QR code screen is opened in the UI,
so authentication token is fresh.
We however don't want to completely invalidate
old authentication codes at the same time,
e.g. they should still be valid for joining groups,
just not result in a verification on the inviter side.

Since a group now can have a lot of authentication tokens,
it is easy to lose track of them
without any way to remove them
as they are not displayed anywhere in the UI.
As a solution, we now remove all
tokens corresponding to a group ID
when one token is withdrawn,
or all non-group tokens
when a single non-group token is withdrawn.

"Reset QR code" option already present
in the UI which works by resetting
current QR code will work without any UI changes,
but will now result in invalidation
of all previously created QR codes and invite links.
2025-09-08 17:51:45 +00:00
bjoern
ab8aedf06e refine call states (#7179)
- sync declined calls from callee to caller, as usual in all larger
messengers
- introduce the call states "Missed call", "Declined call" and
"Cancelled all" ("Ended call" is gone)
- allow calling end_call()/accept_call() for already ended/accepted
calls, in practise, handling all cornercases is tricky in UI - and the
state needs anyways to be tracked.
- track and show the call duration

the duration calculation depends on local time, but it is displayed only
coarse and is not needed for any state. this can be improved as needed,
timestamps of the corresponding messages are probably better at some
point. or ending device sends its view of the time around. but for the
first throw, it seems good enough

if we finally want that set of states, it can be exposed to a json-info
in a subsequent call, so that the UI can render it more nicely. fallback
strings as follows will stay for now to make adaption in other UI easy,
and for debugging:

<img width="320" alt="IMG_0154"
src="https://github.com/user-attachments/assets/09a89bfb-66f4-4184-b05c-e8040b96cf44"
/>

successor of https://github.com/chatmail/core/pull/6650
2025-09-08 15:48:35 +02:00
bjoern
0bbd910883 feat: add call ringing API (#6650)
this PR adds a "ringing" api that can be used for calls later.

see deltachat.h for details about the API; jsonrpc is left out until
things are settled for the needs of android/iOS

UI using this PR already successfully are
https://github.com/deltachat/deltachat-ios/pull/2638 and
https://github.com/deltachat/deltachat-android/pull/3785 ; the "payload"
passed forth and back is optimised for
https://github.com/deltachat/calls-webapp

---------

Co-authored-by: l <link2xt@testrun.org>
2025-08-30 23:48:38 +02:00
link2xt
5c3de759d3 refactor: upgrade to Rust 2024 2025-06-28 17:07:59 +00:00
link2xt
545007aca5 api!: make logging macros private 2025-06-21 11:01:25 +00:00
iequidoo
ce04e904e2 fix: Sort multiple saved messages by timestamp (#6862) 2025-06-06 03:59:36 -03:00
link2xt
4c287075da fix: do not allow chat creation if decryption failed 2025-05-15 18:02:19 +00:00
bjoern
97b0d09ed2 feat: get contact-id for info messages (#6714)
instead of showing addresses in info message, provide an API to get the
contact-id.

UI can then make the info message tappable and open the contact profile
in scope

the corresponding iOS PR - incl. **screencast** - is at
https://github.com/deltachat/deltachat-ios/pull/2652 ; jsonrpc can come
in a subsequent PR when things are settled on android/ios

the number of parameters in `add_info_msg_with_cmd` gets bigger and
bigger, however, i did not want to refactor this in this PR. it is also
not really adding complexity



closes #6702

---------

Co-authored-by: link2xt <link2xt@testrun.org>
Co-authored-by: Hocuri <hocuri@gmx.de>
2025-03-31 18:56:57 +02:00
iequidoo
a9fbdafda5 fix: chat::save_msgs: Interrupt inbox loop to send a sync message
Also fix the `send_sync_msg()` documentation: now it's called from the inbox loop, not SMTP (because
`IMAP APPEND` is used to upload sync messages).
2025-02-26 15:36:48 -03:00
bjoern
8ffdd55f79 sync message deletion to other devices (#6573)
this PR synchronises deletion of messages across devices and adds a test
for it

---------

Co-authored-by: Hocuri <hocuri@gmx.de>
2025-02-26 14:26:19 +00:00
link2xt
67f768fec0 refactor: use mail-builder instead of lettre_email 2025-02-18 21:29:35 +00:00
Hocuri
723ff25067 feat: Set BccSelf to true when receiving a sync message (#6434)
Fix https://github.com/deltachat/deltachat-core-rust/issues/6433

I at first only wanted to do it any outgoing messages, but @link2xt was
concerned that this may accidentally enable bcc_self, e.g. in the
following case:
- you send out a message
- it's deleted, e.g. via ephemeral messages
- Someone forwards this outgoing message to you again, e.g. via a
mailing list.
2025-01-20 22:05:29 +01:00
bjoern
0d8c2ee9ff feat: add API to save messages (#5606)
> _took quite some time until i found the time to finish this PR and to
find a time window that does not disturb other developments too much,
but here we are:_

this PR enables UI to improve "Saved messages" hugely, bringing it on
WhatsApp's "Starred Messages" or Telegram's "Saved Messages" level. with
this PR, UIs can add the following functionality with few effort ([~100
loc on iOS](https://github.com/deltachat/deltachat-ios/pull/2527)):

- add a "Save" button in the messages context menu, allowing to save a
message
- show directly in the chat if a message was saved, eg. by a little star
★
- in "Saved Messages", show the message in its context - so with author,
avatar, date and keep incoming/outgoing state
- in "Saved Messages", a button to go to the original message can be
added
- if the original message was deleted, one can still go to the original
chat

these features were often requested, in the forum, but also in many
one-to-one discussions, recently at the global gathering.

moreover, in contrast to the old method with "forward to saved", no
traffic is wasted - the messages are saved locally, and only a small
sync messages is sent around

this is how it looks out on iOS:

<img width="260" alt="Screenshot 2025-01-17 at 00 02 51"
src="https://github.com/user-attachments/assets/902741b6-167f-4af1-9f9a-bd0439dd20d0"
/> &nbsp; &nbsp; <img width="353" alt="Screenshot 2025-01-17 at 00 05
33"
src="https://github.com/user-attachments/assets/97eceb79-6e43-4a89-9792-2e077e7141cd"
/>

technically, still a copy is done from the original message (with
already now deduplicated blobs), so that things work nicely with
deletion modes; eg. you can save an important message and preserve it
from deletion that way.

jsonrpc can be done in a subsequent PR, i was implementing the UI on iOS
where that was not needed (and most API were part of message object that
is not in use in jsonrpc atm)

@hpk42 the forward issue we discussed earller that day is already solved
(first implementation did not had an explict save_msgs() but was using
forward_msgs(SELF) as saving - with the disadvantage that forwarding to
SELF is not working, eg. if one wants the old behaviour) acutally, that
made the PR a lot nicer, as now very few existing code is changed

<details>
<summary>previous considerations and abandoned things</summary>

while working on this PR, there was also the idea to just set a flag
“starred” in the message table and not copy anything. however, while
tempting, that would result in more complexity, questions and drawbacks
in UI:

- delete-message, delete-chat, auto-deletion, clear-chat would raise
questions - what do do with the “Starred”? having a copy in “Saved
Messages” does not raise this question
- newly saved messages appear naturally as “new” in “Saved Messages”,
simply setting a flag would show them somewhere in between - unless we
do additional effort
- “Saved Messages” already has its place in the UI - and allows to
_directly_ save things there as well - not easily doable with “starring”
- one would need to re-do many things that already exist in “Saved
Messages”, at least in core
- one idea to solve some of the issues could be to have “Starred” as
well as “Saved Messages” - however, that would irritate user, one would
remember exactly what was done with a message, and understand the fine
differences

whatsapp does this “starred”, btw, so when original is deleted, starred
is deleted as well. Telegram does things similar to us, Signal does
nothing. Whatsapp has a per-chat view for starred messages - if needed,
we could do sth. like that as well, however, let’s first see how far the
“all view” goes (in contrast to whatsapp, we have profiles for
separation as well)

for the wording: “saving” is what we’re doing here, this is much more on
point as “starring” - which is more the idea of a “bookmark”, and i
think, whatsapp uses this wording to not raise false expectations
(still, i know of ppl that were quite upset that a “starred” message was
deleted when eg. the chat was cleared to save some memory)

wrt webxdc app updates: options that come into mind were: _empty_ (as
now), _snapshot_ (copy all updates) or _shortcut_ (always open
original). i am not sure what the best solution is, the easiest was
_empty_, so i went for that, as it is (a) obvious, and what is already
done with forwarding and (b) the original is easy to open now (in
contrast to forwarding).
so, might totally be that we need or want to tweak things here, but i
would leave that outside the first iteration, things are not worsened in
that area

wrt reactions: as things are detached, similar to webxdc updates, we do
not not to show the original reactions - that way, one can use reactions
for private markers (telegram is selling that feature :)

to the icon: a disk or a bookmark might be other options, but the star
is nicer and also know from other apps - and anyways a but vague UX
wise. so i think, it is fine

finally, known issue is that if a message was saved that does not exist
on another device, it does not get there. i think, that issue is a weak
one, and can be ignored mostly, most times, user will save messages soon
after receiving, and if on some devices auto-deletion is done, it is
maybe not even expected to have suddenly another copy there

</details>

EDIT: once this is merged, detailed issues about what to do should be
filed for android/desktop (however, they do not have urgency to adapt,
things will continue working as is)

---------

Co-authored-by: Hocuri <hocuri@gmx.de>
2025-01-19 15:44:57 +00:00
iequidoo
1792d48144 fix: Don't treat location-only and sync messages as bot ones (#6357) 2025-01-02 13:14:56 -03:00
iequidoo
d6845bd5e9 feat: Use IMAP APPEND command to upload sync messages (#5845)
Why:
- With IMAP APPEND we can upload messages directly to the DeltaChat folder (for non-chatmail
  accounts).
- We can set the `\Seen` flag immediately so that if the user has other MUA, it doesn't alert about
  a new message if it's just a sync message (there were several such reports on the support
  forum). Though this also isn't useful for chatmail.
- We don't need SMTP envelope and overall remove some overhead on processing sync messages.
2024-09-20 17:07:45 -03:00
iequidoo
5a6efdff44 fix: Save QR code token regardless of whether the group exists (#5954)
Groups promotion to other devices and QR code tokens synchronisation are not synchronised processes,
so there are reasons why a QR code token may arrive earlier than the first group message:
- We are going to upload sync messages via IMAP while group messages are sent by SMTP.
- If sync messages go to the mvbox, they can be fetched earlier than group messages from Inbox.
2024-09-16 16:40:26 -03:00
iequidoo
418dfbf994 fix: Don't sync QR code token before populating the group (#5935)
Otherwise other devices don't yet know about the group and can't handle the sync message correctly.
2024-09-04 15:18:26 -03:00
iequidoo
e4d65b2f3b fix: Call send_sync_msg() only from the SMTP loop (#5780)
`Context::send_sync_msg()` mustn't be called from multiple tasks in parallel to avoid sending the
same sync items twice because sync items are removed from the db only after successful
sending. Let's guarantee this by calling `send_sync_msg()` only from the SMTP loop. Before
`send_sync_msg()` could be called in parallel from the SMTP loop and another task doing
e.g. `chat::sync()` which led to `test_multidevice_sync_chat` being flaky because of events
triggered by duplicated sync messages.
2024-07-21 12:10:06 -03:00
iequidoo
5fa7cff468 feat: Disable sending sync messages for bots (#5705)
If currently there are no multi-device bots, let's disable sync messages for bots at all. Another
option is to auto-disable sync messages when `Config::Bot` is set, so sync messages can be reenabled
if needed. But let's leave this option for the future.
2024-07-01 21:30:02 -03:00
link2xt
8953c2a7de fix: do not send sync messages if bcc_self is disabled 2024-06-19 22:11:56 +00:00
link2xt
c069190b68 api: don't load trashed messages with Message::load_from_db
API now pretends that trashed messages don't exist.
This way callers don't have to check if loaded message
belongs to trash chat.
If message may be trashed by the time it is attempted to be loaded,
callers should use Message::load_from_db_optional.

Most changes are around receive_status_update() function
because previously it relied on loading trashed status update
messages immediately after adding them to the database.
2024-04-14 17:43:41 +00:00
link2xt
2030de11d9 chore: fix 2024-03-05 nightly clippy warnings 2024-03-08 02:53:47 +00:00
iequidoo
656d4ed506 feat: Sync self-avatar across devices (#4893)
Use sync messages for that as it is done for e.g. Config::Displayname. Maybe we need to remove
avatar synchronisation via usual messages then, but let's think of it a bit.
2024-02-19 12:18:13 -03:00
iequidoo
6e55f0c6e3 feat: Mock SystemTime::now() for the tests
Add a new crate `deltachat_time` with a fake `struct SystemTimeTools` for mocking
`SystemTime::now()` for test purposes. One still needs to use `std::time::SystemTime` as a struct
representing a system time. I think such a minimalistic approach is ok -- even if somebody uses the
original `SystemTime::now()` instead of the mock by mistake, that could break only tests but not the
program itself. The worst thing that can happen is that tests using `SystemTime::shift()` and
checking messages timestamps f.e. wouldn't catch the corresponding bugs, but now we don't have such
tests at all which is much worse.
2024-02-15 14:24:46 -03:00
link2xt
0fcdee8857 refactor: resultify token::exists 2024-02-09 04:36:32 +00:00
link2xt
2f8a8f9f50 ci: update to Rust 1.75.0 and fix clippy 2024-01-08 20:01:40 +00:00
iequidoo
a47fec7f6c feat: Sync Config::{MdnsEnabled,ShowEmails} across devices (#4954)
Motivation: Syncing these options will improve UX in very most cases and should be done. Other
candidates are less clear or are advanced options, we can reconsider that at some point later.

Approach:
- Sync options one-by-one when the corresponding option is set (even if to the same value).
- Don't sync when an option is reset to a default as defaults may differ across client versions.
- Check on both sides that the option should be synced so that if there are different client
  versions, the synchronisation of the option is either done or not done in both directions.
  Moreover, receivers of a config value need to check if a key can be synced because some settings
  (e.g. Avatar path) could otherwise lead to exfiltration of files from a receiver's device if we
  assume an attacker to have control of a device in a multi-device setting or if multiple users are
  sharing an account.
- Don't sync `SyncMsgs` itself.
2023-12-01 21:41:58 -03:00
link2xt
b0ef082b2a fix(sync): ignore unknown sync items to provide forward compatibility 2023-11-15 19:17:38 +00:00
iequidoo
34a434f07c refactor: Move chat-related code from sync to chat module
- Reduce cross-module dependencies.
- Stop bloating the `sync` module while implementing synchronisation of more entities.
- Now there's the only `ChatId` :)
2023-11-13 05:00:57 -03:00
iequidoo
dc944d8ca7 test: Broadcast lists synchronisation (#4953) 2023-11-13 05:00:57 -03:00
iequidoo
b06a7e7197 fix: Context::execute_sync_items: Ignore all errors (#4817)
An error while executing an item mustn't prevent next items from being executed. There was a comment
that only critical errors like db write failures must be reported upstack, but in fact it's hard to
achieve in the current design, there are no error codes or so, so it's bug-prone. E.g.
`ChatAction::Block` and `Unblock` already reported all errors upstack. So, let's make error handling
the same as everywhere and just ignore any errors in the item execution loop. In the worst case we
just do more unsuccessful db writes f.e.
2023-11-13 05:00:57 -03:00
iequidoo
7977c9ab44 feat: Sync creating broadcast lists across devices (#4953) 2023-11-13 05:00:57 -03:00
iequidoo
4d1a9c2aa1 feat: Sync chat contacts across devices (#4953)
Sync chat contacts across devices for broadcast lists and groups. This needs the corresponding chat
to exist on other devices which is not the case for unpromoted groups, so it fails for them now but
it's only a warning and will work once creation of unpromoted groups is synchronised too.
2023-11-13 05:00:57 -03:00
iequidoo
013467d6c6 test: Group chats device synchronisation 2023-11-06 20:02:28 +00:00
iequidoo
e923983dca fix: Synchronise self-chat
It just didn't work before, sync messages were not generated.
2023-11-04 19:16:35 -03:00
iequidoo
f4753862f1 feat: Sync chat state immediately (#4817)
Sync messages are only sent on explicit user actions and only one per action, so it's safe to send
them right away not worrying about the rate limit on the server.
2023-11-04 19:16:35 -03:00
iequidoo
cdcb10fb58 refactor: Make SyncData::AlterChat an inline struct 2023-11-02 08:47:20 -03:00
iequidoo
6cd7296001 refactor: Replace Context::nosync flag with internal functions taking enum Sync (#4817) 2023-11-02 08:47:20 -03:00
iequidoo
168021523f feat: Sync Contact::blocked across devices (#4817) 2023-11-02 08:47:20 -03:00
iequidoo
03f2635296 feat: Sync chat mute_duration across devices (#4817) 2023-11-02 08:47:20 -03:00