diff --git a/customize.dist/main.css b/customize.dist/main.css index d54ec6a98..0f2de7ab9 100644 --- a/customize.dist/main.css +++ b/customize.dist/main.css @@ -413,6 +413,7 @@ font-family: FontAwesome; } .dropdown-bar button .fa-caret-down { + margin-right: 0px; margin-left: 5px; } .dropdown-bar .dropdown-bar-content { diff --git a/customize.dist/src/less/dropdown.less b/customize.dist/src/less/dropdown.less index 79a7edbec..2d93bba8b 100644 --- a/customize.dist/src/less/dropdown.less +++ b/customize.dist/src/less/dropdown.less @@ -18,6 +18,7 @@ button { .fa-caret-down{ + margin-right: 0px; margin-left: 5px; } } diff --git a/customize.dist/src/less/toolbar.less b/customize.dist/src/less/toolbar.less index a199730cd..15ab91911 100644 --- a/customize.dist/src/less/toolbar.less +++ b/customize.dist/src/less/toolbar.less @@ -28,7 +28,10 @@ box-sizing: border-box; padding: 0px 6px; - .fa {font-family: FontAwesome;} + .fa { + font: normal normal normal 14px/1 FontAwesome; + font-family: FontAwesome; + } .unselectable; @@ -42,6 +45,10 @@ } button { + font: @toolbar-button-font; + * { + font: @toolbar-button-font; + } &#shareButton, &.buttonSuccess { // Bootstrap 4 colors color: #fff; @@ -83,7 +90,7 @@ // Bootstrap 4 colors (btn-secondary) border: 1px solid transparent; border-radius: .25rem; - color: #292b2c; + color: #000; background-color: #fff; border-color: #ccc; &:hover { @@ -165,6 +172,7 @@ margin: 3px; vertical-align: top; box-sizing: content-box; + text-align: center; span { display: inline-block; width: 4px; @@ -232,6 +240,7 @@ padding-right: 5px; padding-left: 5px; margin: 3px 2px; + box-sizing: border-box; } .dropdown-bar-content { @@ -492,6 +501,7 @@ margin: 8px; line-height: 16px; font-size: 16px; + text-align: center; } .cryptpad-readonly { margin-right: 5px; diff --git a/customize.dist/src/less/variables.less b/customize.dist/src/less/variables.less index 8a0b4222e..43bcb393b 100644 --- a/customize.dist/src/less/variables.less +++ b/customize.dist/src/less/variables.less @@ -72,6 +72,7 @@ @toolbar-gradient-start: #f5f5f5; @toolbar-gradient-end: #DDDDDD; +@toolbar-button-font: 12px Ubuntu, Arial, sans-serif; @topbar-back: #fff; @topbar-color: #000; diff --git a/customize.dist/toolbar.css b/customize.dist/toolbar.css index d2385dfc1..3d7e0df0b 100644 --- a/customize.dist/toolbar.css +++ b/customize.dist/toolbar.css @@ -7,6 +7,7 @@ font-family: FontAwesome; } .dropdown-bar button .fa-caret-down { + margin-right: 0px; margin-left: 5px; } .dropdown-bar .dropdown-bar-content { @@ -112,18 +113,23 @@ z-index: 9001; } .cryptpad-toolbar .fa { + font: normal normal normal 14px/1 FontAwesome; font-family: FontAwesome; } .cryptpad-toolbar a { float: right; } .cryptpad-toolbar button { + font: 12px Ubuntu, Arial, sans-serif; border: 1px solid transparent; border-radius: .25rem; - color: #292b2c; + color: #000; background-color: #fff; border-color: #ccc; } +.cryptpad-toolbar button * { + font: 12px Ubuntu, Arial, sans-serif; +} .cryptpad-toolbar button#shareButton, .cryptpad-toolbar button.buttonSuccess { color: #fff; @@ -239,6 +245,7 @@ margin: 3px; vertical-align: top; box-sizing: content-box; + text-align: center; } .cryptpad-toolbar .cryptpad-lag span { display: inline-block; @@ -314,6 +321,7 @@ padding-right: 5px; padding-left: 5px; margin: 3px 2px; + box-sizing: border-box; } .cryptpad-toolbar .dropdown-bar-content { margin-top: -3px; @@ -566,6 +574,7 @@ margin: 8px; line-height: 16px; font-size: 16px; + text-align: center; } .cryptpad-readonly { margin-right: 5px; diff --git a/customize.dist/translations/messages.fr.js b/customize.dist/translations/messages.fr.js index e2bbdd082..e719a44d9 100644 --- a/customize.dist/translations/messages.fr.js +++ b/customize.dist/translations/messages.fr.js @@ -226,10 +226,16 @@ define(function () { out.fm_info_template = "Contient tous les fichiers que vous avez sauvés en tant que modèle afin de les réutiliser lors de la création d'un nouveau pad."; out.fm_info_trash = 'Les fichiers supprimés dans la corbeille sont également enlevés de "Tous les fichiers" et il est impossible de les récupérer depuis l\'explorateur de fichiers.'; // Same here for "All files" and "out.fm_filesDataName" out.fm_info_allFiles = 'Contient tous les fichiers de "Documents", "Fichiers non triés" et "Corbeille". Vous ne pouvez pas supprimer ou déplacer des fichiers depuis cet endroit.'; // Same here + out.fm_info_anonymous = 'Vous n\'êtes pas connectés, ces pads risquent donc d\'être supprimés (découvrez pourquoi). ' + + 'Inscrivez-vous ou connectez-vous pour les maintenir en vie.'; out.fm_alert_backupUrl = "Lien de secours pour ce disque.
" + "Il est fortement recommandé de garder ce lien pour vous-même.
" + "Elle vous servira en cas de perte des données de votre navigateur afin de retrouver vos fichiers.
" + "Quiconque se trouve en possession de celle-ci peut modifier ou supprimer tous les fichiers de ce gestionnaire.
"; + out.fm_alert_anonymous = "Bonjour ! Vous utilisez actuellement Cryptpad de manière anonyme, ce qui ne pose pas de problème mais vos pads peuvent être supprimés après un certain temps " + + "d'inactivité. Nous avons désactivé certaines fonctionnalités avancées de CryptDrive pour les utilisateurs anonymes afin de rendre clair le fait que ce n'est pas " + + 'un endroit sûr pour le stockage des documents. Vous pouvez en lire plus concernant ' + + 'nos raisons pour ces changements et pourquoi vous devriez vraiment vous enregistrer et vous connecter.'; out.fm_backup_title = 'Lien de secours'; out.fm_nameFile = 'Comment souhaitez-vous nommer ce fichier ?'; // File - Context menu diff --git a/customize.dist/translations/messages.js b/customize.dist/translations/messages.js index 15f5dfc2b..c6ae72ce5 100644 --- a/customize.dist/translations/messages.js +++ b/customize.dist/translations/messages.js @@ -228,10 +228,18 @@ define(function () { out.fm_info_template = 'Contains all the pads stored as templates and that you can re-use when you create a new pad.'; out.fm_info_trash = 'Files deleted from the trash are also removed from "All files" and it is impossible to recover them from the file manager.'; // Same here for "All files" and "out.fm_filesDataName" out.fm_info_allFiles = 'Contains all the files from "Documents", "Unsorted" and "Trash". You can\'t move or remove files from here.'; // Same here + out.fm_info_login = "Log in"; + out.fm_info_register = "Sign up"; + out.fm_info_anonymous = 'You are not logged in so these pads may be deleted (find out why). ' + + 'Sign up or Log in to keep them alive.'; out.fm_alert_backupUrl = "Backup link for this drive.
" + "It is highly recommended that you keep ip for yourself only.
" + "You can use it to retrieve all your files in case your browser memory got erased.
" + "Anybody with that link can edit or remove all the files in your file manager.
"; + out.fm_alert_anonymous = "Hello there, you are currently using CryptPad anonymously, that's ok but your pads may be deleted after a period of " + + "inactivity. We have disabled advanced features of the drive for anonymous users because we want to be clear that it is " + + 'not a safe place to store things. You can read more about ' + + 'why we are doing this and why you really should Sign up and Log in.'; out.fm_backup_title = 'Backup link'; out.fm_nameFile = 'How would you like to name that file?'; // File - Context menu diff --git a/www/common/common-hash.js b/www/common/common-hash.js index afb6bca2b..c6bf29ce9 100644 --- a/www/common/common-hash.js +++ b/www/common/common-hash.js @@ -1,8 +1,9 @@ define([ '/common/common-util.js', + '/common/common-interface.js', '/bower_components/chainpad-crypto/crypto.js', '/bower_components/tweetnacl/nacl-fast.min.js' -], function (Util, Crypto) { +], function (Util, UI, Crypto) { var Nacl = window.nacl; var Hash = {}; @@ -34,6 +35,9 @@ define([ var getFileHashFromKeys = Hash.getFileHashFromKeys = function (fileKey, cryptKey) { return '/1/' + hexToBase64(fileKey) + '/' + Crypto.b64RemoveSlashes(cryptKey) + '/'; }; + Hash.getUserHrefFromKeys = function (username, pubkey) { + return window.location.origin + '/user/#/1/' + username + '/' + pubkey.replace(/\//g, '-'); + }; var fixDuplicateSlashes = function (s) { return s.replace(/\/+/g, '/'); @@ -173,14 +177,14 @@ Version 1 secret.keys = Crypto.createEditCryptor(parsed.key); secret.key = secret.keys.editKeyStr; if (secret.channel.length !== 32 || secret.key.length !== 24) { - Hash.alert("The channel key and/or the encryption key is invalid"); + UI.alert("The channel key and/or the encryption key is invalid"); throw new Error("The channel key and/or the encryption key is invalid"); } } else if (parsed.mode === 'view') { secret.keys = Crypto.createViewCryptor(parsed.key); if (secret.channel.length !== 32) { - Hash.alert("The channel key is invalid"); + UI.alert("The channel key is invalid"); throw new Error("The channel key is invalid"); } } @@ -188,6 +192,9 @@ Version 1 // version 2 hashes are to be used for encrypted blobs secret.channel = parsed.channel; secret.keys = { fileKeyStr: parsed.key }; + } else if (parsed.type === "user") { + // version 2 hashes are to be used for encrypted blobs + throw new Error("User hashes can't be opened (yet)"); } } } diff --git a/www/common/cryptpad-common.js b/www/common/cryptpad-common.js index 91d000efb..4061f53fd 100644 --- a/www/common/cryptpad-common.js +++ b/www/common/cryptpad-common.js @@ -85,6 +85,7 @@ define([ common.getEditHashFromKeys = Hash.getEditHashFromKeys; common.getViewHashFromKeys = Hash.getViewHashFromKeys; common.getFileHashFromKeys = Hash.getFileHashFromKeys; + common.getUserHrefFromKeys = Hash.getUserHrefFromKeys; common.getSecrets = Hash.getSecrets; common.getHashes = Hash.getHashes; common.createChannelId = Hash.createChannelId; diff --git a/www/drive/file.css b/www/drive/file.css index 2f353a371..946167d43 100644 --- a/www/drive/file.css +++ b/www/drive/file.css @@ -259,6 +259,9 @@ span.fa-folder-open { margin-left: 10px; float: right; } +#content .info-box.noclose { + padding-right: 10px; +} #content li { cursor: default; } @@ -447,7 +450,7 @@ span.fa-folder-open { #driveToolbar { background: #ddd; color: #555; - height: 40px; + height: 30px; display: flex; flex-flow: row; border-top: 1px solid #ccc; @@ -455,6 +458,7 @@ span.fa-folder-open { box-shadow: 0 2px 4px rgba(0, 0, 0, 0.2); z-index: 100; box-sizing: content-box; + padding: 0 6px; /* The container
- needed to position the dropdown content */ } #driveToolbar .newPadContainer { @@ -462,24 +466,32 @@ span.fa-folder-open { height: 100%; } #driveToolbar button { - height: 30px; + height: 24px; + font: 12px Ubuntu, Arial, sans-serif; +} +#driveToolbar button span { + font: 12px Ubuntu, Arial, sans-serif; +} +#driveToolbar button .fa, +#driveToolbar button.fa { + font-family: FontAwesome; } #driveToolbar button.element { border-radius: 2px; background: #888; color: #eee; - font-size: 16px; - border: none; + font-size: 14px; + border: 1px solid #888; font-weight: bold; } #driveToolbar button.element:hover { - box-shadow: 0px 0px 2px #000; + background: #777; } #driveToolbar button.new { padding: 0 5px; } #driveToolbar .dropdown-bar { - margin: 5px 5px; + margin: 2px 2px; line-height: 1em; position: relative; display: inline-block; @@ -513,7 +525,7 @@ span.fa-folder-open { #driveToolbar .path { display: inline-block; height: 100%; - line-height: 40px; + line-height: 30px; cursor: default; width: auto; overflow: hidden; diff --git a/www/drive/file.less b/www/drive/file.less index 13a8adc6b..7ea8ecb97 100644 --- a/www/drive/file.less +++ b/www/drive/file.less @@ -1,3 +1,5 @@ +@import "../../customize.dist/src/less/variables.less"; + @tree-bg: #fff; @tree-fg: #000; @tree-lines-col: #888; @@ -17,6 +19,8 @@ @toolbar-fg: #555; @toolbar-border-col: #ccc; @toolbar-button-bg: #888; +@toolbar-button-border: #888; +@toolbar-button-bg-hover: #777; @toolbar-button-fg: #eee; @toolbar-path-bg: #fff; @toolbar-path-border: #888; @@ -303,6 +307,9 @@ span { margin-left: 10px; float: right; } + &.noclose { + padding-right: 10px; + } } li { cursor: default; @@ -512,7 +519,7 @@ span { #driveToolbar { background: @toolbar-bg; color: @toolbar-fg; - height: 40px; + height: 30px; display: flex; flex-flow: row; border-top: 1px solid @toolbar-border-col; @@ -520,6 +527,7 @@ span { box-shadow: 0 2px 4px rgba(0,0,0,0.2); z-index: 100; box-sizing: content-box; + padding: 0 6px; .newPadContainer { display: inline-block; @@ -527,16 +535,23 @@ span { } button { - height: 30px; + height: 24px; + font: @toolbar-button-font; + span { + font: @toolbar-button-font; + } + .fa, &.fa { + font-family: FontAwesome; + } &.element { border-radius: 2px; background: @toolbar-button-bg; color: @toolbar-button-fg; - font-size: 16px; - border: none; + font-size: 14px; + border: 1px solid @toolbar-button-border; font-weight: bold; &:hover { - box-shadow: 0px 0px 2px #000; + background: @toolbar-button-bg-hover; } } &.new { @@ -545,7 +560,7 @@ span { } /* The container
- needed to position the dropdown content */ .dropdown-bar { - margin: 5px 5px; + margin: 2px 2px; line-height: 1em; position: relative; display: inline-block; @@ -580,7 +595,7 @@ span { .path { display: inline-block; height: 100%; - line-height: 40px; + line-height: 30px; cursor: default; width: auto; overflow: hidden; diff --git a/www/drive/main.js b/www/drive/main.js index 27671f54e..af2974767 100644 --- a/www/drive/main.js +++ b/www/drive/main.js @@ -226,9 +226,14 @@ define([ if (AppConfig.enableTemplates) { displayedCategories.push(TEMPLATE); } if (isWorkgroup()) { displayedCategories = [ROOT, TRASH, SEARCH]; } - if (!Cryptpad.isLoggedIn()) { + if (!APP.loggedIn) { displayedCategories = [FILES_DATA]; currentPath = [FILES_DATA]; + $tree.hide(); + if (Object.keys(files.root).length && !proxy.anonymousAlert) { + Cryptpad.alert(Messages.fm_alert_anonymous, null, true); + proxy.anonymousAlert = true; + } } if (!APP.readOnly) { @@ -607,7 +612,6 @@ define([ } hasFolder = true; hide.push($menu.find('a.open_ro')); - // TODO: folder properties in the future? hide.push($menu.find('a.properties')); } // If we're in the trash, hide restore and properties for non-root elements @@ -1292,6 +1296,12 @@ define([ default: msg = undefined; } + if (!APP.loggedIn) { + msg = Messages.fm_info_anonymous; + $box.html(msg); + $box.addClass('noclose'); + return $box; + } if (!msg || Cryptpad.getLSAttribute('hide-info-' + path[0]) === '1') { $box.hide(); } else { @@ -2200,7 +2210,7 @@ define([ .appendTo($d); } - if (Cryptpad.isLoggedIn() && AppConfig.enablePinning) { + if (APP.loggedIn && AppConfig.enablePinning) { // check the size of this file... Cryptpad.getFileSize(el, function (e, bytes) { if (e) { @@ -2315,8 +2325,7 @@ define([ else if ($(this).hasClass('delete')) { var pathsList = []; paths.forEach(function (p) { pathsList.push(p.path); }); - if (!Cryptpad.isLoggedIn()) { - console.log(paths); + if (!APP.loggedIn) { var msg = Messages._getKey("fm_removeSeveralPermanentlyDialog", [paths.length]); if (paths.length === 1) { msg = Messages.fm_removePermanentlyDialog; @@ -2450,7 +2459,7 @@ define([ $appContainer.on('keydown', function (e) { // "Del" if (e.which === 46) { - if (filesOp.isPathIn(currentPath, [FILES_DATA]) && Cryptpad.isLoggedIn()) { + if (filesOp.isPathIn(currentPath, [FILES_DATA]) && APP.loggedIn) { return; // We can't remove elements directly from filesData } var $selected = $iframe.find('.selected'); @@ -2462,7 +2471,7 @@ define([ paths.push($(elmt).data('path')); }); // If we are in the trash or anon pad or if we are holding the "shift" key, delete permanently, - if (!Cryptpad.isLoggedIn() || isTrash || e.shiftKey) { + if (!APP.loggedIn || isTrash || e.shiftKey) { var msg = Messages._getKey("fm_removeSeveralPermanentlyDialog", [paths.length]); if (paths.length === 1) { msg = Messages.fm_removePermanentlyDialog; @@ -2616,7 +2625,7 @@ define([ // don't initialize until the store is ready. Cryptpad.ready(function () { Cryptpad.reportAppUsage(); - if (!Cryptpad.isLoggedIn()) { Cryptpad.feedback('ANONYMOUS_DRIVE'); } + if (!APP.loggedIn) { Cryptpad.feedback('ANONYMOUS_DRIVE'); } APP.$bar = $iframe.find('#toolbar'); var storeObj = Cryptpad.getStore().getProxy && Cryptpad.getStore().getProxy().proxy ? Cryptpad.getStore().getProxy() : undefined; @@ -2752,6 +2761,7 @@ define([ }; var $hist = Cryptpad.createButton('history', true, {histConfig: histConfig}); $rightside.append($hist); + if (!APP.loggedIn) { $hist.hide(); } if (!readOnly && !APP.loggedIn) { var $backupButton = Cryptpad.createButton('', true).removeClass('fa').removeClass('fa-question'); diff --git a/www/pad/inner.html b/www/pad/inner.html index 9d649f85e..c43af938c 100644 --- a/www/pad/inner.html +++ b/www/pad/inner.html @@ -12,6 +12,7 @@ } #cke_1_top { overflow: visible; + padding: 0 6px; } #cke_1_toolbox { display: inline-block; diff --git a/www/settings/main.js b/www/settings/main.js index 7abff2e85..6a14fe819 100644 --- a/www/settings/main.js +++ b/www/settings/main.js @@ -49,13 +49,14 @@ define([ var publicKey = obj.edPublic; if (publicKey) { + var userHref = Cryptpad.getUserHrefFromKeys(accountName, publicKey); var $pubLabel = $('', {'class': 'label'}) .text(Messages.settings_publicSigningKey + ':'); var $pubKey = $('', {type: 'text', readonly: true}) .css({ width: '28em' }) - .val(publicKey); + .val(userHref); $div.append('
').append($pubLabel).append($pubKey); }