diff --git a/CHANGELOG.md b/CHANGELOG.md index d8ac2cb2..edd85024 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -4,7 +4,7 @@ * ADDED: script for data storage backend migrations (#1012) * ADDED: Translations for Turkish, Slovak, Greek and Thai * ADDED: S3 Storage backend (#994) - * CHANGED: Switched to Jdenticons as the default for comment icons (#793) + * ADDED: Jdenticons as an option for comment icons (#793) * CHANGED: Avoid `SUPER` privilege for setting the `sql_mode` for MariaDB/MySQL (#919) * CHANGED: Upgrading libraries to: zlib 1.2.13 * FIXED: Revert to CREATE INDEX without IF NOT EXISTS clauses, to support MySQL (#943) diff --git a/INSTALL.md b/INSTALL.md index 57777c94..dfdb4b6a 100644 --- a/INSTALL.md +++ b/INSTALL.md @@ -26,7 +26,7 @@ install and configure PrivateBin on your server. It's available on - `open_basedir` access to `/dev/urandom` - mcrypt extension AND `open_basedir` access to `/dev/urandom` - com_dotnet extension -- GD extension +- GD extension (when using identicon or vizhash icons, jdenticon works without it) - zlib extension - some disk space or a database supported by [PDO](https://php.net/manual/book.pdo.php) - ability to create files and folders in the installation directory and the PATH diff --git a/bin/icon-test b/bin/icon-test index 7794e478..57145e13 100755 --- a/bin/icon-test +++ b/bin/icon-test @@ -9,6 +9,7 @@ use Identicon\Generator\GdGenerator; use Identicon\Generator\ImageMagickGenerator; use Identicon\Generator\SvgGenerator; use Identicon\Identicon; +use Jdenticon\Identicon as Jdenticon; use PrivateBin\Vizhash16x16; @@ -17,7 +18,19 @@ $vizhash = new Vizhash16x16(); $identiconGenerators = array( 'identicon GD' => new Identicon(new GdGenerator()), 'identicon ImageMagick' => new Identicon(new ImageMagickGenerator()), - 'identicon SVG' => new Identicon(new SvgGenerator()) + 'identicon SVG' => new Identicon(new SvgGenerator()), +); +$jdenticon = new Jdenticon(array( + 'size' => 16, + 'style' => array( + 'backgroundColor' => '#fff0', // fully transparent, for dark mode + 'padding' => 0, + ), +)); +$jdenticonGenerators = array( + 'jdenticon' => 'png', + 'jdenticon ImageMagick' => 'png', + 'jdenticon SVG' => 'svg', ); $results = array( 'vizhash' => array( @@ -35,21 +48,30 @@ $results = array( 'identicon SVG' => array( 'lengths' => array(), 'time' => 0 - ) + ), + 'jdenticon' => array( + 'lengths' => array(), + 'time' => 0 + ), + 'jdenticon ImageMagick' => array( + 'lengths' => array(), + 'time' => 0 + ), + 'jdenticon SVG' => array( + 'lengths' => array(), + 'time' => 0 + ), ); $hmacs = array(); echo 'generate ', ITERATIONS, ' hmacs and pre-populate the result array, so tests wont be slowed down', PHP_EOL; for ($i = 0; $i < ITERATIONS; ++$i) { $hmacs[$i] = hash_hmac('sha512', '127.0.0.1', bin2hex(random_bytes(256))); - $results['vizhash']['lengths'][$i] = 0; - $results['identicon GD']['lengths'][$i] = 0; - $results['identicon ImageMagick']['lengths'][$i] = 0; - $results['identicon SVG']['lengths'][$i] = 0; + foreach (array_keys($results) as $test) { + $results[$test]['lengths'][$i] = 0; + } } - - echo 'run vizhash tests', PHP_EOL; $start = microtime(true); foreach ($hmacs as $i => $hmac) { @@ -60,7 +82,6 @@ foreach ($hmacs as $i => $hmac) { } $results['vizhash']['time'] = microtime(true) - $start; - foreach ($identiconGenerators as $key => $identicon) { echo 'run ', $key,' tests', PHP_EOL; $start = microtime(true); @@ -71,9 +92,35 @@ foreach ($identiconGenerators as $key => $identicon) { $results[$key]['time'] = microtime(true) - $start; } +foreach ($jdenticonGenerators as $key => $format) { + echo 'run ', $key,' tests', PHP_EOL; + if ($key === 'jdenticon ImageMagick') { + $jdenticon->enableImageMagick = true; + } else { + $jdenticon->enableImageMagick = false; + } + $start = microtime(true); + foreach ($hmacs as $i => $hmac) { + $jdenticon->setHash($hmac); + $data = $jdenticon->getImageDataUri($format); + $results[$key]['lengths'][$i] = strlen($data); + } + $results[$key]['time'] = microtime(true) - $start; +} -define('PADDING_LENGTH', max(array_map(function ($key) { return strlen($key); }, array_keys($results))) + 1); +define( + 'PADDING_LENGTH', + max( + array_map( + function ($key) { + return strlen($key); + }, + array_keys($results) + ) + ) + 1 +); + function format_result_line($generator, $min, $max, $avg, $sec) { echo str_pad($generator, PADDING_LENGTH, ' '), "\t", str_pad($min, 4, ' ', STR_PAD_LEFT), "\t", @@ -84,7 +131,10 @@ function format_result_line($generator, $min, $max, $avg, $sec) { echo PHP_EOL; format_result_line('Generator:', 'min', 'max', 'avg', 'seconds'); -format_result_line(str_repeat('─', PADDING_LENGTH), str_repeat('─', 4), str_repeat('─', 4), str_repeat('─', 4), str_repeat('─', 7)); +format_result_line( + str_repeat('─', PADDING_LENGTH), str_repeat('─', 4), str_repeat('─', 4), + str_repeat('─', 4), str_repeat('─', 7) +); foreach ($results as $generator => $result) { sort($result['lengths']); format_result_line( diff --git a/cfg/conf.sample.php b/cfg/conf.sample.php index 541bb751..7dca6d48 100644 --- a/cfg/conf.sample.php +++ b/cfg/conf.sample.php @@ -70,7 +70,7 @@ languageselection = false ; used to get the IP of a comment poster if the server salt is leaked and a ; SHA512 HMAC rainbow table is generated for all (relevant) IPs. ; Can be set to one these values: -; "none" / "vizhash" / "identicon" / "jdenticon" (default). +; "none" / "identicon" (default) / "jdenticon" / "vizhash". ; icon = "none" ; Content Security Policy headers allow a website to restrict what sources are diff --git a/lib/Configuration.php b/lib/Configuration.php index f1e2897f..5588791a 100644 --- a/lib/Configuration.php +++ b/lib/Configuration.php @@ -53,7 +53,7 @@ class Configuration 'languagedefault' => '', 'urlshortener' => '', 'qrcode' => true, - 'icon' => 'jdenticon', + 'icon' => 'identicon', 'cspheader' => 'default-src \'none\'; base-uri \'self\'; form-action \'none\'; manifest-src \'self\'; connect-src * blob:; script-src \'self\' \'unsafe-eval\'; style-src \'self\'; font-src \'self\'; frame-ancestors \'none\'; 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, diff --git a/lib/Model/Comment.php b/lib/Model/Comment.php index 8e4142ee..ffb27fc4 100644 --- a/lib/Model/Comment.php +++ b/lib/Model/Comment.php @@ -165,7 +165,10 @@ class Comment extends AbstractModel if ($icon != 'none') { $pngdata = ''; $hmac = TrafficLimiter::getHash(); - if ($icon == 'jdenticon') { + if ($icon == 'identicon') { + $identicon = new Identicon(); + $pngdata = $identicon->getImageDataUri($hmac, 16); + } elseif ($icon == 'jdenticon') { $jdenticon = new Jdenticon(array( 'hash' => $hmac, 'size' => 16, @@ -175,9 +178,6 @@ class Comment extends AbstractModel ), )); $pngdata = $jdenticon->getImageDataUri('png'); - } elseif ($icon == 'identicon') { - $identicon = new Identicon(); - $pngdata = $identicon->getImageDataUri($hmac, 16); } elseif ($icon == 'vizhash') { $vh = new Vizhash16x16(); $pngdata = 'data:image/png;base64,' . base64_encode( diff --git a/tst/ModelTest.php b/tst/ModelTest.php index 00a172db..562bdc4d 100644 --- a/tst/ModelTest.php +++ b/tst/ModelTest.php @@ -1,6 +1,6 @@ get(); $comment->store(); - $identicon = new Identicon(array( - 'hash' => TrafficLimiter::getHash(), - 'size' => 16, - 'style' => array( - 'backgroundColor' => '#fff0', // fully transparent, for dark mode - 'padding' => 0, - ), - )); - $pngdata = $identicon->getImageDataUri('png'); + $identicon = new Identicon(); + $pngdata = $identicon->getImageDataUri(TrafficLimiter::getHash(), 16); $comment = current($this->_model->getPaste(Helper::getPasteId())->get()['comments']); $this->assertEquals($pngdata, $comment['meta']['icon'], 'icon gets set'); }