Merge branch 'qrcode'

This commit is contained in:
El RIDO 2018-01-02 08:43:42 +01:00
commit dae11fdd16
No known key found for this signature in database
GPG key ID: 0F5C940A6BD81F92
11 changed files with 104 additions and 14 deletions

View file

@ -56,6 +56,10 @@ languageselection = false
; the pastes encryption key ; the pastes encryption key
; urlshortener = "https://shortener.example.com/api?link=" ; urlshortener = "https://shortener.example.com/api?link="
; (optional) Let users create a QR code for sharing the paste URL with one click.
; It works both when a new paste is created and when you view a paste.
; qrcode = true
; (optional) IP based icons are a weak mechanism to detect if a comment was from ; (optional) IP based icons are a weak mechanism to detect if a comment was from
; a different user when the same username was used in a comment. It might be ; a different user when the same username was used in a comment. It might be
; used to get the IP of a non anonymous comment poster if the server salt is ; used to get the IP of a non anonymous comment poster if the server salt is

View file

@ -76,6 +76,16 @@ body.loading {
#deletelink { #deletelink {
float: right; float: right;
margin-left: 5px;
}
#qrcodemodalClose {
float: right;
}
#qrcode-display {
width: 200px;
height: 200px;
margin: auto;
} }
#pastelink { #pastelink {

View file

