diff --git a/CHANGELOG.md b/CHANGELOG.md index b3278931..8e416b9e 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -3,6 +3,7 @@ * **1.4 (not yet released)** * ADDED: Translation for Estonian * ADDED: new HTTP headers improving security (#765) + * ADDED: Download button for paste text (#774) * ADDED: Opt-out of federated learning of cohorts (FLoC) (#776) * CHANGED: Language selection cookie only transmitted over HTTPS (#472) * **1.3.5 (2021-04-05)** diff --git a/cfg/conf.sample.php b/cfg/conf.sample.php index 570503ce..ceddad62 100644 --- a/cfg/conf.sample.php +++ b/cfg/conf.sample.php @@ -87,7 +87,7 @@ languageselection = false ; async functions and display an error if not and for Chrome to enable ; webassembly support (used for zlib compression). You can remove it if Chrome ; doesn't need to be supported and old browsers don't need to be warned. -; cspheader = "default-src 'none'; base-uri 'self'; manifest-src 'self'; connect-src * blob:; script-src 'self' 'unsafe-eval' resource:; style-src 'self'; font-src 'self'; img-src 'self' data: blob:; media-src blob:; object-src blob:; sandbox allow-same-origin allow-scripts allow-forms allow-popups allow-modals allow-downloads" +; cspheader = "default-src 'none'; base-uri 'self'; form-action 'none'; manifest-src 'self'; connect-src * blob:; script-src 'self' 'unsafe-eval' resource:; style-src 'self'; font-src 'self'; img-src 'self' data: blob:; media-src blob:; object-src blob:; sandbox allow-same-origin allow-scripts allow-forms allow-popups allow-modals allow-downloads" ; stay compatible with PrivateBin Alpha 0.19, less secure ; if enabled will use base64.js version 1.7 instead of 2.1.9 and sha1 instead of diff --git a/css/privatebin.css b/css/privatebin.css index 8b4e6a0a..f852d396 100644 --- a/css/privatebin.css +++ b/css/privatebin.css @@ -249,6 +249,10 @@ button img { padding: 1px 0 1px 0; } +#downloadtextbutton img { + padding: 1px 0 1px 0; +} + #remainingtime, #password { color: #94a3b4; display: inline; diff --git a/i18n/en.json b/i18n/en.json index 295f5129..a96bab5d 100644 --- a/i18n/en.json +++ b/i18n/en.json @@ -184,5 +184,6 @@ "Close": "Close", "Encrypted note on PrivateBin": "Encrypted note on PrivateBin", "Visit this link to see the note. Giving the URL to anyone allows them to access the note, too.": "Visit this link to see the note. Giving the URL to anyone allows them to access the note, too.", - "URL shortener may expose your decrypt key in URL.": "URL shortener may expose your decrypt key in URL." + "URL shortener may expose your decrypt key in URL.": "URL shortener may expose your decrypt key in URL.", + "Save paste": "Save paste" } diff --git a/js/privatebin.js b/js/privatebin.js index 05199701..6218700a 100644 --- a/js/privatebin.js +++ b/js/privatebin.js @@ -3525,6 +3525,7 @@ jQuery.PrivateBin = (function($, RawDeflate) { $password, $passwordInput, $rawTextButton, + $downloadTextButton, $qrCodeLink, $emailLink, $sendButton, @@ -3666,6 +3667,30 @@ jQuery.PrivateBin = (function($, RawDeflate) { newDoc.close(); } + /** + * download text + * + * @name TopNav.downloadText + * @private + * @function + */ + function downloadText() + { + var filename='paste-' + Model.getPasteId() + '.txt'; + var text = PasteViewer.getText(); + + var element = document.createElement('a'); + element.setAttribute('href', 'data:text/plain;charset=utf-8,' + encodeURIComponent(text)); + element.setAttribute('download', filename); + + element.style.display = 'none'; + document.body.appendChild(element); + + element.click(); + + document.body.removeChild(element); + } + /** * saves the language in a cookie and reloads the page * @@ -3892,6 +3917,7 @@ jQuery.PrivateBin = (function($, RawDeflate) { $newButton.removeClass('hidden'); $cloneButton.removeClass('hidden'); $rawTextButton.removeClass('hidden'); + $downloadTextButton.removeClass('hidden'); $qrCodeLink.removeClass('hidden'); viewButtonsDisplayed = true; @@ -3912,6 +3938,7 @@ jQuery.PrivateBin = (function($, RawDeflate) { $cloneButton.addClass('hidden'); $newButton.addClass('hidden'); $rawTextButton.addClass('hidden'); + $downloadTextButton.addClass('hidden'); $qrCodeLink.addClass('hidden'); me.hideEmailButton(); @@ -4073,6 +4100,17 @@ jQuery.PrivateBin = (function($, RawDeflate) { $rawTextButton.addClass('hidden'); }; + /** + * only hides the download text button + * + * @name TopNav.hideRawButton + * @function + */ + me.hideDownloadButton = function() + { + $downloadTextButton.addClass('hidden'); + }; + /** * only hides the qr code button * @@ -4334,6 +4372,7 @@ jQuery.PrivateBin = (function($, RawDeflate) { $password = $('#password'); $passwordInput = $('#passwordinput'); $rawTextButton = $('#rawtextbutton'); + $downloadTextButton = $('#downloadtextbutton'); $retryButton = $('#retrybutton'); $sendButton = $('#sendbutton'); $qrCodeLink = $('#qrcodelink'); @@ -4351,6 +4390,7 @@ jQuery.PrivateBin = (function($, RawDeflate) { $sendButton.click(PasteEncrypter.sendPaste); $cloneButton.click(Controller.clonePaste); $rawTextButton.click(rawText); + $downloadTextButton.click(downloadText); $retryButton.click(clickRetryButton); $fileRemoveButton.click(removeAttachment); $qrCodeLink.click(displayQrCode); @@ -4689,6 +4729,7 @@ jQuery.PrivateBin = (function($, RawDeflate) { TopNav.showEmailButton(); TopNav.hideRawButton(); + TopNav.hideDownloadButton(); Editor.hide(); // parse and show text diff --git a/lib/Configuration.php b/lib/Configuration.php index 426cd158..e509d983 100644 --- a/lib/Configuration.php +++ b/lib/Configuration.php @@ -55,7 +55,7 @@ class Configuration 'urlshortener' => '', 'qrcode' => true, 'icon' => 'identicon', - 'cspheader' => 'default-src \'none\'; base-uri \'self\'; manifest-src \'self\'; connect-src * blob:; script-src \'self\' \'unsafe-eval\' resource:; style-src \'self\'; font-src \'self\'; img-src \'self\' data: blob:; media-src blob:; object-src blob:; sandbox allow-same-origin allow-scripts allow-forms allow-popups allow-modals allow-downloads', + 'cspheader' => 'default-src \'none\'; base-uri \'self\'; form-action \'none\'; manifest-src \'self\'; connect-src * blob:; script-src \'self\' \'unsafe-eval\' resource:; style-src \'self\'; font-src \'self\'; img-src \'self\' data: blob:; media-src blob:; object-src blob:; sandbox allow-same-origin allow-scripts allow-forms allow-popups allow-modals allow-downloads', 'zerobincompatibility' => false, 'httpwarning' => true, 'compression' => 'zlib', diff --git a/tpl/bootstrap.php b/tpl/bootstrap.php index f8f94446..1e4eae00 100644 --- a/tpl/bootstrap.php +++ b/tpl/bootstrap.php @@ -72,7 +72,7 @@ endif; ?> - + @@ -212,6 +212,9 @@ endif; + diff --git a/tpl/page.php b/tpl/page.php index a2272326..28f37b90 100644 --- a/tpl/page.php +++ b/tpl/page.php @@ -50,7 +50,7 @@ endif; ?> - + @@ -127,6 +127,7 @@ endif; +