1
0
mirror of https://github.com/matrix-org/matrix-js-sdk.git synced 2025-11-29 16:43:09 +03:00

Avoid sending unencrypted messages in e2e room

Reshuffle the logic for determining whether to encrypt a message so that it can
run independently of whether our app actually supports e2e - and then throw an
error if it looks like we should be encrypting but don't support it.

This seems a preferable situation to just falling back to plain text if we get
a dodgy build.
This commit is contained in:
Richard van der Hoff
2017-08-08 12:29:26 +01:00
parent 8563dd5860
commit 3e79575602
2 changed files with 75 additions and 34 deletions

View File

@@ -605,11 +605,28 @@ MatrixClient.prototype.setRoomEncryption = function(roomId, config) {
* @return {bool} whether encryption is enabled.
*/
MatrixClient.prototype.isRoomEncrypted = function(roomId) {
if (!this._crypto) {
const room = this.getRoom(roomId);
if (!room) {
// we don't know about this room, so can't determine if it should be
// encrypted. Let's assume not.
return false;
}
return this._crypto.isRoomEncrypted(roomId);
// if there is an 'm.room.encryption' event in this room, it should be
// encrypted (independently of whether we actually support encryption)
const ev = room.currentState.getStateEvents("m.room.encryption", "");
if (ev) {
return true;
}
// we don't have an m.room.encrypted event, but that might be because
// the server is hiding it from us. Check the store to see if it was
// previously encrypted.
if (!this._sessionStore) {
return false;
}
return Boolean(this._sessionStore.getEndToEndRoom(roomId));
};
/**
@@ -997,17 +1014,16 @@ function _sendEvent(client, room, event, callback) {
// so that we can handle synchronous and asynchronous exceptions with the
// same code path.
return Promise.resolve().then(function() {
let encryptionPromise = null;
if (client._crypto) {
encryptionPromise = client._crypto.encryptEventIfNeeded(event, room);
const encryptionPromise = _encryptEventIfNeeded(client, event, room);
if (!encryptionPromise) {
return null;
}
if (encryptionPromise) {
_updatePendingEventStatus(room, event, EventStatus.ENCRYPTING);
encryptionPromise = encryptionPromise.then(function() {
_updatePendingEventStatus(room, event, EventStatus.SENDING);
});
}
return encryptionPromise;
_updatePendingEventStatus(room, event, EventStatus.ENCRYPTING);
return encryptionPromise.then(() => {
_updatePendingEventStatus(room, event, EventStatus.SENDING);
});
}).then(function() {
let promise;
// this event may be queued
@@ -1054,6 +1070,43 @@ function _sendEvent(client, room, event, callback) {
});
}
/**
* Encrypt an event according to the configuration of the room, if necessary.
*
* @param {MatrixClient} client
*
* @param {module:models/event.MatrixEvent} event event to be sent
*
* @param {module:models/room?} room destination room. Null if the destination
* is not a room we have seen over the sync pipe.
*
* @return {module:client.Promise?} Promise which resolves when the event has been
* encrypted, or null if nothing was needed
*/
function _encryptEventIfNeeded(client, event, room) {
if (event.isEncrypted()) {
// this event has already been encrypted; this happens if the
// encryption step succeeded, but the send step failed on the first
// attempt.
return null;
}
if (!client.isRoomEncrypted(event.getRoomId())) {
// looks like this room isn't encrypted.
return null;
}
if (!client._crypto) {
throw new Error(
"This room is configured to use encryption, but your client does " +
"not support encryption.",
);
}
return client._crypto.encryptEvent(event, room);
}
function _updatePendingEventStatus(room, event, newStatus) {
if (room) {
room.updatePendingEvent(event, newStatus);