diff --git a/CHANGELOG.md b/CHANGELOG.md index 93433b97..f249b1c7 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -3,6 +3,7 @@ * **next (not yet released)** * ADDED: Translations for Italian * ADDED: Loading message displayed until decryption succeeded for slower (in terms of CPU or network) systems + * CHANGED: Using modal dialog to request password input instead of native JS input window (#69) * CHANGED: Suppressed referrer HTTP header sending when following links in a paste or comment (#96) and added additional HTTP headers for XSS mitigation (#91) * CHANGED: Updated random_compat and jQuery libraries * **1.0 (2016-08-25)** diff --git a/CREDITS.md b/CREDITS.md index e6bf6136..6170a2ed 100644 --- a/CREDITS.md +++ b/CREDITS.md @@ -20,6 +20,7 @@ Sébastien Sauvage - original idea and main developer * rugk - new logo/icons * Sobak - PSR-4 and PSR-2 refactoring * Nathaniel Olsen - jQuery upgrade +* Alexander Demenshin - modal password dialog ## Translations * Hexalyse - French diff --git a/i18n/de.json b/i18n/de.json index eaafd086..5d274de1 100644 --- a/i18n/de.json +++ b/i18n/de.json @@ -141,5 +141,9 @@ "Preview": "Vorschau", "PrivateBin requires the PATH to end in a \"%s\". Please update the PATH in your index.php.": "Der PATH muss bei PrivateBin mit einem \"%s\" enden. Bitte passe Deinen PATH in Deiner index.php an.", + "Decrypt": + "Entschlüsseln", + "Enter password": + "Passwort eingeben", "Loading…": "Lädt…" } diff --git a/i18n/fr.json b/i18n/fr.json index 586c0f98..9652f43a 100644 --- a/i18n/fr.json +++ b/i18n/fr.json @@ -150,5 +150,9 @@ "Preview": "Prévisualiser", "PrivateBin requires the PATH to end in a \"%s\". Please update the PATH in your index.php.": "PrivateBin requires the PATH to end in a \"%s\". Please update the PATH in your index.php.", + "Decrypt": + "Decrypt", + "Enter password": + "Entrez le mot de passe", "Loading…": "Loading…" } diff --git a/i18n/it.json b/i18n/it.json index e8c31023..a67528b1 100644 --- a/i18n/it.json +++ b/i18n/it.json @@ -79,7 +79,7 @@ "This document will expire in %d months.": ["Questo documento scadrà tra un mese.", "Questo documento scadrà in %d mesi."], "Please enter the password for this paste:": - "Inserisci la passowrd per questo messaggio:", + "Inserisci la password per questo messaggio:", "Could not decrypt data (Wrong key?)": "Non riesco a decifrari i dati (Chiave errata?)", "Could not delete the paste, it was not stored in burn after reading mode.": @@ -141,5 +141,9 @@ "Preview": "Preview", "PrivateBin requires the PATH to end in a \"%s\". Please update the PATH in your index.php.": "PrivateBin necessita che PATH termini con \"%s\". Aggiorna la variabile PATH nel tuo index.php.", + "Decrypt": + "Decrypt", + "Enter password": + "Inserisci la password", "Loading…": "Loading…" } diff --git a/i18n/pl.json b/i18n/pl.json index 1dd21e8d..54708dde 100644 --- a/i18n/pl.json +++ b/i18n/pl.json @@ -141,5 +141,9 @@ "Preview": "Zapowiedź", "PrivateBin requires the PATH to end in a \"%s\". Please update the PATH in your index.php.": "PrivateBin requires the PATH to end in a \"%s\". Please update the PATH in your index.php.", + "Decrypt": + "Decrypt", + "Enter password": + "Wpisz hasło", "Loading…": "Loading…" } diff --git a/i18n/sl.json b/i18n/sl.json index 06a51f0d..c5cc0adf 100644 --- a/i18n/sl.json +++ b/i18n/sl.json @@ -150,5 +150,9 @@ "Preview": "Predogled", "PrivateBin requires the PATH to end in a \"%s\". Please update the PATH in your index.php.": "PrivateBin requires the PATH to end in a \"%s\". Please update the PATH in your index.php.", + "Decrypt": + "Decrypt", + "Enter password": + "Prosim vnesi geslo", "Loading…": "Loading…" } diff --git a/i18n/zh.json b/i18n/zh.json index aa03c25a..9b748e20 100644 --- a/i18n/zh.json +++ b/i18n/zh.json @@ -141,5 +141,9 @@ "Preview": "預習", "PrivateBin requires the PATH to end in a \"%s\". Please update the PATH in your index.php.": "PrivateBin requires the PATH to end in a \"%s\". Please update the PATH in your index.php.", + "Decrypt": + "Decrypt", + "Enter password": + "Enter password", "Loading…": "Loading…" } diff --git a/js/privatebin.js b/js/privatebin.js index faf09602..8bfd7f75 100644 --- a/js/privatebin.js +++ b/js/privatebin.js @@ -611,23 +611,26 @@ $(function() { }, /** - * ask the user for the password and return it - * - * @throws error when dialog canceled - * @return string password + * ask the user for the password and set it */ requestPassword: function() { - var password = prompt(i18n._('Please enter the password for this paste:'), ''); - if (password === null) - { - throw 'password prompt canceled'; + if (this.passwordModal.length === 0) { + var password = prompt(i18n._('Please enter the password for this paste:'), ''); + if (password === null) + { + throw 'password prompt canceled'; + } + if (password.length === 0) + { + this.requestPassword(); + } else { + this.passwordInput.val(password); + this.displayMessages(); + } + } else { + this.passwordModal.modal(); } - if (password.length === 0) - { - return this.requestPassword(); - } - return password; }, /** @@ -688,14 +691,15 @@ $(function() { /** * Show decrypted text in the display area, including discussion (if open) * - * @param string key : decryption key - * @param object paste : paste object including comments to display (items = array with keys ('data','meta') + * @param object paste (optional) object including comments to display (items = array with keys ('data','meta') */ - displayMessages: function(key, paste) + displayMessages: function(paste) { - // Try to decrypt the paste. + paste = paste || $.parseJSON(this.cipherData.text()); + var key = this.pageKey(); var password = this.passwordInput.val(); if (!this.prettyPrint.hasClass('prettyprinted')) { + // Try to decrypt the paste. try { if (paste.attachment) @@ -705,7 +709,8 @@ $(function() { { if (password.length === 0) { - password = this.requestPassword(); + this.requestPassword(); + return; } attachment = filter.decipher(key, password, paste.attachment); } @@ -740,8 +745,8 @@ $(function() { var cleartext = filter.decipher(key, password, paste.data); if (cleartext.length === 0 && password.length === 0 && !paste.attachment) { - password = this.requestPassword(); - cleartext = filter.decipher(key, password, paste.data); + this.requestPassword(); + return; } if (cleartext.length === 0 && !paste.attachment) { @@ -942,7 +947,7 @@ $(function() { { if (data.status === 0) { - privatebin.displayMessages(privatebin.pageKey(), data); + privatebin.displayMessages(data); } else if (data.status === 1) { @@ -1161,7 +1166,7 @@ $(function() { /** * Put the screen in "Existing paste" mode. * - * @param boolean preview (optional) : tell if the preview tabs should be displayed, defaults to false. + * @param boolean preview (optional) tell if the preview tabs should be displayed, defaults to false. */ stateExistingPaste: function(preview) { @@ -1420,6 +1425,34 @@ $(function() { this.fileWrap.removeClass('hidden'); }, + /** + * Focus on the modal password dialog. + */ + focusPasswordModal: function() + { + this.passwordDecrypt.focus(); + }, + + /** + * Decrypt using the password from the modal dialog. + */ + decryptPasswordModal: function() + { + this.passwordInput.val(this.passwordDecrypt.val()); + this.displayMessages(); + }, + + /** + * Submit a password in the modal dialog. + * + * @param Event event + */ + submitPasswordModal: function(event) + { + event.preventDefault(); + this.passwordModal.modal('hide'); + }, + /** * Display an error message * (We use the same function for paste and reply to comments) @@ -1507,6 +1540,11 @@ $(function() { // page template drop down $('#language select option').click($.proxy(this.setLanguage, this)); + + // handle modal password request on decryption + this.passwordModal.on('shown.bs.modal', $.proxy(this.focusPasswordModal, this)); + this.passwordModal.on('hidden.bs.modal', $.proxy(this.decryptPasswordModal, this)); + this.passwordForm.submit($.proxy(this.submitPasswordModal, this)); }, /** @@ -1543,6 +1581,9 @@ $(function() { this.openDiscussion = $('#opendiscussion'); this.password = $('#password'); this.passwordInput = $('#passwordinput'); + this.passwordModal = $('#passwordmodal'); + this.passwordForm = $('#passwordform'); + this.passwordDecrypt = $('#passworddecrypt'); this.pasteResult = $('#pasteresult'); this.prettyMessage = $('#prettymessage'); this.prettyPrint = $('#prettyprint'); @@ -1573,13 +1614,9 @@ $(function() { return; } - // List of messages to display. - var data = $.parseJSON(this.cipherData.text()); - // Show proper elements on screen. this.stateExistingPaste(); - - this.displayMessages(this.pageKey(), data); + this.displayMessages(); } // Display error message from php code. else if (this.errorMessage.text().length > 1) diff --git a/tpl/bootstrap-compact.php b/tpl/bootstrap-compact.php index 5c497d43..fa937b59 100644 --- a/tpl/bootstrap-compact.php +++ b/tpl/bootstrap-compact.php @@ -52,7 +52,7 @@ if ($MARKDOWN): - + @@ -66,6 +66,21 @@ endif; +