From 6fcd82fb85f277f9e974a62763024d7958ff218d Mon Sep 17 00:00:00 2001 From: El RIDO Date: Tue, 27 Aug 2019 07:38:27 +0200 Subject: [PATCH] making the feature detection more robust, let users with no WASM create uncompressed pastes, remove dead & duplicate code --- i18n/bg.json | 4 +- i18n/cs.json | 4 +- i18n/de.json | 4 +- i18n/es.json | 4 +- i18n/fr.json | 4 +- i18n/hu.json | 4 +- i18n/it.json | 4 +- i18n/nl.json | 4 +- i18n/no.json | 4 +- i18n/oc.json | 4 +- i18n/pl.json | 4 +- i18n/pt.json | 4 +- i18n/ru.json | 4 +- i18n/sl.json | 4 +- i18n/zh.json | 4 +- js/privatebin.js | 107 ++++++++++++++++++++++++------------------- js/test/CryptTool.js | 3 ++ tpl/bootstrap.php | 2 +- tpl/page.php | 2 +- 19 files changed, 110 insertions(+), 64 deletions(-) diff --git a/i18n/bg.json b/i18n/bg.json index c51ab0f4..07a929c1 100644 --- a/i18n/bg.json +++ b/i18n/bg.json @@ -161,5 +161,7 @@ "For more information see this FAQ entry.": "Вижте тази страница за повече информация.", "Your browser may require an HTTPS connection to support the WebCrypto API. Try switching to HTTPS.": - "Браузъра ви може да се нуждае от HTTPS връзка за да използва WebCrypto API. Пробвай да минеш на HTTPS." + "Браузъра ви може да се нуждае от HTTPS връзка за да използва WebCrypto API. Пробвай да минеш на HTTPS.", + "Your browser doesn't support WebAssembly, used for zlib compression. You can create uncompressed documents, but can't read compressed ones.": + "Your browser doesn't support WebAssembly, used for zlib compression. You can create uncompressed documents, but can't read compressed ones." } diff --git a/i18n/cs.json b/i18n/cs.json index a36ef8ba..365d6110 100644 --- a/i18n/cs.json +++ b/i18n/cs.json @@ -161,5 +161,7 @@ "For more information see this FAQ entry.": "For more information see this FAQ entry.", "Your browser may require an HTTPS connection to support the WebCrypto API. Try switching to HTTPS.": - "Your browser may require an HTTPS connection to support the WebCrypto API. Try switching to HTTPS." + "Your browser may require an HTTPS connection to support the WebCrypto API. Try switching to HTTPS.", + "Your browser doesn't support WebAssembly, used for zlib compression. You can create uncompressed documents, but can't read compressed ones.": + "Your browser doesn't support WebAssembly, used for zlib compression. You can create uncompressed documents, but can't read compressed ones." } diff --git a/i18n/de.json b/i18n/de.json index 3f99404f..a89f8208 100644 --- a/i18n/de.json +++ b/i18n/de.json @@ -161,5 +161,7 @@ "For more information see this FAQ entry.": "Besuche diesen FAQ Eintrag für weitere Informationen dazu.", "Your browser may require an HTTPS connection to support the WebCrypto API. Try switching to HTTPS.": - "Dein Browser benötigt möglicherweise eine HTTPS Verbindung um das WebCrypto API nutzen zu können. Versuche auf HTTPS zu wechseln." + "Dein Browser benötigt möglicherweise eine HTTPS Verbindung um das WebCrypto API nutzen zu können. Versuche auf HTTPS zu wechseln.", + "Your browser doesn't support WebAssembly, used for zlib compression. You can create uncompressed documents, but can't read compressed ones.": + "Dein Browser unterstützt WebAssembly nicht, welches für zlib Komprimierung benötigt wird. Du kannst unkomprimierte Dokumente erzeugen, aber keine komprimierten lesen." } diff --git a/i18n/es.json b/i18n/es.json index 6dd9e912..de6fa543 100644 --- a/i18n/es.json +++ b/i18n/es.json @@ -161,5 +161,7 @@ "For more information see this FAQ entry.": "For more information see this FAQ entry.", "Your browser may require an HTTPS connection to support the WebCrypto API. Try switching to HTTPS.": - "Your browser may require an HTTPS connection to support the WebCrypto API. Try switching to HTTPS." + "Your browser may require an HTTPS connection to support the WebCrypto API. Try switching to HTTPS.", + "Your browser doesn't support WebAssembly, used for zlib compression. You can create uncompressed documents, but can't read compressed ones.": + "Your browser doesn't support WebAssembly, used for zlib compression. You can create uncompressed documents, but can't read compressed ones." } diff --git a/i18n/fr.json b/i18n/fr.json index fabb1d29..bebd1857 100644 --- a/i18n/fr.json +++ b/i18n/fr.json @@ -170,5 +170,7 @@ "For more information see this FAQ entry.": "Pour plus d'informations consultez cette rubrique de la FAQ.", "Your browser may require an HTTPS connection to support the WebCrypto API. Try switching to HTTPS.": - "Votre navigateur peut nécessiter une connexion HTTPS pour prendre en charge l’API WebCrypto. Essayez de passer en HTTPS." + "Votre navigateur peut nécessiter une connexion HTTPS pour prendre en charge l’API WebCrypto. Essayez de passer en HTTPS.", + "Your browser doesn't support WebAssembly, used for zlib compression. You can create uncompressed documents, but can't read compressed ones.": + "Your browser doesn't support WebAssembly, used for zlib compression. You can create uncompressed documents, but can't read compressed ones." } diff --git a/i18n/hu.json b/i18n/hu.json index da2dd525..cf1fe02b 100644 --- a/i18n/hu.json +++ b/i18n/hu.json @@ -161,5 +161,7 @@ "For more information see this FAQ entry.": "For more information see this FAQ entry.", "Your browser may require an HTTPS connection to support the WebCrypto API. Try switching to HTTPS.": - "Your browser may require an HTTPS connection to support the WebCrypto API. Try switching to HTTPS." + "Your browser may require an HTTPS connection to support the WebCrypto API. Try switching to HTTPS.", + "Your browser doesn't support WebAssembly, used for zlib compression. You can create uncompressed documents, but can't read compressed ones.": + "Your browser doesn't support WebAssembly, used for zlib compression. You can create uncompressed documents, but can't read compressed ones." } diff --git a/i18n/it.json b/i18n/it.json index 125812fa..22f6838a 100644 --- a/i18n/it.json +++ b/i18n/it.json @@ -161,5 +161,7 @@ "For more information see this FAQ entry.": "For more information see this FAQ entry.", "Your browser may require an HTTPS connection to support the WebCrypto API. Try switching to HTTPS.": - "Your browser may require an HTTPS connection to support the WebCrypto API. Try switching to HTTPS." + "Your browser may require an HTTPS connection to support the WebCrypto API. Try switching to HTTPS.", + "Your browser doesn't support WebAssembly, used for zlib compression. You can create uncompressed documents, but can't read compressed ones.": + "Your browser doesn't support WebAssembly, used for zlib compression. You can create uncompressed documents, but can't read compressed ones." } diff --git a/i18n/nl.json b/i18n/nl.json index 4c93d784..00aea3b7 100644 --- a/i18n/nl.json +++ b/i18n/nl.json @@ -161,5 +161,7 @@ "For more information see this FAQ entry.": "For more information see this FAQ entry.", "Your browser may require an HTTPS connection to support the WebCrypto API. Try switching to HTTPS.": - "Your browser may require an HTTPS connection to support the WebCrypto API. Try switching to HTTPS." + "Your browser may require an HTTPS connection to support the WebCrypto API. Try switching to HTTPS.", + "Your browser doesn't support WebAssembly, used for zlib compression. You can create uncompressed documents, but can't read compressed ones.": + "Your browser doesn't support WebAssembly, used for zlib compression. You can create uncompressed documents, but can't read compressed ones." } diff --git a/i18n/no.json b/i18n/no.json index 108ce8d3..9f9fa62e 100644 --- a/i18n/no.json +++ b/i18n/no.json @@ -161,5 +161,7 @@ "For more information see this FAQ entry.": "For more information see this FAQ entry.", "Your browser may require an HTTPS connection to support the WebCrypto API. Try switching to HTTPS.": - "Your browser may require an HTTPS connection to support the WebCrypto API. Try switching to HTTPS." + "Your browser may require an HTTPS connection to support the WebCrypto API. Try switching to HTTPS.", + "Your browser doesn't support WebAssembly, used for zlib compression. You can create uncompressed documents, but can't read compressed ones.": + "Your browser doesn't support WebAssembly, used for zlib compression. You can create uncompressed documents, but can't read compressed ones." } diff --git a/i18n/oc.json b/i18n/oc.json index ec81c89b..6cd33cab 100644 --- a/i18n/oc.json +++ b/i18n/oc.json @@ -170,5 +170,7 @@ "For more information see this FAQ entry.": "Per mai d’informacions vejatz aqueste article de FAQ.", "Your browser may require an HTTPS connection to support the WebCrypto API. Try switching to HTTPS.": - "Se pòt que vòstre navigator faga besonh d’una connexion HTTPS per èsser compatible amb l’API WebCrypto. Ensajatz de passar al HTTPS." + "Se pòt que vòstre navigator faga besonh d’una connexion HTTPS per èsser compatible amb l’API WebCrypto. Ensajatz de passar al HTTPS.", + "Your browser doesn't support WebAssembly, used for zlib compression. You can create uncompressed documents, but can't read compressed ones.": + "Your browser doesn't support WebAssembly, used for zlib compression. You can create uncompressed documents, but can't read compressed ones." } diff --git a/i18n/pl.json b/i18n/pl.json index f1ae43f0..3be5baa0 100644 --- a/i18n/pl.json +++ b/i18n/pl.json @@ -161,5 +161,7 @@ "For more information see this FAQ entry.": "For more information see this FAQ entry.", "Your browser may require an HTTPS connection to support the WebCrypto API. Try switching to HTTPS.": - "Your browser may require an HTTPS connection to support the WebCrypto API. Try switching to HTTPS." + "Your browser may require an HTTPS connection to support the WebCrypto API. Try switching to HTTPS.", + "Your browser doesn't support WebAssembly, used for zlib compression. You can create uncompressed documents, but can't read compressed ones.": + "Your browser doesn't support WebAssembly, used for zlib compression. You can create uncompressed documents, but can't read compressed ones." } diff --git a/i18n/pt.json b/i18n/pt.json index f7b7e0bb..3ff603e0 100644 --- a/i18n/pt.json +++ b/i18n/pt.json @@ -161,5 +161,7 @@ "For more information see this FAQ entry.": "For more information see this FAQ entry.", "Your browser may require an HTTPS connection to support the WebCrypto API. Try switching to HTTPS.": - "Your browser may require an HTTPS connection to support the WebCrypto API. Try switching to HTTPS." + "Your browser may require an HTTPS connection to support the WebCrypto API. Try switching to HTTPS.", + "Your browser doesn't support WebAssembly, used for zlib compression. You can create uncompressed documents, but can't read compressed ones.": + "Your browser doesn't support WebAssembly, used for zlib compression. You can create uncompressed documents, but can't read compressed ones." } diff --git a/i18n/ru.json b/i18n/ru.json index d25b3465..66d413c7 100644 --- a/i18n/ru.json +++ b/i18n/ru.json @@ -171,5 +171,7 @@ "For more information see this FAQ entry.": "Для продробностей прочтите информацию в FAQ.", "Your browser may require an HTTPS connection to support the WebCrypto API. Try switching to HTTPS.": - "Ваш браузер требует использования HTTPS подключения для поддержки WebCrypto API. Попробуйте переключиться на HTTPS." + "Ваш браузер требует использования HTTPS подключения для поддержки WebCrypto API. Попробуйте переключиться на HTTPS.", + "Your browser doesn't support WebAssembly, used for zlib compression. You can create uncompressed documents, but can't read compressed ones.": + "Your browser doesn't support WebAssembly, used for zlib compression. You can create uncompressed documents, but can't read compressed ones." } diff --git a/i18n/sl.json b/i18n/sl.json index e88961d0..5e61d197 100644 --- a/i18n/sl.json +++ b/i18n/sl.json @@ -170,5 +170,7 @@ "For more information see this FAQ entry.": "For more information see this FAQ entry.", "Your browser may require an HTTPS connection to support the WebCrypto API. Try switching to HTTPS.": - "Your browser may require an HTTPS connection to support the WebCrypto API. Try switching to HTTPS." + "Your browser may require an HTTPS connection to support the WebCrypto API. Try switching to HTTPS.", + "Your browser doesn't support WebAssembly, used for zlib compression. You can create uncompressed documents, but can't read compressed ones.": + "Your browser doesn't support WebAssembly, used for zlib compression. You can create uncompressed documents, but can't read compressed ones." } diff --git a/i18n/zh.json b/i18n/zh.json index 2e2c7de9..2577b55a 100644 --- a/i18n/zh.json +++ b/i18n/zh.json @@ -161,5 +161,7 @@ "For more information see this FAQ entry.": "For more information see this FAQ entry.", "Your browser may require an HTTPS connection to support the WebCrypto API. Try switching to HTTPS.": - "Your browser may require an HTTPS connection to support the WebCrypto API. Try switching to HTTPS." + "Your browser may require an HTTPS connection to support the WebCrypto API. Try switching to HTTPS.", + "Your browser doesn't support WebAssembly, used for zlib compression. You can create uncompressed documents, but can't read compressed ones.": + "Your browser doesn't support WebAssembly, used for zlib compression. You can create uncompressed documents, but can't read compressed ones." } diff --git a/js/privatebin.js b/js/privatebin.js index b141779b..c990c359 100644 --- a/js/privatebin.js +++ b/js/privatebin.js @@ -789,7 +789,8 @@ jQuery.PrivateBin = (function($, RawDeflate) { utf16To8(message) ); if (mode === 'zlib') { - return z.deflate(message).buffer; + let zlib = (await z); + return zlib.deflate(message).buffer; } return message; } @@ -809,7 +810,12 @@ jQuery.PrivateBin = (function($, RawDeflate) { { if (mode === 'zlib' || mode === 'none') { if (mode === 'zlib') { - data = z.inflate( + let zlib = (await z); + if (typeof zlib === 'undefined') { + Alert.showError('Your browser doesn\'t support WebAssembly, used for zlib compression. You can create uncompressed documents, but can\'t read compressed ones.') + return ''; + } + data = zlib.inflate( new Uint8Array(data) ).buffer; } @@ -883,7 +889,7 @@ jQuery.PrivateBin = (function($, RawDeflate) { stringToArraybuffer( utf16To8(password) ) - ); + ).catch(Alert.showError); password = Array.prototype.map.call( new Uint8Array(passwordBuffer), x => ('00' + x.toString(16)).slice(-2) @@ -903,7 +909,7 @@ jQuery.PrivateBin = (function($, RawDeflate) { {name: 'PBKDF2'}, // we use PBKDF2 for key derivation false, // the key may not be exported ['deriveKey'] // we may only use it for key derivation - ); + ).catch(Alert.showError); // derive a stronger key for use with AES return window.crypto.subtle.deriveKey( @@ -920,7 +926,7 @@ jQuery.PrivateBin = (function($, RawDeflate) { }, false, // the key may not be exported ['encrypt', 'decrypt'] // we may only use it for en- and decryption - ); + ).catch(Alert.showError); } /** @@ -959,16 +965,21 @@ jQuery.PrivateBin = (function($, RawDeflate) { { // AES in Galois Counter Mode, keysize 256 bit, // authentication tag 128 bit, 10000 iterations in key derivation - const spec = [ - getRandomBytes(16), // initialization vector - getRandomBytes(8), // salt - 100000, // iterations - 256, // key size - 128, // tag size - 'aes', // algorithm - 'gcm', // algorithm mode - $('body').data('compression') || 'zlib' // compression - ], encodedSpec = []; + const compression = ( + typeof (await z) === 'undefined' ? + 'none' : // client lacks support for WASM + $('body').data('compression') || 'zlib' + ), + spec = [ + getRandomBytes(16), // initialization vector + getRandomBytes(8), // salt + 100000, // iterations + 256, // key size + 128, // tag size + 'aes', // algorithm + 'gcm', // algorithm mode + compression // compression + ], encodedSpec = []; for (let i = 0; i < spec.length; ++i) { encodedSpec[i] = i < 2 ? btoa(spec[i]) : spec[i]; } @@ -987,8 +998,8 @@ jQuery.PrivateBin = (function($, RawDeflate) { await window.crypto.subtle.encrypt( cryptoSettings(JSON.stringify(adata), spec), await deriveKey(key, password, spec), - await compress(message, spec[7]) - ) + await compress(message, compression) + ).catch(Alert.showError) ) ), adata @@ -1043,7 +1054,7 @@ jQuery.PrivateBin = (function($, RawDeflate) { stringToArraybuffer( atob(cipherMessage) ) - ), + ).catch(Alert.showError), spec[7] ); } catch(err) { @@ -1194,7 +1205,6 @@ jQuery.PrivateBin = (function($, RawDeflate) { me.getPasteId = function() { const idRegEx = /^[a-z0-9]{16}$/; - const idRegExFind = /[a-z0-9]{16}/; // return cached value if (id !== null) { @@ -1573,6 +1583,22 @@ jQuery.PrivateBin = (function($, RawDeflate) { handleNotification(1, $statusMessage, message, icon); }; + /** + * display a warning message + * + * This automatically passes the text to I18n for translation. + * + * @name Alert.showWarning + * @function + * @param {string|array} message string, use an array for %s/%d options + * @param {string|null} icon optional, the icon to show, default: + * leave previous icon + */ + me.showWarning = function(message, icon) + { + handleNotification(2, $errorMessage, message, icon); + }; + /** * display an error message * @@ -1699,7 +1725,7 @@ jQuery.PrivateBin = (function($, RawDeflate) { currentIcon = [ 'glyphicon-time', // loading icon 'glyphicon-info-sign', // status icon - '', // reserved for warning, not used yet + 'glyphicon-warning-sign', // warning icon 'glyphicon-alert' // error icon ]; }; @@ -1768,14 +1794,14 @@ jQuery.PrivateBin = (function($, RawDeflate) { return; } } - Alert.showError( - I18n._('Cannot parse response from URL shortener.') - ); + Alert.showError('Cannot parse response from URL shortener.'); } }) .fail(function(data, textStatus, errorThrown) { console.error(textStatus, errorThrown); - // we don't know why it failed, could be CORS of the external server not setup properly, in which case we follow old behavior to open it in new tab + // we don't know why it failed, could be CORS of the external + // server not setup properly, in which case we follow old + // behavior to open it in new tab window.open( `${$shortenButton.data('shortener')}${encodeURIComponent($pasteUrl.attr('href'))}`, '_blank', @@ -2731,9 +2757,7 @@ jQuery.PrivateBin = (function($, RawDeflate) { // revert loading status… me.hideAttachment(); me.hideAttachmentPreview(); - Alert.showError( - I18n._('Your browser does not support uploading encrypted files. Please use a newer browser.') - ); + Alert.showWarning('Your browser does not support uploading encrypted files. Please use a newer browser.'); return; } @@ -4194,8 +4218,6 @@ jQuery.PrivateBin = (function($, RawDeflate) { const PasteEncrypter = (function () { const me = {}; - let requirementsChecked = false; - /** * called after successful paste upload * @@ -4428,16 +4450,13 @@ jQuery.PrivateBin = (function($, RawDeflate) { }); cipherMessage['attachment'] = await fileReading; } else { - Alert.showError( - I18n._('Cannot process attachment data.') - ); - throw new TypeError('Cannot process attachment data.'); + const error = 'Cannot process attachment data.'; + Alert.showError(error); + throw new TypeError(error); } } catch (error) { console.error(error); - Alert.showError( - I18n._('Cannot retrieve attachment.') - ); + Alert.showError('Cannot retrieve attachment.'); throw error; } } @@ -4528,8 +4547,6 @@ jQuery.PrivateBin = (function($, RawDeflate) { } } - let format = '', - text = ''; if (paste.v > 1) { // version 2 paste const pasteMessage = JSON.parse(pastePlain); @@ -4630,9 +4647,7 @@ jQuery.PrivateBin = (function($, RawDeflate) { // log detailed error, but display generic translation console.error(message); - Alert.showError( - I18n._('Could not decrypt data. Did you enter a wrong password? Retry with the button at the top.') - ); + Alert.showError('Could not decrypt data. Did you enter a wrong password? Retry with the button at the top.'); // reset password, so it can be re-entered Prompt.reset(); @@ -4702,8 +4717,6 @@ jQuery.PrivateBin = (function($, RawDeflate) { * initial (security) check * * @name InitialCheck - * @param {object} window - * @param {object} document * @class */ const InitialCheck = (function () { @@ -4848,6 +4861,9 @@ jQuery.PrivateBin = (function($, RawDeflate) { $('#httpnotice').removeClass('hidden'); } + z = zlib.catch(function () { + Alert.showWarning('Your browser doesn\'t support WebAssembly, used for zlib compression. You can create uncompressed documents, but can\'t read compressed ones.'); + }); return true; } @@ -4926,9 +4942,7 @@ jQuery.PrivateBin = (function($, RawDeflate) { // missing decryption key (or paste ID) in URL? if (window.location.hash.length === 0) { - Alert.showError( - I18n._('Cannot decrypt paste: Decryption key missing in URL (Did you use a redirector or an URL shortener which strips part of the URL?)') - ); + Alert.showError('Cannot decrypt paste: Decryption key missing in URL (Did you use a redirector or an URL shortener which strips part of the URL?)'); return; } } @@ -5054,7 +5068,6 @@ jQuery.PrivateBin = (function($, RawDeflate) { Prompt.init(); TopNav.init(); UiHelper.init(); - z = (await zlib); if (!InitialCheck.init()) { // something major is wrong, stop right away return; diff --git a/js/test/CryptTool.js b/js/test/CryptTool.js index 80ea5ecb..9589ef97 100644 --- a/js/test/CryptTool.js +++ b/js/test/CryptTool.js @@ -8,6 +8,9 @@ describe('CryptTool', function () { await new Promise(resolve => setTimeout(resolve, 1900)); }); + // ensure zlib is getting loaded + $.PrivateBin.InitialCheck.init(); + this.timeout(30000); it('can en- and decrypt any message', function () { jsc.assert(jsc.forall( diff --git a/tpl/bootstrap.php b/tpl/bootstrap.php index 2d07fe22..caf4bb5f 100644 --- a/tpl/bootstrap.php +++ b/tpl/bootstrap.php @@ -71,7 +71,7 @@ if ($MARKDOWN): endif; ?> - + diff --git a/tpl/page.php b/tpl/page.php index eec66ae7..9b33be46 100644 --- a/tpl/page.php +++ b/tpl/page.php @@ -49,7 +49,7 @@ if ($MARKDOWN): endif; ?> - +