2012-04-22 12:45:45 +02:00
|
|
|
|
/**
|
2016-07-11 11:58:15 +02:00
|
|
|
|
* PrivateBin
|
2012-04-23 16:30:02 +02:00
|
|
|
|
*
|
2012-04-30 22:58:08 +02:00
|
|
|
|
* a zero-knowledge paste bin
|
|
|
|
|
*
|
2016-07-11 11:58:15 +02:00
|
|
|
|
* @link https://github.com/PrivateBin/PrivateBin
|
2012-04-30 22:58:08 +02:00
|
|
|
|
* @copyright 2012 Sébastien SAUVAGE (sebsauvage.net)
|
2016-07-19 13:56:52 +02:00
|
|
|
|
* @license https://www.opensource.org/licenses/zlib-license.php The zlib/libpng License
|
2016-12-26 12:13:50 +01:00
|
|
|
|
* @version 1.1
|
2012-04-22 12:45:45 +02:00
|
|
|
|
*/
|
2012-04-21 21:59:45 +02:00
|
|
|
|
|
2015-09-06 13:07:46 +02:00
|
|
|
|
'use strict';
|
2016-07-11 15:47:42 +02:00
|
|
|
|
/** global: Base64 */
|
|
|
|
|
/** global: FileReader */
|
|
|
|
|
/** global: RawDeflate */
|
|
|
|
|
/** global: history */
|
|
|
|
|
/** global: navigator */
|
|
|
|
|
/** global: prettyPrint */
|
|
|
|
|
/** global: prettyPrintOne */
|
|
|
|
|
/** global: showdown */
|
|
|
|
|
/** global: sjcl */
|
2015-09-06 13:07:46 +02:00
|
|
|
|
|
2012-04-21 21:59:45 +02:00
|
|
|
|
// Immediately start random number generator collector.
|
|
|
|
|
sjcl.random.startCollectors();
|
|
|
|
|
|
2015-09-06 13:07:46 +02:00
|
|
|
|
$(function() {
|
2015-09-05 17:12:11 +02:00
|
|
|
|
/**
|
|
|
|
|
* static helper methods
|
|
|
|
|
*/
|
|
|
|
|
var helper = {
|
|
|
|
|
/**
|
2015-09-06 15:54:43 +02:00
|
|
|
|
* Converts a duration (in seconds) into human friendly approximation.
|
2015-09-05 17:12:11 +02:00
|
|
|
|
*
|
|
|
|
|
* @param int seconds
|
2015-09-06 15:54:43 +02:00
|
|
|
|
* @return array
|
2015-09-05 17:12:11 +02:00
|
|
|
|
*/
|
|
|
|
|
secondsToHuman: function(seconds)
|
|
|
|
|
{
|
2016-07-11 15:47:42 +02:00
|
|
|
|
var v;
|
2015-09-05 17:12:11 +02:00
|
|
|
|
if (seconds < 60)
|
|
|
|
|
{
|
2016-07-11 15:47:42 +02:00
|
|
|
|
v = Math.floor(seconds);
|
2015-09-06 15:54:43 +02:00
|
|
|
|
return [v, 'second'];
|
2015-09-05 17:12:11 +02:00
|
|
|
|
}
|
|
|
|
|
if (seconds < 60 * 60)
|
|
|
|
|
{
|
2016-07-11 15:47:42 +02:00
|
|
|
|
v = Math.floor(seconds / 60);
|
2015-09-06 15:54:43 +02:00
|
|
|
|
return [v, 'minute'];
|
2015-09-05 17:12:11 +02:00
|
|
|
|
}
|
|
|
|
|
if (seconds < 60 * 60 * 24)
|
|
|
|
|
{
|
2016-07-11 15:47:42 +02:00
|
|
|
|
v = Math.floor(seconds / (60 * 60));
|
2015-09-06 15:54:43 +02:00
|
|
|
|
return [v, 'hour'];
|
2015-09-05 17:12:11 +02:00
|
|
|
|
}
|
|
|
|
|
// If less than 2 months, display in days:
|
|
|
|
|
if (seconds < 60 * 60 * 24 * 60)
|
|
|
|
|
{
|
2016-07-11 15:47:42 +02:00
|
|
|
|
v = Math.floor(seconds / (60 * 60 * 24));
|
2015-09-06 15:54:43 +02:00
|
|
|
|
return [v, 'day'];
|
2015-09-05 17:12:11 +02:00
|
|
|
|
}
|
2016-07-11 15:47:42 +02:00
|
|
|
|
v = Math.floor(seconds / (60 * 60 * 24 * 30));
|
2015-09-06 15:54:43 +02:00
|
|
|
|
return [v, 'month'];
|
2015-09-05 17:12:11 +02:00
|
|
|
|
},
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* Converts an associative array to an encoded string
|
|
|
|
|
* for appending to the anchor.
|
|
|
|
|
*
|
|
|
|
|
* @param object associative_array Object to be serialized
|
|
|
|
|
* @return string
|
|
|
|
|
*/
|
|
|
|
|
hashToParameterString: function(associativeArray)
|
|
|
|
|
{
|
|
|
|
|
var parameterString = '';
|
2016-07-19 14:13:52 +02:00
|
|
|
|
for (var key in associativeArray)
|
2015-09-05 17:12:11 +02:00
|
|
|
|
{
|
|
|
|
|
if(parameterString === '')
|
|
|
|
|
{
|
|
|
|
|
parameterString = encodeURIComponent(key);
|
|
|
|
|
parameterString += '=' + encodeURIComponent(associativeArray[key]);
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
parameterString += '&' + encodeURIComponent(key);
|
|
|
|
|
parameterString += '=' + encodeURIComponent(associativeArray[key]);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
// padding for URL shorteners
|
|
|
|
|
parameterString += '&p=p';
|
|
|
|
|
|
|
|
|
|
return parameterString;
|
|
|
|
|
},
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* Converts a string to an associative array.
|
|
|
|
|
*
|
|
|
|
|
* @param string parameter_string String containing parameters
|
|
|
|
|
* @return object
|
|
|
|
|
*/
|
|
|
|
|
parameterStringToHash: function(parameterString)
|
|
|
|
|
{
|
|
|
|
|
var parameterHash = {};
|
|
|
|
|
var parameterArray = parameterString.split('&');
|
|
|
|
|
for (var i = 0; i < parameterArray.length; i++)
|
|
|
|
|
{
|
|
|
|
|
var pair = parameterArray[i].split('=');
|
|
|
|
|
var key = decodeURIComponent(pair[0]);
|
|
|
|
|
var value = decodeURIComponent(pair[1]);
|
|
|
|
|
parameterHash[key] = value;
|
|
|
|
|
}
|
2012-04-22 12:45:45 +02:00
|
|
|
|
|
2015-09-05 17:12:11 +02:00
|
|
|
|
return parameterHash;
|
|
|
|
|
},
|
2013-02-23 15:11:45 +01:00
|
|
|
|
|
2015-09-05 17:12:11 +02:00
|
|
|
|
/**
|
|
|
|
|
* Get an associative array of the parameters found in the anchor
|
|
|
|
|
*
|
|
|
|
|
* @return object
|
|
|
|
|
*/
|
|
|
|
|
getParameterHash: function()
|
|
|
|
|
{
|
|
|
|
|
var hashIndex = window.location.href.indexOf('#');
|
|
|
|
|
if (hashIndex >= 0)
|
|
|
|
|
{
|
|
|
|
|
return this.parameterStringToHash(window.location.href.substring(hashIndex + 1));
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
return {};
|
|
|
|
|
}
|
|
|
|
|
},
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* Text range selection.
|
2016-07-19 13:56:52 +02:00
|
|
|
|
* From: https://stackoverflow.com/questions/985272/jquery-selecting-text-in-an-element-akin-to-highlighting-with-your-mouse
|
2015-09-05 17:12:11 +02:00
|
|
|
|
*
|
|
|
|
|
* @param string element : Indentifier of the element to select (id="").
|
|
|
|
|
*/
|
|
|
|
|
selectText: function(element)
|
|
|
|
|
{
|
|
|
|
|
var doc = document,
|
|
|
|
|
text = doc.getElementById(element),
|
|
|
|
|
range,
|
|
|
|
|
selection;
|
|
|
|
|
|
|
|
|
|
// MS
|
|
|
|
|
if (doc.body.createTextRange)
|
|
|
|
|
{
|
|
|
|
|
range = doc.body.createTextRange();
|
|
|
|
|
range.moveToElementText(text);
|
|
|
|
|
range.select();
|
|
|
|
|
}
|
|
|
|
|
// all others
|
|
|
|
|
else if (window.getSelection)
|
|
|
|
|
{
|
|
|
|
|
selection = window.getSelection();
|
|
|
|
|
range = doc.createRange();
|
|
|
|
|
range.selectNodeContents(text);
|
|
|
|
|
selection.removeAllRanges();
|
|
|
|
|
selection.addRange(range);
|
|
|
|
|
}
|
|
|
|
|
},
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* Set text of a DOM element (required for IE)
|
|
|
|
|
* This is equivalent to element.text(text)
|
|
|
|
|
*
|
|
|
|
|
* @param object element : a DOM element.
|
|
|
|
|
* @param string text : the text to enter.
|
|
|
|
|
*/
|
|
|
|
|
setElementText: function(element, text)
|
|
|
|
|
{
|
2015-09-06 13:07:46 +02:00
|
|
|
|
// For IE<10: Doesn't support white-space:pre-wrap; so we have to do this...
|
2015-09-05 17:12:11 +02:00
|
|
|
|
if ($('#oldienotice').is(':visible')) {
|
|
|
|
|
var html = this.htmlEntities(text).replace(/\n/ig,'\r\n<br>');
|
|
|
|
|
element.html('<pre>'+html+'</pre>');
|
|
|
|
|
}
|
|
|
|
|
// for other (sane) browsers:
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
element.text(text);
|
|
|
|
|
}
|
|
|
|
|
},
|
|
|
|
|
|
2015-09-12 17:33:16 +02:00
|
|
|
|
/**
|
|
|
|
|
* replace last child of element with message
|
|
|
|
|
*
|
|
|
|
|
* @param object element : a jQuery wrapped DOM element.
|
|
|
|
|
* @param string message : the message to append.
|
|
|
|
|
*/
|
|
|
|
|
setMessage: function(element, message)
|
|
|
|
|
{
|
|
|
|
|
var content = element.contents();
|
|
|
|
|
if (content.length > 0)
|
|
|
|
|
{
|
|
|
|
|
content[content.length - 1].nodeValue = ' ' + message;
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
this.setElementText(element, message);
|
|
|
|
|
}
|
|
|
|
|
},
|
|
|
|
|
|
2015-09-05 17:12:11 +02:00
|
|
|
|
/**
|
|
|
|
|
* Convert URLs to clickable links.
|
|
|
|
|
* URLs to handle:
|
|
|
|
|
* <code>
|
|
|
|
|
* magnet:?xt.1=urn:sha1:YNCKHTQCWBTRNJIV4WNAE52SJUQCZO5C&xt.2=urn:sha1:TXGCZQTH26NL6OUQAJJPFALHG2LTGBC7
|
|
|
|
|
* http://localhost:8800/zero/?6f09182b8ea51997#WtLEUO5Epj9UHAV9JFs+6pUQZp13TuspAUjnF+iM+dM=
|
|
|
|
|
* http://user:password@localhost:8800/zero/?6f09182b8ea51997#WtLEUO5Epj9UHAV9JFs+6pUQZp13TuspAUjnF+iM+dM=
|
|
|
|
|
* </code>
|
|
|
|
|
*
|
|
|
|
|
* @param object element : a jQuery DOM element.
|
|
|
|
|
*/
|
|
|
|
|
urls2links: function(element)
|
|
|
|
|
{
|
2015-09-06 13:07:46 +02:00
|
|
|
|
var markup = '<a href="$1" rel="nofollow">$1</a>';
|
2015-09-05 17:12:11 +02:00
|
|
|
|
element.html(
|
|
|
|
|
element.html().replace(
|
|
|
|
|
/((http|https|ftp):\/\/[\w?=&.\/-;#@~%+-]+(?![\w\s?&.\/;#~%"=-]*>))/ig,
|
2015-09-06 13:07:46 +02:00
|
|
|
|
markup
|
2015-09-05 17:12:11 +02:00
|
|
|
|
)
|
|
|
|
|
);
|
|
|
|
|
element.html(
|
|
|
|
|
element.html().replace(
|
|
|
|
|
/((magnet):[\w?=&.\/-;#@~%+-]+)/ig,
|
2015-09-06 13:07:46 +02:00
|
|
|
|
markup
|
2015-09-05 17:12:11 +02:00
|
|
|
|
)
|
|
|
|
|
);
|
2015-09-06 13:07:46 +02:00
|
|
|
|
},
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* minimal sprintf emulation for %s and %d formats
|
2016-07-19 13:56:52 +02:00
|
|
|
|
* From: https://stackoverflow.com/questions/610406/javascript-equivalent-to-printf-string-format#4795914
|
2015-09-06 13:07:46 +02:00
|
|
|
|
*
|
|
|
|
|
* @param string format
|
|
|
|
|
* @param mixed args one or multiple parameters injected into format string
|
|
|
|
|
* @return string
|
|
|
|
|
*/
|
|
|
|
|
sprintf: function()
|
|
|
|
|
{
|
|
|
|
|
var args = arguments;
|
2016-07-11 16:09:38 +02:00
|
|
|
|
if (typeof arguments[0] === 'object')
|
2016-07-11 15:47:42 +02:00
|
|
|
|
{
|
|
|
|
|
args = arguments[0];
|
|
|
|
|
}
|
2015-09-06 13:07:46 +02:00
|
|
|
|
var string = args[0],
|
|
|
|
|
i = 1;
|
|
|
|
|
return string.replace(/%((%)|s|d)/g, function (m) {
|
|
|
|
|
// m is the matched format, e.g. %s, %d
|
2016-07-11 15:47:42 +02:00
|
|
|
|
var val;
|
2015-09-06 13:07:46 +02:00
|
|
|
|
if (m[2]) {
|
|
|
|
|
val = m[2];
|
|
|
|
|
} else {
|
|
|
|
|
val = args[i];
|
|
|
|
|
// A switch statement so that the formatter can be extended.
|
2015-09-08 20:48:18 +02:00
|
|
|
|
switch (m)
|
|
|
|
|
{
|
2015-09-06 13:07:46 +02:00
|
|
|
|
case '%d':
|
|
|
|
|
val = parseFloat(val);
|
|
|
|
|
if (isNaN(val)) {
|
|
|
|
|
val = 0;
|
|
|
|
|
}
|
|
|
|
|
break;
|
2016-07-11 15:47:42 +02:00
|
|
|
|
default:
|
|
|
|
|
// Default is %s
|
2015-09-06 13:07:46 +02:00
|
|
|
|
}
|
|
|
|
|
++i;
|
|
|
|
|
}
|
|
|
|
|
return val;
|
|
|
|
|
});
|
2015-09-19 11:21:13 +02:00
|
|
|
|
},
|
2015-09-21 22:43:00 +02:00
|
|
|
|
|
2015-09-19 11:21:13 +02:00
|
|
|
|
/**
|
|
|
|
|
* get value of cookie, if it was set, empty string otherwise
|
|
|
|
|
* From: http://www.w3schools.com/js/js_cookies.asp
|
|
|
|
|
*
|
|
|
|
|
* @param string cname
|
|
|
|
|
* @return string
|
|
|
|
|
*/
|
|
|
|
|
getCookie: function(cname) {
|
|
|
|
|
var name = cname + '=';
|
|
|
|
|
var ca = document.cookie.split(';');
|
2016-08-09 14:46:32 +02:00
|
|
|
|
for (var i = 0; i < ca.length; ++i) {
|
2015-09-19 11:21:13 +02:00
|
|
|
|
var c = ca[i];
|
2016-07-11 15:47:42 +02:00
|
|
|
|
while (c.charAt(0) === ' ') c = c.substring(1);
|
|
|
|
|
if (c.indexOf(name) === 0)
|
|
|
|
|
{
|
|
|
|
|
return c.substring(name.length, c.length);
|
|
|
|
|
}
|
2015-09-19 11:21:13 +02:00
|
|
|
|
}
|
|
|
|
|
return '';
|
2016-07-19 16:12:11 +02:00
|
|
|
|
},
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* Convert all applicable characters to HTML entities.
|
|
|
|
|
* From: https://github.com/janl/mustache.js/blob/master/mustache.js#L60
|
2016-12-25 13:04:06 +01:00
|
|
|
|
* Also: https://www.owasp.org/index.php/XSS_(Cross_Site_Scripting)_Prevention_Cheat_Sheet#RULE_.231_-_HTML_Escape_Before_Inserting_Untrusted_Data_into_HTML_Element_Content
|
2016-07-19 16:12:11 +02:00
|
|
|
|
*
|
2017-01-07 15:48:42 +01:00
|
|
|
|
* @param string str |