Commit graph

24 commits

Author SHA1 Message Date
ivk
83a81c31b8 Fix incorrect imports from @tutao/tutanota-utils 2025-09-30 16:40:14 +02:00
vis
c8b2fd130e
Create user group identity keys for existing users
We add an event type to EventBusListener to be able to perform the migration in the worker once the synchronization is done.

We send error any to the main thread so the user can reporet them, but we do not stop processing the event queue.

tuta#2079
2025-08-07 09:59:20 +02:00
ivk
a0735599b9 Enable stricter eslint rules
Co-authored-by: hrb-hub <hrb-hub@users.noreply.github.com>
2025-08-04 13:34:21 +02:00
abp
7bd8b570c8
don't try to decrypt the instance on entityUpdate if session key is null
Co-authored-by: das <das@tutao.de>
Co-authored-by: jomapp <17314077+jomapp@users.noreply.github.com>
Co-authored-by: ganthern <nig@tutao.de>
Co-authored-by: Kinan <104761667+kibibytium@users.noreply.github.com>
Co-authored-by: sug <sug@tutao.de>
2025-07-10 13:08:46 +02:00
jhm
784c91f23c
improve handling of decryption _errors for instances on entityUpdates
We should make sure that we never process nor write any entry instance
from an entityUpdate to the offline database in case we encountered
_errors while decrypting the instance. Otherwise, we can end up in
an inconsistent offline database state.
2025-07-09 12:26:36 +02:00
jhm
ce0e77b6a8
merge eventQueue and eventInstancePrefetcher progressMonitor 2025-07-08 19:40:54 +02:00
abp
2f26f4d7b4
fix websocket message processing breaking when the message contains ;
WebSocket messages can contain the ';' character as we include the
instance on the websocket when the client is online now. This will break
the separation logic between the message type and the message. We need
to join them together to make sure the message remains a valid JSON.
2025-07-08 19:25:42 +02:00
abp
1e265af490
do not use the instance on the update for File type
Co-authored-by: sug <sug@tutao.de>
2025-07-07 14:32:25 +02:00
jhm
5e8aa2bf05
introduce PrefetchStatus in entityUpdateData
We introduce a PrefetchStatus to account for instances not returned
by the server as early as possible. This ensures that we do not throw
in case of 404 not found or 403 not authorized error, when instances
corresponding to create or update entityUpdates have already been
deleted or permissions have been revoked.

Co-authored-by: abp <abp@tutao.de>
2025-07-04 14:14:32 +02:00
map
8374741340
sync metrics 2025-07-02 14:00:12 +02:00
abp
4db7e9b1e9
add prefetching to missed entityUpdates, instance/patch on EntityUpdate
When processing the missed entityUpdates in EventQueue in EventBusClient
, we group entityUpdates based on typeRefs and listIds and do
loadMultiple requests instead of loading them one-by-one (prefetching).
Additionally, when the client is online, the server enriches the
WebSocket message with either the instance (in case of a CREATE event),
or with the patches list (in case of an UPDATE event) so that we do not
need to do an additional GET request and can either put the instance
into the cache or update the entry on the cache using the PatchMerger
instead.

Co-authored-by: abp <abp@tutao.de>
Co-authored-by: das <das@tutao.de>
Co-authored-by: jomapp <17314077+jomapp@users.noreply.github.com>
Co-authored-by: Kinan <104761667+kibibytium@users.noreply.github.com>
Co-authored-by: map <mpfau@users.noreply.github.com>
Co-authored-by: sug <sug@tutao.de>
2025-07-02 14:00:11 +02:00
ivk
86d5775e16 Add SQLite search on clients where offline storage is available
- Introduce a separate Indexer for SQLite using FTS5
- Split search backends and use the right one based on client (IndexedDB
  for Browser, and OfflineStorage everywhere else)
- Split SearchFacade into two implementations
- Adds a table for storing unindexed metadata for mails
- Escape special character for SQLite search
  To escape special characters from fts5 syntax. However, simply
  surrounding each token in quotes is sufficient to do this.
  See section 3.1 "FTS5 Strings" here: https://www.sqlite.org/fts5.html
  which states that a string may be specified by surrounding it in
  quotes, and that special string requirements only exist for strings
  that are not in quotes.
- Add EncryptedDbWrapper
- Simplify out of sync logic in IndexedDbIndexer
- Fix deadlock when initializing IndexedDbIndexer
- Cleanup indexedDb index when migrating to offline storage index
- Pass contactSuggestionFacade to IndexedDbSearchFacade
    The only suggestion facade used by IndexedDbSearchFacade was the
    contact suggestion facade. So we made it clearer.
- Remove IndexerCore stats
- Split custom cache handlers into separate files
  We were already doing this with user, so we should do this with the
  other entity types.

- Rewrite IndexedDb tests
- Add OfflineStorage indexer tests
- Add custom cache handlers tests to OfflineStorageTest
- Add tests for custom cache handlers with ephemeral storage
- Use dbStub instead of dbMock in IndexedDbIndexerTest
- Replace spy with testdouble in IndexedDbIndexerTest

Close #8550

Co-authored-by: ivk <ivk@tutao.de>
Co-authored-by: paw <paw-hub@users.noreply.github.com>
Co-authored-by: wrd <wrd@tutao.de>
Co-authored-by: bir <bir@tutao.de>
Co-authored-by: hrb-hub <hrb-hub@users.noreply.github.com>
2025-06-04 10:36:46 +02:00
ivk
9312ade83a Inject type model resolvers
Passing instances explicitly avoids the situations where some of them
might not be initialized.