@ -72,13 +72,13 @@ h3.title {
bottom: 8px; bottom: 8px;
} }
#aboutbox { #aboutbox {
color: #94a3b4; color: #94a3b4;
padding: 4px 8px 4px 16px; padding: 4px 8px 4px 16px;
position: relative; position: relative;
top: 10px; top: 10px;
border-left: 2px solid #94a3b4; border-left: 2px solid #94a3b4;
float: right; float: right;
width: 60%; width: 60%;
} }
@ -109,12 +109,12 @@ h3.title {
height: auto; height: auto;
} }
#status { #status {
clear: both; clear: both;
padding: 5px 10px; padding: 5px 10px;
} }
#pasteresult { #pasteresult {
background-color: #1F2833; background-color: #1F2833;
color: #fff; color: #fff;
padding: 4px 12px; padding: 4px 12px;
@ -132,7 +132,7 @@ h3.title {
#toolbar, #status { margin-bottom: 5px; } #toolbar, #status { margin-bottom: 5px; }
#copyhint { color: #666; font-size: 0.85em; } #copyhint { color: #666; font-size: 0.85em }
button, .button { button, .button {
color: #fff; color: #fff;

BIN
img/icon_qr.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 437 B

2
js/kjua-0.1.2.js Normal file

File diff suppressed because one or more lines are too long

View file

@ -21,6 +21,7 @@
/** global: prettyPrintOne */ /** global: prettyPrintOne */
/** global: showdown */ /** global: showdown */
/** global: sjcl */ /** global: sjcl */
/** global: kjua */
// Immediately start random number generator collector. // Immediately start random number generator collector.
sjcl.random.startCollectors(); sjcl.random.startCollectors();
@ -2408,6 +2409,7 @@ jQuery.PrivateBin = function($, sjcl, Base64, RawDeflate) {
$password, $password,
$passwordInput, $passwordInput,
$rawTextButton, $rawTextButton,
$qrCodeLink,
$sendButton; $sendButton;
var pasteExpiration = '1week'; var pasteExpiration = '1week';
@ -2585,6 +2587,22 @@ jQuery.PrivateBin = function($, sjcl, Base64, RawDeflate) {
event.preventDefault(); event.preventDefault();
} }
/**
* Shows the QR code of the current paste (URL).
*
* @name TopNav.displayQrCode
* @function
* @param {Event} event
*/
function displayQrCode(event)
{
var qrCanvas = kjua({
render: 'canvas',
text: window.location.href
});
$('#qrcode-display').html(qrCanvas);
}
/** /**
* Shows all elements belonging to viwing an existing pastes * Shows all elements belonging to viwing an existing pastes
* *
@ -2601,6 +2619,7 @@ jQuery.PrivateBin = function($, sjcl, Base64, RawDeflate) {
$newButton.removeClass('hidden'); $newButton.removeClass('hidden');
$cloneButton.removeClass('hidden'); $cloneButton.removeClass('hidden');
$rawTextButton.removeClass('hidden'); $rawTextButton.removeClass('hidden');
$qrCodeLink.removeClass('hidden');
viewButtonsDisplayed = true; viewButtonsDisplayed = true;
} }
@ -2621,6 +2640,7 @@ jQuery.PrivateBin = function($, sjcl, Base64, RawDeflate) {
$newButton.addClass('hidden'); $newButton.addClass('hidden');
$cloneButton.addClass('hidden'); $cloneButton.addClass('hidden');
$rawTextButton.addClass('hidden'); $rawTextButton.addClass('hidden');
$qrCodeLink.addClass('hidden');
viewButtonsDisplayed = false; viewButtonsDisplayed = false;
} }
@ -2871,6 +2891,7 @@ jQuery.PrivateBin = function($, sjcl, Base64, RawDeflate) {
$passwordInput = $('#passwordinput'); $passwordInput = $('#passwordinput');
$rawTextButton = $('#rawtextbutton'); $rawTextButton = $('#rawtextbutton');
$sendButton = $('#sendbutton'); $sendButton = $('#sendbutton');
$qrCodeLink = $('#qrcodelink');
// bootstrap template drop down // bootstrap template drop down
$('#language ul.dropdown-menu li a').click(setLanguage); $('#language ul.dropdown-menu li a').click(setLanguage);
@ -2885,6 +2906,7 @@ jQuery.PrivateBin = function($, sjcl, Base64, RawDeflate) {
$cloneButton.click(Controller.clonePaste); $cloneButton.click(Controller.clonePaste);
$rawTextButton.click(rawText); $rawTextButton.click(rawText);
$fileRemoveButton.click(removeAttachment); $fileRemoveButton.click(removeAttachment);
$qrCodeLink.click(displayQrCode);
// bootstrap template drop downs // bootstrap template drop downs
$('ul.dropdown-menu li a', $('#expiration').parent()).click(updateExpiration); $('ul.dropdown-menu li a', $('#expiration').parent()).click(updateExpiration);

View file

@ -52,6 +52,7 @@ class Configuration
'languageselection' => false, 'languageselection' => false,
'languagedefault' => '', 'languagedefault' => '',
'urlshortener' => '', 'urlshortener' => '',
'qrcode' => true,
'icon' => 'identicon', 'icon' => 'identicon',
'cspheader' => 'default-src \'none\'; manifest-src \'self\'; connect-src *; script-src \'self\'; style-src \'self\'; font-src \'self\'; img-src \'self\' data:; referrer no-referrer; sandbox allow-same-origin allow-scripts allow-forms allow-popups', 'cspheader' => 'default-src \'none\'; manifest-src \'self\'; connect-src *; script-src \'self\'; style-src \'self\'; font-src \'self\'; img-src \'self\' data:; referrer no-referrer; sandbox allow-same-origin allow-scripts allow-forms allow-popups',
'zerobincompatibility' => false, 'zerobincompatibility' => false,

View file

@ -448,6 +448,7 @@ class PrivateBin
$page->assign('EXPIREDEFAULT', $this->_conf->getKey('default', 'expire')); $page->assign('EXPIREDEFAULT', $this->_conf->getKey('default', 'expire'));
$page->assign('EXPIRECLONE', !$this->_doesExpire || ($this->_doesExpire && $this->_conf->getKey('clone', 'expire'))); $page->assign('EXPIRECLONE', !$this->_doesExpire || ($this->_doesExpire && $this->_conf->getKey('clone', 'expire')));
$page->assign('URLSHORTENER', $this->_conf->getKey('urlshortener')); $page->assign('URLSHORTENER', $this->_conf->getKey('urlshortener'));
$page->assign('QRCODE', $this->_conf->getKey('qrcode'));
$page->draw($this->_conf->getKey('template')); $page->draw($this->_conf->getKey('template'));
} }

View file

@ -44,6 +44,11 @@ endif;
<script type="text/javascript" src="js/jquery-3.1.1.js" integrity="sha512-U6K1YLIFUWcvuw5ucmMtT9HH4t0uz3M366qrF5y4vnyH6dgDzndlcGvH/Lz5k8NFh80SN95aJ5rqGZEdaQZ7ZQ==" crossorigin="anonymous"></script> <script type="text/javascript" src="js/jquery-3.1.1.js" integrity="sha512-U6K1YLIFUWcvuw5ucmMtT9HH4t0uz3M366qrF5y4vnyH6dgDzndlcGvH/Lz5k8NFh80SN95aJ5rqGZEdaQZ7ZQ==" crossorigin="anonymous"></script>
<script type="text/javascript" src="js/sjcl-1.0.6.js" integrity="sha512-DsyxLV/uBoQlRTJmW5Gb2SxXUXB+aYeZ6zk+NuXy8LuLyi8oGti9AGn6He5fUY2DtgQ2//RjfaZog8exFuunUQ==" crossorigin="anonymous"></script> <script type="text/javascript" src="js/sjcl-1.0.6.js" integrity="sha512-DsyxLV/uBoQlRTJmW5Gb2SxXUXB+aYeZ6zk+NuXy8LuLyi8oGti9AGn6He5fUY2DtgQ2//RjfaZog8exFuunUQ==" crossorigin="anonymous"></script>
<?php <?php
if ($QRCODE):
?>
<script async type="text/javascript" src="js/kjua-0.1.2.js" integrity="sha512-hmvfOhcr4J8bjQ2GuNVzfSbuulv72wgQCJpgnXc2+cCHKqvYo8pK2nc0Q4Esem2973zo1radyIMTEkt+xJlhBA==" crossorigin="anonymous"></script>
<?php
endif;
if ($ZEROBINCOMPATIBILITY): if ($ZEROBINCOMPATIBILITY):
?> ?>
<script type="text/javascript" src="js/base64-1.7.js" integrity="sha512-JdwsSP3GyHR+jaCkns9CL9NTt4JUJqm/BsODGmYhBcj5EAPKcHYh+OiMfyHbcDLECe17TL0hjXADFkusAqiYgA==" crossorigin="anonymous"></script> <script type="text/javascript" src="js/base64-1.7.js" integrity="sha512-JdwsSP3GyHR+jaCkns9CL9NTt4JUJqm/BsODGmYhBcj5EAPKcHYh+OiMfyHbcDLECe17TL0hjXADFkusAqiYgA==" crossorigin="anonymous"></script>
@ -70,7 +75,7 @@ if ($MARKDOWN):
<?php <?php
endif; endif;
?> ?>
<script type="text/javascript" src="js/privatebin.js?<?php echo rawurlencode($VERSION); ?>" integrity="sha512-51v9MtL1fUeIOp2VekfHq4VR6kdR/SyYqkAT1WGRZXDP5+ct6A1qktVW9HNNL6EXYQbMpzgVuYUIZ6HhULcGSA==" crossorigin="anonymous"></script> <script type="text/javascript" src="js/privatebin.js?<?php echo rawurlencode($VERSION); ?>" integrity="sha512-ongf6gpLgDPRVlBPaFlvxyDu3rCb1APhvzJLUFj9JuXCi6Zd0vqxt//vR8Zz3Ez9Fq+mw14HU8z52H7EjZewfA==" crossorigin="anonymous"></script>
<!--[if lt IE 10]> <!--[if lt IE 10]>
<style type="text/css">body {padding-left:60px;padding-right:60px;} #ienotice {display:block;} #oldienotice {display:block;}</style> <style type="text/css">body {padding-left:60px;padding-right:60px;} #ienotice {display:block;} #oldienotice {display:block;}</style>
<![endif]--> <![endif]-->
@ -88,8 +93,8 @@ if ($isCpct):
?> class="navbar-spacing"<?php ?> class="navbar-spacing"<?php
endif; endif;
?>> ?>>
<div id="passwordmodal" class="modal fade" role="dialog"> <div id="passwordmodal" tabindex="-1" class="modal fade" role="dialog" aria-hidden="true">
<div class="modal-dialog"> <div class="modal-dialog" role="document">
<div class="modal-content"> <div class="modal-content">
<div class="modal-body"> <div class="modal-body">
<form id="passwordform" role="form"> <form id="passwordform" role="form">
@ -103,6 +108,22 @@ endif;
</div> </div>
</div> </div>
</div> </div>
<?php
if ($QRCODE):
?>
<div id="qrcodemodal" tabindex="-1" class="modal fade" aria-labelledby="qrcodemodalTitle" role="dialog" aria-hidden="true">
<div class="modal-dialog" role="document">
<div class="modal-content">
<div class="modal-body">
<div class="mx-auto" id="qrcode-display"></div>
</div>
<button type="button" class="btn btn-primary btn-block" data-dismiss="modal"><?php echo I18n::_('Close') ?></button>
</div>
</div>
</div>
<?php
endif;
?>
<nav class="navbar navbar-<?php echo $isDark ? 'inverse' : 'default'; ?> navbar-<?php echo $isCpct ? 'fixed' : 'static'; ?>-top"><?php <nav class="navbar navbar-<?php echo $isDark ? 'inverse' : 'default'; ?> navbar-<?php echo $isCpct ? 'fixed' : 'static'; ?>-top"><?php
if ($isCpct): if ($isCpct):
?><div class="container"><?php ?><div class="container"><?php
@ -150,6 +171,15 @@ endif;
<button id="rawtextbutton" type="button" class="hidden btn btn-<?php echo $isDark ? 'warning' : 'default'; ?> navbar-btn"> <button id="rawtextbutton" type="button" class="hidden btn btn-<?php echo $isDark ? 'warning' : 'default'; ?> navbar-btn">
<span class="glyphicon glyphicon-text-background" aria-hidden="true"></span> <?php echo I18n::_('Raw text'), PHP_EOL; ?> <span class="glyphicon glyphicon-text-background" aria-hidden="true"></span> <?php echo I18n::_('Raw text'), PHP_EOL; ?>
</button> </button>
<?php
if ($QRCODE):
?>
<button id="qrcodelink" type="button" data-toggle="modal" data-target="#qrcodemodal" class="hidden btn btn-<?php echo $isDark ? 'warning' : 'default'; ?> navbar-btn">
<span class="glyphicon glyphicon-qrcode" aria-hidden="true"></span> <?php echo I18n::_('QR code'), PHP_EOL; ?>
</button>
<?php
endif;
?>
</li> </li>
<li class="dropdown"> <li class="dropdown">
<select id="pasteExpiration" name="pasteExpiration" class="hidden"> <select id="pasteExpiration" name="pasteExpiration" class="hidden">
@ -271,7 +301,7 @@ else:
endif; endif;
?> /> ?> />
<?php echo I18n::_('Open discussion'), PHP_EOL; ?> <?php echo I18n::_('Open discussion'), PHP_EOL; ?>
</label> </label>
</div> </div>
</li> </li>
<?php <?php

View file

@ -22,6 +22,7 @@ endif;
?> ?>
<script type="text/javascript" src="js/jquery-3.1.1.js" integrity="sha512-U6K1YLIFUWcvuw5ucmMtT9HH4t0uz3M366qrF5y4vnyH6dgDzndlcGvH/Lz5k8NFh80SN95aJ5rqGZEdaQZ7ZQ==" crossorigin="anonymous"></script> <script type="text/javascript" src="js/jquery-3.1.1.js" integrity="sha512-U6K1YLIFUWcvuw5ucmMtT9HH4t0uz3M366qrF5y4vnyH6dgDzndlcGvH/Lz5k8NFh80SN95aJ5rqGZEdaQZ7ZQ==" crossorigin="anonymous"></script>
<script type="text/javascript" src="js/sjcl-1.0.6.js" integrity="sha512-DsyxLV/uBoQlRTJmW5Gb2SxXUXB+aYeZ6zk+NuXy8LuLyi8oGti9AGn6He5fUY2DtgQ2//RjfaZog8exFuunUQ==" crossorigin="anonymous"></script> <script type="text/javascript" src="js/sjcl-1.0.6.js" integrity="sha512-DsyxLV/uBoQlRTJmW5Gb2SxXUXB+aYeZ6zk+NuXy8LuLyi8oGti9AGn6He5fUY2DtgQ2//RjfaZog8exFuunUQ==" crossorigin="anonymous"></script>
<script type="text/javascript" src="js/kjua.min.js" integrity="sha512-hmvfOhcr4J8bjQ2GuNVzfSbuulv72wgQCJpgnXc2+cCHKqvYo8pK2nc0Q4Esem2973zo1radyIMTEkt+xJlhBA==" crossorigin="anonymous"></script>
<?php <?php
if ($ZEROBINCOMPATIBILITY): if ($ZEROBINCOMPATIBILITY):
?> ?>
@ -47,8 +48,13 @@ if ($MARKDOWN):
<script type="text/javascript" src="js/purify-1.0.3.js?<?php echo rawurlencode($VERSION); ?>" integrity="sha512-uhzhZJSgc+XJoaxCOjiuRzQaf5klPlSSVKGw69+zT72hhfLbVwB4jbwI+f7NRucuRz6u0aFGMeZ+0PnGh73iBQ==" crossorigin="anonymous"></script> <script type="text/javascript" src="js/purify-1.0.3.js?<?php echo rawurlencode($VERSION); ?>" integrity="sha512-uhzhZJSgc+XJoaxCOjiuRzQaf5klPlSSVKGw69+zT72hhfLbVwB4jbwI+f7NRucuRz6u0aFGMeZ+0PnGh73iBQ==" crossorigin="anonymous"></script>
<?php <?php
endif; endif;
if ($QRCODE):
?> ?>
<script type="text/javascript" src="js/privatebin.js?<?php echo rawurlencode($VERSION); ?>" integrity="sha512-51v9MtL1fUeIOp2VekfHq4VR6kdR/SyYqkAT1WGRZXDP5+ct6A1qktVW9HNNL6EXYQbMpzgVuYUIZ6HhULcGSA==" crossorigin="anonymous"></script> <script async type="text/javascript" src="js/kjua-0.1.2.js" integrity="sha512-hmvfOhcr4J8bjQ2GuNVzfSbuulv72wgQCJpgnXc2+cCHKqvYo8pK2nc0Q4Esem2973zo1radyIMTEkt+xJlhBA==" crossorigin="anonymous"></script>
<?php
endif;
?>
<script type="text/javascript" src="js/privatebin.js?<?php echo rawurlencode($VERSION); ?>" integrity="sha512-ongf6gpLgDPRVlBPaFlvxyDu3rCb1APhvzJLUFj9JuXCi6Zd0vqxt//vR8Zz3Ez9Fq+mw14HU8z52H7EjZewfA==" crossorigin="anonymous"></script>
<!--[if lt IE 10]> <!--[if lt IE 10]>
<style type="text/css">body {padding-left:60px;padding-right:60px;} #ienotice {display:block;} #oldienotice {display:block;}</style> <style type="text/css">body {padding-left:60px;padding-right:60px;} #ienotice {display:block;} #oldienotice {display:block;}</style>
<![endif]--> <![endif]-->
@ -99,6 +105,13 @@ if ($EXPIRECLONE):
endif; endif;
?> ?>
<button id="rawtextbutton" class="hidden"><img src="img/icon_raw.png" width="15" height="15" alt="" /><?php echo I18n::_('Raw text'); ?></button> <button id="rawtextbutton" class="hidden"><img src="img/icon_raw.png" width="15" height="15" alt="" /><?php echo I18n::_('Raw text'); ?></button>
<?php
if ($QRCODE):
?>
<button id="qrcodelink" class="hidden"><img src="img/icon_qr.png" width="15" height="15" alt="" /><?php echo I18n::_('QR code'); ?></button>
<?php
endif;
?>
<div id="expiration" class="hidden button"><?php echo I18n::_('Expires'); ?>: <div id="expiration" class="hidden button"><?php echo I18n::_('Expires'); ?>:
<select id="pasteExpiration" name="pasteExpiration"> <select id="pasteExpiration" name="pasteExpiration">
<?php <?php
@ -185,7 +198,13 @@ if (strlen($LANGUAGESELECTION)):
endif; endif;
?> ?>
</div> </div>
<div id="pastesuccess" class="hidden"> <?php
if ($QRCODE):
?>
<div id="qrcode-display"></div>
<?php
endif;
?> <div id="pastesuccess" class="hidden">
<div id="deletelink"></div> <div id="deletelink"></div>
<div id="pastelink"> <div id="pastelink">
<?php <?php
@ -242,7 +261,7 @@ if ($DISCUSSION):
endif; endif;
?> ?>
</div> </div>
<section class="container"> <section class="container">
<div id="noscript" role="alert" class="nonworking alert alert-info noscript-hide"><span class="glyphicon glyphicon-exclamation-sign" aria-hidden="true"> <div id="noscript" role="alert" class="nonworking alert alert-info noscript-hide"><span class="glyphicon glyphicon-exclamation-sign" aria-hidden="true">
<span> <?php echo I18n::_('Loading…'); ?></span><br> <span> <?php echo I18n::_('Loading…'); ?></span><br>
<span class="small"><?php echo I18n::_('In case this message never disappears please have a look at <a href="https://github.com/PrivateBin/PrivateBin/wiki/FAQ#why-does-not-the-loading-message-go-away">this FAQ for information to troubleshoot</a>.'); ?></span> <span class="small"><?php echo I18n::_('In case this message never disappears please have a look at <a href="https://github.com/PrivateBin/PrivateBin/wiki/FAQ#why-does-not-the-loading-message-go-away">this FAQ for information to troubleshoot</a>.'); ?></span>

View file

@ -56,6 +56,7 @@ class ViewTest extends PHPUnit_Framework_TestCase
$page->assign('EXPIREDEFAULT', self::$expire_default); $page->assign('EXPIREDEFAULT', self::$expire_default);
$page->assign('EXPIRECLONE', true); $page->assign('EXPIRECLONE', true);
$page->assign('URLSHORTENER', ''); $page->assign('URLSHORTENER', '');
$page->assign('QRCODE', true);
$dir = dir(PATH . 'tpl'); $dir = dir(PATH . 'tpl');
while (false !== ($file = $dir->read())) { while (false !== ($file = $dir->read())) {