From 76fdadee7f929ede08270de077c21175935c6a97 Mon Sep 17 00:00:00 2001
From: yflory <yann.flory@xwiki.com>
Date: Mon, 3 Oct 2016 18:23:59 +0200
Subject: [PATCH] Store only the strongest hash in the localstorage

---
 www/code/main.js              |  2 +-
 www/common/cryptpad-common.js | 82 +++++++++++++++++------------------
 www/pad/main.js               |  2 +-
 www/poll/main.js              |  2 +-
 www/slide/main.js             |  2 +-
 5 files changed, 44 insertions(+), 46 deletions(-)

diff --git a/www/code/main.js b/www/code/main.js
index ae8d783e0..fc10fd7c9 100644
--- a/www/code/main.js
+++ b/www/code/main.js
@@ -476,7 +476,7 @@ define([
                         return;
                     }
                     document.title = title || info.channel.slice(0, 8);
-                    Cryptpad.rememberPad(title, function (err, data) {
+                    Cryptpad.setPadTitle(title, function (err, data) {
                         if (err) {
                             console.log("Unable to set pad title");
                             console.error(err);
diff --git a/www/common/cryptpad-common.js b/www/common/cryptpad-common.js
index 7387808fa..6b7562551 100644
--- a/www/common/cryptpad-common.js
+++ b/www/common/cryptpad-common.js
@@ -137,6 +137,26 @@ define([
     };
 
 
+    var parseHash = common.parseHash = function (hash) {
+        var parsed = {};
+        if (hash.slice(0,1) !== '/' && hash.length >= 56) {
+            // Old hash
+            parsed.channel = hash.slice(0, 32);
+            parsed.key = hash.slice(32);
+            parsed.version = 0;
+            return parsed;
+        }
+        var hashArr = hash.split('/');
+        if (hashArr[1] && hashArr[1] === '1') {
+            parsed.version = 1;
+            parsed.mode = hashArr[2];
+            parsed.channel = hashArr[3];
+            parsed.key = hashArr[4];
+            parsed.present = hashArr[5] && hashArr[5] === 'present';
+            return parsed;
+        }
+        return;
+    };
     var getEditHashFromKeys = common.getEditHashFromKeys = function (chanKey, keys) {
         if (typeof keys === 'string') {
             return chanKey + keys;
@@ -401,51 +421,10 @@ define([
         }, legacy);
     };
 
-    // STORAGE
-    var rememberPad = common.rememberPad = window.rememberPad = function (title, cb) {
-        // bail out early
-        if (!/#/.test(window.location.hash)) { return; }
-
-        getRecentPads(function (err, pads) {
-            if (err) {
-                cb(err);
-                return;
-            }
-
-            var now = ''+new Date();
-            var href = window.location.href;
-
-            var parsed = parsePadUrl(window.location.href);
-            var isUpdate = false;
-
-            var out = pads.map(function (pad) {
-                var p = parsePadUrl(pad.href);
-                if (p.hash === parsed.hash && p.type === parsed.type) {
-                    isUpdate = true;
-                    // bump the atime
-                    pad.atime = now;
-
-                    pad.title = title;
-                    pad.href = href;
-                }
-                return pad;
-            });
-
-            if (!isUpdate) {
-                // href, ctime, atime, title
-                out.push(makePad(href, title));
-            }
-            setRecentPads(out, function (err, data) {
-                cb(err, data);
-            });
-        });
-    };
-
     // STORAGE
     var setPadTitle = common.setPadTitle = function (name, cb) {
         var href = window.location.href;
         var parsed = parsePadUrl(href);
-
         getRecentPads(function (err, recent) {
             if (err) {
                 cb(err);
@@ -456,7 +435,26 @@ define([
 
             var renamed = recent.map(function (pad) {
                 var p = parsePadUrl(pad.href);
-                if (p.hash === parsed.hash && p.type === parsed.type) {
+
+                if (p.type !== parsed.type) { return pad; }
+
+                // Version 1 : we have up to 4 differents hash for 1 pad, keep the strongest :
+                // Edit > Edit (present) > View > View (present)
+                var bypass = false;
+                var pHash = parseHash(p.hash);
+                var parsedHash = parseHash(parsed.hash);
+                if (pHash.version === 1 && parsedHash.version === 1 && pHash.channel === parsedHash.channel) {
+                    if (pHash.mode === 'view' && parsedHash.mode === 'edit') { bypass = true; }
+                    else if (pHash.mode === parsedHash.mode && pHash.present) { bypass = true; }
+                    else {
+                        // Editing a "weaker" version of a stored hash : update the date and do not push the current hash
+                        pad.atime = new Date().toISOString();
+                        contains = true;
+                        return pad;
+                    }
+                }
+
+                if (p.hash === parsed.hash || bypass) {
                     contains = true;
                     // update the atime
                     pad.atime = new Date().toISOString();
diff --git a/www/pad/main.js b/www/pad/main.js
index 9fb92992e..0c28055f6 100644
--- a/www/pad/main.js
+++ b/www/pad/main.js
@@ -608,7 +608,7 @@ define([
                         return;
                     }
                     document.title = title || info.channel.slice(0, 8);
-                    Cryptpad.rememberPad(title, function (err, data) {
+                    Cryptpad.setPadTitle(title, function (err, data) {
                         if (err) {
                             console.log("Couldn't remember pad");
                             console.error(err);
diff --git a/www/poll/main.js b/www/poll/main.js
index 9b1ab0e68..05c452f5a 100644
--- a/www/poll/main.js
+++ b/www/poll/main.js
@@ -923,7 +923,7 @@ define([
             Cryptpad.getPadTitle(function (err, title) {
                 title = document.title = title || info.channel.slice(0, 8);
 
-                Cryptpad.rememberPad(title, function (err, data) {
+                Cryptpad.setPadTitle(title, function (err, data) {
                     if (err) {
                         console.log("unable to remember pad");
                         console.log(err);
diff --git a/www/slide/main.js b/www/slide/main.js
index 78ca23fb3..f0f139a6a 100644
--- a/www/slide/main.js
+++ b/www/slide/main.js
@@ -490,7 +490,7 @@ define([
                         return;
                     }
                     document.title = APP.title = title || info.channel.slice(0, 8);
-                    Cryptpad.rememberPad(title, function (err, data) {
+                    Cryptpad.setPadTitle(title, function (err, data) {
                         if (err) {
                             console.log("Unable to set pad title");
                             console.error(err);