diff --git a/customize.dist/pages/contact.js b/customize.dist/pages/contact.js index 36f1b401f..816dc445b 100644 --- a/customize.dist/pages/contact.js +++ b/customize.dist/pages/contact.js @@ -12,7 +12,7 @@ define([ return function () { document.title = Msg.contact; - var developerEmail = "contact@cryptpad.fr"; + var developerEmail = "contact@cryptpad.org"; var adminEmail = Config.adminEmail && [ 'i.did.not.read.my.config@cryptpad.fr', developerEmail diff --git a/docs/ARCHITECTURE.md b/docs/ARCHITECTURE.md index 32ba43d65..c21cd9959 100644 --- a/docs/ARCHITECTURE.md +++ b/docs/ARCHITECTURE.md @@ -69,7 +69,7 @@ This means that using chainpad, clients can collaborate in realtime while using ## Datastore -While it's possible for messages to propogate using a [gossip protocol](https://en.wikipedia.org/wiki/Gossip_protocol) and therefore not rely on havinga centralized service for storing messages, it's possible for the members of a gossip network to [Netsplit](https://en.wikipedia.org/wiki/Netsplit). +While it's possible for messages to propagate using a [gossip protocol](https://en.wikipedia.org/wiki/Gossip_protocol) and therefore not rely on having a centralized service for storing messages, it's possible for the members of a gossip network to [Netsplit](https://en.wikipedia.org/wiki/Netsplit). Chainpad currently has no mechanism for resolving such an event. If a member of a session disconnects (as defined by not responding to a ping with a pong in a specified timeframe) any revisions that they make to their version of a document will be ignored. @@ -128,7 +128,7 @@ If an interface is interactive, which they typically are, then the user will lik If the interface is a plain text editor, maintaining the location of the cursor while updating the contents of the editor is not especially difficult. The process involves checking where the user's selection is located (possibly a start and end), determining whether the changes to the document occurred before or after those points, and updating the selection boundaries if necessary. -If the interface is a WYSIWYG editor, maintaining the location of the cursor is more difficult, as the number of characters changed in the authoratative document does not correspond directly to the number of characters which the user perceives. +If the interface is a WYSIWYG editor, maintaining the location of the cursor is more difficult, as the number of characters changed in the authoritative document does not correspond directly to the number of characters which the user perceives. It is the application developers' responsibility to infer from the new content where the cursor should be, and to render the modified content in such a way that it does not disrupt user experience. In the process of developing its [Realtime CKEditor](https://cryptpad.fr) XWiki Labs discovered that many of the [existing Javascript libraries](https://github.com/Matt-Esch/virtual-dom) for updating a **DOM** are very destructive, and replace elements completely once a difference is detected within the tree (when scanning left to right). @@ -213,7 +213,7 @@ The encryption scheme employed by CryptPad is a [symmetric encryption](https://e Encryption is complex, and poorly understood by the majority of those who use it on a daily basis. Pre-shared-keys are among the weakest possible cryptographic tools available today, however, few if any other encryption schemes scale to any number of users. -For our purposes, we would like our application to offerthe benefits of encryption without being any more difficult to use. +For our purposes, we would like our application to offer the benefits of encryption without being any more difficult to use. Since the method of collaborating on any web resource typically involves sharing the URL, we use the hash of the URl to share the pre-shared-key. Anything in a URL which follows a `#` is not sent to the server, meaning that our web app will store your users' messages without ever knowing their content. diff --git a/www/checkup/checkup-tools.js b/www/checkup/checkup-tools.js index 2529b8906..ee281c4f8 100644 --- a/www/checkup/checkup-tools.js +++ b/www/checkup/checkup-tools.js @@ -22,7 +22,7 @@ define([ var OS_HINTS = { "Win": "Windows", - "Mac": "MacOS", + "Mac": "macOS", "X11": "UNIX", "Linux": "Linux", }; diff --git a/www/common/cryptpad-common.js b/www/common/cryptpad-common.js index a385266c9..3feec9a36 100644 --- a/www/common/cryptpad-common.js +++ b/www/common/cryptpad-common.js @@ -431,6 +431,14 @@ define([ cb(obj); }); }; + common.getAccountObject = function (teamId, cb) { + postMessage("GET", { + teamId: teamId, + key: [] + }, function (obj) { + cb(obj); + }); + }; common.getSharedFolder = function (data, cb) { postMessage("GET_SHARED_FOLDER", data, function (obj) { cb(obj); diff --git a/www/settings/main.js b/www/settings/main.js index 2e3cc86bb..6143e900f 100644 --- a/www/settings/main.js +++ b/www/settings/main.js @@ -23,43 +23,55 @@ define([ }); }); sframeChan.on('Q_SETTINGS_DRIVE_GET', function (d, cb) { + if (d !== "full") { + Cryptpad.getAccountObject(null, function (obj) { + cb(obj); + }); + return; + } Cryptpad.getUserObject(null, function (obj) { if (obj.error) { return void cb(obj); } - if (d === "full") { - // We want shared folders too - var result = { - uo: obj, - sf: {} - }; - if (!obj.drive || !obj.drive.sharedFolders) { return void cb(result); } - Utils.nThen(function (waitFor) { - Object.keys(obj.drive.sharedFolders).forEach(function (id) { - Cryptpad.getSharedFolder({ - id: id - }, waitFor(function (obj) { - result.sf[id] = obj; - })); - }); - }).nThen(function () { - cb(result); + // We want shared folders too + var result = { + uo: obj, + sf: {} + }; + if (!obj.drive || !obj.drive.sharedFolders) { return void cb(result); } + Utils.nThen(function (waitFor) { + Object.keys(obj.drive.sharedFolders).forEach(function (id) { + Cryptpad.getSharedFolder({ + id: id + }, waitFor(function (obj) { + result.sf[id] = obj; + })); }); - return; - } - // We want only the user object - cb(obj); + }).nThen(function () { + cb(result); + }); }); }); sframeChan.on('Q_SETTINGS_DRIVE_SET', function (data, cb) { if (data && data.uo) { data = data.uo; } - var sjson = JSON.stringify(data); - require([ - '/common/cryptget.js', - ], function (Crypt) { - var k = Cryptpad.userHash || Utils.LocalStore.getFSHash(); - Crypt.put(k, sjson, function (err) { - cb(err); + const drive = JSON.parse(JSON.stringify(data.drive || '')); + const todo = () => { + var sjson = JSON.stringify(data); + require([ + '/common/cryptget.js', + ], function (Crypt) { + var k = Cryptpad.userHash || Utils.LocalStore.getFSHash(); + Crypt.put(k, sjson, function (err) { + cb(err); + }); }); - }); + }; + if (Object.keys(data).length === 1 && data.drive) { + return Cryptpad.getAccountObject(null, function (obj) { + data = JSON.parse(JSON.stringify(obj)); + data.drive = drive; + todo(); + }); + } + todo(); }); sframeChan.on('Q_SETTINGS_LOGOUT_PROPERLY', function (data, cb) { Utils.LocalStore.clearLoginToken();