We also simplified the entity handling by converting entity updates to
data with resolved types early so that the listening code doesn't have
to deal with it.

We did fix some of the bad test practices, e.g. setting/restoring env
incorrectly. This matters now because accessors for type model
initializers check env.mode.

Co-authored-by: paw <paw-hub@users.noreply.github.com>
2025-06-04 10:36:45 +02:00
kib
11617861cd fix server model info not being initialized
We observed clients that managed to get stuck with a missing server
model, which made login from stored credentials impossible and required
getting a new session.

The reason was that only the service executor, rest client and event bus
client cared to update the server model if they were missing.
However, the offline database also stores data in the server's model and
thus requires it to read any data. Since logging in will hit
the cache before requesting the server, a corrupted or missing server
model causes us to not be able to log in.

This commit gives the responsibility of acquiring the models to
ServerModelInfo.resolveServerTypeReference if they are missing or out
of date to avoid situations where we call resolveServerTypeReference
without first checking if the model is initialized.

Additionally, we show a dialog to the user if the models cannot be
initialized instead of an uncaught error.

We considered having the error handler try to repeat model
initialization, but since the original request already failed at that
point, getting back to a normal state would require an extra manual
retry.

fix #9004

Co-authored-by: nig <nig@tutao.de>
Co-authored-by: sug <sug@tutao.de>
Co-authored-by: kib <104761667+kibibytium@users.noreply.github.com>
2025-05-27 14:52:44 +02:00
ivk
9e31ee0409 Inject type model resolvers
Passing instances explicitly avoids the situations where some of them
might not be initialized.

We also simplified the entity handling by converting entity updates to
data with resolved types early so that the listening code doesn't have
to deal with it.

We did fix some of the bad test practices, e.g. setting/restoring env
incorrectly. This matters now because accessors for type model
initializers check env.mode.

Co-authored-by: paw <paw-hub@users.noreply.github.com>
2025-05-27 14:52:44 +02:00
map
f8a61909ea allow passing client name 2025-04-28 17:01:05 +02:00
Kinan
edbf281b88
switch to typeIds and attrIds, add SystemMV126, TutanotaMV86, BaseMV2
Refactor our instance deserialization/serialization pipeline, both on
TypeScript and on Rust [sdk] to use typeId and attributeIds instead of
typeNames and attributeNames. We furthermore ignore cardinalities
on associations until the instance layer and always
store associations as arrays. This commit introduces **eventual
consistency** on the client, i.e. we are from now on always storing data
in the newest schema format (activeApplicationVersionsForWritingSum)
which ensures that all data is already available on the client after
updating the client to a newer version. This removes the need for
offline migrations on the client and also removes backward migrations
on the server. Furthermore, the server model types are now available
on the client, retrievable through the ApplicationTypesFacade. This is
our first step towards FastSync.

Co-authored-by: nig <nig@tutao.de>
Co-authored-by: abp <abp@tutao.de>
Co-authored-by: jomapp <17314077+jomapp@users.noreply.github.com>
Co-authored-by: map <mpfau@users.noreply.github.com>
Co-authored-by: sug <sug@tutao.de>
Co-authored-by: Kinan <104761667+kibibytium@users.noreply.github.com>
2025-04-28 12:44:35 +02:00
mup
937300e2d9 Adds SyncTracker to track initial sync status
Calendar subscriptions can collide with entity updates during
application startup. This commit adds a SyncTracker to track the
progress of initial entity updates, and after processing the entire
batch, mark the sync as done, allowing calendars to synchronize with
fewer chance to collisions.
2025-02-26 13:34:56 +01:00
paw
8c1ed56072
update eslint to v9
Co-authored-by: paw-hub <paw-hub@users.noreply.github.com>
2025-01-09 14:55:11 +01:00
vis
159ac3bdc5
Bypass the cache when getting keys via adminEncGKey
When getting the current group key for a given group, it can be the case
that the group is loaded from the cache before the cache is updated by
the EventBusClient with a new key, so the key that we return is not
actually the current one. Bypassing the cache solves this problem.

It does come with the disadvantage that we may be doing unnecessary
network requests.

tutadb#1883
2024-10-18 16:14:15 +02:00
ivk
f3f17ea6d9
Fix "UPDATE not allowed after DELETE"
`batchMod()` was implemented incorrectly and was just picking the first
event.

Co-authored-by: paw <paw-hub@users.noreply.github.com>
2024-09-09 17:58:46 +02:00
ivk
531bc30464
Fix sync progress not shown as finished
Previous change to sync progress tracking did not take into account
event optimization where some batches might be skipped, either
immediately or retroactively (e.g. after we receive a delete event).

One change is to not start counting progress until we know how many
batches will be actually processed (so not until they are added to the
queue).

Another change is to not remove empty event batches from the queue to
not invalidate the expected number of batches that we process.

Note that the batches can still be optimized away completely at the
moment when they are added. That's why the caller must check the return
value of `add()`.

Co-authored-by: paw <paw-hub@users.noreply.github.com>
2024-09-09 14:25:51 +02:00
nig
bbbd33e4bb
filter for unknown types in EventBusClient
We might receive entityEventUpdates for types that are unknown to the
client and therefore want to exclude these types from being processed.
Therefore, we now remove unknown types that are not in tutanotaTypes
from the eventBatch.

Co-authored-by: nig <nig@tutao.de>
2024-09-03 13:07:18 +02:00
wrd
8ab3b14edd Move files to new folder structure
Co-authored-by: @rih-tutao
2024-07-26 16:42:13 +02:00
Renamed from src/api/worker/EventBusClient.ts (Browse further)