diff --git a/lib/client.js b/lib/client.js
index b6ea2bead..7aae83b5d 100644
--- a/lib/client.js
+++ b/lib/client.js
@@ -151,12 +151,10 @@ function MatrixClient(opts) {
if (CRYPTO_ENABLED && opts.sessionStore !== null &&
userId !== null && this.deviceId !== null) {
this._crypto = new Crypto(
- this,
+ this, this,
opts.sessionStore,
userId, this.deviceId
);
-
- setupCryptoEventHandler(this);
}
}
utils.inherits(MatrixClient, EventEmitter);
@@ -408,41 +406,6 @@ MatrixClient.prototype.isEventSenderVerified = function(event) {
);
};
-/**
- * Register a listener for m.room.encryption events which will enable encryption
- * for a room.
- *
- * @param {MatrixClient} client
- */
-function setupCryptoEventHandler(client) {
- client.on("event", function(event) {
- if (!event.isState() || event.getType() != "m.room.encryption") {
- return;
- }
- onCryptoEvent(client, event);
- });
- client.on("RoomMember.membership",
- client._crypto.onRoomMembership.bind(client._crypto));
-
- client.on("toDeviceEvent", function(event) {
- if (event.getType() == "m.room_key") {
- client._crypto.onRoomKeyEvent(event);
- }
- });
-}
-
-function onCryptoEvent(client, event) {
- var roomId = event.getRoomId();
- var content = event.getContent();
-
- try {
- client.setRoomEncryption(roomId, content).done();
- } catch (e) {
- console.error("Error configuring encryption in room " + roomId +
- ":", e);
- }
-}
-
/**
* Enable end-to-end encryption for a room.
* @param {string} roomId The room ID to enable encryption in.
@@ -2694,6 +2657,16 @@ module.exports.CRYPTO_ENABLED = CRYPTO_ENABLED;
* });
*/
+/**
+ * Fires whenever the SDK receives a new to-device event.
+ * @event module:client~MatrixClient#"toDeviceEvent"
+ * @param {MatrixEvent} event The matrix event which caused this event to fire.
+ * @example
+ * matrixClient.on("toDeviceEvent", function(event){
+ * var sender = event.getSender();
+ * });
+ */
+
/**
* Fires whenever the SDK's syncing state is updated. The state can be one of:
*
diff --git a/lib/crypto.js b/lib/crypto.js
index 1e69bbd35..5cc5faa56 100644
--- a/lib/crypto.js
+++ b/lib/crypto.js
@@ -39,6 +39,9 @@ var DeviceVerification = DeviceInfo.DeviceVerification;
*
* @param {module:base-apis~MatrixBaseApis} baseApis base matrix api interface
*
+ * @param {external:EventEmitter} eventEmitter event source where we can register
+ * for event notifications
+ *
* @param {module:store/session/webstorage~WebStorageSessionStore} sessionStore
* Store to be used for end-to-end crypto session data
*
@@ -46,7 +49,7 @@ var DeviceVerification = DeviceInfo.DeviceVerification;
*
* @param {string} deviceId The identifier for this device.
*/
-function Crypto(baseApis, sessionStore, userId, deviceId) {
+function Crypto(baseApis, eventEmitter, sessionStore, userId, deviceId) {
this._baseApis = baseApis;
this._sessionStore = sessionStore;
this._userId = userId;
@@ -81,6 +84,28 @@ function Crypto(baseApis, sessionStore, userId, deviceId) {
this._sessionStore.storeEndToEndDevicesForUser(
this._userId, myDevices
);
+
+ _registerEventHandlers(this, eventEmitter);
+}
+
+function _registerEventHandlers(crypto, eventEmitter) {
+ eventEmitter.on(
+ "RoomMember.membership",
+ crypto._onRoomMembership.bind(crypto)
+ );
+
+ eventEmitter.on("toDeviceEvent", function(event) {
+ if (event.getType() == "m.room_key") {
+ crypto._onRoomKeyEvent(event);
+ }
+ });
+
+ eventEmitter.on("event", function(event) {
+ if (!event.isState() || event.getType() != "m.room.encryption") {
+ return;
+ }
+ crypto._onCryptoEvent(event);
+ });
}
/**
@@ -772,13 +797,31 @@ Crypto.prototype.decryptEvent = function(event) {
return alg.decryptEvent(event);
};
+/**
+ * handle an m.room.encryption event
+ *
+ * @private
+ * @param {module:models/event.MatrixEvent} event encryption event
+ */
+Crypto.prototype._onCryptoEvent = function(event) {
+ var roomId = event.getRoomId();
+ var content = event.getContent();
+
+ try {
+ this.setRoomEncryption(roomId, content);
+ } catch (e) {
+ console.error("Error configuring encryption in room " + roomId +
+ ":", e);
+ }
+};
/**
* Handle a key event
*
+ * @private
* @param {module:models/event.MatrixEvent} event key event
*/
-Crypto.prototype.onRoomKeyEvent = function(event) {
+Crypto.prototype._onRoomKeyEvent = function(event) {
var content = event.getContent();
var AlgClass = algorithms.DECRYPTION_CLASSES[content.algorithm];
if (!AlgClass) {
@@ -795,10 +838,11 @@ Crypto.prototype.onRoomKeyEvent = function(event) {
/**
* Handle a change in the membership state of a member of a room
*
+ * @private
* @param {module:models/event.MatrixEvent} event event causing the change
* @param {module:models/room-member} member user whose membership changed
*/
-Crypto.prototype.onRoomMembership = function(event, member) {
+Crypto.prototype._onRoomMembership = function(event, member) {
// this event handler is registered on the *client* (as opposed to the
// room member itself), which means it is only called on changes to the