2019-09-14 09:41:52 +02:00
/ * *
* 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 :
* - ES6 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 5 or 6 , to at least display the error message
* /
// main application start, called when DOM is fully loaded
jQuery ( document ) . ready ( function ( ) {
'use strict' ;
// run main controller
$ . Legacy . Check . init ( ) ;
} ) ;
jQuery . Legacy = ( function ( $ ) {
'use strict' ;
/ * *
* 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
2019-09-14 09:50:47 +02:00
for ( var j = 0 ; j < hostname . length ; j ++ ) {
if ( window . location . hostname === hostname [ j ] ) {
2019-09-14 09:41:52 +02:00
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 ;
}
// not checking for async/await, ES6 or Promise support, as most
// browsers introduced these earlier then webassembly and webcrypto:
// https://github.com/PrivateBin/PrivateBin/pull/431#issuecomment-493129359
return false ;
}
/ * *
* returns if the check has concluded
*
* @ name Check . getInit
* @ function
* @ return { bool }
* /
me . getInit = function ( )
{
return init ;
2019-09-14 09:53:22 +02:00
} ;
2019-09-14 09:41:52 +02:00
/ * *
* returns the current status of the check
*
* @ name Check . getStatus
* @ function
* @ return { bool }
* /
me . getStatus = function ( )
{
return status ;
2019-09-14 09:53:22 +02:00
} ;
2019-09-14 09:41:52 +02:00
/ * *
* 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 ( ) ) {
$ . PrivateBin . Alert . 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 ( ) ) {
$ . PrivateBin . 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' ) ;
init = true ;
return ;
}
if ( ! isSecureContext ( ) ) {
$ ( '#httpnotice' ) . removeClass ( 'hidden' ) ;
}
init = true ;
// only if everything passed, we set the status to true
status = true ;
2019-09-14 09:53:22 +02:00
} ;
2019-09-14 09:41:52 +02:00
return me ;
} ) ( ) ;
return {
Check : Check
} ;
} ) ( jQuery ) ;