mirror of
https://github.com/cryptpad/cryptpad.git
synced 2026-09-12 19:49:59 +05:00
fix(office): fix loading template using linked documents
This commit is contained in:
parent
176bfe4c4c
commit
ff552b968e
@ -22,7 +22,7 @@ define([
|
||||
History.loadHistoryData = (cfg) => {
|
||||
const {
|
||||
sframeChan, mainRtChannel, downloadId,
|
||||
currentCp, nextCp
|
||||
currentCp, nextCp, href, password
|
||||
} = cfg;
|
||||
|
||||
return new Promise((resolve, reject) => {
|
||||
@ -30,6 +30,7 @@ define([
|
||||
if (currentCp?.rtChannel) {
|
||||
// Load all messages from currentCp.rtChannel
|
||||
sframeChan.query('Q_GET_FULL_HISTORY', {
|
||||
href, password, // get secret from other pad (template)
|
||||
channel: currentCp.rtChannel,
|
||||
isDownload: downloadId,
|
||||
full: true
|
||||
@ -41,11 +42,15 @@ define([
|
||||
}
|
||||
|
||||
// Old CP or no CP: use mainRtChannel
|
||||
if (!mainRtChannel) {
|
||||
return void reject('EINVAL');
|
||||
}
|
||||
|
||||
// No CP and no nextCp hash
|
||||
if (!currentCp && !nextCp?.hash) {
|
||||
// Load all messages from mainRtChannel
|
||||
sframeChan.query('Q_GET_FULL_HISTORY', {
|
||||
href, password, // get secret from other pad (template)
|
||||
channel: mainRtChannel,
|
||||
isDownload: downloadId,
|
||||
full: true
|
||||
@ -63,6 +68,7 @@ define([
|
||||
|
||||
if (currentCp?.hash || nextCp?.hash) {
|
||||
sframeChan.query('Q_GET_HISTORY_RANGE', {
|
||||
href, password, // get secret from other pad (template)
|
||||
channel: mainRtChannel,
|
||||
lastKnownHash: endHash,
|
||||
toHash: startHash,
|
||||
@ -257,7 +263,7 @@ define([
|
||||
// Dropdown to select checkpoint (or "major version")
|
||||
const makeDropdown = ($dropdown) => {
|
||||
const all = sortedCp.slice();
|
||||
all.unshift(0);
|
||||
if (mainRtChannel) { all.unshift(0); }
|
||||
const options = all.map((id, idx) => {
|
||||
const cp = hashes[id] || {};
|
||||
let time = '';;
|
||||
@ -281,12 +287,17 @@ define([
|
||||
buttonCls: 'btn btn-default small'
|
||||
};
|
||||
const dd = UIElements.createDropdown(dropdownConfig);
|
||||
dd.setValue(cpIdx + 1);
|
||||
if (mainRtChannel) { dd.setValue(cpIdx + 1); }
|
||||
else { dd.setValue(cpIdx); }
|
||||
dd.onChange.reg((id, idx) => {
|
||||
loading = true;
|
||||
dd.find('> button').attr('disabled', 'disabled');
|
||||
|
||||
cpIdx = idx - 1; // -1 because we've added "0" to the list
|
||||
if (!mainRtChannel) { cpIdx = idx; }
|
||||
else {
|
||||
cpIdx = idx - 1; // -1 because we've added "0" to the list
|
||||
}
|
||||
|
||||
hideVersion();
|
||||
|
||||
loadMessages().then(() => {
|
||||
|
||||
@ -3042,7 +3042,7 @@ Uncaught TypeError: Cannot read property 'calculatedType' of null
|
||||
}
|
||||
};
|
||||
|
||||
var loadTemplate = function (href, pw, parsed) {
|
||||
var loadTemplate = function (href, password, parsed) {
|
||||
APP.history = true;
|
||||
APP.template = true;
|
||||
var editor = getEditor();
|
||||
@ -3058,29 +3058,16 @@ Uncaught TypeError: Cannot read property 'calculatedType' of null
|
||||
var lastIndex = idx[idx.length - 1];
|
||||
var lastCp = hashes[lastIndex] || {};
|
||||
|
||||
// Current cp or initial hash (invalid hash ==> initial hash)
|
||||
var toHash = lastCp.hash || 'NONE';
|
||||
// Last hash
|
||||
var fromHash = 'NONE';
|
||||
|
||||
content.mediasSources = medias;
|
||||
|
||||
sframeChan.query('Q_GET_HISTORY_RANGE', {
|
||||
href: href,
|
||||
password: pw,
|
||||
channel: _content.channel,
|
||||
lastKnownHash: fromHash,
|
||||
toHash: toHash,
|
||||
}, function (err, data) {
|
||||
if (err) { return void console.error(err); }
|
||||
if (!Array.isArray(data.messages)) { return void console.error('Not an array!'); }
|
||||
|
||||
// The first "cp" in history is the empty doc. It doesn't include the first patch
|
||||
// of the history
|
||||
var initialCp = !lastCp.hash;
|
||||
|
||||
var messages = (data.messages || []).slice(initialCp ? 0 : 1);
|
||||
|
||||
History.loadHistoryData({
|
||||
sframeChan,
|
||||
href, password,
|
||||
mainRtChannel: content.channel,
|
||||
currentCp: lastCp,
|
||||
nextCp: undefined
|
||||
}).then(messages => {
|
||||
if (!Array.isArray(messages)) { return void console.error('Not an array!'); }
|
||||
ooChannel.queue = messages.map(function (obj) {
|
||||
return {
|
||||
hash: obj.serverHash,
|
||||
@ -3090,6 +3077,8 @@ Uncaught TypeError: Cannot read property 'calculatedType' of null
|
||||
ooChannel.historyLastHash = ooChannel.lastHash;
|
||||
ooChannel.currentIndex = ooChannel.cpIndex;
|
||||
loadCp(lastCp, true);
|
||||
}).catch(err => {
|
||||
console.error(err);
|
||||
});
|
||||
};
|
||||
|
||||
@ -3561,7 +3550,7 @@ Uncaught TypeError: Cannot read property 'calculatedType' of null
|
||||
Title.updateTitle(Title.defaultTitle);
|
||||
}
|
||||
|
||||
if (!content.channel) {
|
||||
if (!content.channel && !Object.keys(content.hashes).length) {
|
||||
content.channel = Hash.createChannelId();
|
||||
APP.onLocal();
|
||||
checkLinkedDocs();
|
||||
|
||||
@ -15,6 +15,9 @@ const factory = () => {
|
||||
const lastCp = hashes[lastIdx];
|
||||
if (!lastCp) { return content; }
|
||||
content.content.hashes = hashes = {};
|
||||
if (lastCp.rtChannel) {
|
||||
delete content.content.channel;
|
||||
}
|
||||
hashes[lastIdx] = lastCp;
|
||||
return content;
|
||||
};
|
||||
|
||||
@ -1443,6 +1443,53 @@ define([
|
||||
}
|
||||
}, cb);
|
||||
});
|
||||
|
||||
// History
|
||||
sframeChan.on('Q_GET_FULL_HISTORY', function (data, cb) {
|
||||
let nSecret = secret;
|
||||
if (data.isDownload && ooDownloadData[data.isDownload]) {
|
||||
var ooData = ooDownloadData[data.isDownload];
|
||||
delete ooDownloadData[data.isDownload];
|
||||
nSecret = Utils.Hash.getSecrets('sheet', ooData.hash, ooData.password);
|
||||
} else if (data.href) {
|
||||
var _parsed = Utils.Hash.parsePadUrl(data.href);
|
||||
nSecret = Utils.Hash.getSecrets(_parsed.type, _parsed.hash, data.password);
|
||||
}
|
||||
var crypto = Crypto.createEncryptor(nSecret.keys);
|
||||
Cryptpad.getFullHistory({
|
||||
debug: data?.debug,
|
||||
full: data?.full,
|
||||
channel: data.channel || nSecret.channel,
|
||||
validateKey: nSecret.keys.validateKey
|
||||
}, function (encryptedMsgs) {
|
||||
var nt = nThen;
|
||||
var decryptedMsgs = [];
|
||||
var total = encryptedMsgs.length;
|
||||
encryptedMsgs.forEach(function (_msg, i) {
|
||||
nt = nt(function (waitFor) {
|
||||
// The 3rd parameter "true" means we're going to skip signature validation.
|
||||
// We don't need it since the message is already validated serverside by hk
|
||||
if (typeof(_msg) === "object") {
|
||||
decryptedMsgs.push({
|
||||
author: _msg.author,
|
||||
serverHash: _msg.serverHash,
|
||||
time: _msg.time,
|
||||
msg: crypto.decrypt(_msg.msg, true, true)
|
||||
});
|
||||
} else {
|
||||
decryptedMsgs.push(crypto.decrypt(_msg, true, true));
|
||||
}
|
||||
setTimeout(waitFor(function () {
|
||||
sframeChan.event('EV_FULL_HISTORY_STATUS', (i+1)/total);
|
||||
}));
|
||||
}).nThen;
|
||||
});
|
||||
nt(function () {
|
||||
cb(decryptedMsgs);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
sframeChan.on('Q_GET_HISTORY_RANGE', function (data, cb) {
|
||||
var nSecret = secret;
|
||||
if (cfg.isDrive) {
|
||||
@ -1747,49 +1794,6 @@ define([
|
||||
Cryptpad.anonGetPreviewContent(data, cb);
|
||||
});
|
||||
|
||||
// History
|
||||
sframeChan.on('Q_GET_FULL_HISTORY', function (data, cb) {
|
||||
let nSecret = secret;
|
||||
if (data.isDownload && ooDownloadData[data.isDownload]) {
|
||||
var ooData = ooDownloadData[data.isDownload];
|
||||
delete ooDownloadData[data.isDownload];
|
||||
nSecret = Utils.Hash.getSecrets('sheet', ooData.hash, ooData.password);
|
||||
}
|
||||
var crypto = Crypto.createEncryptor(nSecret.keys);
|
||||
Cryptpad.getFullHistory({
|
||||
debug: data?.debug,
|
||||
full: data?.full,
|
||||
channel: data.channel || nSecret.channel,
|
||||
validateKey: nSecret.keys.validateKey
|
||||
}, function (encryptedMsgs) {
|
||||
var nt = nThen;
|
||||
var decryptedMsgs = [];
|
||||
var total = encryptedMsgs.length;
|
||||
encryptedMsgs.forEach(function (_msg, i) {
|
||||
nt = nt(function (waitFor) {
|
||||
// The 3rd parameter "true" means we're going to skip signature validation.
|
||||
// We don't need it since the message is already validated serverside by hk
|
||||
if (typeof(_msg) === "object") {
|
||||
decryptedMsgs.push({
|
||||
author: _msg.author,
|
||||
serverHash: _msg.serverHash,
|
||||
time: _msg.time,
|
||||
msg: crypto.decrypt(_msg.msg, true, true)
|
||||
});
|
||||
} else {
|
||||
decryptedMsgs.push(crypto.decrypt(_msg, true, true));
|
||||
}
|
||||
setTimeout(waitFor(function () {
|
||||
sframeChan.event('EV_FULL_HISTORY_STATUS', (i+1)/total);
|
||||
}));
|
||||
}).nThen;
|
||||
});
|
||||
nt(function () {
|
||||
cb(decryptedMsgs);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
// Store
|
||||
sframeChan.on('Q_DRIVE_GETDELETED', function (data, cb) {
|
||||
Cryptpad.getDeletedPads(data, function (err, obj) {
|
||||
@ -2093,7 +2097,7 @@ define([
|
||||
nThen(function (waitFor) {
|
||||
channels.forEach(function (chan) {
|
||||
if (chan === "chainpad") { chan = secret.channel; }
|
||||
console.error(chan);
|
||||
if (!chan) { return; }
|
||||
Utils.Cache.clearChannel(chan, waitFor());
|
||||
});
|
||||
}).nThen(cb);
|
||||
|
||||
Loading…
Reference in New Issue
Block a user