diff --git a/customize.dist/about.html b/customize.dist/about.html index 65cbe1abe..5fa15ab7e 100644 --- a/customize.dist/about.html +++ b/customize.dist/about.html @@ -81,20 +81,20 @@
@@ -111,7 +111,7 @@
  • IRC
  • Twitter
  • GitHub
  • -
  • Email
  • +
  • Email
  • diff --git a/customize.dist/application_config.js b/customize.dist/application_config.js index e391134eb..f1cbcb090 100644 --- a/customize.dist/application_config.js +++ b/customize.dist/application_config.js @@ -12,8 +12,5 @@ define(function() { */ config.notificationTimeout = 5000; - config.USE_FS_STORE = true; - config.USE_HOMEPAGE_TABLE = false; - return config; }); diff --git a/customize.dist/contact.html b/customize.dist/contact.html index e1060bacb..0d404a18a 100644 --- a/customize.dist/contact.html +++ b/customize.dist/contact.html @@ -78,20 +78,20 @@
    @@ -108,7 +108,7 @@
  • IRC
  • Twitter
  • GitHub
  • -
  • Email
  • +
  • Email
  • diff --git a/customize.dist/fsStore.js b/customize.dist/fsStore.js index bbf3d34e6..34c77616d 100644 --- a/customize.dist/fsStore.js +++ b/customize.dist/fsStore.js @@ -16,133 +16,116 @@ define([ */ var Store = {}; - var storeObj; - var ready = false; - var filesOp; - var exp = {}; + var store; - var safeSet = function (key, val) { - storeObj[key] = val; - }; + var initStore = function (filesOp, storeObj, exp) { + var ret = {}; - // Store uses nodebacks... - Store.set = function (key, val, cb) { - safeSet(key, val); - cb(); - }; + var safeSet = function (key, val) { + storeObj[key] = val; + }; - // implement in alternative store - Store.setBatch = function (map, cb) { - Object.keys(map).forEach(function (key) { - safeSet(key, map[key]); - }); - cb(void 0, map); - }; + // Store uses nodebacks... + ret.set = function (key, val, cb) { + safeSet(key, val); + cb(); + }; - Store.setDrive = function (key, val, cb) { - storeObj.drive[key] = val; - cb(); - }; - - var safeGet = window.safeGet = function (key) { - return storeObj[key]; - }; - - Store.get = function (key, cb) { - cb(void 0, safeGet(key)); - }; - - // implement in alternative store - Store.getBatch = function (keys, cb) { - var res = {}; - keys.forEach(function (key) { - res[key] = safeGet(key); - }); - cb(void 0, res); - }; - - Store.getDrive = function (key, cb) { - cb(void 0, storeObj.drive[key]); - }; - - var safeRemove = function (key) { - delete storeObj[key]; - }; - - Store.remove = function (key, cb) { - safeRemove(key); - cb(); - }; - - // implement in alternative store - Store.removeBatch = function (keys, cb) { - keys.forEach(function (key) { - safeRemove(key); - }); - cb(); - }; - - Store.keys = function (cb) { - cb(void 0, Object.keys(storeObj)); - }; - - Store.addPad = function (href, path, name) { - filesOp.addPad(href, path, name); - }; - - Store.forgetPad = function (href, cb) { - filesOp.forgetPad(href); - cb(); - }; - - Store.addTemplate = function (href) { - filesOp.addTemplate(href); - }; - - Store.listTemplates = function () { - return filesOp.listTemplates(); - }; - - Store.getProxy = function () { - return exp; - }; - - Store.getLoginName = function () { - return storeObj.login_name; - }; - - var changeHandlers = Store.changeHandlers = []; - - Store.change = function (f) { - if (typeof(f) !== 'function') { - throw new Error('[Store.change] callback must be a function'); - } - changeHandlers.push(f); - - if (changeHandlers.length === 1) { - // start listening for changes -/* TODO: listen for changes in the proxy - window.addEventListener('storage', function (e) { - changeHandlers.forEach(function (f) { - f({ - key: e.key, - oldValue: e.oldValue, - newValue: e.newValue, - }); - }); + // implement in alternative store + ret.setBatch = function (map, cb) { + Object.keys(map).forEach(function (key) { + safeSet(key, map[key]); }); -*/ - } + cb(void 0, map); + }; + + ret.setDrive = function (key, val, cb) { + storeObj.drive[key] = val; + cb(); + }; + + var safeGet = function (key) { + return storeObj[key]; + }; + + ret.get = function (key, cb) { + cb(void 0, safeGet(key)); + }; + + // implement in alternative store + ret.getBatch = function (keys, cb) { + var res = {}; + keys.forEach(function (key) { + res[key] = safeGet(key); + }); + cb(void 0, res); + }; + + ret.getDrive = function (key, cb) { + cb(void 0, storeObj.drive[key]); + }; + + var safeRemove = function (key) { + delete storeObj[key]; + }; + + ret.remove = function (key, cb) { + safeRemove(key); + cb(); + }; + + // implement in alternative store + ret.removeBatch = function (keys, cb) { + keys.forEach(function (key) { + safeRemove(key); + }); + cb(); + }; + + ret.keys = function (cb) { + cb(void 0, Object.keys(storeObj)); + }; + + ret.addPad = function (href, path, name) { + filesOp.addPad(href, path, name); + }; + + ret.forgetPad = function (href, cb) { + filesOp.forgetPad(href); + cb(); + }; + + ret.addTemplate = function (href) { + filesOp.addTemplate(href); + }; + + ret.listTemplates = function () { + return filesOp.listTemplates(); + }; + + ret.getProxy = function () { + return exp; + }; + + ret.getLoginName = function () { + return storeObj.login_name; + }; + + var changeHandlers = ret.changeHandlers = []; + + ret.change = function (f) {}; + + return ret; }; - var onReady = function (f, proxy, storageKey) { - filesOp = FO.init(proxy.drive, { + var onReady = function (f, proxy, storageKey, exp) { + var fo = FO.init(proxy.drive, { storageKey: storageKey }); - storeObj = proxy; - ready = true; + //storeObj = proxy; + store = initStore(fo, proxy, exp); if (typeof(f) === 'function') { - f(void 0, Store); + f(void 0, store); } }; @@ -167,6 +150,8 @@ define([ logLevel: 1, }; + var exp = {}; + window.addEventListener('storage', function (e) { var key = e.key; if (e.key !== Cryptpad.userHashKey) { return; } @@ -175,8 +160,6 @@ define([ if (!o && n) { window.location.reload(); } else if (o && !n) { - //window.location.reload(); - //window.location.href = '/'; $(window).on('keyup', function (e) { if (e.keyCode === 27) { Cryptpad.removeLoadingScreen(); @@ -192,6 +175,7 @@ define([ }); var rt = window.rt = Listmap.create(listmapConfig); + exp.proxy = rt.proxy; rt.proxy.on('create', function (info) { exp.info = info; @@ -199,44 +183,36 @@ define([ localStorage.FS_hash = Cryptpad.getEditHashFromKeys(info.channel, secret.keys); } }).on('ready', function () { - if (ready) { return; } + if (store) { return; } // the store is already ready, it is a reconnection if (!rt.proxy.drive || typeof(rt.proxy.drive) !== 'object') { rt.proxy.drive = {}; } var drive = rt.proxy.drive; // Creating a new anon drive: import anon pads from localStorage if (!drive[Cryptpad.storageKey] || !Cryptpad.isArray(drive[Cryptpad.storageKey])) { - var oldStore = Cryptpad.getStore(true); - Cryptpad.getRecentPads(function (err, s) { - drive[Cryptpad.storageKey] = s; - onReady(f, rt.proxy, Cryptpad.storageKey); - }, true); + Cryptpad.getLegacyPads(function (err, data) { + drive[Cryptpad.storageKey] = data; + onReady(f, rt.proxy, Cryptpad.storageKey, exp); + }); return; } - onReady(f, rt.proxy, Cryptpad.storageKey); + // Drive already exist: return the existing drive, don't load data from legacy store + onReady(f, rt.proxy, Cryptpad.storageKey, exp); }) .on('disconnect', function (info) { - //setEditable(false); + // We only manage errors during the loading screen here. Other websocket errors are handled by the apps if (info.error) { - //Cryptpad.alert(Messages.websocketError); if (typeof Cryptpad.storeError === "function") { Cryptpad.storeError(); } return; } - //Cryptpad.alert(Messages.common_connectionLost); }); }; Store.ready = function (f, Cryptpad) { - /*if (Cryptpad.parsePadUrl(window.location.href).type === "file") { + if (store) { // Store.ready probably called twice, store already ready if (typeof(f) === 'function') { - f(void 0, Cryptpad.getStore(true)); - } - return; - }*/ - if (ready) { - if (typeof(f) === 'function') { - f(void 0, Store); + f(void 0, store); } } else { init(f, Cryptpad); diff --git a/customize.dist/index.html b/customize.dist/index.html index edb128920..539374e69 100644 --- a/customize.dist/index.html +++ b/customize.dist/index.html @@ -69,25 +69,20 @@
    +
    +
    @@ -204,20 +200,20 @@
      -
    • CryptPad
    • -
    • -
    • -
    • +
    • CryptPad
    • +
    • +
    • +
    • -
    • -
    • -
    • -
    • +
    • +
    • +
    • +
    @@ -234,7 +230,7 @@
  • IRC
  • Twitter
  • GitHub
  • -
  • Email
  • +
  • Email
  • diff --git a/customize.dist/main.css b/customize.dist/main.css index b00a31bab..58dc5c174 100644 --- a/customize.dist/main.css +++ b/customize.dist/main.css @@ -450,28 +450,33 @@ #cryptpadTopBar .right a { font-weight: 500; font-size: 0.75em; - color: #558; + color: #41b7d8; } #cryptpadTopBar .right a:hover { + color: #279ebf !important; text-decoration: underline; } +#cryptpadTopBar .right a:visited { + color: #41b7d8; +} .cp footer { - background: #cccccc; + background: #f4f4f4; font-family: -apple-system, system-ui, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", Arial, sans-serif; padding-top: 1em; + font-size: 1.2em; } .cp footer a { - color: #555; + color: #41b7d8; } .cp footer a:visited { - color: #777; + color: #41b7d8; } .cp footer a:hover { - color: #333; + color: #279ebf !important; } .cp footer li:first-child { + font-size: 1.2em; font-weight: bold; - text-decoration: underline; } html.cp, .cp body { @@ -560,10 +565,10 @@ html.cp, text-decoration: none; } .cp a:hover { - color: #279ebf; + color: #279ebf !important; } .cp a:visited { - color: #558; + color: #41b7d8; } .cp img { height: auto; @@ -600,7 +605,7 @@ html.cp, } .cp .page .info-container { color: #121212; - width: 900px; + width: 800px; max-width: 100%; margin: 0 auto; } @@ -630,7 +635,7 @@ html.cp, @media screen and (max-width: 800px) { } .cp .page.category { - background: #f7f7f7; + background: #f4f4f4; } .cp .page .app { display: inline-block; @@ -687,7 +692,6 @@ html.cp, } .cp .page p { font-size: 18px; - text-align: justify; } .cp .btn-default:hover { background-color: #d8d8d8; @@ -757,8 +761,8 @@ html.cp, z-index: 1; font-size: medium; } -.cp #main #main-container, -.cp #main_other #main-container { +.cp #main #align-container, +.cp #main_other #align-container { position: absolute; top: 50%; left: 50%; @@ -769,24 +773,29 @@ html.cp, width: 1000px; max-width: 90%; } -.cp #main #data, -.cp #main_other #data { - width: 600px; - max-width: 60%; - color: #fff; - padding: 15px; - box-sizing: border-box; +.cp #main #main-container, +.cp #main_other #main-container { position: absolute; display: inline-block; top: 50%; left: 0; transform: translateY(-50%); + width: 100%; +} +.cp #main #data, +.cp #main_other #data { + width: 600px; + max-width: 60%; + color: #fff; + padding: 0 15px; + box-sizing: border-box; + display: inline-block; } .cp #main #data p, .cp #main_other #data p { margin: 0; padding: 0; - font-size: 20px; + font-size: 28px; line-height: 1.5em; } .cp #main #data h1, @@ -797,6 +806,7 @@ html.cp, font-size: 48px; line-height: 1.2em; color: #fff; + padding: 0; } .cp #main #data h5, .cp #main_other #data h5 { @@ -810,15 +820,11 @@ html.cp, } .cp #main #loggedIn, .cp #main_other #loggedIn { + float: right; color: #fff; display: inline-block; - position: absolute; - top: 50%; - right: 0; - margin-left: 50px; width: 350px; max-width: 35%; - transform: translateY(-50%); text-align: center; font-weight: bold; } @@ -836,11 +842,7 @@ html.cp, } .cp #main #userForm, .cp #main_other #userForm { - position: absolute; - right: 0; - top: 50%; - transform: translateY(-50%); - margin-left: 50px; + float: right; display: inline-block; width: 350px; max-width: 35%; @@ -848,47 +850,15 @@ html.cp, box-sizing: border-box; font-family: lato, Helvetica, sans-serif; color: #fff; - /*.remember { - vertical-align: middle; - line-height: 28px; - height: 28px; - display: inline-block; - margin: 10px 0 20px 0; - } - - - [type="checkbox"] { - vertical-align: text-top; - margin: 0; - //margin-top: 10px; - margin-right: 5px; - } - */ -} -.cp #main #userForm h1, -.cp #main_other #userForm h1 { - color: #fff; - padding: 0; -} -.cp #main #userForm [type="text"], -.cp #main_other #userForm [type="text"], -.cp #main #userForm [type="password"], -.cp #main_other #userForm [type="password"] { - width: 100%; } .cp #main #userForm label, .cp #main_other #userForm label { margin-bottom: 0; } -.cp #main #userForm [type="checkbox"], -.cp #main_other #userForm [type="checkbox"] { - margin-right: 5px; -} .cp #main #userForm button, .cp #main_other #userForm button { font-weight: bold; width: 100%; - margin: 2px 0px; cursor: pointer; } .cp #main #userForm button.half, @@ -899,17 +869,80 @@ html.cp, .cp #main_other #userForm button.half:not(.first) { float: right; } +.cp #main #userForm p, +.cp #main_other #userForm p { + margin: 0; + padding: 0; +} +.cp #main #userForm p.buttons, +.cp #main_other #userForm p.buttons { + margin-bottom: 10px; +} +.cp #main #userForm p.buttons .dropdown-bar, +.cp #main_other #userForm p.buttons .dropdown-bar { + display: block; +} +.cp #main #userForm p.buttons .dropdown-bar button, +.cp #main_other #userForm p.buttons .dropdown-bar button { + white-space: normal; + text-align: left; +} +.cp #main #userForm p.buttons .dropdown-bar button .fa, +.cp #main_other #userForm p.buttons .dropdown-bar button .fa { + float: right; +} +.cp #main #userForm p.separator, +.cp #main_other #userForm p.separator { + margin: 5px 0 15px 0; + text-align: center; + font-weight: bold; + font-size: 1.1em; +} +.cp #main #userForm p a, +.cp #main_other #userForm p a { + color: #fff; + font-weight: bold; + font-size: 14px; +} +.cp #main #userForm p a:hover, +.cp #main_other #userForm p a:hover, +.cp #main #userForm p a :visited, +.cp #main_other #userForm p a :visited { + color: #fff !important; +} +.cp #main #userForm .driveLink, +.cp #main_other #userForm .driveLink { + padding-left: 1rem; + font-size: 1em; +} +.cp #main #userForm > *, +.cp #main_other #userForm > * { + margin-bottom: 10px; +} @media screen and (max-width: 800px) { - .cp #main #main-container, - .cp #main_other #main-container { + .cp #main, + .cp #main_other { + position: relative; + height: auto; + } + .cp #main #align-container, + .cp #main_other #align-container { transform: initial; position: relative; display: block; width: 90%; left: 0; } -} -@media screen and (max-width: 800px) { + .cp #main #main-container, + .cp #main_other #main-container { + position: relative; + transform: unset; + top: 0; + } + .cp #main #data, + .cp #main_other #data { + text-align: center; + } .cp #main #userForm, .cp #main_other #userForm, .cp #main #loggedIn, @@ -923,42 +956,13 @@ html.cp, max-width: 100%; margin: 10px 0; box-sizing: border-box; - } -} -@media screen and (max-width: 800px) { - .cp #main #userForm, - .cp #main_other #userForm, - .cp #main #loggedIn, - .cp #main_other #loggedIn { - border: 1px solid #888; - } -} -@media screen and (max-width: 800px) { - .cp #main, - .cp #main_other { - position: relative; - height: auto; - top: -10px; + float: none; } } .cp #main .buttons, .cp #main_other .buttons { margin-top: 15px; } -.cp p.buttons, -.cp div.buttons { - text-align: center; -} -.cp p.buttons button, -.cp div.buttons button { - font-weight: bold; - cursor: pointer; - margin-top: 10px; -} -.cp p.buttons .dropdown-bar, -.cp div.buttons .dropdown-bar { - margin-left: 4px; -} .cp #fileManagerIframe { width: 100%; height: 500px; diff --git a/customize.dist/main.js b/customize.dist/main.js index bebc3cbc6..66eaaf75d 100644 --- a/customize.dist/main.js +++ b/customize.dist/main.js @@ -7,111 +7,114 @@ define([ '/bower_components/jquery/dist/jquery.min.js', ], function (Messages, Config, Cryptpad, LilUri, LS) { var $ = window.$; - var $main = $('#mainBlock'); var APP = window.APP = { Cryptpad: Cryptpad, }; - // Language selector - var $sel = $('#language-selector'); - Cryptpad.createLanguageSelector(undefined, $sel); - $sel.find('button').addClass('btn').addClass('btn-secondary'); - $sel.show(); + $(function () { + var $main = $('#mainBlock'); - $(window).click(function () { - $('.cryptpad-dropdown').hide(); - }); + // Language selector + var $sel = $('#language-selector'); + Cryptpad.createLanguageSelector(undefined, $sel); + $sel.find('button').addClass('btn').addClass('btn-secondary'); + $sel.show(); - // main block is hidden in case javascript is disabled - $main.removeClass('hidden'); + $(window).click(function () { + $('.cryptpad-dropdown').hide(); + }); - // Make sure we don't display non-translated content (empty button) - $main.find('#data').removeClass('hidden'); - if (Cryptpad.isLoggedIn()) { - var name = localStorage[Cryptpad.userNameKey] || sessionStorage[Cryptpad.userNameKey]; - var $loggedInBlock = $main.find('#loggedIn'); - var $hello = $loggedInBlock.find('#loggedInHello'); - var $logout = $loggedInBlock.find('#loggedInLogOut'); + // main block is hidden in case javascript is disabled + $main.removeClass('hidden'); - if (name) { - $hello.text(Messages._getKey('login_hello', [name])); + // Make sure we don't display non-translated content (empty button) + $main.find('#data').removeClass('hidden'); + + if (Cryptpad.isLoggedIn()) { + var name = localStorage[Cryptpad.userNameKey] || sessionStorage[Cryptpad.userNameKey]; + var $loggedInBlock = $main.find('#loggedIn'); + var $hello = $loggedInBlock.find('#loggedInHello'); + var $logout = $loggedInBlock.find('#loggedInLogOut'); + + if (name) { + $hello.text(Messages._getKey('login_hello', [name])); + } else { + $hello.text(Messages.login_helloNoName); + } + $('#buttons').find('.nologin').hide(); + + $logout.click(function () { + Cryptpad.logout(function () { + window.location.reload(); + }); + }); + + $loggedInBlock.removeClass('hidden'); + //return; } else { - $hello.text(Messages.login_helloNoName); + $main.find('#userForm').removeClass('hidden'); } - $('#buttons').find('.nologin').hide(); - $logout.click(function () { - Cryptpad.logout(function () { - window.location.reload(); + var displayCreateButtons = function () { + var $parent = $('#buttons'); + var options = []; + var $container = $('
    ', {'class': 'dropdown-bar'}).appendTo($parent); + Config.availablePadTypes.forEach(function (el) { + if (el === 'drive') { return; } + options.push({ + tag: 'a', + attributes: { + 'class': 'newdoc', + 'href': '/' + el + '/', + 'target': '_blank' + }, + content: Messages['button_new' + el] // Pretty name of the language value + }); }); - }); - - $loggedInBlock.removeClass('hidden'); - //return; - } else { - $main.find('#userForm').removeClass('hidden'); - } - - var displayCreateButtons = function () { - var $parent = $('#buttons'); - var options = []; - Config.availablePadTypes.forEach(function (el) { - if (el === 'drive') { return; } - options.push({ - tag: 'a', - attributes: { - 'class': 'newdoc', - 'href': '/' + el + '/', - 'target': '_blank' - }, - content: Messages['button_new' + el] // Pretty name of the language value - }); - }); - var dropdownConfig = { - text: Messages.makeAPad, // Button initial text - options: options, // Entries displayed in the menu + var dropdownConfig = { + text: Messages.login_makeAPad, // Button initial text + options: options, // Entries displayed in the menu + container: $container + }; + var $block = Cryptpad.createDropdown(dropdownConfig); + $block.find('button').addClass('btn').addClass('btn-primary'); + $block.appendTo($parent); }; - var $block = Cryptpad.createDropdown(dropdownConfig); - $block.find('button').addClass('btn').addClass('btn-success'); - $block.appendTo($parent); - }; - var addButtonHandlers = function () { - $('button.login').click(function (e) { - var username = $('#name').val(); - var passwd = $('#password').val(); - var remember = $('#rememberme').is(':checked'); - sessionStorage.login_user = username; - sessionStorage.login_pass = passwd; - sessionStorage.login_rmb = remember; - sessionStorage.login = 1; - document.location.href = '/user/'; - }); - $('button.register').click(function (e) { - var username = $('#name').val(); - var passwd = $('#password').val(); - var remember = $('#rememberme').is(':checked'); - sessionStorage.login_user = username; - sessionStorage.login_pass = passwd; - sessionStorage.login_rmb = remember; - sessionStorage.register = 1; - document.location.href = '/user/'; - }); - $('button.nologin').click(function (e) { - document.location.href = '/drive/'; - }); + var addButtonHandlers = function () { + $('button.login').click(function (e) { + var username = $('#name').val(); + var passwd = $('#password').val(); + var remember = $('#rememberme').is(':checked'); + sessionStorage.login_user = username; + sessionStorage.login_pass = passwd; + sessionStorage.login_rmb = remember; + sessionStorage.login = 1; + document.location.href = '/user/'; + }); + $('button.register').click(function (e) { + var username = $('#name').val(); + var passwd = $('#password').val(); + var remember = $('#rememberme').is(':checked'); + sessionStorage.login_user = username; + sessionStorage.login_pass = passwd; + sessionStorage.login_rmb = remember; + sessionStorage.register = 1; + document.location.href = '/user/'; + }); - var $passwd = $('#password'); - $passwd.on('keyup', function (e) { - if (e.which !== 13) { return; } // enter - $('button.login').click(); - }); - }; + var $passwd = $('#password'); + $passwd.on('keyup', function (e) { + if (e.which !== 13) { return; } // enter + $('button.login').click(); + }); + }; - displayCreateButtons(); + displayCreateButtons(); - addButtonHandlers(); - console.log("ready"); + addButtonHandlers(); + console.log("ready"); + }); }); diff --git a/customize.dist/privacy.html b/customize.dist/privacy.html index ba8550ee7..222793a90 100644 --- a/customize.dist/privacy.html +++ b/customize.dist/privacy.html @@ -100,20 +100,20 @@
      -
    • CryptPad
    • -
    • -
    • -
    • +
    • CryptPad
    • +
    • +
    • +
    • -
    • -
    • -
    • -
    • +
    • +
    • +
    • +
    @@ -130,7 +130,7 @@
  • IRC
  • Twitter
  • GitHub
  • -
  • Email
  • +
  • Email
  • diff --git a/customize.dist/src/fragments/footer.html b/customize.dist/src/fragments/footer.html index 97344bf52..49f3ee957 100644 --- a/customize.dist/src/fragments/footer.html +++ b/customize.dist/src/fragments/footer.html @@ -3,20 +3,20 @@
      -
    • CryptPad
    • -
    • -
    • -
    • +
    • CryptPad
    • +
    • +
    • +
    • -
    • -
    • -
    • -
    • +
    • +
    • +
    • +
    @@ -33,7 +33,7 @@
  • IRC
  • Twitter
  • GitHub
  • -
  • Email
  • +
  • Email
  • diff --git a/customize.dist/src/fragments/index.html b/customize.dist/src/fragments/index.html index 7cfcd0e13..9a91722ad 100644 --- a/customize.dist/src/fragments/index.html +++ b/customize.dist/src/fragments/index.html @@ -2,25 +2,20 @@
    +
    +
    diff --git a/customize.dist/src/less/cryptpad.less b/customize.dist/src/less/cryptpad.less index 9d0722b03..5423476b2 100644 --- a/customize.dist/src/less/cryptpad.less +++ b/customize.dist/src/less/cryptpad.less @@ -96,16 +96,15 @@ h6 { a { cursor: pointer; - color: @cp-light-blue; - //#41b7d8; //@cp-darkblue; + color: @cp-link; text-decoration: none; &:hover { - color: darken(@cp-light-blue, 10%); //@cp-accent2; + color: @cp-link-hover; } &:visited { - color: @cp-purple; + color: @cp-link-visited; } } @@ -143,7 +142,7 @@ body.html { .info-container { color: #121212; - width: 900px; + width: 800px; max-width: 100%; margin: 0 auto; &>div{ @@ -179,7 +178,7 @@ body.html { //background: darken(@base, 1%); } &.category { - background: darken(@base, 3%); + background: @category-bg; } .app { @@ -233,7 +232,7 @@ body.html { p { font-size: 18px; - text-align: justify; + //text-align: justify; } } @@ -313,7 +312,7 @@ body.html { font-size: medium; - #main-container { + #align-container { position: absolute; top: 50%; left: 50%; @@ -325,11 +324,20 @@ body.html { max-width: 90%; } + #main-container { + position: absolute; + display: inline-block; + top: 50%; + left: 0; + transform: translateY(-50%); + width: 100%; + } + #data { p { margin: 0; padding: 0; - font-size: 20px; + font-size: 28px; line-height: 1.5em; } h1, h2 { @@ -337,6 +345,7 @@ body.html { font-size: 48px; line-height: 1.2em; color: @main-color; + padding: 0; } h5 { @@ -346,13 +355,9 @@ body.html { width: 600px; max-width: 60%; color: @main-color; - padding: 15px; + padding: 0 15px; box-sizing: border-box; - position: absolute; display: inline-block; - top: 50%; - left: 0; - transform: translateY(-50%); #tryit { margin-top: 20px; @@ -361,15 +366,11 @@ body.html { } #loggedIn { + float: right; color: @main-color; display: inline-block; - position: absolute; - top: 50%; - right: 0; - margin-left: 50px; width: 350px; max-width: 35%; - transform: translateY(-50%); text-align: center; font-weight: bold; button { @@ -386,11 +387,7 @@ body.html { } #userForm { - position: absolute; - right: 0; - top: 50%; - transform: translateY(-50%); - margin-left: 50px; + float: right; display: inline-block; width: 350px; max-width: 35%; @@ -399,42 +396,13 @@ body.html { font-family: lato, Helvetica, sans-serif; color: @main-color; - h1 { - color: @main-color; - padding: 0; - } - - [type="text"], [type="password"] { - width: 100%; - } - label { margin-bottom: 0; } - /*.remember { - vertical-align: middle; - line-height: 28px; - height: 28px; - display: inline-block; - margin: 10px 0 20px 0; - } - - - [type="checkbox"] { - vertical-align: text-top; - margin: 0; - //margin-top: 10px; - margin-right: 5px; - } - */ - [type="checkbox"] { - margin-right: 5px; - } button { font-weight: bold; width: 100%; - margin: 2px 0px; cursor: pointer; &.half { width: ~"calc(50% - 2px)"; @@ -443,18 +411,66 @@ body.html { } } } + + p { + margin: 0; + padding: 0; + &.buttons { + margin-bottom: 10px; + .dropdown-bar { + button { + white-space: normal; + text-align: left; + .fa { + float: right; + } + } + display: block; + } + } + &.separator { + margin: 5px 0 15px 0; + text-align: center; + font-weight: bold; + font-size: 1.1em; + } + a { + color: @main-color; + font-weight:bold; + font-size: 14px; + &:hover, :visited { + color: @main-color !important; + } + } + } + + .driveLink { + padding-left: 1rem; //Bootstrap padding in buttons + font-size: 1em; + } + + &> * { + margin-bottom: 10px; + } } - #main-container { - @media screen and (max-width: @media-not-big) { + @media screen and (max-width: @media-not-big) { + #align-container { transform: initial; position: relative; display: block; width: 90%; left: 0; } - } - #userForm, #loggedIn, #data { - @media screen and (max-width: @media-not-big) { + #main-container { + position: relative; + transform: unset; + top:0; + + } + #data { + text-align: center; + } + #userForm, #loggedIn, #data { transform: initial; position: relative; display: block; @@ -462,34 +478,19 @@ body.html { max-width: 100%; margin: 10px 0; box-sizing: border-box; + float: none; } - } - #userForm, #loggedIn { - @media screen and (max-width: @media-not-big) { - border: 1px solid #888; + #userForm, #loggedIn { + //border: 1px solid #888; } - } - @media screen and (max-width: @media-not-big) { position: relative; height: auto; - top: -10px; } .buttons { margin-top: 15px; } } -p.buttons, div.buttons { - text-align: center; - button { - font-weight: bold; - cursor: pointer; - margin-top: 10px; - } - .dropdown-bar { - margin-left: 4px; - } -} #fileManagerIframe { width: 100%; diff --git a/customize.dist/src/less/footer.less b/customize.dist/src/less/footer.less index 6b13ea4e0..a26d35c37 100644 --- a/customize.dist/src/less/footer.less +++ b/customize.dist/src/less/footer.less @@ -1,20 +1,21 @@ @import "./variables.less"; .cp footer { - background: @dark-base; + background: @category-bg; font-family: -apple-system,system-ui,BlinkMacSystemFont,"Segoe UI",Roboto,"Helvetica Neue",Arial,sans-serif; padding-top: 1em; + font-size: 1.2em; a { - color: #555; + color: @cp-link; &:visited { - color: #777; + color: @cp-link-visited; } &:hover { - color: #333; + color: @cp-link-hover; } } li:first-child { + font-size: 1.2em; font-weight: bold; - text-decoration: underline; } } diff --git a/customize.dist/src/less/topbar.less b/customize.dist/src/less/topbar.less index 600031d00..dc1890d04 100644 --- a/customize.dist/src/less/topbar.less +++ b/customize.dist/src/less/topbar.less @@ -50,11 +50,15 @@ a { font-weight: 500; font-size: 0.75em; - color: @cp-purple; + color: @cp-link; &:hover { + color: @cp-link-hover; text-decoration: underline; } + &:visited { + color: @cp-link-visited; + } } } } diff --git a/customize.dist/src/less/variables.less b/customize.dist/src/less/variables.less index d3a9c81bb..5e8700f0b 100644 --- a/customize.dist/src/less/variables.less +++ b/customize.dist/src/less/variables.less @@ -24,6 +24,11 @@ @page-white: #fafafa; +// links +@cp-link: @cp-light-blue; +@cp-link-visited: @cp-light-blue; +@cp-link-hover: darken(@cp-light-blue, 10%) !important; + // alertify things @box-shadow: 0 2px 5px 0 rgba(0,0,0,.2); @@ -88,3 +93,4 @@ @main-color: #fff; @main-bg: url('/customize/bg3.jpg') no-repeat center center; +@category-bg: #f4f4f4; diff --git a/customize.dist/terms.html b/customize.dist/terms.html index 014148e9a..15497e4cc 100644 --- a/customize.dist/terms.html +++ b/customize.dist/terms.html @@ -82,20 +82,20 @@
      -
    • CryptPad
    • -
    • -
    • -
    • +
    • CryptPad
    • +
    • +
    • +
    • -
    • -
    • -
    • -
    • +
    • +
    • +
    • +
    @@ -112,7 +112,7 @@
  • IRC
  • Twitter
  • GitHub
  • -
  • Email
  • +
  • Email
  • diff --git a/customize.dist/translations/messages.de.js b/customize.dist/translations/messages.de.js index 8b1139836..5915b4684 100644 --- a/customize.dist/translations/messages.de.js +++ b/customize.dist/translations/messages.de.js @@ -103,8 +103,6 @@ out.notifyRenamed = "{0} heißt nun {1}"; out.notifyLeft = "{0} hat die gemeinsame Sitzung verlassen"; - out.disconnectAlert = 'Netzwerkverbindung verloren!'; - out.tryIt = 'Probier\'s aus!'; out.recentPads = 'Deine letzten Pads (diese Liste ist nur in deinem Browser gespeichert))'; diff --git a/customize.dist/translations/messages.es.js b/customize.dist/translations/messages.es.js index e6f8460bb..be6f87b29 100644 --- a/customize.dist/translations/messages.es.js +++ b/customize.dist/translations/messages.es.js @@ -100,8 +100,6 @@ define(function () { out.notifyRenamed = "{0} ahora se conoce como {1}"; out.notifyLeft = "{0} ha dejado la sesión de colaboración"; - out.disconnectAlert = '¡Conexión a la red perdida!'; - out.tryIt = '¡PROBARLO!'; out.recentPads = 'Tus documentos recientes (almacenadas solo en el navegador)'; diff --git a/customize.dist/translations/messages.fr.js b/customize.dist/translations/messages.fr.js index 1bc60132e..89237f351 100644 --- a/customize.dist/translations/messages.fr.js +++ b/customize.dist/translations/messages.fr.js @@ -118,8 +118,6 @@ define(function () { out.notifyRenamed = "{0} a changé son nom en {1}"; out.notifyLeft = "{0} a quitté la session collaborative"; - out.disconnectAlert = 'Perte de la connexion au réseau !'; - out.okButton = 'OK (Entrée)'; out.cancel = "Annuler"; @@ -244,7 +242,8 @@ define(function () { // login out.login_login = "Connexion"; - out.login_nologin = "Documents récents de ce navigateur"; + out.login_makeAPad = 'Créer un document anonymement'; + out.login_nologin = "Voir les documents récents"; out.login_register = "Inscription"; out.logoutButton = "Déconnexion"; @@ -253,9 +252,9 @@ define(function () { out.username_label = "Nom d'utilisateur : "; out.displayname_label = "Nom affiché : "; - out.login_username = "votre nom d'utilisateur"; - out.login_password = "votre mot de passe"; - out.login_confirm = "confirmer votre mot de passe"; + out.login_username = "Nom d'utilisateur"; + out.login_password = "Mot de passe"; + out.login_confirm = "Confirmer votre mot de passe"; out.login_remember = "Se souvenir de moi"; out.login_cancel_prompt = "...ou si vous avez entré le mauvais nom d'utilisateur ou mot de passe, annulez pour essayer à nouveau."; @@ -281,11 +280,12 @@ define(function () { out.login_hello = 'Bonjour {0},'; // {0} is the username out.login_helloNoName = 'Bonjour,'; out.login_accessDrive = 'Accédez à votre drive'; + out.login_orNoLogin = 'ou'; // index.html //out.main_p1 = 'CryptPad est l\'éditeur collaboratif en temps réel zero knowledge. Le chiffrement est effectué depuis votre navigateur, ce qui protège les données contre le serveur, le cloud, et la NSA. La clé de chiffrement est stockée dans l\'identifieur de fragment de l\'URL qui n\'est jamais envoyée au serveur mais est accessible depuis javascript, de sorte qu\'en partageant l\'URL, vous donnez l\'accès au pad à ceux qui souhaitent participer.'; - out.main_p1 = "

    Collaborez en tout confiance


    Développez vos idées collaborativement grâce à des documents partagés en temps-réel, tout en gardant vos données personnelles invisibles, même pour nous, avec la technologie Zero Knowledge."; + out.main_p1 = "

    Collaborez avec confiance


    Développez vos idées en groupe avec des documents partagés; la technologie Zero Knowledge sécurise vos données."; out.main_p2 = 'Ce projet utilise l\'éditeur visuel (WYSIWYG) CKEditor, l\'éditeur de code source CodeMirror, et le moteur temps-réel ChainPad.'; out.main_howitworks_p1 = 'CryptPad utilise une variante de l\'algorithme d\'Operational transformation qui est capable de trouver un consensus distribué en utilisant une chaîne de bloc Nakamoto, un outil popularisé par le Bitcoin. De cette manière, l\'algorithme évite la nécessité d\'utiliser un serveur central pour résoudre les conflits d\'édition de l\'Operational Transformation, et sans ce besoin de résolution des conflits le serveur peut rester ignorant du contenu qui est édité dans le pad.'; out.main_about = 'À propos'; @@ -295,9 +295,9 @@ define(function () { out.main_howitworks = 'Comment ça fonctionne'; out.main_zeroKnowledge = 'Zero Knowledge'; - out.main_zeroKnowledge_p = "Vous n'avez pas besoin de croire que nous n'allons pas regarder vos documents. Avec la technologie Zero Knowledge de Cryptpad, nous ne pouvons pas le faire. Apprenez-en plus sur notre manière de protéger vos données."; - out.main_jotItDown = 'Prenez-en note'; - out.main_jotItDown_p = "Les plus grands projets naissent des plus petites idées. Prenez note de vos moments d'inspiration et de vos idées inattendues car vous ne savez pas lesquels seront des découvertes capitales."; + out.main_zeroKnowledge_p = "Vous n'avez pas besoin de croire que nous n'allons pas regarder vos documents. Avec la technologie Zero Knowledge de Cryptpad, nous ne pouvons pas le faire. Apprenez-en plus sur notre manière de protéger vos données."; + out.main_writeItDown = 'Prenez-en note'; + out.main_writeItDown_p = "Les plus grands projets naissent des plus petites idées. Prenez note de vos moments d'inspiration et de vos idées inattendues car vous ne savez pas lesquels seront des découvertes capitales."; out.main_share = 'Partager le lien, partager le document'; out.main_share_p = "Faites croître vos idées à plusieurs : réalisez des réunions efficaes, collaborez sur vos listes de tâches et réalisez des présentations rapide avec tous vos amis sur tous vos appareils."; out.main_organize = 'Soyez organisés'; @@ -322,7 +322,6 @@ define(function () { out.table_created = 'Créé le'; out.table_last = 'Dernier accès'; - out.makeAPad = 'Créer un document'; out.button_newpad = 'Nouveau document texte'; out.button_newcode = 'Nouvelle page de code'; out.button_newpoll = 'Nouveau sondage'; diff --git a/customize.dist/translations/messages.js b/customize.dist/translations/messages.js index ee09575e7..a93110b84 100644 --- a/customize.dist/translations/messages.js +++ b/customize.dist/translations/messages.js @@ -122,8 +122,6 @@ define(function () { out.notifyRenamed = "{0} is now known as {1}"; out.notifyLeft = "{0} has left the collaborative session"; - out.disconnectAlert = 'Network connection lost!'; - out.okButton = 'OK (enter)'; out.cancel = "Cancel"; @@ -245,7 +243,8 @@ define(function () { // login out.login_login = "Log in"; - out.login_nologin = "Your browser's recent pads"; + out.login_makeAPad = 'Create a pad anonymously'; + out.login_nologin = "Browse local pads"; out.login_register = "Sign up"; out.logoutButton = "Log out"; @@ -254,9 +253,9 @@ define(function () { out.username_label = "Username: "; out.displayname_label = "Display name: "; - out.login_username = "your username"; - out.login_password = "your password"; - out.login_confirm = "confirm your password"; + out.login_username = "Username"; + out.login_password = "Password"; + out.login_confirm = "Confirm your password"; out.login_remember = "Remember me"; out.login_cancel_prompt = "...or if you may have entered the wrong username or password, cancel to try again."; @@ -282,6 +281,7 @@ define(function () { out.login_hello = 'Hello {0},'; // {0} is the username out.login_helloNoName = 'Hello,'; out.login_accessDrive = 'Access your drive'; + out.login_orNoLogin = 'or'; // index.html @@ -298,7 +298,7 @@ define(function () { out.main_howitworks = 'How It Works'; out.main_zeroKnowledge = 'Zero Knowledge'; - out.main_zeroKnowledge_p = "You don't have to trust that we won't look at your pads, with CryptPad's revolutionary Zero Knowledge Technology we can't. Learn more about how we protect your Privacy and Security."; + out.main_zeroKnowledge_p = "You don't have to trust that we won't look at your pads, with CryptPad's revolutionary Zero Knowledge Technology we can't. Learn more about how we protect your Privacy and Security."; out.main_writeItDown = 'Write it down'; out.main_writeItDown_p = "The greatest projects come from the smallest ideas. Take down the moments of inspiration and unexpected ideas because you never know which one might be a breakthrough."; out.main_share = 'Share the link, share the pad'; @@ -325,7 +325,6 @@ define(function () { out.table_created = 'Created'; out.table_last = 'Last Accessed'; - out.makeAPad = 'Make a pad right now'; out.button_newpad = 'New Rich Text pad'; out.button_newcode = 'New Code pad'; out.button_newpoll = 'New Poll'; diff --git a/customize.dist/translations/messages.pl.js b/customize.dist/translations/messages.pl.js index 65e0c2abf..de4a20a38 100644 --- a/customize.dist/translations/messages.pl.js +++ b/customize.dist/translations/messages.pl.js @@ -102,8 +102,6 @@ define(function () { out.notifyRenamed = "{0} jest teraz znany jako {1}"; out.notifyLeft = "{0} opuścił sesję współpracy"; - out.disconnectAlert = 'Utracono połączenie sieciowe!'; - out.tryIt = 'Wypróbuj!'; out.recentPads = 'Ostatnio otwarte dokumenty (przechowywane jedynie w twojej przeglądarce)'; diff --git a/customize.dist/translations/messages.pt-br.js b/customize.dist/translations/messages.pt-br.js index a2aaec567..ba737b62f 100644 --- a/customize.dist/translations/messages.pt-br.js +++ b/customize.dist/translations/messages.pt-br.js @@ -110,8 +110,6 @@ define(function () { out.notifyRenamed = "{0} agora é conhecido como {1}"; out.notifyLeft = "{0} deixou essa sessão colaborativa"; - out.disconnectAlert = 'Conexão de rede perdida!'; - out.tryIt = 'Experimente!'; out.recentPads = 'Seu bloco de nota recente (armazenado em seu navegador)'; diff --git a/www/code/main.js b/www/code/main.js index ba1208a2d..92c63560c 100644 --- a/www/code/main.js +++ b/www/code/main.js @@ -699,7 +699,7 @@ define([ // inform of network disconnect setEditable(false); toolbar.failed(); - Cryptpad.alert(Messages.disconnectAlert); + Cryptpad.alert(Messages.common_connectionLost); }; var onConnectionChange = config.onConnectionChange = function (info) { @@ -710,7 +710,7 @@ define([ toolbar.reconnecting(info.myId); Cryptpad.findOKButton().click(); } else { - Cryptpad.alert(Messages.disconnectAlert); + Cryptpad.alert(Messages.common_connectionLost); } }; diff --git a/www/user/credential.js b/www/common/credential.js similarity index 100% rename from www/user/credential.js rename to www/common/credential.js diff --git a/www/common/cryptpad-common.js b/www/common/cryptpad-common.js index ff2943c16..bc41fc4e5 100644 --- a/www/common/cryptpad-common.js +++ b/www/common/cryptpad-common.js @@ -1,7 +1,7 @@ define([ '/api/config?cb=' + Math.random().toString(16).slice(2), '/customize/messages.js', - '/customize/store.js', + '/customize/fsStore.js', '/bower_components/chainpad-crypto/crypto.js', '/bower_components/alertifyjs/dist/js/alertify.js', '/bower_components/spin.js/spin.min.js', @@ -10,7 +10,7 @@ define([ '/customize/application_config.js', '/bower_components/jquery/dist/jquery.min.js', -], function (Config, Messages, Store, Crypto, Alertify, Spinner, Clipboard, FS, AppConfig) { +], function (Config, Messages, Store, Crypto, Alertify, Spinner, Clipboard, AppConfig) { /* This file exposes functionality which is specific to Cryptpad, but not to any particular pad type. This includes functions for committing metadata about pads to your local storage for future use and improved usability. @@ -19,18 +19,11 @@ define([ */ var $ = window.jQuery; - // When set to true, USE_FS_STORE becomes the default store, but the localStorage store is - // still loaded for migration purpose. When false, the localStorage is used. - var USE_FS_STORE = AppConfig.USE_FS_STORE; - - var storeToUse = USE_FS_STORE ? FS : Store; - var common = window.Cryptpad = { Messages: Messages, Alertify: Alertify, }; var store; - var fsStore; var find = common.find = function (map, path) { return (map && path.reduce(function (p, n) { @@ -38,15 +31,14 @@ define([ }, map)); }; - var getStore = common.getStore = function (legacy) { - if ((!USE_FS_STORE || legacy) && store) { return store; } - if (USE_FS_STORE && !legacy && fsStore) { return fsStore; } + var getStore = common.getStore = function () { + if (store) { return store; } throw new Error("Store is not ready!"); }; var getNetwork = common.getNetwork = function () { - if (USE_FS_STORE && fsStore) { - if (fsStore.getProxy() && fsStore.getProxy().info) { - return fsStore.getProxy().info.network; + if (store) { + if (store.getProxy() && store.getProxy().info) { + return store.getProxy().info.network; } } return; @@ -131,7 +123,6 @@ define([ }; var isLoggedIn = common.isLoggedIn = function () { - //return typeof getStore().getLoginName() === "string"; return typeof getUserHash() === "string"; }; @@ -373,6 +364,23 @@ define([ }); }; + // Get the pads from localStorage to migrate them to the object store + var getLegacyPads = common.getLegacyPads = function (cb) { + require(['/customize/store.js'], function(Legacy) { + Legacy.ready(function (err, legacy) { + if (err) { cb(err, null); return; } + Legacy.get(storageKey, function (err2, recentPads) { + if (err2) { cb(err2, null); return; } + if (isArray(recentPads)) { + cb(void 0, migrateRecentPads(recentPads)); + return; + } + cb(void 0, []); + }); + }); + }); + }; + var getHash = common.getHash = function () { return window.location.hash.slice(1); }; @@ -446,13 +454,13 @@ define([ }; // STORAGE - var setPadAttribute = common.setPadAttribute = function (attr, value, cb, legacy) { - getStore(legacy).setDrive([getHash(), attr].join('.'), value, function (err, data) { + var setPadAttribute = common.setPadAttribute = function (attr, value, cb) { + getStore().setDrive([getHash(), attr].join('.'), value, function (err, data) { cb(err, data); }); }; - var setAttribute = common.setAttribute = function (attr, value, cb, legacy) { - getStore(legacy).set(["cryptpad", attr].join('.'), value, function (err, data) { + var setAttribute = common.setAttribute = function (attr, value, cb) { + getStore().set(["cryptpad", attr].join('.'), value, function (err, data) { cb(err, data); }); }; @@ -461,13 +469,13 @@ define([ }; // STORAGE - var getPadAttribute = common.getPadAttribute = function (attr, cb, legacy) { - getStore(legacy).getDrive([getHash(), attr].join('.'), function (err, data) { + var getPadAttribute = common.getPadAttribute = function (attr, cb) { + getStore().getDrive([getHash(), attr].join('.'), function (err, data) { cb(err, data); }); }; - var getAttribute = common.getAttribute = function (attr, cb, legacy) { - getStore(legacy).get(["cryptpad", attr].join('.'), function (err, data) { + var getAttribute = common.getAttribute = function (attr, cb) { + getStore().get(["cryptpad", attr].join('.'), function (err, data) { cb(err, data); }); }; @@ -493,12 +501,8 @@ define([ // STORAGE /* fetch and migrate your pad history from localStorage */ - var getRecentPads = common.getRecentPads = function (cb, legacy) { - var sstore = getStore(legacy); - if (legacy) { - sstore.getDrive = sstore.get; - } - sstore.getDrive(storageKey, function (err, recentPads) { + var getRecentPads = common.getRecentPads = function (cb) { + getStore().getDrive(storageKey, function (err, recentPads) { if (isArray(recentPads)) { cb(void 0, migrateRecentPads(recentPads)); return; @@ -509,21 +513,14 @@ define([ // STORAGE /* commit a list of pads to localStorage */ - var setRecentPads = common.setRecentPads = function (pads, cb, legacy) { - var sstore = getStore(legacy); - if (legacy) { - sstore.setDrive = sstore.set; - } - sstore.setDrive(storageKey, pads, function (err, data) { + var setRecentPads = common.setRecentPads = function (pads, cb) { + getStore().setDrive(storageKey, pads, function (err, data) { cb(err, data); }); }; // STORAGE - var forgetFSPad = function (href, cb) { - getStore().forgetPad(href, cb); - }; - var forgetPad = common.forgetPad = function (href, cb, legacy) { + var forgetPad = common.forgetPad = function (href, cb) { var parsed = parsePadUrl(href); var callback = function (err, data) { @@ -532,7 +529,7 @@ define([ return; } - getStore(legacy).keys(function (err, keys) { + getStore().keys(function (err, keys) { if (err) { cb(err); return; @@ -545,35 +542,14 @@ define([ cb(); return; } - getStore(legacy).removeBatch(toRemove, function (err, data) { + getStore().removeBatch(toRemove, function (err, data) { cb(err, data); }); }); }; - if (USE_FS_STORE && !legacy) { - // TODO implement forgetPad in store.js - forgetFSPad(href, callback); - return; - } - - getRecentPads(function (err, recentPads) { - setRecentPads(recentPads.filter(function (pad) { - var p = parsePadUrl(pad.href); - // find duplicates - if (parsed.hash === p.hash && parsed.type === p.type) { - console.log("Found a duplicate"); - return; - } - return true; - }), callback, legacy); - }, legacy); - - - - if (typeof(getStore(legacy).forgetPad) === "function") { - // TODO implement forgetPad in store.js - getStore(legacy).forgetPad(href, callback); + if (typeof(getStore().forgetPad) === "function") { + getStore().forgetPad(href, callback); } }; @@ -626,7 +602,7 @@ define([ if (!contains) { var data = makePad(href, name); renamed.push(data); - if (USE_FS_STORE && typeof(getStore().addPad) === "function") { + if (typeof(getStore().addPad) === "function") { getStore().addPad(href, common.initialPath, common.initialName || name); } } @@ -701,58 +677,47 @@ define([ f(void 0, env); }; - var todo = function () { - storeToUse.ready(function (err, store) { - common.store = env.store = store; - if (USE_FS_STORE) { - fsStore = store; - } + Store.ready(function (err, storeObj) { + store = common.store = env.store = storeObj; - $(function() { - // Race condition : if document.body is undefined when alertify.js is loaded, Alertify - // won't work. We have to reset it now to make sure it uses a correct "body" - Alertify.reset(); + $(function() { + // Race condition : if document.body is undefined when alertify.js is loaded, Alertify + // won't work. We have to reset it now to make sure it uses a correct "body" + Alertify.reset(); - // Load the new pad when the hash has changed - var oldHash = document.location.hash.slice(1); - window.onhashchange = function () { - var newHash = document.location.hash.slice(1); - var parsedOld = parseHash(oldHash); - var parsedNew = parseHash(newHash); - if (parsedOld && parsedNew && ( - parsedOld.channel !== parsedNew.channel - || parsedOld.mode !== parsedNew.mode - || parsedOld.key !== parsedNew.key)) { - document.location.reload(); - return; - } - if (parsedNew) { - oldHash = newHash; - } - }; - - // Everything's ready, continue... - if($('#pad-iframe').length) { - var $iframe = $('#pad-iframe'); - var iframe = $iframe[0]; - var iframeDoc = iframe.contentDocument || iframe.contentWindow.document; - if (iframeDoc.readyState === 'complete') { - cb(); - return; - } - $iframe.load(cb); + // Load the new pad when the hash has changed + var oldHash = document.location.hash.slice(1); + window.onhashchange = function () { + var newHash = document.location.hash.slice(1); + var parsedOld = parseHash(oldHash); + var parsedNew = parseHash(newHash); + if (parsedOld && parsedNew && ( + parsedOld.channel !== parsedNew.channel + || parsedOld.mode !== parsedNew.mode + || parsedOld.key !== parsedNew.key)) { + document.location.reload(); return; } - cb(); - }); - }, common); - }; - // If we use the fs store, make sure the localStorage or iframe store is ready - if (USE_FS_STORE) { - Store.ready(todo); - return; - } - todo(); + if (parsedNew) { + oldHash = newHash; + } + }; + + // Everything's ready, continue... + if($('#pad-iframe').length) { + var $iframe = $('#pad-iframe'); + var iframe = $iframe[0]; + var iframeDoc = iframe.contentDocument || iframe.contentWindow.document; + if (iframeDoc.readyState === 'complete') { + cb(); + return; + } + $iframe.load(cb); + return; + } + cb(); + }); + }, common); }; var errorHandlers = []; @@ -1263,15 +1228,6 @@ define([ }; }; - // All code which is called implicitly is found below - Store.ready(function (err, Store) { - if (err) { - console.error(err); - return; - } - store = Store; - }); - $(function () { Messages._applyTranslation(); }); diff --git a/www/common/login.js b/www/common/login.js new file mode 100644 index 000000000..bf3848c70 --- /dev/null +++ b/www/common/login.js @@ -0,0 +1,112 @@ +define([ + '/bower_components/chainpad-listmap/chainpad-listmap.js', + '/bower_components/chainpad-crypto/crypto.js', + '/common/cryptpad-common.js', + '/common/credential.js', + '/bower_components/tweetnacl/nacl-fast.min.js', + '/bower_components/scrypt-async/scrypt-async.min.js', // better load speed + '/bower_components/jquery/dist/jquery.min.js', +], function (Listmap, Crypto, Cryptpad, Cred) { + var Exports = { + Cred: Cred, + }; + + var allocateBytes = function (bytes) { + var dispense = Cred.dispenser(bytes); + + var opt = {}; + + // dispense 18 bytes of entropy for your encryption key + var encryptionSeed = dispense(18); + // 16 bytes for a deterministic channel key + var channelSeed = dispense(16); + // 32 bytes for a curve key + var curveSeed = opt.curveSeed = dispense(32); + // 32 more for a signing key + var edSeed = opt.edSeed = dispense(32); + + var keys = opt.keys = Crypto.createEditCryptor(null, encryptionSeed); + + // 24 bytes of base64 + keys.editKeyStr = keys.editKeyStr.replace(/\//g, '-'); + + // 32 bytes of hex + var channelHex = opt.channelHex = Cryptpad.uint8ArrayToHex(channelSeed); + + // should never happen + if (channelHex.length !== 32) { throw new Error('invalid channel id'); } + + var channel64 = opt.channel64 = Cryptpad.hexToBase64(channelHex); + + var userHash = opt.userHash = '/1/edit/' + [opt.channel64, opt.keys.editKeyStr].join('/'); + + return opt; + }; + + var loadUserObject = function (opt, cb) { + var config = { + websocketURL: Cryptpad.getWebsocketURL(), + channel: opt.channelHex, + data: {}, + validateKey: opt.keys.validateKey, // derived validation key + crypto: Crypto.createEncryptor(opt.keys), + logLevel: 1, + }; + + var rt = opt.rt = Listmap.create(config); + rt.proxy + .on('ready', function (info) { + cb(void 0, rt); + }) + .on('disconnect', function (info) { + cb('E_DISCONNECT', info); + }); + }; + + var isProxyEmpty = function (proxy) { + return Object.keys(proxy).length === 0; + }; + + Exports.loginOrRegister = function (uname, passwd, isRegister, cb) { + if (typeof(cb) !== 'function') { return; } + + // validate inputs + if (!Cred.isValidUsername(uname)) { return void cb('INVAL_USER'); } + if (!Cred.isValidPassword(passwd)) { return void cb('INVAL_PASS'); } + + Cred.deriveFromPassphrase(uname, passwd, 128, function (bytes) { + // results... + var res = { + register: isRegister, + }; + + // run scrypt to derive the user's keys + var opt = res.opt = allocateBytes(bytes); + + // use the derived key to generate an object + loadUserObject(opt, function (err, rt) { + if (err) { return void cb(err); } + + res.proxy = rt.proxy; + res.realtime = rt.realtime; + res.network = rt.network; + + // they tried to just log in but there's no such user + if (!isRegister && isProxyEmpty(rt.proxy)) { + rt.network.disconnect(); // clean up after yourself + return void cb('NO_SUCH_USER', res); + } + + // they're registering... + + res.userHash = opt.userHash; + res.userName = uname; + //res.displayName // TODO + + cb(void 0, res); + }); + }); + }; + + return Exports; +}); diff --git a/www/drive/main.js b/www/drive/main.js index 6cbad00ec..83fc6eb26 100644 --- a/www/drive/main.js +++ b/www/drive/main.js @@ -9,8 +9,9 @@ define([ '/common/cryptpad-common.js', '/common/fileObject.js', '/common/toolbar.js', - '/customize/application_config.js' -], function (Config, Listmap, Crypto, TextPatcher, Messages, JSONSortify, Cryptpad, FO, Toolbar, AppConfig) { + '/customize/application_config.js', + '/common/cryptget.js' +], function (Config, Listmap, Crypto, TextPatcher, Messages, JSONSortify, Cryptpad, FO, Toolbar, AppConfig, Get) { var module = window.MODULE = {}; var $ = window.jQuery; @@ -1854,6 +1855,31 @@ define([ }); }; + // TODO: move that function and use a more generic API + var migrateAnonDrive = function (proxy, cb) { + if (sessionStorage.migrateAnonDrive) { + // Make sure we have an FS_hash and we don't use it, otherwise just stop the migration and cb + if (!localStorage.FS_hash || !APP.loggedIn) { + delete sessionStorage.migrateAnonDrive; + if (typeof(cb) === "function") { cb(); } + } + // Get the content of FS_hash and then merge the objects, remove the migration key and cb + var todo = function (err, doc) { + if (err) { logError("Cannot migrate recent pads", err); return; } + var parsed; + try { parsed = JSON.parse(doc); } catch (e) { logError("Cannot parsed recent pads", e); } + if (parsed) { + $.extend(true, proxy, parsed); + } + delete sessionStorage.migrateAnonDrive; + if (typeof(cb) === "function") { cb(); } + }; + Get.get(localStorage.FS_hash, todo); + } else { + if (typeof(cb) === "function") { cb(); } + } + }; + // don't initialize until the store is ready. Cryptpad.ready(function () { APP.$bar = $iframe.find('#toolbar'); @@ -1950,23 +1976,13 @@ define([ }; var onReady = function () { module.files = proxy; - if (JSON.stringify(proxy) === '{}') { - var store = Cryptpad.getStore(true); - var drive = proxy.drive = {}; - store.get(Cryptpad.storageKey, function (err, s) { - drive[FILES_DATA] = s; - initLocalStorage(); - init(proxy); - APP.userList.onChange(); - Cryptpad.removeLoadingScreen(); - }); - return; - } if (!proxy.drive || typeof(proxy.drive) !== 'object') { proxy.drive = {}; } - initLocalStorage(); - init(proxy); - APP.userList.onChange(); - Cryptpad.removeLoadingScreen(); + migrateAnonDrive(proxy, function () { + initLocalStorage(); + init(proxy); + APP.userList.onChange(); + Cryptpad.removeLoadingScreen(); + }); }; var onDisconnect = function (info) { setEditable(false); diff --git a/www/pad/main.js b/www/pad/main.js index 34a587afa..4ad0c207e 100644 --- a/www/pad/main.js +++ b/www/pad/main.js @@ -739,7 +739,7 @@ define([ setEditable(false); // TODO inform them that the session was torn down toolbar.failed(); - Cryptpad.alert(Messages.disconnectAlert); + Cryptpad.alert(Messages.common_connectionLost); }; var onConnectionChange = realtimeOptions.onConnectionChange = function (info) { @@ -750,7 +750,7 @@ define([ toolbar.reconnecting(info.myId); Cryptpad.findOKButton().click(); } else { - Cryptpad.alert(Messages.disconnectAlert); + Cryptpad.alert(Messages.common_connectionLost); } }; diff --git a/www/register/index.html b/www/register/index.html new file mode 100644 index 000000000..0976f9360 --- /dev/null +++ b/www/register/index.html @@ -0,0 +1,67 @@ + + + + + + Cryptpad: login + + + + + + +
    +
    + +
    +
    + + +
    +
    +
    + + +
    + diff --git a/www/register/main.js b/www/register/main.js new file mode 100644 index 000000000..5c42872bf --- /dev/null +++ b/www/register/main.js @@ -0,0 +1,43 @@ +define([ + '/common/login.js', + '/common/credential.js', + '/bower_components/jquery/dist/jquery.min.js', +], function (Login) { + var $ = window.jQuery; + + // text and password input fields + var $uname = $('#username'); + var $passwd = $('#password'); + var $confirm = $('#password-confirm'); + + // checkboxes + var $checkImport = $('#import-recent'); + var $checkAcceptTerms = $('#accept-terms'); + var $checkPromise = $('#promise'); + + var $register = $('button#register'); + + $register.click(function () { + var uname = $uname.val(); + var passwd = $passwd.val(); + var confirmPassword = $confirm.val(); + + var shouldImport = $checkImport[0].checked; + var doesAccept = $checkAcceptTerms[0].checked; + var doesPromise = $checkPromise[0].checked; + + /* basic validation */ + + // do their passwords match? + + if (passwd !== confirmPassword) { + alert('invalid password'); + return; + } + + Login.loginOrRegister(uname, passwd, true, function (err, out) { + if (err) { alert(err); } + console.log(out); + }) + }); +}); diff --git a/www/slide/main.js b/www/slide/main.js index 226e0249e..7c75a42ce 100644 --- a/www/slide/main.js +++ b/www/slide/main.js @@ -782,7 +782,7 @@ define([ // inform of network disconnect setEditable(false); toolbar.failed(); - Cryptpad.alert(Messages.disconnectAlert); + Cryptpad.alert(Messages.common_connectionLost); }; var onConnectionChange = config.onConnectionChange = function (info) { @@ -793,7 +793,7 @@ define([ toolbar.reconnecting(info.myId); Cryptpad.findOKButton().click(); } else { - Cryptpad.alert(Messages.disconnectAlert); + Cryptpad.alert(Messages.common_connectionLost); } }; diff --git a/www/user/main.js b/www/user/main.js index 039316ef5..8d86d6b9c 100644 --- a/www/user/main.js +++ b/www/user/main.js @@ -1,13 +1,13 @@ define([ - '/api/config?cb=' + Math.random().toString(16).substring(2), '/bower_components/chainpad-listmap/chainpad-listmap.js', '/bower_components/chainpad-crypto/crypto.js', '/common/cryptpad-common.js', - 'credential.js', + '/common/credential.js', + '/common/login.js', '/bower_components/tweetnacl/nacl-fast.min.js', '/bower_components/scrypt-async/scrypt-async.min.js', // better load speed '/bower_components/jquery/dist/jquery.min.js', -], function (Config, Listmap, Crypto, Cryptpad, Cred) { +], function (Listmap, Crypto, Cryptpad, Cred, Login) { var $ = window.jQuery; var Nacl = window.nacl; @@ -16,6 +16,7 @@ define([ var APP = window.APP = { Cryptpad: Cryptpad, Crypto: Crypto, + Login: Login, }; // login elements @@ -161,6 +162,9 @@ define([ }); }; + addEnterListener($confirm, function () { + $register.click(); + }); addEnterListener($password_register, function () { $login.click(); }); @@ -354,7 +358,9 @@ define([ APP.setNotice(Cryptpad.Messages.login_hashing); + // inform the user that we're hashing their password revealNotice(true); + revealLogin(false, function () { window.setTimeout(function () { resetUI();