Просмотр исходного кода

Merge branch 'master' into crowdin-translation

El RIDO 2 лет назад
Родитель
Сommit
4db0db320b
10 измененных файлов с 110 добавлено и 53 удалено
  1. 6 1
      CHANGELOG.md
  2. 3 1
      i18n/en.json
  3. 3 3
      js/common.js
  4. 63 19
      js/privatebin.js
  5. 0 1
      js/purify-3.0.6.js
  6. 1 0
      js/purify-3.0.8.js
  7. 0 0
      js/zlib-1.3.1.js
  8. BIN
      js/zlib-1.3.1.wasm
  9. 31 25
      tpl/bootstrap.php
  10. 3 3
      tpl/page.php

+ 6 - 1
CHANGELOG.md

@@ -3,8 +3,13 @@
 ## 1.6.3 (not yet released)
 * ADDED: Translations for Romanian
 * ADDED: Detect and report on damaged pastes (#1218)
-* CHANGED: Upgrading libraries to: zlib 1.3
+* CHANGED: Ask for confirmation, before loading burn after reading pastes #1237
+* CHANGED: Focus on password input in modal dialog
+* CHANGED: Upgrading libraries to: DOMpurify 3.0.8 & zlib 1.3.1
 * FIXED: Support more types of valid URLs for shorteners, incl. IDN ones (#1224)
+* FIXED: Email timezone buttons overlapping in some languages #1039
+* FIXED: Changing language mangles URL #1191
+* FIXED: Needless reload when visiting default URL
 
 ## 1.6.2 (2023-12-15)
 * FIXED: English not selectable when `languageselection` enabled (#1208)

+ 3 - 1
i18n/en.json

@@ -214,5 +214,7 @@
     "Your IP is not authorized to create pastes.": "Your IP is not authorized to create pastes.",
     "Trying to shorten a URL that isn't pointing at our instance.": "Trying to shorten a URL that isn't pointing at our instance.",
     "Error calling YOURLS. Probably a configuration issue, like wrong or missing \"apiurl\" or \"signature\".": "Error calling YOURLS. Probably a configuration issue, like wrong or missing \"apiurl\" or \"signature\".",
-    "Error parsing YOURLS response.": "Error parsing YOURLS response."
+    "Error parsing YOURLS response.": "Error parsing YOURLS response.",
+    "Burn after reading pastes can only be displayed once upon loading it. Do you want to open it now?": "Burn after reading pastes can only be displayed once upon loading it. Do you want to open it now?",
+    "Yes, load it": "Yes, load it"
 }

+ 3 - 3
js/common.js

@@ -12,12 +12,12 @@ global.WebCrypto = require('@peculiar/webcrypto').Crypto;
 // application libraries to test
 global.$ = global.jQuery = require('./jquery-3.7.0');
 global.RawDeflate = require('./rawinflate-0.3').RawDeflate;
-global.zlib = require('./zlib-1.3').zlib;
+global.zlib = require('./zlib-1.3.1').zlib;
 require('./prettify');
 global.prettyPrint = window.PR.prettyPrint;
 global.prettyPrintOne = window.PR.prettyPrintOne;
 global.showdown = require('./showdown-2.1.0');
-global.DOMPurify = require('./purify-3.0.6');
+global.DOMPurify = require('./purify-3.0.8');
 global.baseX = require('./base-x-4.0.0').baseX;
 global.Legacy = require('./legacy').Legacy;
 require('./bootstrap-3.4.1');
@@ -151,4 +151,4 @@ exports.urlToString = function (url) {
     return url.schema + '://' + url.address.join('') + '/' + (url.query ? '?' +
         encodeURI(url.query.join('').replace(/^&+|&+$/gm,'')) : '') +
         (url.fragment ? '#' + encodeURI(url.fragment) : '');
-};
+};

+ 63 - 19
js/privatebin.js

@@ -77,6 +77,13 @@ jQuery.PrivateBin = (function($, RawDeflate) {
         }
     };
 
+    /**
+     * URL fragment prefix requiring load confirmation
+     *
+     * @private
+     */
+    const loadConfirmPrefix = '#-';
+
     /**
      * CryptoData class
      *
@@ -228,7 +235,7 @@ jQuery.PrivateBin = (function($, RawDeflate) {
             '<': '&lt;',
             '>': '&gt;',
             '"': '&quot;',
-            "'": '&#39;',
+            '\'': '&#39;',
             '/': '&#x2F;',
             '`': '&#x60;',
             '=': '&#x3D;'
@@ -1514,10 +1521,11 @@ jQuery.PrivateBin = (function($, RawDeflate) {
         me.getPasteKey = function()
         {
             if (symmetricKey === null) {
-                let newKey = window.location.hash.substring(1);
-                if (newKey === '') {
-                    throw 'no encryption key given';
+                let startPos = 1;
+                if(window.location.hash.startsWith(loadConfirmPrefix)) {
+                    startPos = loadConfirmPrefix.length;
                 }
+                let newKey = window.location.hash.substring(startPos);
 
                 // Some web 2.0 services and redirectors add data AFTER the anchor
                 // (such as &utm_source=...). We will strip any additional data.
@@ -1526,6 +1534,9 @@ jQuery.PrivateBin = (function($, RawDeflate) {
                 {
                     newKey = newKey.substring(0, ampersandPos);
                 }
+                if (newKey === '') {
+                    throw 'no encryption key given';
+                }
 
                 // version 2 uses base58, version 1 uses base64 without decoding
                 try {
@@ -2252,6 +2263,34 @@ jQuery.PrivateBin = (function($, RawDeflate) {
             PasteDecrypter.run();
         }
 
+        /**
+         * Request users confirmation to load possibly burn after reading paste
+         *
+         * @name   Prompt.requestLoadConfirmation
+         * @function
+         */
+        me.requestLoadConfirmation = function()
+        {
+            const $loadconfirmmodal = $('#loadconfirmmodal');
+            if ($loadconfirmmodal.length > 0) {
+                const $loadconfirmOpenNow = $loadconfirmmodal.find('#loadconfirm-open-now');
+                $loadconfirmOpenNow.off('click.loadPaste');
+                $loadconfirmOpenNow.on('click.loadPaste', PasteDecrypter.run);
+                const $loadconfirmClose = $loadconfirmmodal.find('.close');
+                $loadconfirmClose.off('click.close');
+                $loadconfirmClose.on('click.close', Controller.newPaste);
+                $loadconfirmmodal.modal('show');
+            } else {
+                if (window.confirm(
+                    I18n._('Burn after reading pastes can only be displayed once upon loading it. Do you want to open it now?')
+                )) {
+                    PasteDecrypter.run();
+                } else {
+                    Controller.newPaste();
+                }
+            }
+        }
+
         /**
          * ask the user for the password and set it
          *
@@ -2266,6 +2305,12 @@ jQuery.PrivateBin = (function($, RawDeflate) {
                     backdrop: 'static',
                     keyboard: false
                 });
+                // focus password input
+                $passwordDecrypt.focus();
+                // then re-focus it, when modal causes it to loose focus again
+                setTimeout(function () {
+                    $passwordDecrypt.focus();
+                }, 500);
                 return;
             }
 
@@ -2325,13 +2370,7 @@ jQuery.PrivateBin = (function($, RawDeflate) {
             $passwordForm = $('#passwordform');
             $passwordModal = $('#passwordmodal');
 
-            // bind events
-
-            // focus password input when it is shown
-            $passwordModal.on('shown.bs.Model', function () {
-                $passwordDecrypt.focus();
-            });
-            // handle Model password submission
+            // bind events - handle Model password submission
             $passwordForm.submit(submitPasswordModal);
         };
 
@@ -3565,7 +3604,6 @@ jQuery.PrivateBin = (function($, RawDeflate) {
                 if (fadeOut === true) {
                     setTimeout(function () {
                         $comment.removeClass('highlight');
-
                     }, 300);
                 }
             };
@@ -3813,6 +3851,7 @@ jQuery.PrivateBin = (function($, RawDeflate) {
         {
             document.cookie = 'lang=' + $(event.target).data('lang') + ';secure';
             UiHelper.reloadHome();
+            event.preventDefault();
         }
 
         /**
@@ -3968,10 +4007,6 @@ jQuery.PrivateBin = (function($, RawDeflate) {
             const $emailconfirmmodal = $('#emailconfirmmodal');
             if ($emailconfirmmodal.length > 0) {
                 if (expirationDate !== null) {
-                    I18n._(
-                        $emailconfirmmodal.find('#emailconfirm-display'),
-                        'Recipient may become aware of your timezone, convert time to UTC?'
-                    );
                     const $emailconfirmTimezoneCurrent = $emailconfirmmodal.find('#emailconfirm-timezone-current');
                     const $emailconfirmTimezoneUtc = $emailconfirmmodal.find('#emailconfirm-timezone-utc');
                     $emailconfirmTimezoneCurrent.off('click.sendEmailCurrentTimezone');
@@ -4826,7 +4861,7 @@ jQuery.PrivateBin = (function($, RawDeflate) {
 
             // show notification
             const baseUri   = Helper.baseUri() + '?',
-                  url       = baseUri + data.id + '#' + CryptTool.base58encode(data.encryptionKey),
+                  url       = baseUri + data.id + (TopNav.getBurnAfterReading() ? loadConfirmPrefix : '#') + CryptTool.base58encode(data.encryptionKey),
                   deleteUrl = baseUri + 'pasteid=' + data.id + '&deletetoken=' + data.deletetoken;
             PasteStatus.createPasteNotification(url, deleteUrl);
 
@@ -5245,7 +5280,7 @@ jQuery.PrivateBin = (function($, RawDeflate) {
             Alert.hideMessages();
             Alert.showLoading('Decrypting paste…', 'cloud-download');
 
-            if (typeof paste === 'undefined') {
+            if (typeof paste === 'undefined' || paste.type === 'click') {
                 // get cipher data and wait until it is available
                 Model.getPasteData(me.run);
                 return;
@@ -5352,7 +5387,10 @@ jQuery.PrivateBin = (function($, RawDeflate) {
             AttachmentViewer.removeAttachmentData();
 
             Alert.hideLoading();
-            history.pushState({type: 'create'}, document.title, Helper.baseUri());
+            // only push new state if we are coming from a different one
+            if (Helper.baseUri() != window.location) {
+                history.pushState({type: 'create'}, document.title, Helper.baseUri());
+            }
 
             // clear discussion
             DiscussionViewer.prepareNewDiscussion();
@@ -5378,6 +5416,12 @@ jQuery.PrivateBin = (function($, RawDeflate) {
                 }
             }
 
+            // check if we should request loading confirmation
+            if(window.location.hash.startsWith(loadConfirmPrefix)) {
+                Prompt.requestLoadConfirmation();
+                return;
+            }
+
             // show proper elements on screen
             PasteDecrypter.run();
         };

Разница между файлами не показана из-за своего большого размера
+ 0 - 1
js/purify-3.0.6.js


Разница между файлами не показана из-за своего большого размера
+ 1 - 0
js/purify-3.0.8.js


+ 0 - 0
js/zlib-1.3.js → js/zlib-1.3.1.js


BIN
js/zlib-1.3.wasm → js/zlib-1.3.1.wasm


+ 31 - 25
tpl/bootstrap.php

@@ -55,7 +55,7 @@ if ($ZEROBINCOMPATIBILITY) :
 <?php
 endif;
 ?>
-		<script type="text/javascript" data-cfasync="false" src="js/zlib-1.3.js" integrity="sha512-VL3lLnt8EexTr22ze4a4HfVghpgY48c/Lhf4CcQa8bgYaIRRPjV1nP7EA8RiciGoXXQ1IeiU7tjrclPeVEfxOQ==" crossorigin="anonymous"></script>
+		<script type="text/javascript" data-cfasync="false" src="js/zlib-1.3.1.js" integrity="sha512-VL3lLnt8EexTr22ze4a4HfVghpgY48c/Lhf4CcQa8bgYaIRRPjV1nP7EA8RiciGoXXQ1IeiU7tjrclPeVEfxOQ==" crossorigin="anonymous"></script>
 		<script type="text/javascript" data-cfasync="false" src="js/base-x-4.0.0.js" integrity="sha512-nNPg5IGCwwrveZ8cA/yMGr5HiRS5Ps2H+s0J/mKTPjCPWUgFGGw7M5nqdnPD3VsRwCVysUh3Y8OWjeSKGkEQJQ==" crossorigin="anonymous"></script>
 		<script type="text/javascript" data-cfasync="false" src="js/rawinflate-0.3.js" integrity="sha512-g8uelGgJW9A/Z1tB6Izxab++oj5kdD7B4qC7DHwZkB6DGMXKyzx7v5mvap2HXueI2IIn08YlRYM56jwWdm2ucQ==" crossorigin="anonymous"></script>
 		<script type="text/javascript" data-cfasync="false" src="js/bootstrap-3.4.1.js" integrity="sha512-oBTprMeNEKCnqfuqKd6sbvFzmFQtlXS3e0C/RGFV0hD6QzhHV+ODfaQbAlmY6/q0ubbwlAM/nCJjkrgA3waLzg==" crossorigin="anonymous"></script>
@@ -71,9 +71,9 @@ if ($MARKDOWN) :
 <?php
 endif;
 ?>
-		<script type="text/javascript" data-cfasync="false" src="js/purify-3.0.6.js" integrity="sha512-N3y6/HOk3pbsw3lFh4O8CKKEVwu1B2CF8kinhjURf8Yqa5OfSUt+/arozxFW+TUPOPw3TsDCRT/0u7BGRTEVUw==" crossorigin="anonymous"></script>
+		<script type="text/javascript" data-cfasync="false" src="js/purify-3.0.8.js" integrity="sha512-wWBDKh5wYGtJ1Df+PPZIn59jHVBnJ4/Yb2W/pVnzaXab8cmlZnHVx+FEBGu5JX39s3P2Qlt+aNQou0XnjW86hg==" crossorigin="anonymous"></script>
 		<script type="text/javascript" data-cfasync="false" src="js/legacy.js?<?php echo rawurlencode($VERSION); ?>" integrity="sha512-LYos+qXHIRqFf5ZPNphvtTB0cgzHUizu2wwcOwcwz/VIpRv9lpcBgPYz4uq6jx0INwCAj6Fbnl5HoKiLufS2jg==" crossorigin="anonymous"></script>
-		<script type="text/javascript" data-cfasync="false" src="js/privatebin.js?<?php echo rawurlencode($VERSION); ?>" integrity="sha512-cfRk8a/8RpvMb4g9Su9kcKNcs7+PyGioUxH6z6k9e4vcdZmtz+gM2HwIP/Gd/1r6h3qoxrkO4jodn2E7gtZ7EA==" crossorigin="anonymous"></script>
+		<script type="text/javascript" data-cfasync="false" src="js/privatebin.js?<?php echo rawurlencode($VERSION); ?>" integrity="sha512-FPqSHNhZoXQX1vV5+Sd9vn/indcihNkt0KLmpRpDfXRMM9tTWxokUpbsD07GGpYibfG4mPbCwFy13c2VLvagIg==" crossorigin="anonymous"></script>
 		<!-- icon -->
 		<link rel="apple-touch-icon" href="<?php echo I18n::encode($BASEPATH); ?>img/apple-touch-icon.png" sizes="180x180" />
 		<link rel="icon" type="image/png" href="img/favicon-32x32.png" sizes="32x32" />
@@ -123,22 +123,32 @@ if (count($class)) {
 				</div>
 			</div>
 		</div>
+		<div id="loadconfirmmodal" tabindex="-1" class="modal fade" role="dialog" aria-hidden="true">
+			<div class="modal-dialog" role="document">
+				<div class="modal-content">
+					<div class="modal-header">
+						<button type="button" class="close" data-dismiss="modal" aria-label="<?php echo I18n::_('Close') ?>"><span aria-hidden="true">&times;</span></button>
+						<h4 class="modal-title"><?php echo I18n::_('Burn after reading pastes can only be displayed once upon loading it. Do you want to open it now?') ?></h4>
+					</div>
+					<div class="modal-body text-center">
+						<button id="loadconfirm-open-now" type="button" class="btn btn-success" data-dismiss="modal"><span class="glyphicon glyphicon-download"></span> <?php echo I18n::_('Yes, load it') ?></button>
+					</div>
+				</div>
+			</div>
+		</div>
 <?php
 if ($QRCODE) :
 ?>
-		<div id="qrcodemodal" tabindex="-1" class="modal fade" aria-labelledby="qrcodemodalTitle" role="dialog" aria-hidden="true">
+		<div id="qrcodemodal" tabindex="-1" class="modal fade" role="dialog" aria-hidden="true">
 			<div class="modal-dialog" role="document">
 				<div class="modal-content">
+					<div class="modal-header">
+						<button type="button" class="close" data-dismiss="modal" aria-label="<?php echo I18n::_('Close') ?>"><span aria-hidden="true">&times;</span></button>
+						<h4 class="modal-title"><?php echo I18n::_('QR code') ?></h4>
+					</div>
 					<div class="modal-body">
 						<div class="mx-auto" id="qrcode-display"></div>
 					</div>
-					<div class="row">
-						<div class="btn-group col-xs-12">
-							<span class="col-xs-12">
-								<button type="button" class="btn btn-primary btn-block" data-dismiss="modal"><?php echo I18n::_('Close') ?></button>
-							</span>
-						</div>
-					</div>
 				</div>
 			</div>
 		</div>
@@ -146,23 +156,19 @@ if ($QRCODE) :
 endif;
 if ($EMAIL) :
 ?>
-		<div id="emailconfirmmodal" tabindex="-1" class="modal fade" aria-labelledby="emailconfirmmodalTitle" role="dialog" aria-hidden="true">
+		<div id="emailconfirmmodal" tabindex="-1" class="modal fade" role="dialog" aria-hidden="true">
 			<div class="modal-dialog" role="document">
 				<div class="modal-content">
-					<div class="modal-body">
-						<div id="emailconfirm-display"></div>
+					<div class="modal-header">
+						<button type="button" class="close" data-dismiss="modal" aria-label="<?php echo I18n::_('Close') ?>"><span aria-hidden="true">&times;</span></button>
+						<h4 class="modal-title"><?php echo I18n::_('Recipient may become aware of your timezone, convert time to UTC?') ?></h4>
 					</div>
-					<div class="row">
-						<div class="btn-group col-xs-12" data-toggle="buttons">
-							<span class="col-xs-12 col-md-4">
-								<button id="emailconfirm-timezone-current" type="button" class="btn btn-danger btn-block" data-dismiss="modal"><?php echo I18n::_('Use Current Timezone') ?></button>
-							</span>
-							<span class="col-xs-12 col-md-4">
-								<button id="emailconfirm-timezone-utc" type="button" class="btn btn-default btn-block" data-dismiss="modal"><?php echo I18n::_('Convert To UTC') ?></button>
-							</span>
-							<span class="col-xs-12 col-md-4">
-								<button type="button" class="btn btn-primary btn-block" data-dismiss="modal"><?php echo I18n::_('Close') ?></button>
-							</span>
+					<div class="modal-body row">
+						<div class="col-xs-12 col-md-6">
+							<button id="emailconfirm-timezone-current" type="button" class="btn btn-danger"><span class="glyphicon glyphicon-time"></span> <?php echo I18n::_('Use Current Timezone') ?></button>
+						</div>
+						<div class="col-xs-12 col-md-6 text-right">
+							<button id="emailconfirm-timezone-utc" type="button" class="btn btn-success"><span class="glyphicon glyphicon-globe"></span> <?php echo I18n::_('Convert To UTC') ?></button>
 						</div>
 					</div>
 				</div>

+ 3 - 3
tpl/page.php

@@ -34,7 +34,7 @@ if ($ZEROBINCOMPATIBILITY):
 <?php
 endif;
 ?>
-		<script type="text/javascript" data-cfasync="false" src="js/zlib-1.3.js" integrity="sha512-VL3lLnt8EexTr22ze4a4HfVghpgY48c/Lhf4CcQa8bgYaIRRPjV1nP7EA8RiciGoXXQ1IeiU7tjrclPeVEfxOQ==" crossorigin="anonymous"></script>
+		<script type="text/javascript" data-cfasync="false" src="js/zlib-1.3.1.js" integrity="sha512-VL3lLnt8EexTr22ze4a4HfVghpgY48c/Lhf4CcQa8bgYaIRRPjV1nP7EA8RiciGoXXQ1IeiU7tjrclPeVEfxOQ==" crossorigin="anonymous"></script>
 		<script type="text/javascript" data-cfasync="false" src="js/base-x-4.0.0.js" integrity="sha512-nNPg5IGCwwrveZ8cA/yMGr5HiRS5Ps2H+s0J/mKTPjCPWUgFGGw7M5nqdnPD3VsRwCVysUh3Y8OWjeSKGkEQJQ==" crossorigin="anonymous"></script>
 		<script type="text/javascript" data-cfasync="false" src="js/rawinflate-0.3.js" integrity="sha512-g8uelGgJW9A/Z1tB6Izxab++oj5kdD7B4qC7DHwZkB6DGMXKyzx7v5mvap2HXueI2IIn08YlRYM56jwWdm2ucQ==" crossorigin="anonymous"></script>
 <?php
@@ -49,9 +49,9 @@ if ($MARKDOWN):
 <?php
 endif;
 ?>
-		<script type="text/javascript" data-cfasync="false" src="js/purify-3.0.6.js" integrity="sha512-N3y6/HOk3pbsw3lFh4O8CKKEVwu1B2CF8kinhjURf8Yqa5OfSUt+/arozxFW+TUPOPw3TsDCRT/0u7BGRTEVUw==" crossorigin="anonymous"></script>
+		<script type="text/javascript" data-cfasync="false" src="js/purify-3.0.8.js" integrity="sha512-wWBDKh5wYGtJ1Df+PPZIn59jHVBnJ4/Yb2W/pVnzaXab8cmlZnHVx+FEBGu5JX39s3P2Qlt+aNQou0XnjW86hg==" crossorigin="anonymous"></script>
 		<script type="text/javascript" data-cfasync="false" src="js/legacy.js?<?php echo rawurlencode($VERSION); ?>" integrity="sha512-LYos+qXHIRqFf5ZPNphvtTB0cgzHUizu2wwcOwcwz/VIpRv9lpcBgPYz4uq6jx0INwCAj6Fbnl5HoKiLufS2jg==" crossorigin="anonymous"></script>
-		<script type="text/javascript" data-cfasync="false" src="js/privatebin.js?<?php echo rawurlencode($VERSION); ?>" integrity="sha512-cfRk8a/8RpvMb4g9Su9kcKNcs7+PyGioUxH6z6k9e4vcdZmtz+gM2HwIP/Gd/1r6h3qoxrkO4jodn2E7gtZ7EA==" crossorigin="anonymous"></script>
+		<script type="text/javascript" data-cfasync="false" src="js/privatebin.js?<?php echo rawurlencode($VERSION); ?>" integrity="sha512-FPqSHNhZoXQX1vV5+Sd9vn/indcihNkt0KLmpRpDfXRMM9tTWxokUpbsD07GGpYibfG4mPbCwFy13c2VLvagIg==" crossorigin="anonymous"></script>
 		<!-- icon -->
 		<link rel="apple-touch-icon" href="img/apple-touch-icon.png?<?php echo rawurlencode($VERSION); ?>" sizes="180x180" />
 		<link rel="icon" type="image/png" href="img/favicon-32x32.png?<?php echo rawurlencode($VERSION); ?>" sizes="32x32" />

Некоторые файлы не были показаны из-за большого количества измененных файлов