element-hq / element-hq/hydrogen-web
Ensure room keys are always shared
- Dominant language
- TypeScript
- Stars
- 714
- Forks
- 131
- PR merge metrics
- No merged PRs in 30d
Description
Currently, when creating a new room key, we're persisting the outbound session in a different transaction as the share_key operation. If you close the application at just the right time, or an error is thrown between both transactions, the key would be created but never shared with the current members. This could be more robust by doing it in a single transaction.
The reason that we do this in 2 different transactions is because getting the devices with who to share the key can involve network requests, which would auto-commit any ongoing transaction.
With the following steps, we should be able to do this in one transaction:
1. **decide whether we need to create a new outbound session (but don't create it).**
1. **If so, track the room and fetch only the users we need to share with, not yet the devices.**
This will allow us to create the outbound session right after calling /members. Any incoming membership changes during the /members request will be included in the resulting member list. Any that come in during /keys/query wont. Besides, we write the user ids, not devices in the share_key operation so don't really need the devices until we're about to actually send the keys.
1. **Create the new outbound session if needed (and encrypt a message with it if we're doing that and not pre-sharing).**
It is theoretically possible that we don't have a session but decided we don't need a new one because something discarded it in the meantime. But if we already have a session, we should already be tracking the room, so we won't call members. Hence there is little change to race here with something discarding the session. If it does happen, we throw an error and encryption has to be retried.
1. store a share_key operation with the previously fetched user ids
1. **Share the room key** (possibly in the background)
1. until successful:
1. fetch the devices for the user ids (this will call /keys/query)
1. send the key to the devices
Contributor guide
Assessment
This issue has not been assessed yet.