From ac328260093d87bcb54da21da0090a068870a6e6 Mon Sep 17 00:00:00 2001 From: El RIDO Date: Sun, 28 Jun 2020 14:52:40 +0200 Subject: [PATCH] initial work to add IndexedDB support, including npm module to mock its API in unit tests --- js/common.js | 1 + js/package.json | 5 ++-- js/privatebin.js | 74 +++++++++++++++++++++++++++++++++++++++++++---- tpl/bootstrap.php | 2 +- tpl/page.php | 2 +- 5 files changed, 74 insertions(+), 10 deletions(-) diff --git a/js/common.js b/js/common.js index 6c44a32f..503ad7d5 100644 --- a/js/common.js +++ b/js/common.js @@ -8,6 +8,7 @@ global.cleanup = global.jsdom(); global.URL = require('jsdom-url').URL; global.fs = require('fs'); global.WebCrypto = require('@peculiar/webcrypto').Crypto; +require('fake-indexeddb/auto'); // application libraries to test global.$ = global.jQuery = require('./jquery-3.4.1'); diff --git a/js/package.json b/js/package.json index 489cc677..75d0ae20 100644 --- a/js/package.json +++ b/js/package.json @@ -8,11 +8,12 @@ }, "dependencies": {}, "devDependencies": { + "@peculiar/webcrypto": "^1.1.1", + "fake-indexeddb": "^3.0.2", "jsdom": "^9.12.0", "jsdom-global": "^2.1.1", "jsdom-url": "^2.2.1", - "jsverify": "^0.8.3", - "@peculiar/webcrypto": "^1.1.1" + "jsverify": "^0.8.3" }, "scripts": { "test": "mocha" diff --git a/js/privatebin.js b/js/privatebin.js index 150a126f..5604d233 100644 --- a/js/privatebin.js +++ b/js/privatebin.js @@ -4362,10 +4362,30 @@ jQuery.PrivateBin = (function($, RawDeflate) { * @name Memory * @class */ - const Memory = (function (document) { + const Memory = (function (document, window) { const me = {}; - let urls = []; + let urls = [], + db; + + /** + * called after successfully connecting to the indexedDB + * + * @name Memory.updateCacheFromDb + * @private + * @function + */ + function updateCacheFromDb() + { + const memory = db.transaction('pastes').objectStore('pastes'); + memory.openCursor().onsuccess = function(e) { + let cursor = e.target.result; + if (cursor) { + urls.push(cursor.value.url); + cursor.continue(); + } + }; + } /** * adds a paste URL to the memory @@ -4378,6 +4398,20 @@ jQuery.PrivateBin = (function($, RawDeflate) { me.add = function(pasteUrl) { urls.push(pasteUrl); + if (!window.indexedDB || !db) { + return false; + } + const url = new URL(pasteUrl); + const memory = db.transaction('pastes', 'readwrite').objectStore('pastes'); + memory.add({ + 'https': url.protocol == 'https:', + 'service': url.hostname + url.pathname, + 'pasteid': url.search.replace(/^\?+/, ''), + 'key': url.hash.replace(/^#+/, ''), + // we store the full URL as it may contain additonal information + // required to open the paste, like port, username and password + 'url': pasteUrl + }); return true; }; @@ -4411,15 +4445,43 @@ jQuery.PrivateBin = (function($, RawDeflate) { me.init = function() { urls = []; - $("#menu-toggle").on('click', function(e) { + if (!window.indexedDB) { + $('#menu-toggle').hide(); + return; + } + const request = window.indexedDB.open('privatebin', 1); + request.onerror = function(e) { + Alert.showWarning('Unable to open indexedDB, memory will not be available in this session.'); + $('#menu-toggle').hide(); + }; + request.onupgradeneeded = function(event) { + const newDb = event.target.result; + const objectStore = newDb.createObjectStore('pastes', {keyPath: 'pasteid'}); + objectStore.createIndex('https', 'https', {unique: false}); + objectStore.createIndex('service', 'service', {unique: false}); + objectStore.createIndex('pasteid', 'pasteid', {unique: true}); + objectStore.transaction.oncomplete = function(e) { + db = newDb; + updateCacheFromDb(); + }; + }; + request.onsuccess = function(e) { + db = request.result; + db.onerror = function(e) { + Alert.showError(e); + } + updateCacheFromDb(); + }; + + $('#menu-toggle').on('click', function(e) { e.preventDefault(); - $("main").toggleClass("toggled"); - $("#menu-toggle .glyphicon").toggleClass("glyphicon glyphicon-menu-down glyphicon glyphicon-menu-up") + $('main').toggleClass('toggled'); + $('#menu-toggle .glyphicon').toggleClass('glyphicon glyphicon-menu-down glyphicon glyphicon-menu-up') }); }; return me; - })(document); + })(document, window); /** * Responsible for AJAX requests, transparently handles encryption… diff --git a/tpl/bootstrap.php b/tpl/bootstrap.php index 1816d806..b7ce955c 100644 --- a/tpl/bootstrap.php +++ b/tpl/bootstrap.php @@ -72,7 +72,7 @@ endif; ?> - + diff --git a/tpl/page.php b/tpl/page.php index 252d3e9a..8808d3b1 100644 --- a/tpl/page.php +++ b/tpl/page.php @@ -50,7 +50,7 @@ endif; ?> - +