diff --git a/lib/hk-util.js b/lib/hk-util.js index ed5f43297..14263e481 100644 --- a/lib/hk-util.js +++ b/lib/hk-util.js @@ -662,10 +662,11 @@ const handleGetHistoryRange = function (Env, Server, seq, userId, parsed) { } var oldestKnownHash = map.from; + var untilHash = map.to; var desiredMessages = map.count; var desiredCheckpoint = map.cpCount; var txid = map.txid; - if (typeof(desiredMessages) !== 'number' && typeof(desiredCheckpoint) !== 'number') { + if (typeof(desiredMessages) !== 'number' && typeof(desiredCheckpoint) !== 'number' && !untilHash) { return void Server.send(userId, [seq, 'ERROR', 'UNSPECIFIED_COUNT', HISTORY_KEEPER_ID]); } @@ -674,7 +675,7 @@ const handleGetHistoryRange = function (Env, Server, seq, userId, parsed) { } Server.send(userId, [seq, 'ACK']); - Env.getOlderHistory(channelName, oldestKnownHash, desiredMessages, desiredCheckpoint, function (err, toSend) { + Env.getOlderHistory(channelName, oldestKnownHash, untilHash, desiredMessages, desiredCheckpoint, function (err, toSend) { if (err && err.code !== 'ENOENT') { Env.Log.error("HK_GET_OLDER_HISTORY", err); } diff --git a/lib/workers/db-worker.js b/lib/workers/db-worker.js index d80c2dc21..87b8fe93a 100644 --- a/lib/workers/db-worker.js +++ b/lib/workers/db-worker.js @@ -221,6 +221,7 @@ const computeMetadata = function (data, cb) { const getOlderHistory = function (data, cb) { const oldestKnownHash = data.hash; + const untilHash = data.toHash; const channelName = data.channel; const desiredMessages = data.desiredMessages; const desiredCheckpoint = data.desiredCheckpoint; @@ -251,6 +252,13 @@ const getOlderHistory = function (data, cb) { var toSend = []; if (typeof (desiredMessages) === "number") { toSend = messages.slice(-desiredMessages); + } else if (untilHash) { + for (var i = messages.length - 1; i >= 0; i--) { + toSend.unshift(messages[i]); + if (Array.isArray(messages[i]) && HK.getHash(messages[i][4], Log) === untilHash) { + break; + } + } } else { let cpCount = 0; for (var i = messages.length - 1; i >= 0; i--) { diff --git a/lib/workers/index.js b/lib/workers/index.js index a77de5437..1033aad0b 100644 --- a/lib/workers/index.js +++ b/lib/workers/index.js @@ -281,12 +281,13 @@ Workers.initialize = function (Env, config, _cb) { }); }; - Env.getOlderHistory = function (channel, oldestKnownHash, desiredMessages, desiredCheckpoint, cb) { + Env.getOlderHistory = function (channel, oldestKnownHash, toHash, desiredMessages, desiredCheckpoint, cb) { Env.store.getWeakLock(channel, function (next) { sendCommand({ channel: channel, command: "GET_OLDER_HISTORY", hash: oldestKnownHash, + toHash: toHash, desiredMessages: desiredMessages, desiredCheckpoint: desiredCheckpoint, }, Util.both(next, cb)); diff --git a/www/common/outer/async-store.js b/www/common/outer/async-store.js index 7c8793893..f07378d64 100644 --- a/www/common/outer/async-store.js +++ b/www/common/outer/async-store.js @@ -2069,7 +2069,7 @@ define([ if (first) { // If the first message if not a checkpoint, it means it is the first // message of the pad, so we have the full history! - if (!/^cp\|/.test(msg)) { fullHistory = true; } + if (!/^cp\|/.test(msg) && !data.toHash) { fullHistory = true; } lastKnownHash = msg.slice(0,64); first = false; } @@ -2086,7 +2086,8 @@ define([ network.on('message', onMsg); network.sendto(hk, JSON.stringify(['GET_HISTORY_RANGE', data.channel, { from: data.lastKnownHash, - cpCount: data.cpCount || 2, + to: data.toHash, + cpCount: data.cpCount || 2, // Ignored if "to" is provided txid: txid }])); }; diff --git a/www/common/sframe-common-outer.js b/www/common/sframe-common-outer.js index 28d6678a1..a08ecb0f2 100644 --- a/www/common/sframe-common-outer.js +++ b/www/common/sframe-common-outer.js @@ -1108,6 +1108,7 @@ define([ Cryptpad.getHistoryRange({ channel: channel, validateKey: validate, + toHash: data.toHash, lastKnownHash: data.lastKnownHash }, function (data) { cb({