diff --git a/customize.dist/pages.js b/customize.dist/pages.js index 74c46c4ec..4eef2aa8f 100644 --- a/customize.dist/pages.js +++ b/customize.dist/pages.js @@ -62,7 +62,7 @@ define([ var imprintUrl = AppConfig.imprint && (typeof(AppConfig.imprint) === "boolean" ? '/imprint.html' : AppConfig.imprint); - Pages.versionString = "CryptPad v3.24.0 (YunnanLakeNewt)"; + Pages.versionString = "CryptPad v3.25.0 (ZyzomysPedunculatus)"; // used for the about menu Pages.imprintLink = AppConfig.imprint ? footLink(imprintUrl, 'imprint') : undefined; diff --git a/lib/commands/admin-rpc.js b/lib/commands/admin-rpc.js index 5c64b6086..595b4c6dc 100644 --- a/lib/commands/admin-rpc.js +++ b/lib/commands/admin-rpc.js @@ -160,9 +160,19 @@ var archiveDocument = function (Env, Server, cb, data) { switch (id.length) { case 32: // TODO disconnect users from active sessions - return void Env.msgStore.archiveChannel(id, cb); + return void Env.msgStore.archiveChannel(id, Util.both(cb, function (err) { + Env.Log.info("ARCHIVAL_CHANNEL_BY_ADMIN_RPC", { + channelId: id, + status: err? String(err): "SUCCESS", + }); + })); case 48: - return void Env.blobStore.archive.blob(id, cb); + return void Env.blobStore.archive.blob(id, Util.both(cb, function (err) { + Env.Log.info("ARCHIVAL_BLOB_BY_ADMIN_RPC", { + id: id, + status: err? String(err): "SUCCESS", + }); + })); default: return void cb("INVALID_ID_LENGTH"); } @@ -178,10 +188,21 @@ var restoreArchivedDocument = function (Env, Server, cb, data) { switch (id.length) { case 32: - return void Env.msgStore.restoreArchivedChannel(id, cb); + return void Env.msgStore.restoreArchivedChannel(id, Util.both(cb, function (err) { + Env.Log.info("RESTORATION_CHANNEL_BY_ADMIN_RPC", { + id: id, + status: err? String(err): 'SUCCESS', + }); + })); case 48: - // Env.blobStore.restore.proof(userSafekey, id, cb) // XXX .... - return void Env.blobStore.restore.blob(id, cb); + // FIXME this does not yet restore blob ownership + // Env.blobStore.restore.proof(userSafekey, id, cb) + return void Env.blobStore.restore.blob(id, Util.both(cb, function (err) { + Env.Log.info("RESTORATION_BLOB_BY_ADMIN_RPC", { + id: id, + status: err? String(err): 'SUCCESS', + }); + })); default: return void cb("INVALID_ID_LENGTH"); } diff --git a/lib/storage/file.js b/lib/storage/file.js index 4fbb52b52..d890cb0b9 100644 --- a/lib/storage/file.js +++ b/lib/storage/file.js @@ -722,9 +722,9 @@ var unarchiveChannel = function (env, channelName, cb) { // restore the metadata log Fse.move(archiveMetadataPath, metadataPath, w(function (err) { // if there's nothing to move, you're done. - /*if (err && err.code === 'ENOENT') { + if (err && err.code === 'ENOENT') { return CB(); - }*/ // XXX make sure removing this part won't break anything + } // call back with an error if something goes wrong if (err) { w.abort(); diff --git a/www/assert/main.js b/www/assert/main.js index c29b3bfa3..a467bfc67 100644 --- a/www/assert/main.js +++ b/www/assert/main.js @@ -334,6 +334,12 @@ define([ !secret.hashData.present); }, "test support for ugly tracking query paramaters in url"); + assert(function (cb) { + var url = '//cryptpad.fr/pad/#/2/pad/edit/oRE0oLCtEXusRDyin7GyLGcS/'; + var parsed = Hash.isValidHref(url); + cb(!parsed); + }, "test that protocol relative URLs are rejected"); + assert(function (cb) { var keys = Block.genkeys(Nacl.randomBytes(64)); var hash = Block.getBlockHash(keys); @@ -349,7 +355,7 @@ define([ var v3 = Hash.isValidHref('/pad'); var v4 = Hash.isValidHref('/pad/'); - var res = v1 && v2 && v3 && v4; + var res = Boolean(v1 && v2 && v3 && v4); cb(res); if (!res) { console.log(v1, v2, v3, v4); @@ -361,7 +367,7 @@ define([ var v3 = Hash.isValidHref('/pad#'); // Invalid var v4 = Hash.isValidHref('/pad/#'); - var res = v1 && v2 && v3 && v4; + var res = Boolean(v1 && v2 && v3 && v4); cb(res); if (!res) { console.log(v1, v2, v3, v4); @@ -373,7 +379,7 @@ define([ var v3 = Hash.isValidHref('https://cryptpad.fr/pad/#67b8385b07352be53e40746d2be6ccd7XAYSuJYYqa9NfmInyHci7LNy'); var v4 = Hash.isValidHref('/pad/#/2/pad/edit/HGu0tK2od-2BBnwAz2ZNS-t4/p/embed'); - var res = v1 && v2 && v3 && v4; + var res = Boolean(v1 && v2 && v3 && v4); cb(res); if (!res) { console.log(v1, v2, v3, v4); diff --git a/www/common/common-hash.js b/www/common/common-hash.js index 4f7290b81..afdecbf57 100644 --- a/www/common/common-hash.js +++ b/www/common/common-hash.js @@ -465,7 +465,7 @@ Version 4: Data URL when not a realtime link yet (new pad or "static" app) if (!/^https*:\/\//.test(href)) { // If it doesn't start with http(s), it should be a relative href - if (!/^\//.test(href)) { return ret; } + if (!/^\/($|[^\/])/.test(href)) { return ret; } idx = href.indexOf('/#'); ret.type = href.slice(1, idx); if (idx === -1) { return ret; } diff --git a/www/common/common-ui-elements.js b/www/common/common-ui-elements.js index bd9cb784a..81b202ee0 100644 --- a/www/common/common-ui-elements.js +++ b/www/common/common-ui-elements.js @@ -2687,7 +2687,6 @@ define([ }; - Messages.history_trimPrompt = "This document's history is very large ({0}) and it may impact the loading time. You can delete the unnecessary history."; UIElements.displayTrimHistoryPrompt = function (common, data) { var mb = Util.bytesToMegabytes(data.size); var text = Messages._getKey('history_trimPrompt', [ diff --git a/www/common/media-tag.js b/www/common/media-tag.js index 6755df5a2..86a5a8659 100644 --- a/www/common/media-tag.js +++ b/www/common/media-tag.js @@ -406,10 +406,7 @@ var factory = function () { getBlobCache(cacheKey, function (err, u8) { if (err || !u8) { return void fetch(); } - var size = Decrypt.decodePrefix(u8.subarray(0,2)); - console.error(size); - cb(null, u8.subarray(0, size+2)); }); }; diff --git a/www/common/outer/local-store.js b/www/common/outer/local-store.js index 645493de5..95a3bd88b 100644 --- a/www/common/outer/local-store.js +++ b/www/common/outer/local-store.js @@ -4,7 +4,8 @@ define([ '/common/outer/cache-store.js', '/bower_components/localforage/dist/localforage.min.js', '/customize/application_config.js', -], function (Constants, Hash, Cache, localForage, AppConfig) { + '/common/common-util.js', +], function (Constants, Hash, Cache, localForage, AppConfig, Util) { var LocalStore = {}; LocalStore.setThumbnail = function (key, value, cb) { @@ -120,7 +121,7 @@ define([ return void AppConfig.customizeLogout(cb); } - cb = cb || function () {}; + cb = Util.once(cb || function () {}); try { Cache.clear(cb); diff --git a/www/common/translations/messages.de.json b/www/common/translations/messages.de.json index f7e9ce178..eb2e4abcb 100644 --- a/www/common/translations/messages.de.json +++ b/www/common/translations/messages.de.json @@ -40,7 +40,7 @@ "saved": "Gespeichert", "synced": "Alles gespeichert", "deleted": "Gelöscht", - "deletedFromServer": "Pad wurde vom Server gelöscht", + "deletedFromServer": "Dokument zerstört", "mustLogin": "Du musst angemeldet sein, um auf diese Seite zuzugreifen", "disabledApp": "Diese Anwendung wurde deaktiviert. Kontaktiere den Administrator dieses CryptPads, um mehr Informationen zu erhalten.", "realtime_unrecoverableError": "Es ist ein nicht reparierbarer Fehler aufgetreten. Klicke auf OK, um neu zu laden.", @@ -547,7 +547,7 @@ "upload_notEnoughSpace": "Der verfügbare Speicherplatz in deinem CryptDrive reicht leider nicht für diese Datei.", "upload_notEnoughSpaceBrief": "Unzureichender Speicherplatz", "upload_tooLarge": "Diese Datei überschreitet die für deinen Account erlaubte maximale Größe.", - "upload_tooLargeBrief": "Datei zu groß", + "upload_tooLargeBrief": "Datei überschreitet die maximale Größe von {0} MB", "upload_choose": "Eine Datei wählen", "upload_pending": "In der Warteschlange", "upload_cancelled": "Abgebrochen", @@ -1471,5 +1471,29 @@ "error_unhelpfulScriptError": "Skriptfehler: Siehe Konsole im Browser für Details", "documentID": "Kennung des Dokuments", "errorPopupBlocked": "Für die Funktionsweise von CryptPad ist es erforderlich, dass neue Tabs geöffnet werden können. Bitte erlaube Pop-up-Fenster in der Adressleiste deines Browsers. Diese Fenster werden niemals dafür verwendet, dir Werbung anzuzeigen.", - "unableToDisplay": "Das Dokument kann nicht angezeigt werden. Drücke ESC, um die Seite neu zu laden." + "unableToDisplay": "Das Dokument kann nicht angezeigt werden. Drücke ESC, um die Seite neu zu laden. Wenn das Problem weiterhin besteht, kontaktiere bitte den Support.", + "mediatag_notReady": "Bitte schließe den Download ab", + "settings_mediatagSizeTitle": "Limit für automatisches Herunterladen", + "admin_archiveHint": "Ein Dokument unzugänglich machen, ohne es endgültig zu löschen. Es wird in einem Verzeichnis \"archive\" abgelegt und nach einigen Tagen gelöscht (konfigurierbar in der Konfigurationsdatei des Servers).", + "mediatag_loadButton": "Anhang laden", + "settings_mediatagSizeHint": "Maximale Größe in Megabytes (MB) für das automatische Laden von Medienelementen (Bilder, Videos, PDFs), die in Dokumenten eingebettet sind. Größere Elemente können manuell geladen werden. Gib \"-1\" ein, um Medienelemente immer automatisch zu laden.", + "mediatag_saveButton": "Speichern", + "admin_archiveInput2": "Passwort für das Dokument", + "admin_archiveInput": "URL des Dokuments", + "admin_archiveButton": "Archivieren", + "Offline": "Offline", + "download_zip": "ZIP-Datei erstellen...", + "fileTableHeader": "Downloads und Uploads", + "allowNotifications": "Benachrichtigungen erlauben", + "admin_unarchiveHint": "Ein zuvor archiviertes Dokument wiederherstellen", + "pad_mediatagOpen": "Datei öffnen", + "pad_mediatagShare": "Datei teilen", + "download_zip_file": "Datei {0}/{1}", + "archivedFromServer": "Dokument archiviert", + "restoredFromServer": "Dokument wiederhergestellt", + "admin_archiveInval": "Ungültiges Dokument", + "admin_unarchiveButton": "Wiederherstellen", + "admin_unarchiveTitle": "Dokumente wiederherstellen", + "admin_archiveTitle": "Dokumente archivieren", + "history_trimPrompt": "Dieses Dokument hat einen Verlauf von {0} angesammelt, was das Laden verlangsamen kann. Ziehe in Betracht, den Verlauf zu löschen, sofern er nicht benötigt wird." } diff --git a/www/common/translations/messages.fr.json b/www/common/translations/messages.fr.json index 47980ee0d..72a3fad90 100644 --- a/www/common/translations/messages.fr.json +++ b/www/common/translations/messages.fr.json @@ -1494,5 +1494,7 @@ "admin_archiveButton": "Archiver", "admin_archiveHint": "Rendre un document indisponible sans le supprimer définitivement. Il sera placé dans un répertoire \"archive\" et supprimé après quelques jours (configurable dans le fichier de configuration du serveur).", "admin_archiveTitle": "Archiver les documents", - "mediatag_loadButton": "Charger la pièce jointe" + "mediatag_loadButton": "Charger la pièce jointe", + "history_trimPrompt": "Ce document a accumulé {0} d'historique qui peut ralentir le temps de chargement. Envisagez de supprimer l'historique s'il n'est pas nécessaire.", + "contacts_confirmCancel": "Êtes-vous sûr de vouloir annuler votre demande de contact avec {0} ?" } diff --git a/www/common/translations/messages.json b/www/common/translations/messages.json index f5acaa6c8..f07dab3e0 100644 --- a/www/common/translations/messages.json +++ b/www/common/translations/messages.json @@ -1494,5 +1494,7 @@ "mediatag_notReady": "Please complete the download", "settings_mediatagSizeTitle": "Automatic download limit", "settings_mediatagSizeHint": "Maximum size in megabytes (MB) for automatically loading media elements (images, videos, pdf) embedded into documents. Elements bigger than the specified size can be loaded manually. Use \"-1\" to always load the media elements automatically.", - "mediatag_loadButton": "Load attachment" + "mediatag_loadButton": "Load attachment", + "history_trimPrompt": "This document has accumulated {0} of history that may slow down loading time. Consider deleting the history if it is not needed.", + "contacts_confirmCancel": "Are you sure you want to cancel your contact request with {0}?" } diff --git a/www/profile/inner.js b/www/profile/inner.js index 3917e2b2a..375f9588c 100644 --- a/www/profile/inner.js +++ b/www/profile/inner.js @@ -243,7 +243,6 @@ define([ return; } - Messages.contacts_confirmCancel = "Are you sure you want to cancel your contact request with {0}?"; // XXX var addCancel = function () { var cancelButton = h('button.btn.btn-danger.cp-app-profile-friend-request', [ h('i.fa.fa-user-times'),