mirror of
https://github.com/cryptpad/cryptpad.git
synced 2026-09-12 19:49:59 +05:00
Merge branch 'staging' into http-upload
This commit is contained in:
commit
61cc1f5f86
@ -1,10 +0,0 @@
|
||||
This is free and unencumbered software released into the public domain.
|
||||
|
||||
Anyone is free to copy, modify, publish, use, compile, sell, or distribute this software, either in source code form or as a compiled binary, for any purpose, commercial or non-commercial, and by any means.
|
||||
|
||||
In jurisdictions that recognize copyright laws, the author or authors of this software dedicate any and all copyright interest in the software to the public domain. We make this dedication for the benefit of the public at large and to the detriment of our heirs and
|
||||
successors. We intend this dedication to be an overt act of relinquishment in perpetuity of all present and future rights to this software under copyright law.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
|
||||
For more information, please refer to <http://unlicense.org/>
|
||||
@ -1,3 +1,9 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2025 XWiki CryptPad Team <contact@cryptpad.org> and contributors
|
||||
*
|
||||
* SPDX-License-Identifier: AGPL-3.0-or-later
|
||||
*/
|
||||
|
||||
@import (reference) "./colortheme-all.less";
|
||||
@import (reference) "./variables.less";
|
||||
.badges_vars(
|
||||
|
||||
@ -104,6 +104,7 @@ server {
|
||||
# Enable SharedArrayBuffer in Firefox (for .xlsx export)
|
||||
add_header Cross-Origin-Resource-Policy cross-origin;
|
||||
add_header Cross-Origin-Embedder-Policy require-corp;
|
||||
add_header Referrer-Policy same-origin;
|
||||
|
||||
# Insert the path to your CryptPad repository root here
|
||||
root /home/cryptpad/cryptpad;
|
||||
@ -169,6 +170,7 @@ server {
|
||||
# they unfortunately still require exceptions to the sandboxing to work correctly.
|
||||
if ($uri ~ ^/(?:sheet|doc|presentation)/inner.html) { set $unsafe 1; }
|
||||
if ($uri ~ ^/common/onlyoffice/.*/.*\.html) { set $unsafe 1; }
|
||||
if ($uri ~ ^/common/onlyoffice/dist/.*/sdkjs/common/spell/spell/spell.js.*$) { set $unsafe 1; }
|
||||
|
||||
# everything except the sandbox domain is a privileged scope, as they might be used to handle keys
|
||||
if ($host != $sandbox_domain) { set $unsafe 0; }
|
||||
|
||||
@ -28,7 +28,7 @@ main() {
|
||||
ask_for_license
|
||||
|
||||
# Check if 'oldest_needed_version' is already set, if not, set it to v8
|
||||
if [ -z "${PROPS['oldest_needed_version']}" ]; then
|
||||
if [ -z "${PROPS['oldest_needed_version']+set}" ]; then
|
||||
echo "'oldest_needed_version' is not set. Setting it to v8."
|
||||
set_prop "oldest_needed_version" "v8"
|
||||
else
|
||||
@ -84,7 +84,7 @@ main() {
|
||||
rm -rf "$OO_DIR/v6/web-apps/apps/spreadsheeteditor/main/resources/help"
|
||||
;;
|
||||
v7)
|
||||
install_version v7 v7.3.3.60+10 be3c926d534b0c77aa1ed83b170a38b9e56ebbbfd73a1a968f523d63c5ed69ecdb063fad08740812de82c1e79af7309faf67ffdd81b45451adce539192f3414c
|
||||
install_version v7 v7.3.3.60+11 1e65be6dc87d97e82b4972f303956e5397b34d637ca80a4239c48e49ab829ee5afc8f5b1680b2fb14230d63ff872ec5f9b562bb6c3f1811316b68f8b436f7ee6
|
||||
rm -rf "$OO_DIR/v7/web-apps/apps/documenteditor/main/resources/help"
|
||||
rm -rf "$OO_DIR/v7/web-apps/apps/presentationeditor/main/resources/help"
|
||||
rm -rf "$OO_DIR/v7/web-apps/apps/spreadsheeteditor/main/resources/help"
|
||||
@ -92,7 +92,7 @@ main() {
|
||||
# From all the older versions only v7 has 'dictionaries', we remove it for the same reasons
|
||||
rm -rf "$OO_DIR/v7/dictionaries/"
|
||||
;;
|
||||
v8) install_version v8 v8.3.3.23+1 b9647468ef26c915788da3b2528e0496ba5fa78d5e7acb85eca11241cc325478d94f5508fdcf085b42adf0cad8eda830d71be87c58918d1f01a86c979da6f4e5 ;;
|
||||
v8) install_version v8 v8.3.3.23+3 6a00704df88c87bf5810257d99e83b32b76b86326ebd668b09c257f0abc283991b9ec3c121e0801173afc4b8deb21d4539c307da26e40e42f6d4f3af195526c2 ;;
|
||||
x2t) install_x2t v7.3+1 ab0c05b0e4c81071acea83f0c6a8e75f5870c360ec4abc4af09105dd9b52264af9711ec0b7020e87095193ac9b6e20305e446f2321a541f743626a598e5318c1 ;;
|
||||
*)
|
||||
echo "Unknown version: $version"
|
||||
|
||||
@ -57,6 +57,7 @@ Default.httpHeaders = function (Env) {
|
||||
"X-XSS-Protection": "1; mode=block",
|
||||
"X-Content-Type-Options": "nosniff",
|
||||
"Access-Control-Allow-Origin": Env.enableEmbedding? '*': Env.permittedEmbedders,
|
||||
"Referrer-Policy": "same-origin",
|
||||
"Permissions-policy":"interest-cohort=()"
|
||||
};
|
||||
};
|
||||
|
||||
@ -658,6 +658,10 @@ const factory = (Sortify, UserObject, ProxyManager,
|
||||
if (data.password) { pad.password = data.password; }
|
||||
if (data.channel || secret) { pad.channel = data.channel || secret.channel; }
|
||||
if (data.readme) { pad.readme = 1; }
|
||||
Object.keys(data.attributes || {}).forEach(k => {
|
||||
if (!data.attributes[k]) { return; } // undefined
|
||||
pad[k] = data.attributes[k];
|
||||
});
|
||||
|
||||
if (data.teamId === -1) { data.teamId = undefined; }
|
||||
var s = getStore(data.teamId);
|
||||
@ -1212,7 +1216,8 @@ const factory = (Sortify, UserObject, ProxyManager,
|
||||
owners: owners,
|
||||
expire: expire,
|
||||
password: data.password,
|
||||
path: data.path
|
||||
path: data.path,
|
||||
attributes: data.attributes
|
||||
}, cb);
|
||||
// Let inner know that dropped files shouldn't trigger the popup
|
||||
postMessage(clientId, "AUTOSTORE_DISPLAY_POPUP", {
|
||||
@ -2282,6 +2287,14 @@ const factory = (Sortify, UserObject, ProxyManager,
|
||||
}
|
||||
};
|
||||
|
||||
const startCacheModules = (clientId, returned, _cb) => {
|
||||
const cb = Util.mkAsync(_cb);
|
||||
onCacheReady(clientId, function () {
|
||||
onCacheReadyEvt.fire();
|
||||
cb(returned);
|
||||
});
|
||||
};
|
||||
|
||||
// onReady: called when the drive is synced (not using the cache anymore)
|
||||
// "cb" is wrapped in Util.once() and may have already been called
|
||||
// if we have a local cache
|
||||
@ -2656,13 +2669,6 @@ const factory = (Sortify, UserObject, ProxyManager,
|
||||
andThen();
|
||||
};
|
||||
|
||||
const startCacheModules = (clientId, returned, _cb) => {
|
||||
const cb = Util.mkAsync(_cb);
|
||||
onCacheReady(clientId, function () {
|
||||
onCacheReadyEvt.fire();
|
||||
cb(returned);
|
||||
});
|
||||
};
|
||||
const startModules = (clientId, returned, cb) => {
|
||||
if (store.manager) {
|
||||
return void onCacheReadyEvt.reg(function () {
|
||||
|
||||
@ -1,3 +1,7 @@
|
||||
// SPDX-FileCopyrightText: 2025 XWiki CryptPad Team <contact@cryptpad.org> and contributors
|
||||
//
|
||||
// SPDX-License-Identifier: AGPL-3.0-or-later
|
||||
|
||||
import nacl from 'tweetnacl/nacl-fast';
|
||||
import nThen from 'nthen';
|
||||
import { Module, ModuleObject, Callback } from '../types'
|
||||
|
||||
@ -112,6 +112,7 @@ const factory = () => {
|
||||
txid: txid,
|
||||
lastKnownHash: chan.lastKnownHash || chan.lastCpHash,
|
||||
metadata: {
|
||||
forcePlaceholder: true,
|
||||
validateKey: obj.validateKey,
|
||||
owners: obj.owners,
|
||||
expire: obj.expire
|
||||
@ -157,7 +158,10 @@ const factory = () => {
|
||||
ctx.emit('READY', chan.clients, chan.clients);
|
||||
return;
|
||||
}
|
||||
if (parsed.error && parsed.channel) { return; }
|
||||
if (parsed.error && parsed.channel) {
|
||||
ctx.emit('READY', chan.clients, chan.clients);
|
||||
return;
|
||||
}
|
||||
|
||||
// If there is a txid, make sure it's ours or abort
|
||||
if (Array.isArray(parsed) && parsed[0] && parsed[0] !== txid) {
|
||||
|
||||
@ -1145,6 +1145,13 @@ define([
|
||||
}
|
||||
}
|
||||
|
||||
// Make sure we also store additionnal data to pin all the channels
|
||||
// (OO and forms)
|
||||
data.attributes = {};
|
||||
Object.keys(common?.otherPadAttrs || {}).forEach(k => {
|
||||
data.attributes[k] = common.otherPadAttrs[k];
|
||||
});
|
||||
|
||||
postMessage("SET_PAD_TITLE", data, function (obj) {
|
||||
if (obj && obj.error) {
|
||||
if (obj.error !== "EAUTH") { console.log("unable to set pad title"); }
|
||||
@ -1167,6 +1174,8 @@ define([
|
||||
return;
|
||||
}
|
||||
|
||||
let rtChannel, lastVersion, answersChannel;
|
||||
let attributes = {};
|
||||
nThen(function (waitFor) {
|
||||
if (parsed.hashData.type !== 'pad') { return; }
|
||||
// Set the correct owner and expiration time if we can find them
|
||||
@ -1177,6 +1186,14 @@ define([
|
||||
data.owners = obj.owners;
|
||||
data.expire = +obj.expire;
|
||||
}));
|
||||
common.getPadAttribute('', waitFor(function (err, _data) {
|
||||
attributes.rtChannel = _data?.rtChannel;
|
||||
attributes.lastVersion = _data?.lastVersion;
|
||||
attributes.answersChannel = _data?.answersChannel;
|
||||
Object.keys(common?.otherPadAttrs || {}).forEach(k => {
|
||||
attributes[k] = common.otherPadAttrs[k];
|
||||
});
|
||||
}), data.href);
|
||||
}).nThen(function () {
|
||||
postMessage("SET_PAD_TITLE", {
|
||||
teamId: data.teamId,
|
||||
@ -1187,6 +1204,7 @@ define([
|
||||
path: data.path,
|
||||
owners: data.owners,
|
||||
expire: data.expire,
|
||||
attributes,
|
||||
forceSave: 1
|
||||
}, function (obj) {
|
||||
if (obj && obj.error) { return void cb(obj.error); }
|
||||
|
||||
@ -22,6 +22,7 @@ define([
|
||||
'/common/onlyoffice/oocell_base.js',
|
||||
'/common/onlyoffice/oodoc_base.js',
|
||||
'/common/onlyoffice/ooslide_base.js',
|
||||
'/common/outer/worker-channel.js',
|
||||
|
||||
'/common/onlyoffice/current-version.js',
|
||||
'/common/onlyoffice/broken-formats.js',
|
||||
@ -50,10 +51,12 @@ define([
|
||||
EmptyCell,
|
||||
EmptyDoc,
|
||||
EmptySlide,
|
||||
Channel,
|
||||
OOCurrentVersion,
|
||||
BrokenFormats)
|
||||
{
|
||||
var saveAs = window.saveAs;
|
||||
var Nacl = window.nacl;
|
||||
var APP = window.APP = {
|
||||
$: $,
|
||||
urlArgs: Util.find(ApiConfig, ['requireConf', 'urlArgs'])
|
||||
@ -1087,6 +1090,71 @@ define([
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
var handleAuth = function (obj, send) {
|
||||
//setEditable(false);
|
||||
|
||||
var changes = [];
|
||||
if (content.version > 2) {
|
||||
ooChannel.queue.forEach(function (data) {
|
||||
Array.prototype.push.apply(changes, data.msg.changes);
|
||||
});
|
||||
ooChannel.ready = true;
|
||||
|
||||
ooChannel.cpIndex += ooChannel.queue.length;
|
||||
var last = ooChannel.queue.pop();
|
||||
if (last) { ooChannel.lastHash = last.hash; }
|
||||
} else {
|
||||
setEditable(false, true);
|
||||
}
|
||||
send({
|
||||
type: "authChanges",
|
||||
changes: changes
|
||||
});
|
||||
|
||||
// Answer to the auth command
|
||||
var p = getParticipants();
|
||||
send({
|
||||
type: "auth",
|
||||
result: 1,
|
||||
sessionId: "sessionId",
|
||||
participants: p.list,
|
||||
locks: [],
|
||||
changes: [],
|
||||
changesIndex: 0,
|
||||
indexUser: p.index,
|
||||
buildVersion: "5.2.6",
|
||||
buildNumber: 2,
|
||||
licenseType: 3,
|
||||
//"g_cAscSpellCheckUrl": "/spellchecker",
|
||||
//"settings":{"spellcheckerUrl":"/spellchecker","reconnection":{"attempts":50,"delay":2000}}
|
||||
});
|
||||
// Open the document
|
||||
send({
|
||||
type: "documentOpen",
|
||||
data: {"type":"open","status":"ok","data":{"Editor.bin":obj.openCmd.url}}
|
||||
});
|
||||
|
||||
/*
|
||||
// TODO: make sure we don't have new popups that can break our integration
|
||||
var observer = new MutationObserver(function(mutations) {
|
||||
mutations.forEach(function(mutation) {
|
||||
if (mutation.type === "childList") {
|
||||
for (var i = 0; i < mutation.addedNodes.length; i++) {
|
||||
if (mutation.addedNodes[i].classList.contains('asc-window') &&
|
||||
mutation.addedNodes[i].classList.contains('alert')) {
|
||||
$(mutation.addedNodes[i]).find('button').not('.custom').click();
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
});
|
||||
observer.observe(window.frames[0].document.body, {
|
||||
childList: true,
|
||||
});
|
||||
*/
|
||||
};
|
||||
|
||||
var handleLock = function (obj, send) {
|
||||
if (APP.history) { return; }
|
||||
|
||||
@ -1557,6 +1625,227 @@ define([
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
var makeChannel = function () {
|
||||
var msgEv = Util.mkEvent();
|
||||
var iframe = $('#cp-app-oo-editor > iframe')[0].contentWindow;
|
||||
var type = common.getMetadataMgr().getPrivateData().ooType;
|
||||
window.addEventListener('message', function (msg) {
|
||||
if (msg.source !== iframe) { return; }
|
||||
msgEv.fire(msg);
|
||||
});
|
||||
var postMsg = function (data) {
|
||||
iframe.postMessage(data, ApiConfig.httpSafeOrigin);
|
||||
};
|
||||
Channel.create(msgEv, postMsg, function (chan) {
|
||||
APP.chan = chan;
|
||||
|
||||
var send = ooChannel.send = function (obj, force) {
|
||||
// can't push to OO before reloading cp
|
||||
if (APP.onStrictSaveChanges && !force) { return; }
|
||||
// We only need to release locks for sheets
|
||||
if (type !== "sheet" && obj.type === "releaseLock") { return; }
|
||||
if (type === "presentation" && obj.type === "cp_theme") {
|
||||
console.error(obj);
|
||||
return;
|
||||
}
|
||||
|
||||
debug(obj, 'toOO');
|
||||
chan.event('CMD', obj);
|
||||
if (obj && obj.type === "saveChanges") {
|
||||
evIntegrationSave.fire();
|
||||
}
|
||||
};
|
||||
|
||||
chan.on('CMD', function (obj) {
|
||||
debug(obj, 'fromOO');
|
||||
switch (obj.type) {
|
||||
case "auth":
|
||||
handleAuth(obj, send);
|
||||
break;
|
||||
case "isSaveLock":
|
||||
// TODO ping the server to check if we're online first?
|
||||
if (!offline) {
|
||||
if (APP.waitLock) {
|
||||
APP.waitLock.reg(function () {
|
||||
send({
|
||||
type: "saveLock",
|
||||
saveLock: false
|
||||
}, true);
|
||||
});
|
||||
} else {
|
||||
send({
|
||||
type: "saveLock",
|
||||
saveLock: false
|
||||
}, true);
|
||||
}
|
||||
}
|
||||
break;
|
||||
case "cursor":
|
||||
if (cursor && cursor.updateCursor) {
|
||||
cursor.updateCursor({
|
||||
type: "cursor",
|
||||
messages: [{
|
||||
cursor: obj.cursor,
|
||||
time: +new Date(),
|
||||
user: myUniqueOOId,
|
||||
useridoriginal: myOOId
|
||||
}]
|
||||
});
|
||||
}
|
||||
break;
|
||||
case "forceSaveStart":
|
||||
if (APP.integrationSave) {
|
||||
APP.integrationSave(obj => {
|
||||
if (obj?.error) {
|
||||
console.error(obj.error);
|
||||
return void UI.warn(Messages.error);
|
||||
}
|
||||
content.integrationSave = `${myUniqueOOId}-${+new Date()}`;
|
||||
APP.integrationSaved = content.integrationSave;
|
||||
APP.onLocal();
|
||||
UI.log(Messages.saved);
|
||||
});
|
||||
}
|
||||
break;
|
||||
case "getLock":
|
||||
handleLock(obj, send);
|
||||
break;
|
||||
case "getMessages":
|
||||
// OO chat messages?
|
||||
send({ type: "message" });
|
||||
break;
|
||||
case "saveChanges":
|
||||
if (readOnly) {
|
||||
return;
|
||||
}
|
||||
|
||||
// If we have unsaved data before reloading for a checkpoint...
|
||||
if (APP.onStrictSaveChanges) {
|
||||
delete APP.unsavedLocks;
|
||||
APP.unsavedChanges = {
|
||||
type: "saveChanges",
|
||||
changes: parseChanges(obj.changes),
|
||||
changesIndex: ooChannel.cpIndex || 0,
|
||||
locks: type === "sheet" ? [] : APP.unsavedLocks,
|
||||
excelAdditionalInfo: null,
|
||||
recover: true
|
||||
};
|
||||
APP.onStrictSaveChanges();
|
||||
return;
|
||||
}
|
||||
var AscCommon = window.frames[0] && window.frames[0].AscCommon;
|
||||
if (Util.find(AscCommon, ['CollaborativeEditing','m_bFast'])
|
||||
&& APP.themeLocked) {
|
||||
obj = APP.themeLocked;
|
||||
APP.themeLocked = undefined;
|
||||
obj.type = "cp_theme";
|
||||
console.error(obj);
|
||||
}
|
||||
if (APP.themeRemote) {
|
||||
delete APP.themeRemote;
|
||||
send({
|
||||
type: "unSaveLock",
|
||||
index: ooChannel.cpIndex,
|
||||
time: +new Date()
|
||||
});
|
||||
return;
|
||||
}
|
||||
|
||||
// We're sending our changes to netflux
|
||||
handleChanges(obj, send);
|
||||
// If we're alone, clean up the medias
|
||||
var m = metadataMgr.getChannelMembers().slice().filter(function (nId) {
|
||||
return nId.length === 32;
|
||||
});
|
||||
if (m.length === 1 && APP.loadingImage <= 0) {
|
||||
try {
|
||||
// "docs" contains the correct images that we've just uploaded
|
||||
// "docs2" contains the correct images from the .bin checkpoint
|
||||
// both of them are not reliable in the other case
|
||||
var docs = getWindow().AscCommon.g_oDocumentUrls.urls;
|
||||
var docs2 = getEditor().ImageLoader.map_image_index;
|
||||
var mediasSources = getMediasSources();
|
||||
Object.keys(mediasSources).forEach(function (name) {
|
||||
if (!docs && !docs2) { return; }
|
||||
if (!docs['media/'+name] && !docs2[name]) {
|
||||
delete mediasSources[name];
|
||||
}
|
||||
});
|
||||
APP.onLocal();
|
||||
} catch (e) {}
|
||||
}
|
||||
break;
|
||||
case "unLockDocument":
|
||||
if (obj.releaseLocks && content.locks && content.locks[getId()]) {
|
||||
send({
|
||||
type: "releaseLock",
|
||||
locks: getUserLock(getId())
|
||||
});
|
||||
delete content.locks[getId()];
|
||||
APP.onLocal();
|
||||
}
|
||||
if (obj.isSave) {
|
||||
send({
|
||||
type: "unSaveLock",
|
||||
time: -1,
|
||||
index: -1
|
||||
});
|
||||
}
|
||||
if (APP.onDocumentUnlock) {
|
||||
APP.onDocumentUnlock();
|
||||
APP.onDocumentUnlock = undefined;
|
||||
}
|
||||
break;
|
||||
case 'openDocument':
|
||||
// When duplicating a slide, OO may ask the URLs of the images
|
||||
// in that slide
|
||||
var _obj = obj.message;
|
||||
if (_obj.c === "imgurls") {
|
||||
var _mediasSources = getMediasSources();
|
||||
var images = _obj.data || [];
|
||||
if (!Array.isArray(images)) { return; }
|
||||
var urls = [];
|
||||
nThen(function (waitFor) {
|
||||
images.forEach(function (name) {
|
||||
if (/^data\:image/.test(name)) {
|
||||
Util.fetch(name, waitFor(function (err, u8) {
|
||||
if (err) { return; }
|
||||
var b = new Blob([u8]);
|
||||
urls.push(URL.createObjectURL(b));
|
||||
}));
|
||||
return;
|
||||
}
|
||||
var data = _mediasSources[name];
|
||||
if (!data) { return; }
|
||||
var media = mediasData[data.src];
|
||||
if (!media) { return; }
|
||||
urls.push({
|
||||
path: name,
|
||||
url: media.blobUrl,
|
||||
});
|
||||
});
|
||||
}).nThen(function () {
|
||||
send({
|
||||
type: "documentOpen",
|
||||
data: {
|
||||
type: "imgurls",
|
||||
status: "ok",
|
||||
data: {
|
||||
urls: urls,
|
||||
error: 0
|
||||
}
|
||||
}
|
||||
});
|
||||
});
|
||||
}
|
||||
break;
|
||||
}
|
||||
});
|
||||
});
|
||||
};
|
||||
|
||||
|
||||
var x2tConvertData = function (data, fileName, format, cb) {
|
||||
var sframeChan = common.getSframeChannel();
|
||||
var editor = getEditor();
|
||||
@ -2145,6 +2434,98 @@ Uncaught TypeError: Cannot read property 'calculatedType' of null
|
||||
};
|
||||
|
||||
APP.loadingImage = 0;
|
||||
|
||||
APP.getImageURL = function(name, callback) {
|
||||
if (name && /^data:image/.test(name)) {
|
||||
return void callback('');
|
||||
}
|
||||
|
||||
var mediasSources = getMediasSources();
|
||||
var data = mediasSources[name];
|
||||
downloadImages[name] = Util.mkEvent(true);
|
||||
|
||||
if (typeof data === 'undefined') {
|
||||
if (/^http/.test(name) && /slide\/themes\/theme/.test(name)) {
|
||||
Util.fetch(name, function (err, u8) {
|
||||
if (err) { return; }
|
||||
mediasData[name] = {
|
||||
blobUrl: name,
|
||||
content: u8,
|
||||
name: name
|
||||
};
|
||||
var b = new Blob([u8], {type: "image/jpeg"});
|
||||
var blobUrl = URL.createObjectURL(b);
|
||||
return void callback(blobUrl);
|
||||
});
|
||||
return;
|
||||
}
|
||||
debug("CryptPad - could not find matching media for " + name);
|
||||
return void callback("");
|
||||
}
|
||||
|
||||
var blobUrl = (typeof mediasData[data.src] === 'undefined') ? "" : mediasData[data.src].blobUrl;
|
||||
if (blobUrl) {
|
||||
delete downloadImages[name];
|
||||
debug("CryptPad Image already loaded " + blobUrl);
|
||||
|
||||
// Fix: https://github.com/cryptpad/cryptpad/issues/1500
|
||||
// Maybe OO was reloaded, but the CryptPad cache is still intact?
|
||||
// -> Add the image to OnlyOffice again.
|
||||
const documentUrls = window.frames[0].AscCommon.g_oDocumentUrls;
|
||||
if (!(data.name in documentUrls.getUrls())) {
|
||||
documentUrls.addImageUrl(data.name, blobUrl);
|
||||
}
|
||||
|
||||
return void callback(blobUrl);
|
||||
}
|
||||
|
||||
APP.loadingImage++;
|
||||
Util.fetch(data.src, function (err, u8) {
|
||||
if (err) {
|
||||
APP.loadingImage--;
|
||||
console.error(err);
|
||||
return void callback("");
|
||||
}
|
||||
try {
|
||||
debug("Decrypt with key " + data.key);
|
||||
FileCrypto.decrypt(u8, Nacl.util.decodeBase64(data.key), function (err, res) {
|
||||
APP.loadingImage--;
|
||||
if (err || !res.content) {
|
||||
debug("Decrypting failed");
|
||||
return void callback("");
|
||||
}
|
||||
|
||||
try {
|
||||
var blobUrl = URL.createObjectURL(res.content);
|
||||
// store media blobUrl and content for cache and export
|
||||
var mediaData = {
|
||||
blobUrl : blobUrl,
|
||||
content : "",
|
||||
name: name
|
||||
};
|
||||
mediasData[data.src] = mediaData;
|
||||
var reader = new FileReader();
|
||||
reader.onloadend = function () {
|
||||
debug("MediaData set");
|
||||
mediaData.content = reader.result;
|
||||
downloadImages[name].fire();
|
||||
};
|
||||
reader.readAsArrayBuffer(res.content);
|
||||
debug("Adding CryptPad Image " + data.name + ": " + blobUrl);
|
||||
window.frames[0].AscCommon.g_oDocumentUrls.addImageUrl(data.name, blobUrl);
|
||||
callback(blobUrl);
|
||||
} catch (e) {}
|
||||
});
|
||||
} catch (e) {
|
||||
APP.loadingImage--;
|
||||
debug("Exception decrypting image " + data.name);
|
||||
console.error(e);
|
||||
callback("");
|
||||
}
|
||||
}, void 0, common.getCache());
|
||||
};
|
||||
|
||||
|
||||
// Always hide right menu
|
||||
try {
|
||||
localStorage?.original?.removeItem('sse-hide-right-settings');
|
||||
@ -2155,10 +2536,10 @@ Uncaught TypeError: Cannot read property 'calculatedType' of null
|
||||
APP.docEditor = new window.DocsAPI.DocEditor("cp-app-oo-placeholder-a", APP.ooconfig);
|
||||
|
||||
ooLoaded = true;
|
||||
// TODO move this back to CryptPad
|
||||
// if (content.version < 7) {
|
||||
// APP.docEditor.installLegacyChannel();
|
||||
// }
|
||||
if (content.version < 7) {
|
||||
makeChannel();
|
||||
return;
|
||||
}
|
||||
APP.docEditor.connectMockServer({
|
||||
onMessage: fromOOHandler,
|
||||
getParticipants: getParticipants,
|
||||
@ -2654,7 +3035,7 @@ Uncaught TypeError: Cannot read property 'calculatedType' of null
|
||||
(content.version <= 3 ? 'v2b/' : OOCurrentVersion.currentVersion + '/');
|
||||
var s = h('script', {
|
||||
type:'text/javascript',
|
||||
src: ApiConfig.httpSafeOrigin + '/common/onlyoffice/dist/'+version+'web-apps/apps/api/documents/api.js'
|
||||
src: ApiConfig.httpSafeOrigin + '/common/onlyoffice/dist/'+version+'web-apps/apps/api/documents/api.js?' + APP.urlArgs
|
||||
});
|
||||
$('#cp-app-oo-editor').empty().append(h('div#cp-app-oo-placeholder-a')).append(s);
|
||||
|
||||
@ -3112,7 +3493,7 @@ Uncaught TypeError: Cannot read property 'calculatedType' of null
|
||||
|
||||
var s = h('script', {
|
||||
type:'text/javascript',
|
||||
src: ApiConfig.httpSafeOrigin + '/common/onlyoffice/dist/'+version+'web-apps/apps/api/documents/api.js'
|
||||
src: ApiConfig.httpSafeOrigin + '/common/onlyoffice/dist/'+version+'web-apps/apps/api/documents/api.js?' + APP.urlArgs
|
||||
});
|
||||
$('#cp-app-oo-editor').append(s);
|
||||
|
||||
|
||||
@ -46,20 +46,32 @@ define([
|
||||
sframeChan.on('Q_OO_SAVE', function (data, cb) {
|
||||
var chanId = Utils.Hash.hrefToHexChannelId(data.url);
|
||||
Cryptpad.getPadAttribute('lastVersion', function (err, data) {
|
||||
if (data) {
|
||||
var oldChanId = Utils.Hash.hrefToHexChannelId(data);
|
||||
if (oldChanId !== chanId) { Cryptpad.unpinPads([oldChanId], function () {}); }
|
||||
}
|
||||
if (!data) { return; }
|
||||
var oldChanId = Utils.Hash.hrefToHexChannelId(data);
|
||||
if (oldChanId !== chanId) { Cryptpad.unpinPads([oldChanId], function () {}); }
|
||||
});
|
||||
Cryptpad.pinPads([chanId], function (e) {
|
||||
if (e) { return void cb(e); }
|
||||
Cryptpad.setPadAttribute('lastVersion', data.url, cb);
|
||||
channels.lastVersion = data.url;
|
||||
|
||||
// If pad is stored, pin
|
||||
Cryptpad.getPadAttribute('channel', function (err, data) {
|
||||
if (err || !data) { return; }
|
||||
Cryptpad.pinPads([chanId], function (e) {
|
||||
if (e) { return void cb(e); }
|
||||
});
|
||||
});
|
||||
Cryptpad.setPadAttribute('lastVersion', data.url, cb);
|
||||
channels.lastVersion = data.url;
|
||||
Cryptpad.setPadAttribute('lastCpHash', data.hash, cb);
|
||||
channels.lastCpHash = data.hash;
|
||||
});
|
||||
sframeChan.on('Q_OO_OPENCHANNEL', function (data, cb) {
|
||||
const other = Cryptpad.otherPadAttrs = {
|
||||
rtChannel: data.channel
|
||||
};
|
||||
if (channels.lastVersion) {
|
||||
other.lastVersion = channels.lastVersion;
|
||||
}
|
||||
other.lastCpHash = channels.lastCpHash;
|
||||
|
||||
Cryptpad.getPadAttribute('rtChannel', function (err, res) {
|
||||
// If already stored, don't pin it again
|
||||
if (res && res === data.channel) { return; }
|
||||
|
||||
@ -319,7 +319,7 @@ define([
|
||||
let canNoDrive = false;
|
||||
try {
|
||||
var parsed = Utils.Hash.parsePadUrl(currentPad.href);
|
||||
canNoDrive = !(parsed?.hashData?.version === 3) && !parsed?.hashData?.password;
|
||||
canNoDrive = ![3,4].includes(parsed?.hashData?.version) && !parsed?.hashData?.password;
|
||||
var options = parsed.getOptions();
|
||||
if (options.loginOpts) {
|
||||
var loginOpts = Utils.Hash.decodeDataOptions(options.loginOpts);
|
||||
|
||||
2
www/common/worker.bundle.min.js
vendored
2
www/common/worker.bundle.min.js
vendored
File diff suppressed because one or more lines are too long
@ -45,6 +45,9 @@ define([
|
||||
var addRpc = function (sframeChan, Cryptpad) {
|
||||
sframeChan.on('EV_FORM_PIN', function (data) {
|
||||
channels.answersChannel = data.channel;
|
||||
Cryptpad.otherPadAttrs = {
|
||||
answersChannel: data.channel
|
||||
};
|
||||
Cryptpad.changeMetadata();
|
||||
Cryptpad.getPadAttribute('answersChannel', function (err, res) {
|
||||
// If already stored, don't pin it again
|
||||
|
||||
Loading…
Reference in New Issue
Block a user