Implement MatrixClient.getStoredDevicesForUser which uses
Crypto.getStoredDevicesForUser, which is more powerful than listDeviceKeys, and
isn't deprecated.
Also a couple of accessors for DeviceInfo.
A couple of small refactors which fell out of the aborted stuff for upgrading
to secure Ed25519 keys, but are useful in their own right.
The main functional change here is to calculate the "algorithms" list from
DECRYPTION_CLASSES (and hence include megolm in the list).
- to make way for alternative encryption algorithms. We now store an encryption
object for each room, rather than referring to sessionstore on each event.
Also a little light tidying to the jsdocs.
Use another-json instead of awful manual json building. Sign the device keys at
the point of upload, instead of having to keep the signed string in
memory. Only upload device keys once (they are correctly merged with the
one-time keys by synapse).
Starts work on a class which is intended to just wrap the Matrix apis with very
simple functions.
There is a lot more work to be done here. For now, I have just taken methods
which don't refer to anything in MatrixClient except _http. This excludes a
bunch of things which refer to $userId, as well as the login stuff because of
the deviceId stuff I've just added :/.
For now, it's an internal class. I don't really see any reason it can't be
exposed to applications, though.
A couple of changes to support bigger changes in the react-sdk:
1. Add getDeviceId() to MatrixClient
2. Don't attempt to upload e2e keys if deviceId wasn't set.
To help test the forthcoming device_id support for /login and /register, add
the device_id and initial_device_display_name parameters to those calls. Allow
the app to specify the default device displayname when creating the client (as
well as the device_id).
Also, don't try initialising the Olm layer unless a userId is
provided. Currently this isn't a problem because react-sdk doesn't provide a
sessionStore when it doesn't provide a userId, but that is a bad thing to rely
on (and I am going to break it with a react-sdk PR).
We want to be able to 'block' devices, so that they are not sent copies of our
text. Implement that change, and exclude blocked devices when encrypting
messages.
THis changes the name of the 'deviceVerified' event to
'deviceVerificationChanged', but that just means that the UI won't update
correctly until the changes to react-sdk arrive.
This is the first step in having a cross-room "enable encryption" button.
If encryption is enabled, add an event handler which will set up encryption
when we receive an m.room.encryption event (either at initial /sync, or in
subsequent syncs.)
When we send an encrypted message with Olm, we need to know who to send it
to. Currently that is based on a user list passed to setRoomEncryption. We want
to be able to change the list as people join and leave the room; I also want to
not have to keep the member list in local storage.
So, use the member list at the point of enabling encryption to set up sessions,
and at the point of sending a message to encrypt the message.
Further work here includes:
* updating the react-sdk not to bother setting the member list
* monitoring for new users/devices in the room, and setting up new sessions
with them
Make `MatrixEvent.event` contain the *encrypted* event, and keep the plaintext
payload in a separate `_clearEvent` property.
This achieves several aims:
* means that we have a record of the actual object which was received over
the wire, which can be shown by clients for 'view source'.
* makes sent and received encrypted MatrixEvents more consistent (previously
sent ones had `encryptedType` and `encryptedContent` properties, whereas
received ones threw away the ciphertext).
* Avoids having to make two MatrixEvents in the receive path, and copying
fields from one to the other.
*Hopefully* most clients have followed the advice given in the jsdoc of not
relying on MatrixEvent.event to get at events. If they haven't, I guess they'll
break in the face of encrypted events.
(The pushprocessor didn't follow this advice, so needed some tweaks.)
If an exception was thrown by the encryption process, the event would be
queued, but the exception would not be handled. This meant that the event got
stuck as a grey 'sending' event in the UI.
Fixing this correctly is slightly more complex than just handling the exception
correctly. A naive approach would mean that the event would be shown as a red
'unsent' message, and clicking 'resend' would then send the message *in the
clear*. Hence, move the encryption to _sendEvent, where it will be called again
when the event is resent.