Merge branch 'better-feature-detection'
This commit is contained in:
commit
b496ae42fd
18
.eslintrc
18
.eslintrc
|
@ -1,3 +1,4 @@
|
||||||
|
---
|
||||||
parserOptions:
|
parserOptions:
|
||||||
ecmaVersion: 2017
|
ecmaVersion: 2017
|
||||||
|
|
||||||
|
@ -11,17 +12,16 @@ env:
|
||||||
es6: true
|
es6: true
|
||||||
jquery: true
|
jquery: true
|
||||||
node: true
|
node: true
|
||||||
|
mocha: true
|
||||||
|
|
||||||
globals:
|
globals:
|
||||||
DOMPurify: false
|
DOMPurify: readonly
|
||||||
after: true
|
cleanup: writable
|
||||||
before: true
|
describe: readonly
|
||||||
cleanup: true
|
jsc: readonly
|
||||||
describe: false
|
jsdom: writable
|
||||||
it: false
|
kjua: writable
|
||||||
jsc: false
|
WebCrypto: writable
|
||||||
jsdom: true
|
|
||||||
kjua: true
|
|
||||||
|
|
||||||
# http://eslint.org/docs/rules/
|
# http://eslint.org/docs/rules/
|
||||||
rules:
|
rules:
|
||||||
|
|
|
@ -68,8 +68,17 @@ languageselection = false
|
||||||
; custom scripts from third-party domains to your templates, e.g. tracking
|
; custom scripts from third-party domains to your templates, e.g. tracking
|
||||||
; scripts or run your site behind certain DDoS-protection services.
|
; scripts or run your site behind certain DDoS-protection services.
|
||||||
; Check the documentation at https://content-security-policy.com/
|
; Check the documentation at https://content-security-policy.com/
|
||||||
; Note: If you use a bootstrap theme, you can remove the allow-popups from the sandbox restrictions.
|
; Notes:
|
||||||
; By default this disallows to load images from third-party servers, e.g. when they are embedded in pastes. If you wish to allow that, you can adjust the policy here. See https://github.com/PrivateBin/PrivateBin/wiki/FAQ#why-does-not-it-load-embedded-images for details.
|
; - If you use a bootstrap theme, you can remove the allow-popups from the
|
||||||
|
; sandbox restrictions.
|
||||||
|
; - By default this disallows to load images from third-party servers, e.g. when
|
||||||
|
; they are embedded in pastes. If you wish to allow that, you can adjust the
|
||||||
|
; policy here. See https://github.com/PrivateBin/PrivateBin/wiki/FAQ#why-does-not-it-load-embedded-images
|
||||||
|
; for details.
|
||||||
|
; - The 'unsafe-eval' is used in two cases; to check if the browser supports
|
||||||
|
; 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'; manifest-src 'self'; connect-src * blob:; script-src 'self' 'unsafe-eval'; 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"
|
; cspheader = "default-src 'none'; manifest-src 'self'; connect-src * blob:; script-src 'self' 'unsafe-eval'; 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"
|
||||||
|
|
||||||
; stay compatible with PrivateBin Alpha 0.19, less secure
|
; stay compatible with PrivateBin Alpha 0.19, less secure
|
||||||
|
|
|
@ -35,8 +35,6 @@
|
||||||
"Услугата %s се нуждае от JavaScript, за да работи.<br />Съжаляваме за неудобството.",
|
"Услугата %s се нуждае от JavaScript, за да работи.<br />Съжаляваме за неудобството.",
|
||||||
"%s requires a modern browser to work.":
|
"%s requires a modern browser to work.":
|
||||||
"%s се нуждае от съвременен браузър за да работи.",
|
"%s се нуждае от съвременен браузър за да работи.",
|
||||||
"Still using Internet Explorer? Do yourself a favor, switch to a modern browser:":
|
|
||||||
"Все още използваш Internet Explorer? Направи си услуга и го смени с модерен браузър:",
|
|
||||||
"New":
|
"New":
|
||||||
"Създаване",
|
"Създаване",
|
||||||
"Send":
|
"Send":
|
||||||
|
@ -155,11 +153,12 @@
|
||||||
"Could not get paste data: %s":
|
"Could not get paste data: %s":
|
||||||
"Взимането на информацията беше неуспешно: %s",
|
"Взимането на информацията беше неуспешно: %s",
|
||||||
"QR code": "QR код",
|
"QR code": "QR код",
|
||||||
"I love you too, bot…": "И аз те обичам, бот…",
|
|
||||||
"This website is using an insecure HTTP connection! Please use it only for testing.":
|
"This website is using an insecure HTTP connection! Please use it only for testing.":
|
||||||
"Този сайт използва несигурна HTTP връзка. Моля използвайте само за проби.",
|
"Този сайт използва несигурна HTTP връзка. Моля използвайте само за проби.",
|
||||||
"For more information <a href=\"%s\">see this FAQ entry</a>.":
|
"For more information <a href=\"%s\">see this FAQ entry</a>.":
|
||||||
"<a href=\"%s\">Вижте тази страница</a> за повече информация.",
|
"<a href=\"%s\">Вижте тази страница</a> за повече информация.",
|
||||||
"Your browser may require an HTTPS connection to support the WebCrypto API. Try <a href=\"%s\">switching to HTTPS</a>.":
|
"Your browser may require an HTTPS connection to support the WebCrypto API. Try <a href=\"%s\">switching to HTTPS</a>.":
|
||||||
"Браузъра ви може да се нуждае от HTTPS връзка за да използва WebCrypto API. Пробвай <a href=\"%s\">да минеш на HTTPS</a>."
|
"Браузъра ви може да се нуждае от HTTPS връзка за да използва WebCrypto API. Пробвай <a href=\"%s\">да минеш на HTTPS</a>.",
|
||||||
|
"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."
|
||||||
}
|
}
|
||||||
|
|
|
@ -35,8 +35,6 @@
|
||||||
"JavaScript is required for %s to work.<br />Sorry for the inconvenience.",
|
"JavaScript is required for %s to work.<br />Sorry for the inconvenience.",
|
||||||
"%s requires a modern browser to work.":
|
"%s requires a modern browser to work.":
|
||||||
"%%s requires a modern browser to work.",
|
"%%s requires a modern browser to work.",
|
||||||
"Still using Internet Explorer? Do yourself a favor, switch to a modern browser:":
|
|
||||||
"Still using Internet Explorer? Do yourself a favor, switch to a modern browser:",
|
|
||||||
"New":
|
"New":
|
||||||
"Nový",
|
"Nový",
|
||||||
"Send":
|
"Send":
|
||||||
|
@ -155,11 +153,12 @@
|
||||||
"Could not get paste data: %s":
|
"Could not get paste data: %s":
|
||||||
"Could not get paste data: %s",
|
"Could not get paste data: %s",
|
||||||
"QR code": "QR code",
|
"QR code": "QR code",
|
||||||
"I love you too, bot…": "I love you too, bot…",
|
|
||||||
"This website is using an insecure HTTP connection! Please use it only for testing.":
|
"This website is using an insecure HTTP connection! Please use it only for testing.":
|
||||||
"This website is using an insecure HTTP connection! Please use it only for testing.",
|
"This website is using an insecure HTTP connection! Please use it only for testing.",
|
||||||
"For more information <a href=\"%s\">see this FAQ entry</a>.":
|
"For more information <a href=\"%s\">see this FAQ entry</a>.":
|
||||||
"For more information <a href=\"%s\">see this FAQ entry</a>.",
|
"For more information <a href=\"%s\">see this FAQ entry</a>.",
|
||||||
"Your browser may require an HTTPS connection to support the WebCrypto API. Try <a href=\"%s\">switching to HTTPS</a>.":
|
"Your browser may require an HTTPS connection to support the WebCrypto API. Try <a href=\"%s\">switching to HTTPS</a>.":
|
||||||
"Your browser may require an HTTPS connection to support the WebCrypto API. Try <a href=\"%s\">switching to HTTPS</a>."
|
"Your browser may require an HTTPS connection to support the WebCrypto API. Try <a href=\"%s\">switching to HTTPS</a>.",
|
||||||
|
"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."
|
||||||
}
|
}
|
||||||
|
|
|
@ -35,8 +35,6 @@
|
||||||
"JavaScript ist eine Voraussetzung, um %s zu nutzen.<br />Bitte entschuldige die Unannehmlichkeiten.",
|
"JavaScript ist eine Voraussetzung, um %s zu nutzen.<br />Bitte entschuldige die Unannehmlichkeiten.",
|
||||||
"%s requires a modern browser to work.":
|
"%s requires a modern browser to work.":
|
||||||
"%s setzt einen modernen Browser voraus, um funktionieren zu können.",
|
"%s setzt einen modernen Browser voraus, um funktionieren zu können.",
|
||||||
"Still using Internet Explorer? Do yourself a favor, switch to a modern browser:":
|
|
||||||
"Du benutzt immer noch den Internet Explorer? Tu Dir einen Gefallen und wechsle zu einem moderneren Browser:",
|
|
||||||
"New":
|
"New":
|
||||||
"Neu",
|
"Neu",
|
||||||
"Send":
|
"Send":
|
||||||
|
@ -155,11 +153,12 @@
|
||||||
"Could not get paste data: %s":
|
"Could not get paste data: %s":
|
||||||
"Text konnte nicht geladen werden: %s",
|
"Text konnte nicht geladen werden: %s",
|
||||||
"QR code": "QR code",
|
"QR code": "QR code",
|
||||||
"I love you too, bot…": "Ich mag Dich auch, bot…",
|
|
||||||
"This website is using an insecure HTTP connection! Please use it only for testing.":
|
"This website is using an insecure HTTP connection! Please use it only for testing.":
|
||||||
"Diese Webseite verwendet eine unsichere HTTP Verbindung! Bitte benutze sie nur zum Testen.",
|
"Diese Webseite verwendet eine unsichere HTTP Verbindung! Bitte benutze sie nur zum Testen.",
|
||||||
"For more information <a href=\"%s\">see this FAQ entry</a>.":
|
"For more information <a href=\"%s\">see this FAQ entry</a>.":
|
||||||
"<a href=\"%s\">Besuche diesen FAQ Eintrag</a> für weitere Informationen dazu.",
|
"<a href=\"%s\">Besuche diesen FAQ Eintrag</a> für weitere Informationen dazu.",
|
||||||
"Your browser may require an HTTPS connection to support the WebCrypto API. Try <a href=\"%s\">switching to HTTPS</a>.":
|
"Your browser may require an HTTPS connection to support the WebCrypto API. Try <a href=\"%s\">switching to HTTPS</a>.":
|
||||||
"Dein Browser benötigt möglicherweise eine HTTPS Verbindung um das WebCrypto API nutzen zu können. Versuche <a href=\"%s\">auf HTTPS zu wechseln</a>."
|
"Dein Browser benötigt möglicherweise eine HTTPS Verbindung um das WebCrypto API nutzen zu können. Versuche <a href=\"%s\">auf HTTPS zu wechseln</a>.",
|
||||||
|
"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."
|
||||||
}
|
}
|
||||||
|
|
|
@ -35,8 +35,6 @@
|
||||||
"JavaScript es necesario para que %s funcione.<br />Sentimos los inconvenientes ocasionados.",
|
"JavaScript es necesario para que %s funcione.<br />Sentimos los inconvenientes ocasionados.",
|
||||||
"%s requires a modern browser to work.":
|
"%s requires a modern browser to work.":
|
||||||
"%s requiere un navegador moderno para funcionar.",
|
"%s requiere un navegador moderno para funcionar.",
|
||||||
"Still using Internet Explorer? Do yourself a favor, switch to a modern browser:":
|
|
||||||
"¿Sigues usando Internet Explorer? Hazte un favor, cambia a un navegador moderno:",
|
|
||||||
"New":
|
"New":
|
||||||
"Nuevo",
|
"Nuevo",
|
||||||
"Send":
|
"Send":
|
||||||
|
@ -155,11 +153,12 @@
|
||||||
"Could not get paste data: %s":
|
"Could not get paste data: %s":
|
||||||
"No se pudieron obtener los datos: %s",
|
"No se pudieron obtener los datos: %s",
|
||||||
"QR code": "Código QR",
|
"QR code": "Código QR",
|
||||||
"I love you too, bot…": "I love you too, bot…",
|
|
||||||
"This website is using an insecure HTTP connection! Please use it only for testing.":
|
"This website is using an insecure HTTP connection! Please use it only for testing.":
|
||||||
"This website is using an insecure HTTP connection! Please use it only for testing.",
|
"This website is using an insecure HTTP connection! Please use it only for testing.",
|
||||||
"For more information <a href=\"%s\">see this FAQ entry</a>.":
|
"For more information <a href=\"%s\">see this FAQ entry</a>.":
|
||||||
"For more information <a href=\"%s\">see this FAQ entry</a>.",
|
"For more information <a href=\"%s\">see this FAQ entry</a>.",
|
||||||
"Your browser may require an HTTPS connection to support the WebCrypto API. Try <a href=\"%s\">switching to HTTPS</a>.":
|
"Your browser may require an HTTPS connection to support the WebCrypto API. Try <a href=\"%s\">switching to HTTPS</a>.":
|
||||||
"Your browser may require an HTTPS connection to support the WebCrypto API. Try <a href=\"%s\">switching to HTTPS</a>."
|
"Your browser may require an HTTPS connection to support the WebCrypto API. Try <a href=\"%s\">switching to HTTPS</a>.",
|
||||||
|
"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."
|
||||||
}
|
}
|
||||||
|
|
|
@ -35,8 +35,6 @@
|
||||||
"JavaScript est requis pour faire fonctionner %s. <br />Désolé pour cet inconvénient.",
|
"JavaScript est requis pour faire fonctionner %s. <br />Désolé pour cet inconvénient.",
|
||||||
"%s requires a modern browser to work.":
|
"%s requires a modern browser to work.":
|
||||||
"%s nécessite un navigateur moderne pour fonctionner.",
|
"%s nécessite un navigateur moderne pour fonctionner.",
|
||||||
"Still using Internet Explorer? Do yourself a favor, switch to a modern browser:":
|
|
||||||
"Encore sur Internet Explorer ? Faites-vous une faveur, passez à un navigateur moderne :",
|
|
||||||
"New":
|
"New":
|
||||||
"Nouveau",
|
"Nouveau",
|
||||||
"Send":
|
"Send":
|
||||||
|
@ -164,11 +162,12 @@
|
||||||
"Could not get paste data: %s":
|
"Could not get paste data: %s":
|
||||||
"Impossible d'obtenir les données du paste: %s",
|
"Impossible d'obtenir les données du paste: %s",
|
||||||
"QR code": "QR code",
|
"QR code": "QR code",
|
||||||
"I love you too, bot…": "Je t’aime aussi, bot…",
|
|
||||||
"This website is using an insecure HTTP connection! Please use it only for testing.":
|
"This website is using an insecure HTTP connection! Please use it only for testing.":
|
||||||
"Ce site web utilise une connexion HTTP non sécurisée ! Veuillez l’utiliser uniquement pour des tests.",
|
"Ce site web utilise une connexion HTTP non sécurisée ! Veuillez l’utiliser uniquement pour des tests.",
|
||||||
"For more information <a href=\"%s\">see this FAQ entry</a>.":
|
"For more information <a href=\"%s\">see this FAQ entry</a>.":
|
||||||
"Pour plus d'informations <a href=\"%s\">consultez cette rubrique de la FAQ</a>.",
|
"Pour plus d'informations <a href=\"%s\">consultez cette rubrique de la FAQ</a>.",
|
||||||
"Your browser may require an HTTPS connection to support the WebCrypto API. Try <a href=\"%s\">switching to HTTPS</a>.":
|
"Your browser may require an HTTPS connection to support the WebCrypto API. Try <a href=\"%s\">switching to HTTPS</a>.":
|
||||||
"Votre navigateur peut nécessiter une connexion HTTPS pour prendre en charge l’API WebCrypto. Essayez <a href=\"%s\">de passer en HTTPS</a>."
|
"Votre navigateur peut nécessiter une connexion HTTPS pour prendre en charge l’API WebCrypto. Essayez <a href=\"%s\">de passer en HTTPS</a>.",
|
||||||
|
"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."
|
||||||
}
|
}
|
||||||
|
|
|
@ -35,8 +35,6 @@
|
||||||
"JavaScript szükséges a %s működéséhez. Elnézést a fennakadásért.",
|
"JavaScript szükséges a %s működéséhez. Elnézést a fennakadásért.",
|
||||||
"%s requires a modern browser to work.":
|
"%s requires a modern browser to work.":
|
||||||
"A %s működéséhez a jelenleginél újabb böngészőre van szükség.",
|
"A %s működéséhez a jelenleginél újabb böngészőre van szükség.",
|
||||||
"Still using Internet Explorer? Do yourself a favor, switch to a modern browser:":
|
|
||||||
"Még mindig Internet Explorert használsz? Ideje váltani:",
|
|
||||||
"New":
|
"New":
|
||||||
"Új",
|
"Új",
|
||||||
"Send":
|
"Send":
|
||||||
|
@ -155,11 +153,12 @@
|
||||||
"Could not get paste data: %s":
|
"Could not get paste data: %s":
|
||||||
"Could not get paste data: %s",
|
"Could not get paste data: %s",
|
||||||
"QR code": "QR code",
|
"QR code": "QR code",
|
||||||
"I love you too, bot…": "I love you too, bot…",
|
|
||||||
"This website is using an insecure HTTP connection! Please use it only for testing.":
|
"This website is using an insecure HTTP connection! Please use it only for testing.":
|
||||||
"This website is using an insecure HTTP connection! Please use it only for testing.",
|
"This website is using an insecure HTTP connection! Please use it only for testing.",
|
||||||
"For more information <a href=\"%s\">see this FAQ entry</a>.":
|
"For more information <a href=\"%s\">see this FAQ entry</a>.":
|
||||||
"For more information <a href=\"%s\">see this FAQ entry</a>.",
|
"For more information <a href=\"%s\">see this FAQ entry</a>.",
|
||||||
"Your browser may require an HTTPS connection to support the WebCrypto API. Try <a href=\"%s\">switching to HTTPS</a>.":
|
"Your browser may require an HTTPS connection to support the WebCrypto API. Try <a href=\"%s\">switching to HTTPS</a>.":
|
||||||
"Your browser may require an HTTPS connection to support the WebCrypto API. Try <a href=\"%s\">switching to HTTPS</a>."
|
"Your browser may require an HTTPS connection to support the WebCrypto API. Try <a href=\"%s\">switching to HTTPS</a>.",
|
||||||
|
"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."
|
||||||
}
|
}
|
||||||
|
|
|
@ -35,8 +35,6 @@
|
||||||
"%s funziona solo con JavaScript attivo.<br />Ci dispiace per l'inconveniente.",
|
"%s funziona solo con JavaScript attivo.<br />Ci dispiace per l'inconveniente.",
|
||||||
"%s requires a modern browser to work.":
|
"%s requires a modern browser to work.":
|
||||||
"%s richiede un browser moderno e aggiornato per funzionare.",
|
"%s richiede un browser moderno e aggiornato per funzionare.",
|
||||||
"Still using Internet Explorer? Do yourself a favor, switch to a modern browser:":
|
|
||||||
"Usi ancora Internet Explorer? Ti consigliamo di passare ad un browser più sicuro:",
|
|
||||||
"New":
|
"New":
|
||||||
"Nuovo",
|
"Nuovo",
|
||||||
"Send":
|
"Send":
|
||||||
|
@ -155,11 +153,12 @@
|
||||||
"Could not get paste data: %s":
|
"Could not get paste data: %s":
|
||||||
"Could not get paste data: %s",
|
"Could not get paste data: %s",
|
||||||
"QR code": "QR code",
|
"QR code": "QR code",
|
||||||
"I love you too, bot…": "I love you too, bot…",
|
|
||||||
"This website is using an insecure HTTP connection! Please use it only for testing.":
|
"This website is using an insecure HTTP connection! Please use it only for testing.":
|
||||||
"This website is using an insecure HTTP connection! Please use it only for testing.",
|
"This website is using an insecure HTTP connection! Please use it only for testing.",
|
||||||
"For more information <a href=\"%s\">see this FAQ entry</a>.":
|
"For more information <a href=\"%s\">see this FAQ entry</a>.":
|
||||||
"For more information <a href=\"%s\">see this FAQ entry</a>.",
|
"For more information <a href=\"%s\">see this FAQ entry</a>.",
|
||||||
"Your browser may require an HTTPS connection to support the WebCrypto API. Try <a href=\"%s\">switching to HTTPS</a>.":
|
"Your browser may require an HTTPS connection to support the WebCrypto API. Try <a href=\"%s\">switching to HTTPS</a>.":
|
||||||
"Your browser may require an HTTPS connection to support the WebCrypto API. Try <a href=\"%s\">switching to HTTPS</a>."
|
"Your browser may require an HTTPS connection to support the WebCrypto API. Try <a href=\"%s\">switching to HTTPS</a>.",
|
||||||
|
"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."
|
||||||
}
|
}
|
||||||
|
|
|
@ -35,8 +35,6 @@
|
||||||
"JavaScript vereist om %s te laten werken.<br />Sorry voor het ongemak.",
|
"JavaScript vereist om %s te laten werken.<br />Sorry voor het ongemak.",
|
||||||
"%s requires a modern browser to work.":
|
"%s requires a modern browser to work.":
|
||||||
"%s vereist een moderne browser om te kunnen werken ",
|
"%s vereist een moderne browser om te kunnen werken ",
|
||||||
"Still using Internet Explorer? Do yourself a favor, switch to a modern browser:":
|
|
||||||
"Gebruik je nog steeds Internet explorer? Doe jezelf een plezier en maak gebruik van een moderne browser:",
|
|
||||||
"New":
|
"New":
|
||||||
"Nieuw",
|
"Nieuw",
|
||||||
"Send":
|
"Send":
|
||||||
|
@ -155,11 +153,12 @@
|
||||||
"Could not get paste data: %s":
|
"Could not get paste data: %s":
|
||||||
"Could not get paste data: %s",
|
"Could not get paste data: %s",
|
||||||
"QR code": "QR code",
|
"QR code": "QR code",
|
||||||
"I love you too, bot…": "I love you too, bot…",
|
|
||||||
"This website is using an insecure HTTP connection! Please use it only for testing.":
|
"This website is using an insecure HTTP connection! Please use it only for testing.":
|
||||||
"This website is using an insecure HTTP connection! Please use it only for testing.",
|
"This website is using an insecure HTTP connection! Please use it only for testing.",
|
||||||
"For more information <a href=\"%s\">see this FAQ entry</a>.":
|
"For more information <a href=\"%s\">see this FAQ entry</a>.":
|
||||||
"For more information <a href=\"%s\">see this FAQ entry</a>.",
|
"For more information <a href=\"%s\">see this FAQ entry</a>.",
|
||||||
"Your browser may require an HTTPS connection to support the WebCrypto API. Try <a href=\"%s\">switching to HTTPS</a>.":
|
"Your browser may require an HTTPS connection to support the WebCrypto API. Try <a href=\"%s\">switching to HTTPS</a>.":
|
||||||
"Your browser may require an HTTPS connection to support the WebCrypto API. Try <a href=\"%s\">switching to HTTPS</a>."
|
"Your browser may require an HTTPS connection to support the WebCrypto API. Try <a href=\"%s\">switching to HTTPS</a>.",
|
||||||
|
"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."
|
||||||
}
|
}
|
||||||
|
|
|
@ -35,8 +35,6 @@
|
||||||
"Javascript kreves for at %s skal fungere<br />Beklager.",
|
"Javascript kreves for at %s skal fungere<br />Beklager.",
|
||||||
"%s requires a modern browser to work.":
|
"%s requires a modern browser to work.":
|
||||||
"%s krever en moderne nettleser for å fungere.",
|
"%s krever en moderne nettleser for å fungere.",
|
||||||
"Still using Internet Explorer? Do yourself a favor, switch to a modern browser:":
|
|
||||||
"Fortsatt bruker av Internet Explorer? Gjør deg selv en tjeneste og bytt til en moderne nettleser:",
|
|
||||||
"New":
|
"New":
|
||||||
"Ny",
|
"Ny",
|
||||||
"Send":
|
"Send":
|
||||||
|
@ -155,11 +153,12 @@
|
||||||
"Could not get paste data: %s":
|
"Could not get paste data: %s":
|
||||||
"Kunne ikke hente utklippsdata: %s",
|
"Kunne ikke hente utklippsdata: %s",
|
||||||
"QR code": "QR kode",
|
"QR code": "QR kode",
|
||||||
"I love you too, bot…": "Jeg elsker deg også, bot…",
|
|
||||||
"This website is using an insecure HTTP connection! Please use it only for testing.":
|
"This website is using an insecure HTTP connection! Please use it only for testing.":
|
||||||
"Denne websiden bruker usikker HTTP tilkobling! Bruk den kun for testing.",
|
"Denne websiden bruker usikker HTTP tilkobling! Bruk den kun for testing.",
|
||||||
"For more information <a href=\"%s\">see this FAQ entry</a>.":
|
"For more information <a href=\"%s\">see this FAQ entry</a>.":
|
||||||
"For mer informasjon <a href=\"%s\">se ofte stilte spørsmål</a>.",
|
"For mer informasjon <a href=\"%s\">se ofte stilte spørsmål</a>.",
|
||||||
"Your browser may require an HTTPS connection to support the WebCrypto API. Try <a href=\"%s\">switching to HTTPS</a>.":
|
"Your browser may require an HTTPS connection to support the WebCrypto API. Try <a href=\"%s\">switching to HTTPS</a>.":
|
||||||
"Din nettleser har behov for HTTPS tilkobling for å støtte WebCrypto biblioteket. Prøv å <a href=\"%s\">bytt til HTTPS</a>."
|
"Din nettleser har behov for HTTPS tilkobling for å støtte WebCrypto biblioteket. Prøv å <a href=\"%s\">bytt til HTTPS</a>.",
|
||||||
|
"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."
|
||||||
}
|
}
|
||||||
|
|
|
@ -35,8 +35,6 @@
|
||||||
"JavaScript es requesit per far foncionar %s. <br />O planhèm per l’inconvenient.",
|
"JavaScript es requesit per far foncionar %s. <br />O planhèm per l’inconvenient.",
|
||||||
"%s requires a modern browser to work.":
|
"%s requires a modern browser to work.":
|
||||||
"%s necessita un navigator modèrn per foncionar.",
|
"%s necessita un navigator modèrn per foncionar.",
|
||||||
"Still using Internet Explorer? Do yourself a favor, switch to a modern browser:":
|
|
||||||
"Encora sus Internet Explorer ? Fasètz-vos una favor, passatz a un navigator modèrn :",
|
|
||||||
"New":
|
"New":
|
||||||
"Nòu",
|
"Nòu",
|
||||||
"Send":
|
"Send":
|
||||||
|
@ -164,11 +162,12 @@
|
||||||
"Could not get paste data: %s":
|
"Could not get paste data: %s":
|
||||||
"Recuperacion impossibla de las donadas copiadas : %s",
|
"Recuperacion impossibla de las donadas copiadas : %s",
|
||||||
"QR code": "Còdi QR",
|
"QR code": "Còdi QR",
|
||||||
"I love you too, bot…": "T’aimi tanben, robòt…",
|
|
||||||
"This website is using an insecure HTTP connection! Please use it only for testing.":
|
"This website is using an insecure HTTP connection! Please use it only for testing.":
|
||||||
"Aqueste site utiliza una connexion HTTP pas segura ! Mercés de l’utilizar pas que per d’ensages.",
|
"Aqueste site utiliza una connexion HTTP pas segura ! Mercés de l’utilizar pas que per d’ensages.",
|
||||||
"For more information <a href=\"%s\">see this FAQ entry</a>.":
|
"For more information <a href=\"%s\">see this FAQ entry</a>.":
|
||||||
"Per mai d’informacions <a href=\"%s\">vejatz aqueste article de FAQ</a>.",
|
"Per mai d’informacions <a href=\"%s\">vejatz aqueste article de FAQ</a>.",
|
||||||
"Your browser may require an HTTPS connection to support the WebCrypto API. Try <a href=\"%s\">switching to HTTPS</a>.":
|
"Your browser may require an HTTPS connection to support the WebCrypto API. Try <a href=\"%s\">switching to HTTPS</a>.":
|
||||||
"Se pòt que vòstre navigator faga besonh d’una connexion HTTPS per èsser compatible amb l’API WebCrypto. Ensajatz de <a href=\"%s\">passar al HTTPS</a>."
|
"Se pòt que vòstre navigator faga besonh d’una connexion HTTPS per èsser compatible amb l’API WebCrypto. Ensajatz de <a href=\"%s\">passar al HTTPS</a>.",
|
||||||
|
"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."
|
||||||
}
|
}
|
||||||
|
|
|
@ -35,8 +35,6 @@
|
||||||
"Do działania %sa jest wymagany JavaScript. Przepraszamy za tę niedogodność.",
|
"Do działania %sa jest wymagany JavaScript. Przepraszamy za tę niedogodność.",
|
||||||
"%s requires a modern browser to work.":
|
"%s requires a modern browser to work.":
|
||||||
"%s wymaga do działania nowoczesnej przeglądarki.",
|
"%s wymaga do działania nowoczesnej przeglądarki.",
|
||||||
"Still using Internet Explorer? Do yourself a favor, switch to a modern browser:":
|
|
||||||
"Cały czas używasz Internet Explorera? Zrób sobie przysługę, przesiądź się na nowoczesną przeglądarkę:",
|
|
||||||
"New":
|
"New":
|
||||||
"Nowa",
|
"Nowa",
|
||||||
"Send":
|
"Send":
|
||||||
|
@ -155,11 +153,12 @@
|
||||||
"Could not get paste data: %s":
|
"Could not get paste data: %s":
|
||||||
"Nie można było pobrać danych wklejki: %s",
|
"Nie można było pobrać danych wklejki: %s",
|
||||||
"QR code": "Kod QR",
|
"QR code": "Kod QR",
|
||||||
"I love you too, bot…": "I love you too, bot…",
|
|
||||||
"This website is using an insecure HTTP connection! Please use it only for testing.":
|
"This website is using an insecure HTTP connection! Please use it only for testing.":
|
||||||
"This website is using an insecure HTTP connection! Please use it only for testing.",
|
"This website is using an insecure HTTP connection! Please use it only for testing.",
|
||||||
"For more information <a href=\"%s\">see this FAQ entry</a>.":
|
"For more information <a href=\"%s\">see this FAQ entry</a>.":
|
||||||
"For more information <a href=\"%s\">see this FAQ entry</a>.",
|
"For more information <a href=\"%s\">see this FAQ entry</a>.",
|
||||||
"Your browser may require an HTTPS connection to support the WebCrypto API. Try <a href=\"%s\">switching to HTTPS</a>.":
|
"Your browser may require an HTTPS connection to support the WebCrypto API. Try <a href=\"%s\">switching to HTTPS</a>.":
|
||||||
"Your browser may require an HTTPS connection to support the WebCrypto API. Try <a href=\"%s\">switching to HTTPS</a>."
|
"Your browser may require an HTTPS connection to support the WebCrypto API. Try <a href=\"%s\">switching to HTTPS</a>.",
|
||||||
|
"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."
|
||||||
}
|
}
|
||||||
|
|
|
@ -35,8 +35,6 @@
|
||||||
"JavaScript é necessário para que %s funcione.<br />Pedimos desculpas pela inconveniência.",
|
"JavaScript é necessário para que %s funcione.<br />Pedimos desculpas pela inconveniência.",
|
||||||
"%s requires a modern browser to work.":
|
"%s requires a modern browser to work.":
|
||||||
"%s requer um navegador moderno para funcionar.",
|
"%s requer um navegador moderno para funcionar.",
|
||||||
"Still using Internet Explorer? Do yourself a favor, switch to a modern browser:":
|
|
||||||
"Ainda usando Internet Explorer? Faça-se um favor, mude para um navegador moderno:",
|
|
||||||
"New":
|
"New":
|
||||||
"Novo",
|
"Novo",
|
||||||
"Send":
|
"Send":
|
||||||
|
@ -155,11 +153,12 @@
|
||||||
"Could not get paste data: %s":
|
"Could not get paste data: %s":
|
||||||
"Could not get paste data: %s",
|
"Could not get paste data: %s",
|
||||||
"QR code": "QR code",
|
"QR code": "QR code",
|
||||||
"I love you too, bot…": "I love you too, bot…",
|
|
||||||
"This website is using an insecure HTTP connection! Please use it only for testing.":
|
"This website is using an insecure HTTP connection! Please use it only for testing.":
|
||||||
"This website is using an insecure HTTP connection! Please use it only for testing.",
|
"This website is using an insecure HTTP connection! Please use it only for testing.",
|
||||||
"For more information <a href=\"%s\">see this FAQ entry</a>.":
|
"For more information <a href=\"%s\">see this FAQ entry</a>.":
|
||||||
"For more information <a href=\"%s\">see this FAQ entry</a>.",
|
"For more information <a href=\"%s\">see this FAQ entry</a>.",
|
||||||
"Your browser may require an HTTPS connection to support the WebCrypto API. Try <a href=\"%s\">switching to HTTPS</a>.":
|
"Your browser may require an HTTPS connection to support the WebCrypto API. Try <a href=\"%s\">switching to HTTPS</a>.":
|
||||||
"Your browser may require an HTTPS connection to support the WebCrypto API. Try <a href=\"%s\">switching to HTTPS</a>."
|
"Your browser may require an HTTPS connection to support the WebCrypto API. Try <a href=\"%s\">switching to HTTPS</a>.",
|
||||||
|
"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."
|
||||||
}
|
}
|
||||||
|
|
|
@ -35,8 +35,6 @@
|
||||||
"Для работы %s требуется включенный JavaScript.<br />Приносим извинения за неудобства.",
|
"Для работы %s требуется включенный JavaScript.<br />Приносим извинения за неудобства.",
|
||||||
"%s requires a modern browser to work.":
|
"%s requires a modern browser to work.":
|
||||||
"Для работы %s требуется более современный браузер.",
|
"Для работы %s требуется более современный браузер.",
|
||||||
"Still using Internet Explorer? Do yourself a favor, switch to a modern browser:":
|
|
||||||
"До сих пор используете Internet Explorer? Пожалейте себя, перейдите на более современный браузер:",
|
|
||||||
"New":
|
"New":
|
||||||
"Новая запись",
|
"Новая запись",
|
||||||
"Send":
|
"Send":
|
||||||
|
@ -165,11 +163,12 @@
|
||||||
"Could not get paste data: %s":
|
"Could not get paste data: %s":
|
||||||
"Не удалось получить данные записи: %s",
|
"Не удалось получить данные записи: %s",
|
||||||
"QR code": "QR код",
|
"QR code": "QR код",
|
||||||
"I love you too, bot…": "Я тоже люблю тебя, бот…",
|
|
||||||
"This website is using an insecure HTTP connection! Please use it only for testing.":
|
"This website is using an insecure HTTP connection! Please use it only for testing.":
|
||||||
"Данный сайт использует незащищенное HTTP подключение! Пожалуйста используйте его только для тестирования.",
|
"Данный сайт использует незащищенное HTTP подключение! Пожалуйста используйте его только для тестирования.",
|
||||||
"For more information <a href=\"%s\">see this FAQ entry</a>.":
|
"For more information <a href=\"%s\">see this FAQ entry</a>.":
|
||||||
"Для продробностей <a href=\"%s\">прочтите информацию в FAQ</a>.",
|
"Для продробностей <a href=\"%s\">прочтите информацию в FAQ</a>.",
|
||||||
"Your browser may require an HTTPS connection to support the WebCrypto API. Try <a href=\"%s\">switching to HTTPS</a>.":
|
"Your browser may require an HTTPS connection to support the WebCrypto API. Try <a href=\"%s\">switching to HTTPS</a>.":
|
||||||
"Ваш браузер требует использования HTTPS подключения для поддержки WebCrypto API. Попробуйте <a href=\"%s\">переключиться на HTTPS</a>."
|
"Ваш браузер требует использования HTTPS подключения для поддержки WebCrypto API. Попробуйте <a href=\"%s\">переключиться на HTTPS</a>.",
|
||||||
|
"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."
|
||||||
}
|
}
|
||||||
|
|
|
@ -35,8 +35,6 @@
|
||||||
"Da %s deluje, moraš vklopiti JavaScript.<br />Oprosti za povročene nevšečnosti.",
|
"Da %s deluje, moraš vklopiti JavaScript.<br />Oprosti za povročene nevšečnosti.",
|
||||||
"%s requires a modern browser to work.":
|
"%s requires a modern browser to work.":
|
||||||
"%s za svoje delovanje potrebuje moderen brskalnik.",
|
"%s za svoje delovanje potrebuje moderen brskalnik.",
|
||||||
"Still using Internet Explorer? Do yourself a favor, switch to a modern browser:":
|
|
||||||
"Še vedno uporabljaš Internet Explorer? Naredi si uslugo, preklopi na moderen brskalnik:",
|
|
||||||
"New":
|
"New":
|
||||||
"Nov prilepek",
|
"Nov prilepek",
|
||||||
"Send":
|
"Send":
|
||||||
|
@ -164,11 +162,12 @@
|
||||||
"Could not get paste data: %s":
|
"Could not get paste data: %s":
|
||||||
"Could not get paste data: %s",
|
"Could not get paste data: %s",
|
||||||
"QR code": "QR code",
|
"QR code": "QR code",
|
||||||
"I love you too, bot…": "I love you too, bot…",
|
|
||||||
"This website is using an insecure HTTP connection! Please use it only for testing.":
|
"This website is using an insecure HTTP connection! Please use it only for testing.":
|
||||||
"This website is using an insecure HTTP connection! Please use it only for testing.",
|
"This website is using an insecure HTTP connection! Please use it only for testing.",
|
||||||
"For more information <a href=\"%s\">see this FAQ entry</a>.":
|
"For more information <a href=\"%s\">see this FAQ entry</a>.":
|
||||||
"For more information <a href=\"%s\">see this FAQ entry</a>.",
|
"For more information <a href=\"%s\">see this FAQ entry</a>.",
|
||||||
"Your browser may require an HTTPS connection to support the WebCrypto API. Try <a href=\"%s\">switching to HTTPS</a>.":
|
"Your browser may require an HTTPS connection to support the WebCrypto API. Try <a href=\"%s\">switching to HTTPS</a>.":
|
||||||
"Your browser may require an HTTPS connection to support the WebCrypto API. Try <a href=\"%s\">switching to HTTPS</a>."
|
"Your browser may require an HTTPS connection to support the WebCrypto API. Try <a href=\"%s\">switching to HTTPS</a>.",
|
||||||
|
"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."
|
||||||
}
|
}
|
||||||
|
|
|
@ -35,8 +35,6 @@
|
||||||
"%s需要JavaScript来进行加解密。<br />给你带来的不便敬请谅解。",
|
"%s需要JavaScript来进行加解密。<br />给你带来的不便敬请谅解。",
|
||||||
"%s requires a modern browser to work.":
|
"%s requires a modern browser to work.":
|
||||||
"%s需要在现代浏览器上工作。",
|
"%s需要在现代浏览器上工作。",
|
||||||
"Still using Internet Explorer? Do yourself a favor, switch to a modern browser:":
|
|
||||||
"还在使用Internet Explorer?对自己好点,换一个现代浏览器:",
|
|
||||||
"New":
|
"New":
|
||||||
"新建",
|
"新建",
|
||||||
"Send":
|
"Send":
|
||||||
|
@ -155,11 +153,12 @@
|
||||||
"Could not get paste data: %s":
|
"Could not get paste data: %s":
|
||||||
"无法获取粘贴数据:%s",
|
"无法获取粘贴数据:%s",
|
||||||
"QR code": "二维码",
|
"QR code": "二维码",
|
||||||
"I love you too, bot…": "I love you too, bot…",
|
|
||||||
"This website is using an insecure HTTP connection! Please use it only for testing.":
|
"This website is using an insecure HTTP connection! Please use it only for testing.":
|
||||||
"This website is using an insecure HTTP connection! Please use it only for testing.",
|
"This website is using an insecure HTTP connection! Please use it only for testing.",
|
||||||
"For more information <a href=\"%s\">see this FAQ entry</a>.":
|
"For more information <a href=\"%s\">see this FAQ entry</a>.":
|
||||||
"For more information <a href=\"%s\">see this FAQ entry</a>.",
|
"For more information <a href=\"%s\">see this FAQ entry</a>.",
|
||||||
"Your browser may require an HTTPS connection to support the WebCrypto API. Try <a href=\"%s\">switching to HTTPS</a>.":
|
"Your browser may require an HTTPS connection to support the WebCrypto API. Try <a href=\"%s\">switching to HTTPS</a>.":
|
||||||
"Your browser may require an HTTPS connection to support the WebCrypto API. Try <a href=\"%s\">switching to HTTPS</a>."
|
"Your browser may require an HTTPS connection to support the WebCrypto API. Try <a href=\"%s\">switching to HTTPS</a>.",
|
||||||
|
"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."
|
||||||
}
|
}
|
||||||
|
|
|
@ -19,6 +19,7 @@ global.prettyPrintOne = window.PR.prettyPrintOne;
|
||||||
global.showdown = require('./showdown-1.9.1');
|
global.showdown = require('./showdown-1.9.1');
|
||||||
global.DOMPurify = require('./purify-2.0.1');
|
global.DOMPurify = require('./purify-2.0.1');
|
||||||
global.baseX = require('./base-x-3.0.5.1').baseX;
|
global.baseX = require('./base-x-3.0.5.1').baseX;
|
||||||
|
global.Legacy = require('./legacy').Legacy;
|
||||||
require('./bootstrap-3.3.7');
|
require('./bootstrap-3.3.7');
|
||||||
require('./privatebin');
|
require('./privatebin');
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,309 @@
|
||||||
|
/**
|
||||||
|
* PrivateBin
|
||||||
|
*
|
||||||
|
* a zero-knowledge paste bin
|
||||||
|
*
|
||||||
|
* @see {@link https://github.com/PrivateBin/PrivateBin}
|
||||||
|
* @copyright 2012 Sébastien SAUVAGE ({@link http://sebsauvage.net})
|
||||||
|
* @license {@link https://www.opensource.org/licenses/zlib-license.php The zlib/libpng License}
|
||||||
|
* @version 1.3
|
||||||
|
* @name Legacy
|
||||||
|
* @namespace
|
||||||
|
*
|
||||||
|
* IMPORTANT NOTICE FOR DEVELOPERS:
|
||||||
|
* The logic in this file is intended to run in legacy browsers. Avoid any use of:
|
||||||
|
* - jQuery (doesn't work in older browsers)
|
||||||
|
* - ES5 or newer in general
|
||||||
|
* - const/let, use the traditional var declarations instead
|
||||||
|
* - async/await or Promises, use traditional callbacks
|
||||||
|
* - shorthand function notation "() => output", use the full "function() {return output;}" style
|
||||||
|
* - IE doesn't support:
|
||||||
|
* - URL(), use the traditional window.location object
|
||||||
|
* - endsWith(), use indexof()
|
||||||
|
* - yes, this logic needs to support IE 6, to at least display the error message
|
||||||
|
*/
|
||||||
|
|
||||||
|
'use strict';
|
||||||
|
(function() {
|
||||||
|
/**
|
||||||
|
* compatibility check
|
||||||
|
*
|
||||||
|
* @name Check
|
||||||
|
* @class
|
||||||
|
*/
|
||||||
|
var Check = (function () {
|
||||||
|
var me = {};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Status of the initial check, true means it passed
|
||||||
|
*
|
||||||
|
* @private
|
||||||
|
* @prop {bool}
|
||||||
|
*/
|
||||||
|
var status = false;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Initialization check did run
|
||||||
|
*
|
||||||
|
* @private
|
||||||
|
* @prop {bool}
|
||||||
|
*/
|
||||||
|
var init = false;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* blacklist of UserAgents (parts) known to belong to a bot
|
||||||
|
*
|
||||||
|
* @private
|
||||||
|
* @enum {Array}
|
||||||
|
* @readonly
|
||||||
|
*/
|
||||||
|
var badBotUA = [
|
||||||
|
'Bot',
|
||||||
|
'bot'
|
||||||
|
];
|
||||||
|
|
||||||
|
/**
|
||||||
|
* whitelist of top level domains to consider a secure context,
|
||||||
|
* regardless of protocol
|
||||||
|
*
|
||||||
|
* @private
|
||||||
|
* @enum {Array}
|
||||||
|
* @readonly
|
||||||
|
*/
|
||||||
|
var tld = [
|
||||||
|
'.onion',
|
||||||
|
'.i2p'
|
||||||
|
];
|
||||||
|
|
||||||
|
/**
|
||||||
|
* whitelist of hostnames to consider a secure context,
|
||||||
|
* regardless of protocol
|
||||||
|
*
|
||||||
|
* @private
|
||||||
|
* @enum {Array}
|
||||||
|
* @readonly
|
||||||
|
*/
|
||||||
|
// whitelists of TLDs & local hostnames
|
||||||
|
var hostname = [
|
||||||
|
'localhost',
|
||||||
|
'127.0.0.1',
|
||||||
|
'[::1]'
|
||||||
|
];
|
||||||
|
|
||||||
|
/**
|
||||||
|
* check if the context is secure
|
||||||
|
*
|
||||||
|
* @private
|
||||||
|
* @name Check.isSecureContext
|
||||||
|
* @function
|
||||||
|
* @return {bool}
|
||||||
|
*/
|
||||||
|
function isSecureContext()
|
||||||
|
{
|
||||||
|
// use .isSecureContext if available
|
||||||
|
if (window.isSecureContext === true || window.isSecureContext === false) {
|
||||||
|
return window.isSecureContext;
|
||||||
|
}
|
||||||
|
|
||||||
|
// HTTP is obviously insecure
|
||||||
|
if (window.location.protocol !== 'http:') {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
// filter out actually secure connections over HTTP
|
||||||
|
for (var i = 0; i < tld.length; i++) {
|
||||||
|
if (
|
||||||
|
window.location.hostname.indexOf(
|
||||||
|
tld[i],
|
||||||
|
window.location.hostname.length - tld[i].length
|
||||||
|
) !== -1
|
||||||
|
) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// whitelist localhost for development
|
||||||
|
for (var j = 0; j < hostname.length; j++) {
|
||||||
|
if (window.location.hostname === hostname[j]) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// totally INSECURE http protocol!
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* checks whether this is a bot we dislike
|
||||||
|
*
|
||||||
|
* @private
|
||||||
|
* @name Check.isBadBot
|
||||||
|
* @function
|
||||||
|
* @return {bool}
|
||||||
|
*/
|
||||||
|
function isBadBot() {
|
||||||
|
// check whether a bot user agent part can be found in the current
|
||||||
|
// user agent
|
||||||
|
for (var i = 0; i < badBotUA.length; i++) {
|
||||||
|
if (navigator.userAgent.indexOf(badBotUA[i]) !== -1) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* checks whether this is an unsupported browser, via feature detection
|
||||||
|
*
|
||||||
|
* @private
|
||||||
|
* @name Check.isOldBrowser
|
||||||
|
* @function
|
||||||
|
* @return {bool}
|
||||||
|
*/
|
||||||
|
function isOldBrowser() {
|
||||||
|
// webcrypto support
|
||||||
|
if (!(
|
||||||
|
'crypto' in window &&
|
||||||
|
'getRandomValues' in window.crypto &&
|
||||||
|
'subtle' in window.crypto &&
|
||||||
|
'encrypt' in window.crypto.subtle &&
|
||||||
|
'decrypt' in window.crypto.subtle &&
|
||||||
|
'Uint8Array' in window &&
|
||||||
|
'Uint32Array' in window
|
||||||
|
)) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
// async & ES6 support
|
||||||
|
try {
|
||||||
|
eval('async () => {}');
|
||||||
|
} catch (e) {
|
||||||
|
if (e instanceof SyntaxError) {
|
||||||
|
return true;
|
||||||
|
} else {
|
||||||
|
throw e; // throws CSP error
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* shows an error message
|
||||||
|
*
|
||||||
|
* @private
|
||||||
|
* @name Check.showError
|
||||||
|
* @param {string} message
|
||||||
|
* @function
|
||||||
|
*/
|
||||||
|
function showError(message)
|
||||||
|
{
|
||||||
|
var element = document.getElementById('errormessage');
|
||||||
|
if (message.indexOf('<a') === -1) {
|
||||||
|
element.appendChild(
|
||||||
|
document.createTextNode(message)
|
||||||
|
);
|
||||||
|
} else {
|
||||||
|
element.innerHTML = message;
|
||||||
|
}
|
||||||
|
removeHiddenFromId('errormessage');
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* removes "hidden" CSS class from element with given ID
|
||||||
|
*
|
||||||
|
* @private
|
||||||
|
* @name Check.removeHiddenFromId
|
||||||
|
* @param {string} id
|
||||||
|
* @function
|
||||||
|
*/
|
||||||
|
function removeHiddenFromId(id)
|
||||||
|
{
|
||||||
|
var element = document.getElementById(id);
|
||||||
|
if (element) {
|
||||||
|
element.className = element.className.replace(/\bhidden\b/g, '');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* returns if the check has concluded
|
||||||
|
*
|
||||||
|
* @name Check.getInit
|
||||||
|
* @function
|
||||||
|
* @return {bool}
|
||||||
|
*/
|
||||||
|
me.getInit = function()
|
||||||
|
{
|
||||||
|
return init;
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* returns the current status of the check
|
||||||
|
*
|
||||||
|
* @name Check.getStatus
|
||||||
|
* @function
|
||||||
|
* @return {bool}
|
||||||
|
*/
|
||||||
|
me.getStatus = function()
|
||||||
|
{
|
||||||
|
return status;
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* init on application start, returns an all-clear signal
|
||||||
|
*
|
||||||
|
* @name Check.init
|
||||||
|
* @function
|
||||||
|
*/
|
||||||
|
me.init = function()
|
||||||
|
{
|
||||||
|
// prevent bots from viewing a paste and potentially deleting data
|
||||||
|
// when burn-after-reading is set
|
||||||
|
if (isBadBot()) {
|
||||||
|
showError('I love you too, bot…');
|
||||||
|
init = true;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (isOldBrowser()) {
|
||||||
|
// some browsers (Chrome based ones) would have webcrypto support if using HTTPS
|
||||||
|
if (!isSecureContext()) {
|
||||||
|
removeHiddenFromId('insecurecontextnotice');
|
||||||
|
}
|
||||||
|
removeHiddenFromId('oldnotice');
|
||||||
|
init = true;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!isSecureContext()) {
|
||||||
|
removeHiddenFromId('httpnotice');
|
||||||
|
}
|
||||||
|
init = true;
|
||||||
|
|
||||||
|
// only if everything passed, we set the status to true
|
||||||
|
status = true;
|
||||||
|
};
|
||||||
|
|
||||||
|
return me;
|
||||||
|
})();
|
||||||
|
|
||||||
|
// main application start, called when DOM is fully loaded
|
||||||
|
if (document.readyState === 'complete' || (!document.attachEvent && document.readyState === 'interactive')) {
|
||||||
|
Check.init();
|
||||||
|
} else {
|
||||||
|
if (document.addEventListener) {
|
||||||
|
// first choice is DOMContentLoaded event
|
||||||
|
document.addEventListener('DOMContentLoaded', Check.init, false);
|
||||||
|
// backup is window load event
|
||||||
|
window.addEventListener('load', Check.init, false);
|
||||||
|
} else {
|
||||||
|
// must be IE
|
||||||
|
document.attachEvent('onreadystatechange', Check.init);
|
||||||
|
window.attachEvent('onload', Check.init);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
this.Legacy = {
|
||||||
|
Check: Check
|
||||||
|
};
|
||||||
|
}).call(this);
|
422
js/privatebin.js
422
js/privatebin.js
|
@ -9,20 +9,12 @@
|
||||||
* @version 1.3
|
* @version 1.3
|
||||||
* @name PrivateBin
|
* @name PrivateBin
|
||||||
* @namespace
|
* @namespace
|
||||||
|
*
|
||||||
|
* global Base64, DOMPurify, FileReader, RawDeflate, history, navigator, prettyPrint, prettyPrintOne, showdown, kjua
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/** global: Base64 */
|
|
||||||
/** global: DOMPurify */
|
|
||||||
/** global: FileReader */
|
|
||||||
/** global: RawDeflate */
|
|
||||||
/** global: history */
|
|
||||||
/** global: navigator */
|
|
||||||
/** global: prettyPrint */
|
|
||||||
/** global: prettyPrintOne */
|
|
||||||
/** global: showdown */
|
|
||||||
/** global: kjua */
|
|
||||||
|
|
||||||
jQuery.fn.draghover = function() {
|
jQuery.fn.draghover = function() {
|
||||||
|
'use strict';
|
||||||
return this.each(function() {
|
return this.each(function() {
|
||||||
let collection = $(),
|
let collection = $(),
|
||||||
self = $(this);
|
self = $(this);
|
||||||
|
@ -566,12 +558,11 @@ jQuery.PrivateBin = (function($, RawDeflate) {
|
||||||
|
|
||||||
// if $element is given, apply text to element
|
// if $element is given, apply text to element
|
||||||
if ($element !== null) {
|
if ($element !== null) {
|
||||||
// get last text node of element
|
// avoid HTML entity encoding if translation contains link
|
||||||
let content = $element.contents();
|
if (output.indexOf('<a') === -1) {
|
||||||
if (content.length > 1) {
|
|
||||||
content[content.length - 1].nodeValue = ' ' + output;
|
|
||||||
} else {
|
|
||||||
$element.text(output);
|
$element.text(output);
|
||||||
|
} else {
|
||||||
|
$element.html(output);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -781,15 +772,20 @@ jQuery.PrivateBin = (function($, RawDeflate) {
|
||||||
* @private
|
* @private
|
||||||
* @param {string} message
|
* @param {string} message
|
||||||
* @param {string} mode
|
* @param {string} mode
|
||||||
|
* @param {object} zlib
|
||||||
|
* @throws {string}
|
||||||
* @return {ArrayBuffer} data
|
* @return {ArrayBuffer} data
|
||||||
*/
|
*/
|
||||||
async function compress(message, mode)
|
async function compress(message, mode, zlib)
|
||||||
{
|
{
|
||||||
message = stringToArraybuffer(
|
message = stringToArraybuffer(
|
||||||
utf16To8(message)
|
utf16To8(message)
|
||||||
);
|
);
|
||||||
if (mode === 'zlib') {
|
if (mode === 'zlib') {
|
||||||
return z.deflate(message).buffer;
|
if (typeof zlib === 'undefined') {
|
||||||
|
throw 'Error compressing paste, due to missing WebAssembly support.'
|
||||||
|
}
|
||||||
|
return zlib.deflate(message).buffer;
|
||||||
}
|
}
|
||||||
return message;
|
return message;
|
||||||
}
|
}
|
||||||
|
@ -803,13 +799,18 @@ jQuery.PrivateBin = (function($, RawDeflate) {
|
||||||
* @private
|
* @private
|
||||||
* @param {ArrayBuffer} data
|
* @param {ArrayBuffer} data
|
||||||
* @param {string} mode
|
* @param {string} mode
|
||||||
|
* @param {object} zlib
|
||||||
|
* @throws {string}
|
||||||
* @return {string} message
|
* @return {string} message
|
||||||
*/
|
*/
|
||||||
async function decompress(data, mode)
|
async function decompress(data, mode, zlib)
|
||||||
{
|
{
|
||||||
if (mode === 'zlib' || mode === 'none') {
|
if (mode === 'zlib' || mode === 'none') {
|
||||||
if (mode === 'zlib') {
|
if (mode === 'zlib') {
|
||||||
data = z.inflate(
|
if (typeof zlib === 'undefined') {
|
||||||
|
throw 'Error decompressing paste, due to missing WebAssembly support.'
|
||||||
|
}
|
||||||
|
data = zlib.inflate(
|
||||||
new Uint8Array(data)
|
new Uint8Array(data)
|
||||||
).buffer;
|
).buffer;
|
||||||
}
|
}
|
||||||
|
@ -883,7 +884,7 @@ jQuery.PrivateBin = (function($, RawDeflate) {
|
||||||
stringToArraybuffer(
|
stringToArraybuffer(
|
||||||
utf16To8(password)
|
utf16To8(password)
|
||||||
)
|
)
|
||||||
);
|
).catch(Alert.showError);
|
||||||
password = Array.prototype.map.call(
|
password = Array.prototype.map.call(
|
||||||
new Uint8Array(passwordBuffer),
|
new Uint8Array(passwordBuffer),
|
||||||
x => ('00' + x.toString(16)).slice(-2)
|
x => ('00' + x.toString(16)).slice(-2)
|
||||||
|
@ -903,7 +904,7 @@ jQuery.PrivateBin = (function($, RawDeflate) {
|
||||||
{name: 'PBKDF2'}, // we use PBKDF2 for key derivation
|
{name: 'PBKDF2'}, // we use PBKDF2 for key derivation
|
||||||
false, // the key may not be exported
|
false, // the key may not be exported
|
||||||
['deriveKey'] // we may only use it for key derivation
|
['deriveKey'] // we may only use it for key derivation
|
||||||
);
|
).catch(Alert.showError);
|
||||||
|
|
||||||
// derive a stronger key for use with AES
|
// derive a stronger key for use with AES
|
||||||
return window.crypto.subtle.deriveKey(
|
return window.crypto.subtle.deriveKey(
|
||||||
|
@ -920,7 +921,7 @@ jQuery.PrivateBin = (function($, RawDeflate) {
|
||||||
},
|
},
|
||||||
false, // the key may not be exported
|
false, // the key may not be exported
|
||||||
['encrypt', 'decrypt'] // we may only use it for en- and decryption
|
['encrypt', 'decrypt'] // we may only use it for en- and decryption
|
||||||
);
|
).catch(Alert.showError);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -957,18 +958,24 @@ jQuery.PrivateBin = (function($, RawDeflate) {
|
||||||
*/
|
*/
|
||||||
me.cipher = async function(key, password, message, adata)
|
me.cipher = async function(key, password, message, adata)
|
||||||
{
|
{
|
||||||
|
let zlib = (await z);
|
||||||
// AES in Galois Counter Mode, keysize 256 bit,
|
// AES in Galois Counter Mode, keysize 256 bit,
|
||||||
// authentication tag 128 bit, 10000 iterations in key derivation
|
// authentication tag 128 bit, 10000 iterations in key derivation
|
||||||
const spec = [
|
const compression = (
|
||||||
getRandomBytes(16), // initialization vector
|
typeof zlib === 'undefined' ?
|
||||||
getRandomBytes(8), // salt
|
'none' : // client lacks support for WASM
|
||||||
100000, // iterations
|
($('body').data('compression') || 'zlib')
|
||||||
256, // key size
|
),
|
||||||
128, // tag size
|
spec = [
|
||||||
'aes', // algorithm
|
getRandomBytes(16), // initialization vector
|
||||||
'gcm', // algorithm mode
|
getRandomBytes(8), // salt
|
||||||
$('body').data('compression') || 'zlib' // compression
|
100000, // iterations
|
||||||
], encodedSpec = [];
|
256, // key size
|
||||||
|
128, // tag size
|
||||||
|
'aes', // algorithm
|
||||||
|
'gcm', // algorithm mode
|
||||||
|
compression // compression
|
||||||
|
], encodedSpec = [];
|
||||||
for (let i = 0; i < spec.length; ++i) {
|
for (let i = 0; i < spec.length; ++i) {
|
||||||
encodedSpec[i] = i < 2 ? btoa(spec[i]) : spec[i];
|
encodedSpec[i] = i < 2 ? btoa(spec[i]) : spec[i];
|
||||||
}
|
}
|
||||||
|
@ -987,8 +994,8 @@ jQuery.PrivateBin = (function($, RawDeflate) {
|
||||||
await window.crypto.subtle.encrypt(
|
await window.crypto.subtle.encrypt(
|
||||||
cryptoSettings(JSON.stringify(adata), spec),
|
cryptoSettings(JSON.stringify(adata), spec),
|
||||||
await deriveKey(key, password, spec),
|
await deriveKey(key, password, spec),
|
||||||
await compress(message, spec[7])
|
await compress(message, compression, zlib)
|
||||||
)
|
).catch(Alert.showError)
|
||||||
)
|
)
|
||||||
),
|
),
|
||||||
adata
|
adata
|
||||||
|
@ -1008,7 +1015,8 @@ jQuery.PrivateBin = (function($, RawDeflate) {
|
||||||
*/
|
*/
|
||||||
me.decipher = async function(key, password, data)
|
me.decipher = async function(key, password, data)
|
||||||
{
|
{
|
||||||
let adataString, spec, cipherMessage;
|
let adataString, spec, cipherMessage, plaintext;
|
||||||
|
let zlib = (await z);
|
||||||
if (data instanceof Array) {
|
if (data instanceof Array) {
|
||||||
// version 2
|
// version 2
|
||||||
adataString = JSON.stringify(data[1]);
|
adataString = JSON.stringify(data[1]);
|
||||||
|
@ -1035,20 +1043,29 @@ jQuery.PrivateBin = (function($, RawDeflate) {
|
||||||
}
|
}
|
||||||
spec[0] = atob(spec[0]);
|
spec[0] = atob(spec[0]);
|
||||||
spec[1] = atob(spec[1]);
|
spec[1] = atob(spec[1]);
|
||||||
|
if (spec[7] === 'zlib') {
|
||||||
|
if (typeof zlib === 'undefined') {
|
||||||
|
throw 'Error decompressing paste, due to missing WebAssembly support.'
|
||||||
|
}
|
||||||
|
}
|
||||||
try {
|
try {
|
||||||
return await decompress(
|
plaintext = await window.crypto.subtle.decrypt(
|
||||||
await window.crypto.subtle.decrypt(
|
cryptoSettings(adataString, spec),
|
||||||
cryptoSettings(adataString, spec),
|
await deriveKey(key, password, spec),
|
||||||
await deriveKey(key, password, spec),
|
stringToArraybuffer(
|
||||||
stringToArraybuffer(
|
atob(cipherMessage)
|
||||||
atob(cipherMessage)
|
)
|
||||||
)
|
|
||||||
),
|
|
||||||
spec[7]
|
|
||||||
);
|
);
|
||||||
} catch(err) {
|
} catch(err) {
|
||||||
|
console.error(err);
|
||||||
return '';
|
return '';
|
||||||
}
|
}
|
||||||
|
try {
|
||||||
|
return await decompress(plaintext, spec[7], zlib);
|
||||||
|
} catch(err) {
|
||||||
|
Alert.showError(err);
|
||||||
|
return err;
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -1194,7 +1211,6 @@ jQuery.PrivateBin = (function($, RawDeflate) {
|
||||||
me.getPasteId = function()
|
me.getPasteId = function()
|
||||||
{
|
{
|
||||||
const idRegEx = /^[a-z0-9]{16}$/;
|
const idRegEx = /^[a-z0-9]{16}$/;
|
||||||
const idRegExFind = /[a-z0-9]{16}/;
|
|
||||||
|
|
||||||
// return cached value
|
// return cached value
|
||||||
if (id !== null) {
|
if (id !== null) {
|
||||||
|
@ -1483,7 +1499,7 @@ jQuery.PrivateBin = (function($, RawDeflate) {
|
||||||
const alertType = [
|
const alertType = [
|
||||||
'loading', // not in bootstrap CSS, but using a plausible value here
|
'loading', // not in bootstrap CSS, but using a plausible value here
|
||||||
'info', // status icon
|
'info', // status icon
|
||||||
'warning', // not used yet
|
'warning', // warning icon
|
||||||
'danger' // error icon
|
'danger' // error icon
|
||||||
];
|
];
|
||||||
|
|
||||||
|
@ -1527,28 +1543,35 @@ jQuery.PrivateBin = (function($, RawDeflate) {
|
||||||
icon = null; // icons not supported in this case
|
icon = null; // icons not supported in this case
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
let $translationTarget = $element;
|
||||||
|
|
||||||
// handle icon
|
// handle icon, if template uses one
|
||||||
if (icon !== null && // icon was passed
|
const $glyphIcon = $element.find(':first');
|
||||||
icon !== currentIcon[id] // and it differs from current icon
|
if ($glyphIcon.length) {
|
||||||
) {
|
// if there is an icon, we need to provide an inner element
|
||||||
let $glyphIcon = $element.find(':first');
|
// to translate the message into, instead of the parent
|
||||||
|
$translationTarget = $('<span>');
|
||||||
|
$element.html(' ').prepend($glyphIcon).append($translationTarget);
|
||||||
|
|
||||||
// remove (previous) icon
|
if (icon !== null && // icon was passed
|
||||||
$glyphIcon.removeClass(currentIcon[id]);
|
icon !== currentIcon[id] // and it differs from current icon
|
||||||
|
) {
|
||||||
|
// remove (previous) icon
|
||||||
|
$glyphIcon.removeClass(currentIcon[id]);
|
||||||
|
|
||||||
// any other thing as a string (e.g. 'null') (only) removes the icon
|
// any other thing as a string (e.g. 'null') (only) removes the icon
|
||||||
if (typeof icon === 'string') {
|
if (typeof icon === 'string') {
|
||||||
// set new icon
|
// set new icon
|
||||||
currentIcon[id] = 'glyphicon-' + icon;
|
currentIcon[id] = 'glyphicon-' + icon;
|
||||||
$glyphIcon.addClass(currentIcon[id]);
|
$glyphIcon.addClass(currentIcon[id]);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// show text
|
// show text
|
||||||
if (args !== null) {
|
if (args !== null) {
|
||||||
// add jQuery object to it as first parameter
|
// add jQuery object to it as first parameter
|
||||||
args.unshift($element);
|
args.unshift($translationTarget);
|
||||||
// pass it to I18n
|
// pass it to I18n
|
||||||
I18n._.apply(this, args);
|
I18n._.apply(this, args);
|
||||||
}
|
}
|
||||||
|
@ -1573,6 +1596,25 @@ jQuery.PrivateBin = (function($, RawDeflate) {
|
||||||
handleNotification(1, $statusMessage, message, icon);
|
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)
|
||||||
|
{
|
||||||
|
$errorMessage.find(':first')
|
||||||
|
.removeClass(currentIcon[3])
|
||||||
|
.addClass(currentIcon[2]);
|
||||||
|
handleNotification(2, $errorMessage, message, icon);
|
||||||
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* display an error message
|
* display an error message
|
||||||
*
|
*
|
||||||
|
@ -1699,7 +1741,7 @@ jQuery.PrivateBin = (function($, RawDeflate) {
|
||||||
currentIcon = [
|
currentIcon = [
|
||||||
'glyphicon-time', // loading icon
|
'glyphicon-time', // loading icon
|
||||||
'glyphicon-info-sign', // status icon
|
'glyphicon-info-sign', // status icon
|
||||||
'', // reserved for warning, not used yet
|
'glyphicon-warning-sign', // warning icon
|
||||||
'glyphicon-alert' // error icon
|
'glyphicon-alert' // error icon
|
||||||
];
|
];
|
||||||
};
|
};
|
||||||
|
@ -1768,14 +1810,14 @@ jQuery.PrivateBin = (function($, RawDeflate) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Alert.showError(
|
Alert.showError('Cannot parse response from URL shortener.');
|
||||||
I18n._('Cannot parse response from URL shortener.')
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
.fail(function(data, textStatus, errorThrown) {
|
.fail(function(data, textStatus, errorThrown) {
|
||||||
console.error(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(
|
window.open(
|
||||||
`${$shortenButton.data('shortener')}${encodeURIComponent($pasteUrl.attr('href'))}`,
|
`${$shortenButton.data('shortener')}${encodeURIComponent($pasteUrl.attr('href'))}`,
|
||||||
'_blank',
|
'_blank',
|
||||||
|
@ -2731,9 +2773,7 @@ jQuery.PrivateBin = (function($, RawDeflate) {
|
||||||
// revert loading status…
|
// revert loading status…
|
||||||
me.hideAttachment();
|
me.hideAttachment();
|
||||||
me.hideAttachmentPreview();
|
me.hideAttachmentPreview();
|
||||||
Alert.showError(
|
Alert.showWarning('Your browser does not support uploading encrypted files. Please use a newer browser.');
|
||||||
I18n._('Your browser does not support uploading encrypted files. Please use a newer browser.')
|
|
||||||
);
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2965,11 +3005,11 @@ jQuery.PrivateBin = (function($, RawDeflate) {
|
||||||
me.init = function()
|
me.init = function()
|
||||||
{
|
{
|
||||||
$attachment = $('#attachment');
|
$attachment = $('#attachment');
|
||||||
if($attachment.length){
|
$dragAndDropFileName = $('#dragAndDropFileName');
|
||||||
|
$dropzone = $('#dropzone');
|
||||||
|
if($attachment.length) {
|
||||||
$attachmentLink = $('#attachment a');
|
$attachmentLink = $('#attachment a');
|
||||||
$attachmentPreview = $('#attachmentPreview');
|
$attachmentPreview = $('#attachmentPreview');
|
||||||
$dragAndDropFileName = $('#dragAndDropFileName');
|
|
||||||
$dropzone = $('#dropzone');
|
|
||||||
|
|
||||||
$fileInput = $('#file');
|
$fileInput = $('#file');
|
||||||
addDragDropHandler();
|
addDragDropHandler();
|
||||||
|
@ -4194,8 +4234,6 @@ jQuery.PrivateBin = (function($, RawDeflate) {
|
||||||
const PasteEncrypter = (function () {
|
const PasteEncrypter = (function () {
|
||||||
const me = {};
|
const me = {};
|
||||||
|
|
||||||
let requirementsChecked = false;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* called after successful paste upload
|
* called after successful paste upload
|
||||||
*
|
*
|
||||||
|
@ -4428,16 +4466,13 @@ jQuery.PrivateBin = (function($, RawDeflate) {
|
||||||
});
|
});
|
||||||
cipherMessage['attachment'] = await fileReading;
|
cipherMessage['attachment'] = await fileReading;
|
||||||
} else {
|
} else {
|
||||||
Alert.showError(
|
const error = 'Cannot process attachment data.';
|
||||||
I18n._('Cannot process attachment data.')
|
Alert.showError(error);
|
||||||
);
|
throw new TypeError(error);
|
||||||
throw new TypeError('Cannot process attachment data.');
|
|
||||||
}
|
}
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error(error);
|
console.error(error);
|
||||||
Alert.showError(
|
Alert.showError('Cannot retrieve attachment.');
|
||||||
I18n._('Cannot retrieve attachment.')
|
|
||||||
);
|
|
||||||
throw error;
|
throw error;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -4494,7 +4529,7 @@ jQuery.PrivateBin = (function($, RawDeflate) {
|
||||||
|
|
||||||
// if all tries failed, we can only return an error
|
// if all tries failed, we can only return an error
|
||||||
if (plaindata.length === 0) {
|
if (plaindata.length === 0) {
|
||||||
throw 'failed to decipher data';
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
return plaindata;
|
return plaindata;
|
||||||
|
@ -4523,13 +4558,14 @@ jQuery.PrivateBin = (function($, RawDeflate) {
|
||||||
if (password.length === 0) {
|
if (password.length === 0) {
|
||||||
throw 'waiting on user to provide a password';
|
throw 'waiting on user to provide a password';
|
||||||
} else {
|
} else {
|
||||||
displayDecryptionError('failed to decipher paste text: Incorrect password?');
|
Alert.hideLoading();
|
||||||
throw 'waiting on user to provide correct password';
|
// reset password, so it can be re-entered
|
||||||
|
Prompt.reset();
|
||||||
|
TopNav.showRetryButton();
|
||||||
|
throw 'Could not decrypt data. Did you enter a wrong password? Retry with the button at the top.';
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
let format = '',
|
|
||||||
text = '';
|
|
||||||
if (paste.v > 1) {
|
if (paste.v > 1) {
|
||||||
// version 2 paste
|
// version 2 paste
|
||||||
const pasteMessage = JSON.parse(pastePlain);
|
const pasteMessage = JSON.parse(pastePlain);
|
||||||
|
@ -4616,29 +4652,6 @@ jQuery.PrivateBin = (function($, RawDeflate) {
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* displays and logs decryption errors
|
|
||||||
*
|
|
||||||
* @name PasteDecrypter.displayDecryptionError
|
|
||||||
* @private
|
|
||||||
* @function
|
|
||||||
* @param {string} message
|
|
||||||
*/
|
|
||||||
function displayDecryptionError(message)
|
|
||||||
{
|
|
||||||
Alert.hideLoading();
|
|
||||||
|
|
||||||
// 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.')
|
|
||||||
);
|
|
||||||
|
|
||||||
// reset password, so it can be re-entered
|
|
||||||
Prompt.reset();
|
|
||||||
TopNav.showRetryButton();
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* show decrypted text in the display area, including discussion (if open)
|
* show decrypted text in the display area, including discussion (if open)
|
||||||
*
|
*
|
||||||
|
@ -4690,170 +4703,13 @@ jQuery.PrivateBin = (function($, RawDeflate) {
|
||||||
.catch((err) => {
|
.catch((err) => {
|
||||||
// wait for the user to type in the password,
|
// wait for the user to type in the password,
|
||||||
// then PasteDecrypter.run will be called again
|
// then PasteDecrypter.run will be called again
|
||||||
console.error(err);
|
Alert.showError(err);
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
return me;
|
return me;
|
||||||
})();
|
})();
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* initial (security) check
|
|
||||||
*
|
|
||||||
* @name InitialCheck
|
|
||||||
* @param {object} window
|
|
||||||
* @param {object} document
|
|
||||||
* @class
|
|
||||||
*/
|
|
||||||
const InitialCheck = (function () {
|
|
||||||
const me = {};
|
|
||||||
|
|
||||||
/**
|
|
||||||
* blacklist of UserAgents (parts) known to belong to a bot
|
|
||||||
*
|
|
||||||
* @private
|
|
||||||
* @enum {Array}
|
|
||||||
* @readonly
|
|
||||||
*/
|
|
||||||
const badBotUA = [
|
|
||||||
'Bot',
|
|
||||||
'bot'
|
|
||||||
];
|
|
||||||
|
|
||||||
/**
|
|
||||||
* check if the connection is insecure
|
|
||||||
*
|
|
||||||
* @private
|
|
||||||
* @name InitialCheck.isInsecureConnection
|
|
||||||
* @function
|
|
||||||
* @return {bool}
|
|
||||||
*/
|
|
||||||
function isInsecureConnection()
|
|
||||||
{
|
|
||||||
// use .isSecureContext if available
|
|
||||||
if (window.isSecureContext === true || window.isSecureContext === false) {
|
|
||||||
return !window.isSecureContext;
|
|
||||||
}
|
|
||||||
|
|
||||||
const url = new URL(window.location);
|
|
||||||
|
|
||||||
// HTTP is obviously insecure
|
|
||||||
if (url.protocol !== 'http:') {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
// filter out actually secure connections over HTTP
|
|
||||||
for (const tld of ['.onion', '.i2p']) {
|
|
||||||
if (url.hostname.endsWith(tld)) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// whitelist localhost for development
|
|
||||||
for (const hostname of ['localhost', '127.0.0.1', '[::1]']) {
|
|
||||||
if (url.hostname === hostname) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// totally INSECURE http protocol!
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* checks whether this is a bot we dislike
|
|
||||||
*
|
|
||||||
* @private
|
|
||||||
* @name InitialCheck.isBadBot
|
|
||||||
* @function
|
|
||||||
* @return {bool}
|
|
||||||
*/
|
|
||||||
function isBadBot() {
|
|
||||||
// check whether a bot user agent part can be found in the current
|
|
||||||
// user agent
|
|
||||||
for (const UAfragment of badBotUA) {
|
|
||||||
if (navigator.userAgent.indexOf(UAfragment) >= 0) {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* checks whether this is an unsupported browser, via feature detection
|
|
||||||
*
|
|
||||||
* @private
|
|
||||||
* @name InitialCheck.isOldBrowser
|
|
||||||
* @function
|
|
||||||
* @return {bool}
|
|
||||||
*/
|
|
||||||
function isOldBrowser() {
|
|
||||||
// webcrypto support
|
|
||||||
if (typeof window.crypto !== 'object') {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (typeof WebAssembly !== 'object' && typeof WebAssembly.instantiate !== 'function') {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
try {
|
|
||||||
// [\0, 'a', 's', 'm', (uint_32) 1] - smallest valid wasm module
|
|
||||||
const module = new WebAssembly.Module(Uint8Array.of(0x0, 0x61, 0x73, 0x6d, 0x01, 0x00, 0x00, 0x00));
|
|
||||||
if (
|
|
||||||
!(
|
|
||||||
module instanceof WebAssembly.Module &&
|
|
||||||
new WebAssembly.Instance(module) instanceof WebAssembly.Instance
|
|
||||||
)
|
|
||||||
) {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
} catch (e) {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
// not checking for async/await, ES6, Promise or Uint8Array support,
|
|
||||||
// as most browsers introduced these earlier then webassembly and webcrypto:
|
|
||||||
// https://github.com/PrivateBin/PrivateBin/pull/431#issuecomment-493129359
|
|
||||||
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* init on application start, returns an all-clear signal
|
|
||||||
*
|
|
||||||
* @name InitialCheck.init
|
|
||||||
* @function
|
|
||||||
* @return {bool}
|
|
||||||
*/
|
|
||||||
me.init = function()
|
|
||||||
{
|
|
||||||
// prevent bots from viewing a paste and potentially deleting data
|
|
||||||
// when burn-after-reading is set
|
|
||||||
if (isBadBot()) {
|
|
||||||
Alert.showError('I love you too, bot…');
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (isOldBrowser()) {
|
|
||||||
// some browsers (Chrome based ones) would have webcrypto support if using HTTPS
|
|
||||||
if (isInsecureConnection()) {
|
|
||||||
Alert.showError(['Your browser may require an HTTPS connection to support the WebCrypto API. Try <a href="%s">switching to HTTPS</a>.', 'https' + window.location.href.slice(4)]);
|
|
||||||
}
|
|
||||||
$('#oldnotice').removeClass('hidden');
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (isInsecureConnection()) {
|
|
||||||
$('#httpnotice').removeClass('hidden');
|
|
||||||
}
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
return me;
|
|
||||||
})();
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* (controller) main PrivateBin logic
|
* (controller) main PrivateBin logic
|
||||||
*
|
*
|
||||||
|
@ -4926,9 +4782,7 @@ jQuery.PrivateBin = (function($, RawDeflate) {
|
||||||
|
|
||||||
// missing decryption key (or paste ID) in URL?
|
// missing decryption key (or paste ID) in URL?
|
||||||
if (window.location.hash.length === 0) {
|
if (window.location.hash.length === 0) {
|
||||||
Alert.showError(
|
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?)');
|
||||||
I18n._('Cannot decrypt paste: Decryption key missing in URL (Did you use a redirector or an URL shortener which strips part of the URL?)')
|
|
||||||
);
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -5030,13 +4884,29 @@ jQuery.PrivateBin = (function($, RawDeflate) {
|
||||||
DiscussionViewer.prepareNewDiscussion();
|
DiscussionViewer.prepareNewDiscussion();
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* try initializing zlib or display a warning if it fails,
|
||||||
|
* extracted from main init to allow unit testing
|
||||||
|
*
|
||||||
|
* @name Controller.initZ
|
||||||
|
* @function
|
||||||
|
*/
|
||||||
|
me.initZ = function()
|
||||||
|
{
|
||||||
|
z = zlib.catch(function () {
|
||||||
|
if ($('body').data('compression') !== 'none') {
|
||||||
|
Alert.showWarning('Your browser doesn\'t support WebAssembly, used for zlib compression. You can create uncompressed documents, but can\'t read compressed ones.');
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* application start
|
* application start
|
||||||
*
|
*
|
||||||
* @name Controller.init
|
* @name Controller.init
|
||||||
* @function
|
* @function
|
||||||
*/
|
*/
|
||||||
me.init = async function()
|
me.init = function()
|
||||||
{
|
{
|
||||||
// first load translations
|
// first load translations
|
||||||
I18n.loadTranslations();
|
I18n.loadTranslations();
|
||||||
|
@ -5054,11 +4924,18 @@ jQuery.PrivateBin = (function($, RawDeflate) {
|
||||||
Prompt.init();
|
Prompt.init();
|
||||||
TopNav.init();
|
TopNav.init();
|
||||||
UiHelper.init();
|
UiHelper.init();
|
||||||
z = (await zlib);
|
|
||||||
if (!InitialCheck.init()) {
|
// check for legacy browsers before going any further
|
||||||
|
if (!Legacy.Check.getInit()) {
|
||||||
|
// Legacy check didn't complete, wait and try again
|
||||||
|
setTimeout(init, 500);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (!Legacy.Check.getStatus()) {
|
||||||
// something major is wrong, stop right away
|
// something major is wrong, stop right away
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
me.initZ();
|
||||||
|
|
||||||
// check whether existing paste needs to be shown
|
// check whether existing paste needs to be shown
|
||||||
try {
|
try {
|
||||||
|
@ -5098,7 +4975,6 @@ jQuery.PrivateBin = (function($, RawDeflate) {
|
||||||
ServerInteraction: ServerInteraction,
|
ServerInteraction: ServerInteraction,
|
||||||
PasteEncrypter: PasteEncrypter,
|
PasteEncrypter: PasteEncrypter,
|
||||||
PasteDecrypter: PasteDecrypter,
|
PasteDecrypter: PasteDecrypter,
|
||||||
InitialCheck: InitialCheck,
|
|
||||||
Controller: Controller
|
Controller: Controller
|
||||||
};
|
};
|
||||||
})(jQuery, RawDeflate);
|
})(jQuery, RawDeflate);
|
||||||
|
|
225
js/test/Alert.js
225
js/test/Alert.js
|
@ -4,16 +4,55 @@ var common = require('../common');
|
||||||
describe('Alert', function () {
|
describe('Alert', function () {
|
||||||
describe('showStatus', function () {
|
describe('showStatus', function () {
|
||||||
jsc.property(
|
jsc.property(
|
||||||
'shows a status message',
|
'shows a status message (basic)',
|
||||||
jsc.array(common.jscAlnumString()),
|
jsc.array(common.jscAlnumString()),
|
||||||
jsc.array(common.jscAlnumString()),
|
jsc.array(common.jscAlnumString()),
|
||||||
function (icon, message) {
|
function (icon, message) {
|
||||||
icon = icon.join('');
|
icon = icon.join('');
|
||||||
message = message.join('');
|
message = message.join('');
|
||||||
var expected = '<div id="status" role="alert" ' +
|
const expected = '<div id="status">' + message + '</div>';
|
||||||
|
$('body').html(
|
||||||
|
'<div id="status"></div>'
|
||||||
|
);
|
||||||
|
$.PrivateBin.Alert.init();
|
||||||
|
$.PrivateBin.Alert.showStatus(message, icon);
|
||||||
|
const result = $('body').html();
|
||||||
|
return expected === result;
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
|
jsc.property(
|
||||||
|
'shows a status message (bootstrap)',
|
||||||
|
jsc.array(common.jscAlnumString()),
|
||||||
|
function (message) {
|
||||||
|
message = message.join('');
|
||||||
|
const expected = '<div id="status" role="alert" ' +
|
||||||
|
'class="statusmessage alert alert-info"><span ' +
|
||||||
|
'class="glyphicon glyphicon-info-sign" ' +
|
||||||
|
'aria-hidden="true"></span> <span>' + message + '</span></div>';
|
||||||
|
$('body').html(
|
||||||
|
'<div id="status" role="alert" class="statusmessage ' +
|
||||||
|
'alert alert-info hidden"><span class="glyphicon ' +
|
||||||
|
'glyphicon-info-sign" aria-hidden="true"></span> </div>'
|
||||||
|
);
|
||||||
|
$.PrivateBin.Alert.init();
|
||||||
|
$.PrivateBin.Alert.showStatus(message);
|
||||||
|
const result = $('body').html();
|
||||||
|
return expected === result;
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
|
jsc.property(
|
||||||
|
'shows a status message (bootstrap, custom icon)',
|
||||||
|
jsc.array(common.jscAlnumString()),
|
||||||
|
jsc.array(common.jscAlnumString()),
|
||||||
|
function (icon, message) {
|
||||||
|
icon = icon.join('');
|
||||||
|
message = message.join('');
|
||||||
|
const expected = '<div id="status" role="alert" ' +
|
||||||
'class="statusmessage alert alert-info"><span ' +
|
'class="statusmessage alert alert-info"><span ' +
|
||||||
'class="glyphicon glyphicon-' + icon +
|
'class="glyphicon glyphicon-' + icon +
|
||||||
'" aria-hidden="true"></span> ' + message + '</div>';
|
'" aria-hidden="true"></span> <span>' + message + '</span></div>';
|
||||||
$('body').html(
|
$('body').html(
|
||||||
'<div id="status" role="alert" class="statusmessage ' +
|
'<div id="status" role="alert" class="statusmessage ' +
|
||||||
'alert alert-info hidden"><span class="glyphicon ' +
|
'alert alert-info hidden"><span class="glyphicon ' +
|
||||||
|
@ -21,7 +60,76 @@ describe('Alert', function () {
|
||||||
);
|
);
|
||||||
$.PrivateBin.Alert.init();
|
$.PrivateBin.Alert.init();
|
||||||
$.PrivateBin.Alert.showStatus(message, icon);
|
$.PrivateBin.Alert.showStatus(message, icon);
|
||||||
var result = $('body').html();
|
const result = $('body').html();
|
||||||
|
return expected === result;
|
||||||
|
}
|
||||||
|
);
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('showWarning', function () {
|
||||||
|
before(function () {
|
||||||
|
cleanup();
|
||||||
|
});
|
||||||
|
|
||||||
|
jsc.property(
|
||||||
|
'shows a warning message (basic)',
|
||||||
|
jsc.array(common.jscAlnumString()),
|
||||||
|
jsc.array(common.jscAlnumString()),
|
||||||
|
function (icon, message) {
|
||||||
|
icon = icon.join('');
|
||||||
|
message = message.join('');
|
||||||
|
const expected = '<div id="errormessage">' + message + '</div>';
|
||||||
|
$('body').html(
|
||||||
|
'<div id="errormessage"></div>'
|
||||||
|
);
|
||||||
|
$.PrivateBin.Alert.init();
|
||||||
|
$.PrivateBin.Alert.showWarning(message, icon);
|
||||||
|
const result = $('body').html();
|
||||||
|
return expected === result;
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
|
jsc.property(
|
||||||
|
'shows a warning message (bootstrap)',
|
||||||
|
jsc.array(common.jscAlnumString()),
|
||||||
|
jsc.array(common.jscAlnumString()),
|
||||||
|
function (message) {
|
||||||
|
message = message.join('');
|
||||||
|
const expected = '<div id="errormessage" role="alert" ' +
|
||||||
|
'class="statusmessage alert alert-danger"><span ' +
|
||||||
|
'class="glyphicon glyphicon-warning-sign" ' +
|
||||||
|
'aria-hidden="true"></span> <span>' + message + '</span></div>';
|
||||||
|
$('body').html(
|
||||||
|
'<div id="errormessage" role="alert" class="statusmessage ' +
|
||||||
|
'alert alert-danger hidden"><span class="glyphicon ' +
|
||||||
|
'glyphicon-alert" aria-hidden="true"></span> </div>'
|
||||||
|
);
|
||||||
|
$.PrivateBin.Alert.init();
|
||||||
|
$.PrivateBin.Alert.showWarning(message);
|
||||||
|
const result = $('body').html();
|
||||||
|
return expected === result;
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
|
jsc.property(
|
||||||
|
'shows a warning message (bootstrap, custom icon)',
|
||||||
|
jsc.array(common.jscAlnumString()),
|
||||||
|
jsc.array(common.jscAlnumString()),
|
||||||
|
function (icon, message) {
|
||||||
|
icon = icon.join('');
|
||||||
|
message = message.join('');
|
||||||
|
const expected = '<div id="errormessage" role="alert" ' +
|
||||||
|
'class="statusmessage alert alert-danger"><span ' +
|
||||||
|
'class="glyphicon glyphicon-' + icon +
|
||||||
|
'" aria-hidden="true"></span> <span>' + message + '</span></div>';
|
||||||
|
$('body').html(
|
||||||
|
'<div id="errormessage" role="alert" class="statusmessage ' +
|
||||||
|
'alert alert-danger hidden"><span class="glyphicon ' +
|
||||||
|
'glyphicon-alert" aria-hidden="true"></span> </div>'
|
||||||
|
);
|
||||||
|
$.PrivateBin.Alert.init();
|
||||||
|
$.PrivateBin.Alert.showWarning(message, icon);
|
||||||
|
const result = $('body').html();
|
||||||
return expected === result;
|
return expected === result;
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
|
@ -33,16 +141,56 @@ describe('Alert', function () {
|
||||||
});
|
});
|
||||||
|
|
||||||
jsc.property(
|
jsc.property(
|
||||||
'shows an error message',
|
'shows an error message (basic)',
|
||||||
jsc.array(common.jscAlnumString()),
|
jsc.array(common.jscAlnumString()),
|
||||||
jsc.array(common.jscAlnumString()),
|
jsc.array(common.jscAlnumString()),
|
||||||
function (icon, message) {
|
function (icon, message) {
|
||||||
icon = icon.join('');
|
icon = icon.join('');
|
||||||
message = message.join('');
|
message = message.join('');
|
||||||
var expected = '<div id="errormessage" role="alert" ' +
|
const expected = '<div id="errormessage">' + message + '</div>';
|
||||||
|
$('body').html(
|
||||||
|
'<div id="errormessage"></div>'
|
||||||
|
);
|
||||||
|
$.PrivateBin.Alert.init();
|
||||||
|
$.PrivateBin.Alert.showError(message, icon);
|
||||||
|
const result = $('body').html();
|
||||||
|
return expected === result;
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
|
jsc.property(
|
||||||
|
'shows an error message (bootstrap)',
|
||||||
|
jsc.array(common.jscAlnumString()),
|
||||||
|
jsc.array(common.jscAlnumString()),
|
||||||
|
function (icon, message) {
|
||||||
|
message = message.join('');
|
||||||
|
const expected = '<div id="errormessage" role="alert" ' +
|
||||||
|
'class="statusmessage alert alert-danger"><span ' +
|
||||||
|
'class="glyphicon glyphicon-alert" ' +
|
||||||
|
'aria-hidden="true"></span> <span>' + message + '</span></div>';
|
||||||
|
$('body').html(
|
||||||
|
'<div id="errormessage" role="alert" class="statusmessage ' +
|
||||||
|
'alert alert-danger hidden"><span class="glyphicon ' +
|
||||||
|
'glyphicon-alert" aria-hidden="true"></span> </div>'
|
||||||
|
);
|
||||||
|
$.PrivateBin.Alert.init();
|
||||||
|
$.PrivateBin.Alert.showError(message);
|
||||||
|
const result = $('body').html();
|
||||||
|
return expected === result;
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
|
jsc.property(
|
||||||
|
'shows an error message (bootstrap, custom icon)',
|
||||||
|
jsc.array(common.jscAlnumString()),
|
||||||
|
jsc.array(common.jscAlnumString()),
|
||||||
|
function (icon, message) {
|
||||||
|
icon = icon.join('');
|
||||||
|
message = message.join('');
|
||||||
|
const expected = '<div id="errormessage" role="alert" ' +
|
||||||
'class="statusmessage alert alert-danger"><span ' +
|
'class="statusmessage alert alert-danger"><span ' +
|
||||||
'class="glyphicon glyphicon-' + icon +
|
'class="glyphicon glyphicon-' + icon +
|
||||||
'" aria-hidden="true"></span> ' + message + '</div>';
|
'" aria-hidden="true"></span> <span>' + message + '</span></div>';
|
||||||
$('body').html(
|
$('body').html(
|
||||||
'<div id="errormessage" role="alert" class="statusmessage ' +
|
'<div id="errormessage" role="alert" class="statusmessage ' +
|
||||||
'alert alert-danger hidden"><span class="glyphicon ' +
|
'alert alert-danger hidden"><span class="glyphicon ' +
|
||||||
|
@ -50,7 +198,7 @@ describe('Alert', function () {
|
||||||
);
|
);
|
||||||
$.PrivateBin.Alert.init();
|
$.PrivateBin.Alert.init();
|
||||||
$.PrivateBin.Alert.showError(message, icon);
|
$.PrivateBin.Alert.showError(message, icon);
|
||||||
var result = $('body').html();
|
const result = $('body').html();
|
||||||
return expected === result;
|
return expected === result;
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
|
@ -62,17 +210,36 @@ describe('Alert', function () {
|
||||||
});
|
});
|
||||||
|
|
||||||
jsc.property(
|
jsc.property(
|
||||||
'shows remaining time',
|
'shows remaining time (basic)',
|
||||||
jsc.array(common.jscAlnumString()),
|
jsc.array(common.jscAlnumString()),
|
||||||
jsc.array(common.jscAlnumString()),
|
jsc.array(common.jscAlnumString()),
|
||||||
'integer',
|
'integer',
|
||||||
function (message, string, number) {
|
function (message, string, number) {
|
||||||
message = message.join('');
|
message = message.join('');
|
||||||
string = string.join('');
|
string = string.join('');
|
||||||
var expected = '<div id="remainingtime" role="alert" ' +
|
const expected = '<div id="remainingtime" class="">' + string + message + number + '</div>';
|
||||||
|
$('body').html(
|
||||||
|
'<div id="remainingtime" class="hidden"></div>'
|
||||||
|
);
|
||||||
|
$.PrivateBin.Alert.init();
|
||||||
|
$.PrivateBin.Alert.showRemaining(['%s' + message + '%d', string, number]);
|
||||||
|
const result = $('body').html();
|
||||||
|
return expected === result;
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
|
jsc.property(
|
||||||
|
'shows remaining time (bootstrap)',
|
||||||
|
jsc.array(common.jscAlnumString()),
|
||||||
|
jsc.array(common.jscAlnumString()),
|
||||||
|
'integer',
|
||||||
|
function (message, string, number) {
|
||||||
|
message = message.join('');
|
||||||
|
string = string.join('');
|
||||||
|
const expected = '<div id="remainingtime" role="alert" ' +
|
||||||
'class="alert alert-info"><span ' +
|
'class="alert alert-info"><span ' +
|
||||||
'class="glyphicon glyphicon-fire" aria-hidden="true">' +
|
'class="glyphicon glyphicon-fire" aria-hidden="true">' +
|
||||||
'</span> ' + string + message + number + '</div>';
|
'</span> <span>' + string + message + number + '</span></div>';
|
||||||
$('body').html(
|
$('body').html(
|
||||||
'<div id="remainingtime" role="alert" class="hidden ' +
|
'<div id="remainingtime" role="alert" class="hidden ' +
|
||||||
'alert alert-info"><span class="glyphicon ' +
|
'alert alert-info"><span class="glyphicon ' +
|
||||||
|
@ -80,7 +247,7 @@ describe('Alert', function () {
|
||||||
);
|
);
|
||||||
$.PrivateBin.Alert.init();
|
$.PrivateBin.Alert.init();
|
||||||
$.PrivateBin.Alert.showRemaining(['%s' + message + '%d', string, number]);
|
$.PrivateBin.Alert.showRemaining(['%s' + message + '%d', string, number]);
|
||||||
var result = $('body').html();
|
const result = $('body').html();
|
||||||
return expected === result;
|
return expected === result;
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
|
@ -92,20 +259,42 @@ describe('Alert', function () {
|
||||||
});
|
});
|
||||||
|
|
||||||
jsc.property(
|
jsc.property(
|
||||||
'shows a loading message',
|
'shows a loading message (basic)',
|
||||||
jsc.array(common.jscAlnumString()),
|
jsc.array(common.jscAlnumString()),
|
||||||
jsc.array(common.jscAlnumString()),
|
jsc.array(common.jscAlnumString()),
|
||||||
function (message, icon) {
|
function (message, icon) {
|
||||||
message = message.join('');
|
message = message.join('');
|
||||||
icon = icon.join('');
|
icon = icon.join('');
|
||||||
var defaultMessage = 'Loading…';
|
const defaultMessage = 'Loading…';
|
||||||
if (message.length === 0) {
|
if (message.length === 0) {
|
||||||
message = defaultMessage;
|
message = defaultMessage;
|
||||||
}
|
}
|
||||||
var expected = '<ul class="nav navbar-nav"><li ' +
|
const expected = '<div id="loadingindicator" class="">' + message + '</div>';
|
||||||
|
$('body').html(
|
||||||
|
'<div id="loadingindicator" class="hidden">' + defaultMessage + '</div>'
|
||||||
|
);
|
||||||
|
$.PrivateBin.Alert.init();
|
||||||
|
$.PrivateBin.Alert.showLoading(message, icon);
|
||||||
|
const result = $('body').html();
|
||||||
|
return expected === result;
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
|
jsc.property(
|
||||||
|
'shows a loading message (bootstrap)',
|
||||||
|
jsc.array(common.jscAlnumString()),
|
||||||
|
jsc.array(common.jscAlnumString()),
|
||||||
|
function (message, icon) {
|
||||||
|
message = message.join('');
|
||||||
|
icon = icon.join('');
|
||||||
|
const defaultMessage = 'Loading…';
|
||||||
|
if (message.length === 0) {
|
||||||
|
message = defaultMessage;
|
||||||
|
}
|
||||||
|
const expected = '<ul class="nav navbar-nav"><li ' +
|
||||||
'id="loadingindicator" class="navbar-text"><span ' +
|
'id="loadingindicator" class="navbar-text"><span ' +
|
||||||
'class="glyphicon glyphicon-' + icon +
|
'class="glyphicon glyphicon-' + icon +
|
||||||
'" aria-hidden="true"></span> ' + message + '</li></ul>';
|
'" aria-hidden="true"></span> <span>' + message + '</span></li></ul>';
|
||||||
$('body').html(
|
$('body').html(
|
||||||
'<ul class="nav navbar-nav"><li id="loadingindicator" ' +
|
'<ul class="nav navbar-nav"><li id="loadingindicator" ' +
|
||||||
'class="navbar-text hidden"><span class="glyphicon ' +
|
'class="navbar-text hidden"><span class="glyphicon ' +
|
||||||
|
@ -114,7 +303,7 @@ describe('Alert', function () {
|
||||||
);
|
);
|
||||||
$.PrivateBin.Alert.init();
|
$.PrivateBin.Alert.init();
|
||||||
$.PrivateBin.Alert.showLoading(message, icon);
|
$.PrivateBin.Alert.showLoading(message, icon);
|
||||||
var result = $('body').html();
|
const result = $('body').html();
|
||||||
return expected === result;
|
return expected === result;
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
|
@ -182,7 +371,7 @@ describe('Alert', function () {
|
||||||
jsc.array(common.jscAlnumString()),
|
jsc.array(common.jscAlnumString()),
|
||||||
function (trigger, message) {
|
function (trigger, message) {
|
||||||
message = message.join('');
|
message = message.join('');
|
||||||
var handlerCalled = false,
|
let handlerCalled = false,
|
||||||
defaultMessage = 'Loading…',
|
defaultMessage = 'Loading…',
|
||||||
functions = [
|
functions = [
|
||||||
$.PrivateBin.Alert.showStatus,
|
$.PrivateBin.Alert.showStatus,
|
||||||
|
|
|
@ -0,0 +1,83 @@
|
||||||
|
'use strict';
|
||||||
|
var common = require('../common');
|
||||||
|
/* global Legacy, WebCrypto */
|
||||||
|
|
||||||
|
describe('Check', function () {
|
||||||
|
describe('init', function () {
|
||||||
|
this.timeout(30000);
|
||||||
|
before(function () {
|
||||||
|
cleanup();
|
||||||
|
});
|
||||||
|
|
||||||
|
it('returns false and shows error, if a bot UA is detected', function () {
|
||||||
|
jsc.assert(jsc.forall(
|
||||||
|
'string',
|
||||||
|
jsc.elements(['Bot', 'bot']),
|
||||||
|
'string',
|
||||||
|
function (prefix, botBit, suffix) {
|
||||||
|
const clean = jsdom(
|
||||||
|
'<html><body><div id="errormessage" class="hidden"></div>' +
|
||||||
|
'</body></html>', {
|
||||||
|
'userAgent': prefix + botBit + suffix
|
||||||
|
}
|
||||||
|
);
|
||||||
|
Legacy.Check.init();
|
||||||
|
const result1 = Legacy.Check.getInit() && !Legacy.Check.getStatus(),
|
||||||
|
result2 = (document.getElementById('errormessage').className !== 'hidden');
|
||||||
|
clean();
|
||||||
|
return result1 && result2;
|
||||||
|
}
|
||||||
|
),
|
||||||
|
{tests: 10});
|
||||||
|
});
|
||||||
|
|
||||||
|
jsc.property(
|
||||||
|
'shows error, if no webcrypto is detected',
|
||||||
|
'bool',
|
||||||
|
jsc.elements(['localhost', '127.0.0.1', '[::1]', '']),
|
||||||
|
jsc.nearray(common.jscA2zString()),
|
||||||
|
jsc.elements(['.onion', '.i2p', '']),
|
||||||
|
function (secureProtocol, localhost, domain, tld) {
|
||||||
|
const isDomain = localhost === '',
|
||||||
|
isSecureContext = secureProtocol || !isDomain || tld.length > 0,
|
||||||
|
clean = jsdom(
|
||||||
|
'<html><body><div id="errormessage" class="hidden"></div>' +
|
||||||
|
'<div id="oldnotice" class="hidden"></div>' +
|
||||||
|
'<div id="insecurecontextnotice" class="hidden"></div></body></html>',
|
||||||
|
{
|
||||||
|
'url': (secureProtocol ? 'https' : 'http' ) + '://' +
|
||||||
|
(isDomain ? domain.join('') + tld : localhost) + '/'
|
||||||
|
}
|
||||||
|
);
|
||||||
|
Legacy.Check.init();
|
||||||
|
const result1 = Legacy.Check.getInit() && !Legacy.Check.getStatus(),
|
||||||
|
result2 = isSecureContext === (document.getElementById('insecurecontextnotice').className === 'hidden'),
|
||||||
|
result3 = (document.getElementById('oldnotice').className !== 'hidden');
|
||||||
|
clean();
|
||||||
|
return result1 && result2 && result3;
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
|
jsc.property(
|
||||||
|
'shows error, if HTTP only site is detected',
|
||||||
|
'bool',
|
||||||
|
jsc.nearray(common.jscA2zString()),
|
||||||
|
function (secureProtocol, domain) {
|
||||||
|
const clean = jsdom(
|
||||||
|
'<html><body><div id="httpnotice" class="hidden"></div>' +
|
||||||
|
'</body></html>',
|
||||||
|
{
|
||||||
|
'url': (secureProtocol ? 'https' : 'http' ) + '://' + domain.join('') + '/'
|
||||||
|
}
|
||||||
|
);
|
||||||
|
window.crypto = new WebCrypto();
|
||||||
|
Legacy.Check.init();
|
||||||
|
const result1 = Legacy.Check.getInit() && Legacy.Check.getStatus(),
|
||||||
|
result2 = secureProtocol === (document.getElementById('httpnotice').className === 'hidden');
|
||||||
|
clean();
|
||||||
|
return result1 && result2;
|
||||||
|
}
|
||||||
|
);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
|
@ -18,13 +18,15 @@ describe('CryptTool', function () {
|
||||||
// pause to let async functions conclude
|
// pause to let async functions conclude
|
||||||
await new Promise(resolve => setTimeout(resolve, 300));
|
await new Promise(resolve => setTimeout(resolve, 300));
|
||||||
let clean = jsdom();
|
let clean = jsdom();
|
||||||
|
// ensure zlib is getting loaded
|
||||||
|
$.PrivateBin.Controller.initZ();
|
||||||
window.crypto = new WebCrypto();
|
window.crypto = new WebCrypto();
|
||||||
message = message.trim();
|
message = message.trim();
|
||||||
let cipherMessage = await $.PrivateBin.CryptTool.cipher(
|
let cipherMessage = await $.PrivateBin.CryptTool.cipher(
|
||||||
key, password, message, []
|
key, password, message, []
|
||||||
),
|
),
|
||||||
plaintext = await $.PrivateBin.CryptTool.decipher(
|
plaintext = await $.PrivateBin.CryptTool.decipher(
|
||||||
key, password, cipherMessage
|
key, password, cipherMessage
|
||||||
);
|
);
|
||||||
clean();
|
clean();
|
||||||
return message === plaintext;
|
return message === plaintext;
|
||||||
|
@ -179,6 +181,8 @@ describe('CryptTool', function () {
|
||||||
let message = fs.readFileSync('test/compression-sample.txt', 'utf8'),
|
let message = fs.readFileSync('test/compression-sample.txt', 'utf8'),
|
||||||
clean = jsdom();
|
clean = jsdom();
|
||||||
window.crypto = new WebCrypto();
|
window.crypto = new WebCrypto();
|
||||||
|
// ensure zlib is getting loaded
|
||||||
|
$.PrivateBin.Controller.initZ();
|
||||||
let cipherMessage = await $.PrivateBin.CryptTool.cipher(
|
let cipherMessage = await $.PrivateBin.CryptTool.cipher(
|
||||||
'foo', 'bar', message, []
|
'foo', 'bar', message, []
|
||||||
),
|
),
|
||||||
|
@ -222,6 +226,8 @@ isWhile : interp (while expr sBody) (MemElem mem) =
|
||||||
conseq_or_bottom inv (interp (nth_iterate sBody n) (MemElem mem))
|
conseq_or_bottom inv (interp (nth_iterate sBody n) (MemElem mem))
|
||||||
`;
|
`;
|
||||||
let clean = jsdom();
|
let clean = jsdom();
|
||||||
|
// ensure zlib is getting loaded
|
||||||
|
$.PrivateBin.Controller.initZ();
|
||||||
window.crypto = new WebCrypto();
|
window.crypto = new WebCrypto();
|
||||||
let cipherMessage = await $.PrivateBin.CryptTool.cipher(
|
let cipherMessage = await $.PrivateBin.CryptTool.cipher(
|
||||||
key, password, message, []
|
key, password, message, []
|
||||||
|
|
|
@ -183,9 +183,9 @@ describe('Helper', function () {
|
||||||
'string',
|
'string',
|
||||||
'string',
|
'string',
|
||||||
function (prefix, uint, middle, string, postfix) {
|
function (prefix, uint, middle, string, postfix) {
|
||||||
prefix = prefix.replace(/%(s|d)/g, '%%');
|
prefix = prefix.replace(/%(s|d)/g, '');
|
||||||
middle = middle.replace(/%(s|d)/g, '%%');
|
middle = middle.replace(/%(s|d)/g, '');
|
||||||
postfix = postfix.replace(/%(s|d)/g, '%%');
|
postfix = postfix.replace(/%(s|d)/g, '');
|
||||||
var params = [prefix + '%d' + middle + '%s' + postfix, uint, string],
|
var params = [prefix + '%d' + middle + '%s' + postfix, uint, string],
|
||||||
result = prefix + uint + middle + string + postfix;
|
result = prefix + uint + middle + string + postfix;
|
||||||
return result === $.PrivateBin.Helper.sprintf.apply(this, params);
|
return result === $.PrivateBin.Helper.sprintf.apply(this, params);
|
||||||
|
@ -199,9 +199,9 @@ describe('Helper', function () {
|
||||||
'string',
|
'string',
|
||||||
'string',
|
'string',
|
||||||
function (prefix, uint, middle, string, postfix) {
|
function (prefix, uint, middle, string, postfix) {
|
||||||
prefix = prefix.replace(/%(s|d)/g, '%%');
|
prefix = prefix.replace(/%(s|d)/g, '');
|
||||||
middle = middle.replace(/%(s|d)/g, '%%');
|
middle = middle.replace(/%(s|d)/g, '');
|
||||||
postfix = postfix.replace(/%(s|d)/g, '%%');
|
postfix = postfix.replace(/%(s|d)/g, '');
|
||||||
var params = [prefix + '%s' + middle + '%d' + postfix, string, uint],
|
var params = [prefix + '%s' + middle + '%d' + postfix, string, uint],
|
||||||
result = prefix + string + middle + uint + postfix;
|
result = prefix + string + middle + uint + postfix;
|
||||||
return result === $.PrivateBin.Helper.sprintf.apply(this, params);
|
return result === $.PrivateBin.Helper.sprintf.apply(this, params);
|
||||||
|
|
|
@ -1,88 +0,0 @@
|
||||||
'use strict';
|
|
||||||
var common = require('../common');
|
|
||||||
|
|
||||||
describe('InitialCheck', function () {
|
|
||||||
describe('init', function () {
|
|
||||||
this.timeout(30000);
|
|
||||||
before(function () {
|
|
||||||
cleanup();
|
|
||||||
});
|
|
||||||
|
|
||||||
it('returns false and shows error, if a bot UA is detected', function () {
|
|
||||||
jsc.assert(jsc.forall(
|
|
||||||
'string',
|
|
||||||
jsc.elements(['Bot', 'bot']),
|
|
||||||
'string',
|
|
||||||
function (prefix, botBit, suffix) {
|
|
||||||
const clean = jsdom('', {
|
|
||||||
'userAgent': prefix + botBit + suffix
|
|
||||||
});
|
|
||||||
$('body').html(
|
|
||||||
'<html><body><div id="errormessage" class="hidden"></div>' +
|
|
||||||
'</body></html>'
|
|
||||||
);
|
|
||||||
$.PrivateBin.Alert.init();
|
|
||||||
window.crypto = null;
|
|
||||||
const result1 = !$.PrivateBin.InitialCheck.init(),
|
|
||||||
result2 = !$('#errormessage').hasClass('hidden');
|
|
||||||
clean();
|
|
||||||
return result1 && result2;
|
|
||||||
}
|
|
||||||
),
|
|
||||||
{tests: 10});
|
|
||||||
});
|
|
||||||
|
|
||||||
jsc.property(
|
|
||||||
'shows error, if no webcrypto is detected',
|
|
||||||
'bool',
|
|
||||||
jsc.elements(['localhost', '127.0.0.1', '[::1]', '']),
|
|
||||||
jsc.nearray(common.jscA2zString()),
|
|
||||||
jsc.elements(['.onion', '.i2p', '']),
|
|
||||||
function (secureProtocol, localhost, domain, tld) {
|
|
||||||
const isDomain = localhost === '',
|
|
||||||
isSecureContext = secureProtocol || !isDomain || tld.length > 0,
|
|
||||||
clean = jsdom('', {
|
|
||||||
'url': (secureProtocol ? 'https' : 'http' ) + '://' +
|
|
||||||
(isDomain ? domain.join('') + tld : localhost) + '/'
|
|
||||||
});
|
|
||||||
$('body').html(
|
|
||||||
'<html><body><div id="errormessage" class="hidden"></div>'+
|
|
||||||
'<div id="oldnotice" class="hidden"></div></body></html>'
|
|
||||||
);
|
|
||||||
$.PrivateBin.Alert.init();
|
|
||||||
const result1 = !$.PrivateBin.InitialCheck.init(),
|
|
||||||
result2 = isSecureContext === $('#errormessage').hasClass('hidden'),
|
|
||||||
result3 = !$('#oldnotice').hasClass('hidden');
|
|
||||||
clean();
|
|
||||||
return result1 && result2 && result3;
|
|
||||||
}
|
|
||||||
);
|
|
||||||
|
|
||||||
jsc.property(
|
|
||||||
'shows error, if HTTP only site is detected',
|
|
||||||
'bool',
|
|
||||||
jsc.elements(['localhost', '127.0.0.1', '[::1]', '']),
|
|
||||||
jsc.nearray(common.jscA2zString()),
|
|
||||||
jsc.elements(['.onion', '.i2p', '']),
|
|
||||||
function (secureProtocol, localhost, domain, tld) {
|
|
||||||
const isDomain = localhost === '',
|
|
||||||
isSecureContext = secureProtocol || !isDomain || tld.length > 0,
|
|
||||||
clean = jsdom('', {
|
|
||||||
'url': (secureProtocol ? 'https' : 'http' ) + '://' +
|
|
||||||
(isDomain ? domain.join('') + tld : localhost) + '/'
|
|
||||||
});
|
|
||||||
$('body').html(
|
|
||||||
'<html><body><div id="httpnotice" class="hidden"></div>'+
|
|
||||||
'</body></html>'
|
|
||||||
);
|
|
||||||
$.PrivateBin.Alert.init();
|
|
||||||
window.crypto = null;
|
|
||||||
const result1 = $.PrivateBin.InitialCheck.init(),
|
|
||||||
result2 = isSecureContext === $('#httpnotice').hasClass('hidden');
|
|
||||||
clean();
|
|
||||||
return result1 && result2;
|
|
||||||
}
|
|
||||||
);
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
|
@ -388,6 +388,7 @@ class Controller
|
||||||
$page->assign('URLSHORTENER', $this->_conf->getKey('urlshortener'));
|
$page->assign('URLSHORTENER', $this->_conf->getKey('urlshortener'));
|
||||||
$page->assign('QRCODE', $this->_conf->getKey('qrcode'));
|
$page->assign('QRCODE', $this->_conf->getKey('qrcode'));
|
||||||
$page->assign('HTTPWARNING', $this->_conf->getKey('httpwarning'));
|
$page->assign('HTTPWARNING', $this->_conf->getKey('httpwarning'));
|
||||||
|
$page->assign('HTTPSLINK', 'https://' . $this->_request->getHost() . $this->_request->getRequestUri());
|
||||||
$page->assign('COMPRESSION', $this->_conf->getKey('compression'));
|
$page->assign('COMPRESSION', $this->_conf->getKey('compression'));
|
||||||
$page->draw($this->_conf->getKey('template'));
|
$page->draw($this->_conf->getKey('template'));
|
||||||
}
|
}
|
||||||
|
|
|
@ -193,6 +193,19 @@ class Request
|
||||||
$this->_params[$param] : $default;
|
$this->_params[$param] : $default;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get host as requested by the client
|
||||||
|
*
|
||||||
|
* @access public
|
||||||
|
* @return string
|
||||||
|
*/
|
||||||
|
public function getHost()
|
||||||
|
{
|
||||||
|
return array_key_exists('HTTP_HOST', $_SERVER) ?
|
||||||
|
htmlspecialchars($_SERVER['HTTP_HOST']) :
|
||||||
|
'localhost';
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get request URI
|
* Get request URI
|
||||||
*
|
*
|
||||||
|
@ -202,8 +215,8 @@ class Request
|
||||||
public function getRequestUri()
|
public function getRequestUri()
|
||||||
{
|
{
|
||||||
return array_key_exists('REQUEST_URI', $_SERVER) ?
|
return array_key_exists('REQUEST_URI', $_SERVER) ?
|
||||||
htmlspecialchars(
|
htmlspecialchars(
|
||||||
parse_url($_SERVER['REQUEST_URI'], PHP_URL_PATH)
|
parse_url($_SERVER['REQUEST_URI'], PHP_URL_PATH)
|
||||||
) : '/';
|
) : '/';
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -5,5 +5,4 @@
|
||||||
# directory.
|
# directory.
|
||||||
|
|
||||||
User-agent: *
|
User-agent: *
|
||||||
Allow: /index.php
|
|
||||||
Disallow: /
|
Disallow: /
|
||||||
|
|
|
@ -71,10 +71,8 @@ if ($MARKDOWN):
|
||||||
endif;
|
endif;
|
||||||
?>
|
?>
|
||||||
<script type="text/javascript" data-cfasync="false" src="js/purify-2.0.1.js" integrity="sha512-ddI36MdUoXp/o7yhQtr9/qj4G3oFwCRga4jCGaoUYtORg0PPmFKVKG4Ess3fIknYzxwwKMlrIL9o4NwuPTCc1Q==" crossorigin="anonymous"></script>
|
<script type="text/javascript" data-cfasync="false" src="js/purify-2.0.1.js" integrity="sha512-ddI36MdUoXp/o7yhQtr9/qj4G3oFwCRga4jCGaoUYtORg0PPmFKVKG4Ess3fIknYzxwwKMlrIL9o4NwuPTCc1Q==" crossorigin="anonymous"></script>
|
||||||
<script type="text/javascript" data-cfasync="false" src="js/privatebin.js?<?php echo rawurlencode($VERSION); ?>" integrity="sha512-86VTqw2HsaCQ0DAunK2MH68P+8RLbbaK7HZP8nwDtwNoF44usxDCptmD8TC+zwQc7HM46AkrvVFb3ZkIb6VhMQ==" crossorigin="anonymous"></script>
|
<script type="text/javascript" data-cfasync="false" src="js/legacy.js?<?php echo rawurlencode($VERSION); ?>" integrity="sha512-dReLYyMJO3kV7/etVKlGWSbmJoWavMpbgG8Hg3759MNHv0mYuonh4Azif3y0F0oopKKlz3vtj8XZV7VY+e6dSQ==" crossorigin="anonymous"></script>
|
||||||
<!--[if IE]>
|
<script type="text/javascript" data-cfasync="false" src="js/privatebin.js?<?php echo rawurlencode($VERSION); ?>" integrity="sha512-4iMFqnyyoJ/FJ33aHov+QeItaZ0JegMUjx7J5pXeknEwjXzx4oLw9F9ePI3WK/h3sUYTOK+hdv2JINNGMwi2Vg==" crossorigin="anonymous"></script>
|
||||||
<style type="text/css">body {padding-left:60px;padding-right:60px;} #ienotice {display:block;}</style>
|
|
||||||
<![endif]-->
|
|
||||||
<link rel="apple-touch-icon" href="img/apple-touch-icon.png?<?php echo rawurlencode($VERSION); ?>" sizes="180x180" />
|
<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" />
|
<link rel="icon" type="image/png" href="img/favicon-32x32.png?<?php echo rawurlencode($VERSION); ?>" sizes="32x32" />
|
||||||
<link rel="icon" type="image/png" href="img/favicon-16x16.png?<?php echo rawurlencode($VERSION); ?>" sizes="16x16" />
|
<link rel="icon" type="image/png" href="img/favicon-16x16.png?<?php echo rawurlencode($VERSION); ?>" sizes="16x16" />
|
||||||
|
@ -446,10 +444,6 @@ endif;
|
||||||
<div id="oldnotice" role="alert" class="hidden alert alert-danger">
|
<div id="oldnotice" role="alert" class="hidden alert alert-danger">
|
||||||
<span class="glyphicon glyphicon-alert" aria-hidden="true"></span>
|
<span class="glyphicon glyphicon-alert" aria-hidden="true"></span>
|
||||||
<?php echo I18n::_('%s requires a modern browser to work.', I18n::_($NAME)), PHP_EOL; ?>
|
<?php echo I18n::_('%s requires a modern browser to work.', I18n::_($NAME)), PHP_EOL; ?>
|
||||||
</div>
|
|
||||||
<div id="ienotice" role="alert" class="hidden alert alert-danger">
|
|
||||||
<span class="glyphicon glyphicon-question-sign" aria-hidden="true"></span>
|
|
||||||
<?php echo I18n::_('Still using Internet Explorer? Do yourself a favor, switch to a modern browser:'), PHP_EOL; ?>
|
|
||||||
<a href="https://www.mozilla.org/firefox/">Firefox</a>,
|
<a href="https://www.mozilla.org/firefox/">Firefox</a>,
|
||||||
<a href="https://www.opera.com/">Opera</a>,
|
<a href="https://www.opera.com/">Opera</a>,
|
||||||
<a href="https://www.google.com/chrome">Chrome</a>…
|
<a href="https://www.google.com/chrome">Chrome</a>…
|
||||||
|
@ -462,6 +456,10 @@ if ($HTTPWARNING):
|
||||||
<?php echo I18n::_('This website is using an insecure connection! Please only use it for testing.'), PHP_EOL; ?><br />
|
<?php echo I18n::_('This website is using an insecure connection! Please only use it for testing.'), PHP_EOL; ?><br />
|
||||||
<span class="small"><?php echo I18n::_('For more information <a href="%s">see this FAQ entry</a>.', 'https://github.com/PrivateBin/PrivateBin/wiki/FAQ#why-does-it-show-me-an-error-about-an-insecure-connection'); ?></span>
|
<span class="small"><?php echo I18n::_('For more information <a href="%s">see this FAQ entry</a>.', 'https://github.com/PrivateBin/PrivateBin/wiki/FAQ#why-does-it-show-me-an-error-about-an-insecure-connection'); ?></span>
|
||||||
</div>
|
</div>
|
||||||
|
<div id="insecurecontextnotice" role="alert" class="hidden alert alert-danger">
|
||||||
|
<span class="glyphicon glyphicon-alert" aria-hidden="true"></span>
|
||||||
|
<?php echo I18n::_('Your browser may require an HTTPS connection to support the WebCrypto API. Try <a href="%s">switching to HTTPS</a>.', $HTTPSLINK); ?>
|
||||||
|
</div>
|
||||||
<?php
|
<?php
|
||||||
endif;
|
endif;
|
||||||
?>
|
?>
|
||||||
|
|
14
tpl/page.php
14
tpl/page.php
|
@ -49,10 +49,8 @@ if ($MARKDOWN):
|
||||||
endif;
|
endif;
|
||||||
?>
|
?>
|
||||||
<script type="text/javascript" data-cfasync="false" src="js/purify-2.0.1.js" integrity="sha512-ddI36MdUoXp/o7yhQtr9/qj4G3oFwCRga4jCGaoUYtORg0PPmFKVKG4Ess3fIknYzxwwKMlrIL9o4NwuPTCc1Q==" crossorigin="anonymous"></script>
|
<script type="text/javascript" data-cfasync="false" src="js/purify-2.0.1.js" integrity="sha512-ddI36MdUoXp/o7yhQtr9/qj4G3oFwCRga4jCGaoUYtORg0PPmFKVKG4Ess3fIknYzxwwKMlrIL9o4NwuPTCc1Q==" crossorigin="anonymous"></script>
|
||||||
<script type="text/javascript" data-cfasync="false" src="js/privatebin.js?<?php echo rawurlencode($VERSION); ?>" integrity="sha512-86VTqw2HsaCQ0DAunK2MH68P+8RLbbaK7HZP8nwDtwNoF44usxDCptmD8TC+zwQc7HM46AkrvVFb3ZkIb6VhMQ==" crossorigin="anonymous"></script>
|
<script type="text/javascript" data-cfasync="false" src="js/legacy.js?<?php echo rawurlencode($VERSION); ?>" integrity="sha512-dReLYyMJO3kV7/etVKlGWSbmJoWavMpbgG8Hg3759MNHv0mYuonh4Azif3y0F0oopKKlz3vtj8XZV7VY+e6dSQ==" crossorigin="anonymous"></script>
|
||||||
<!--[if IE]>
|
<script type="text/javascript" data-cfasync="false" src="js/privatebin.js?<?php echo rawurlencode($VERSION); ?>" integrity="sha512-4iMFqnyyoJ/FJ33aHov+QeItaZ0JegMUjx7J5pXeknEwjXzx4oLw9F9ePI3WK/h3sUYTOK+hdv2JINNGMwi2Vg==" crossorigin="anonymous"></script>
|
||||||
<style type="text/css">body {padding-left:60px;padding-right:60px;} #ienotice {display:block;}</style>
|
|
||||||
<![endif]-->
|
|
||||||
<link rel="apple-touch-icon" href="img/apple-touch-icon.png?<?php echo rawurlencode($VERSION); ?>" sizes="180x180" />
|
<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" />
|
<link rel="icon" type="image/png" href="img/favicon-32x32.png?<?php echo rawurlencode($VERSION); ?>" sizes="32x32" />
|
||||||
<link rel="icon" type="image/png" href="img/favicon-16x16.png?<?php echo rawurlencode($VERSION); ?>" sizes="16x16" />
|
<link rel="icon" type="image/png" href="img/favicon-16x16.png?<?php echo rawurlencode($VERSION); ?>" sizes="16x16" />
|
||||||
|
@ -77,8 +75,7 @@ endif;
|
||||||
<h2 class="title"><?php echo I18n::_('Because ignorance is bliss'); ?></h2><br />
|
<h2 class="title"><?php echo I18n::_('Because ignorance is bliss'); ?></h2><br />
|
||||||
<h3 class="title"><?php echo $VERSION; ?></h3>
|
<h3 class="title"><?php echo $VERSION; ?></h3>
|
||||||
<noscript><div id="noscript" class="nonworking"><?php echo I18n::_('JavaScript is required for %s to work.<br />Sorry for the inconvenience.', I18n::_($NAME)); ?></div></noscript>
|
<noscript><div id="noscript" class="nonworking"><?php echo I18n::_('JavaScript is required for %s to work.<br />Sorry for the inconvenience.', I18n::_($NAME)); ?></div></noscript>
|
||||||
<div id="oldnotice" class="nonworking"><?php echo I18n::_('%s requires a modern browser to work.', I18n::_($NAME)); ?></div>
|
<div id="oldnotice" class="nonworking hidden"><?php echo I18n::_('%s requires a modern browser to work.', I18n::_($NAME)), PHP_EOL; ?>
|
||||||
<div id="ienotice" class="nonworking"><?php echo I18n::_('Still using Internet Explorer? Do yourself a favor, switch to a modern browser:'), PHP_EOL; ?>
|
|
||||||
<a href="https://www.mozilla.org/firefox/">Firefox</a>,
|
<a href="https://www.mozilla.org/firefox/">Firefox</a>,
|
||||||
<a href="https://www.opera.com/">Opera</a>,
|
<a href="https://www.opera.com/">Opera</a>,
|
||||||
<a href="https://www.google.com/chrome">Chrome</a>…
|
<a href="https://www.google.com/chrome">Chrome</a>…
|
||||||
|
@ -86,10 +83,13 @@ endif;
|
||||||
<?php
|
<?php
|
||||||
if ($HTTPWARNING):
|
if ($HTTPWARNING):
|
||||||
?>
|
?>
|
||||||
<div id="httpnotice" class="errorMessage">
|
<div id="httpnotice" class="errorMessage hidden">
|
||||||
<?php echo I18n::_('This website is using an insecure connection! Please only use it for testing.'); ?>
|
<?php echo I18n::_('This website is using an insecure connection! Please only use it for testing.'); ?>
|
||||||
<span class="small"><?php echo I18n::_('For more information <a href="%s">see this FAQ entry</a>.', 'https://github.com/PrivateBin/PrivateBin/wiki/FAQ#why-does-it-show-me-an-error-about-an-insecure-connection'); ?></span>
|
<span class="small"><?php echo I18n::_('For more information <a href="%s">see this FAQ entry</a>.', 'https://github.com/PrivateBin/PrivateBin/wiki/FAQ#why-does-it-show-me-an-error-about-an-insecure-connection'); ?></span>
|
||||||
</div>
|
</div>
|
||||||
|
<div id="insecurecontextnotice" class="errorMessage hidden">
|
||||||
|
<?php echo I18n::_('Your browser may require an HTTPS connection to support the WebCrypto API. Try <a href="%s">switching to HTTPS</a>.', $HTTPSLINK); ?>
|
||||||
|
</div>
|
||||||
<?php
|
<?php
|
||||||
endif;
|
endif;
|
||||||
?>
|
?>
|
||||||
|
|
|
@ -56,6 +56,7 @@ class ViewTest extends PHPUnit_Framework_TestCase
|
||||||
$page->assign('URLSHORTENER', '');
|
$page->assign('URLSHORTENER', '');
|
||||||
$page->assign('QRCODE', true);
|
$page->assign('QRCODE', true);
|
||||||
$page->assign('HTTPWARNING', true);
|
$page->assign('HTTPWARNING', true);
|
||||||
|
$page->assign('HTTPSLINK', 'https://example.com/');
|
||||||
$page->assign('COMPRESSION', 'zlib');
|
$page->assign('COMPRESSION', 'zlib');
|
||||||
|
|
||||||
$dir = dir(PATH . 'tpl');
|
$dir = dir(PATH . 'tpl');
|
||||||
|
|
Loading…
Reference in New Issue