From 1d427a1ea879bd0178875d49bf490066671b69e2 Mon Sep 17 00:00:00 2001 From: "J. Ryan Stinnett" Date: Fri, 5 Jul 2019 13:59:04 +0100 Subject: [PATCH 1/2] Block read marker and read receipt from advancing into pending events This changes the methods that update the read marker and read receipts to prevent advancing into pending events. Part of https://github.com/vector-im/riot-web/issues/9952 --- src/client.js | 22 ++++++++++++++++------ src/models/room.js | 19 ++++++++++++++++++- 2 files changed, 34 insertions(+), 7 deletions(-) diff --git a/src/client.js b/src/client.js index b2cdcd47764..ed7e67bc593 100644 --- a/src/client.js +++ b/src/client.js @@ -2148,7 +2148,12 @@ MatrixClient.prototype.sendReceipt = function(event, receiptType, callback) { * @return {module:client.Promise} Resolves: TODO * @return {module:http-api.MatrixError} Rejects: with an error response. */ -MatrixClient.prototype.sendReadReceipt = function(event, callback) { +MatrixClient.prototype.sendReadReceipt = async function(event, callback) { + const eventId = event.getId(); + const room = this.getRoom(event.getRoomId()); + if (room && room.hasPendingEvent(eventId)) { + throw new Error(`Cannot set read receipt to a pending event (${eventId})`); + } return this.sendReceipt(event, "m.read", callback); }; @@ -2158,20 +2163,25 @@ MatrixClient.prototype.sendReadReceipt = function(event, callback) { * and displayed as a horizontal line in the timeline that is visually distinct to the * position of the user's own read receipt. * @param {string} roomId ID of the room that has been read - * @param {string} eventId ID of the event that has been read + * @param {string} rmEventId ID of the event that has been read * @param {string} rrEvent the event tracked by the read receipt. This is here for * convenience because the RR and the RM are commonly updated at the same time as each * other. The local echo of this receipt will be done if set. Optional. * @return {module:client.Promise} Resolves: the empty object, {}. */ -MatrixClient.prototype.setRoomReadMarkers = function(roomId, eventId, rrEvent) { - const rmEventId = eventId; - let rrEventId; +MatrixClient.prototype.setRoomReadMarkers = async function(roomId, rmEventId, rrEvent) { + const room = this.getRoom(roomId); + if (room && room.hasPendingEvent(rmEventId)) { + throw new Error(`Cannot set read marker to a pending event (${rmEventId})`); + } // Add the optional RR update, do local echo like `sendReceipt` + let rrEventId; if (rrEvent) { rrEventId = rrEvent.getId(); - const room = this.getRoom(roomId); + if (room && room.hasPendingEvent(rrEventId)) { + throw new Error(`Cannot set read receipt to a pending event (${rrEventId})`); + } if (room) { room._addLocalEchoReceipt(this.credentials.userId, rrEvent, "m.read"); } diff --git a/src/models/room.js b/src/models/room.js index 3969ede4cf3..9898d58558e 100644 --- a/src/models/room.js +++ b/src/models/room.js @@ -346,13 +346,30 @@ Room.prototype.userMayUpgradeRoom = function(userId) { Room.prototype.getPendingEvents = function() { if (this._opts.pendingEventOrdering !== "detached") { throw new Error( - "Cannot call getPendingEventList with pendingEventOrdering == " + + "Cannot call getPendingEvents with pendingEventOrdering == " + this._opts.pendingEventOrdering); } return this._pendingEventList; }; +/** + * Check whether the pending event list contains a given event by ID. + * + * @param {string} eventId The event ID to check for. + * @return {boolean} + * @throws If opts.pendingEventOrdering was not 'detached' + */ +Room.prototype.hasPendingEvent = function(eventId) { + if (this._opts.pendingEventOrdering !== "detached") { + throw new Error( + "Cannot call hasPendingEvent with pendingEventOrdering == " + + this._opts.pendingEventOrdering); + } + + return this._pendingEventList.some(event => event.getId() === eventId); +}; + /** * Get the live unfiltered timeline for this room. * From 24a869d15bbf5ab7ebc46d69fbf11a005e383dda Mon Sep 17 00:00:00 2001 From: "J. Ryan Stinnett" Date: Fri, 5 Jul 2019 15:07:56 +0100 Subject: [PATCH 2/2] Update copyright header --- src/client.js | 1 + src/models/room.js | 1 + 2 files changed, 2 insertions(+) diff --git a/src/client.js b/src/client.js index ed7e67bc593..b9cbd941c7b 100644 --- a/src/client.js +++ b/src/client.js @@ -2,6 +2,7 @@ Copyright 2015, 2016 OpenMarket Ltd Copyright 2017 Vector Creations Ltd Copyright 2018-2019 New Vector Ltd +Copyright 2019 The Matrix.org Foundation C.I.C. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. diff --git a/src/models/room.js b/src/models/room.js index 9898d58558e..7f5c031a33f 100644 --- a/src/models/room.js +++ b/src/models/room.js @@ -1,6 +1,7 @@ /* Copyright 2015, 2016 OpenMarket Ltd Copyright 2018, 2019 New Vector Ltd +Copyright 2019 The Matrix.org Foundation C.I.C. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License.