1648 lines
58 KiB
Plaintext
1648 lines
58 KiB
Plaintext
/**
|
||
* PrivateBin
|
||
*
|
||
* a zero-knowledge paste bin
|
||
*
|
||
* @link https://github.com/PrivateBin/PrivateBin
|
||
* @copyright 2012 Sébastien SAUVAGE (sebsauvage.net)
|
||
* @license https://www.opensource.org/licenses/zlib-license.php The zlib/libpng License
|
||
* @version 1.1
|
||
*/
|
||
|
||
'use strict';
|
||
/** global: Base64 */
|
||
/** global: FileReader */
|
||
/** global: RawDeflate */
|
||
/** global: history */
|
||
/** global: navigator */
|
||
/** global: prettyPrint */
|
||
/** global: prettyPrintOne */
|
||
/** global: showdown */
|
||
/** global: sjcl */
|
||
|
||
// Immediately start random number generator collector.
|
||
sjcl.random.startCollectors();
|
||
|
||
$(function() {
|
||
/**
|
||
* static helper methods
|
||
*/
|
||
var helper = {
|
||
/**
|
||
* Converts a duration (in seconds) into human friendly approximation.
|
||
*
|
||
* @param int seconds
|
||
* @return array
|
||
*/
|
||
secondsToHuman: function(seconds)
|
||
{
|
||
var v;
|
||
if (seconds < 60)
|
||
{
|
||
v = Math.floor(seconds);
|
||
return [v, 'second'];
|
||
}
|
||
if (seconds < 60 * 60)
|
||
{
|
||
v = Math.floor(seconds / 60);
|
||
return [v, 'minute'];
|
||
}
|
||
if (seconds < 60 * 60 * 24)
|
||
{
|
||
v = Math.floor(seconds / (60 * 60));
|
||
return [v, 'hour'];
|
||
}
|
||
// If less than 2 months, display in days:
|
||
if (seconds < 60 * 60 * 24 * 60)
|
||
{
|
||
v = Math.floor(seconds / (60 * 60 * 24));
|
||
return [v, 'day'];
|
||
}
|
||
v = Math.floor(seconds / (60 * 60 * 24 * 30));
|
||
return [v, 'month'];
|
||
},
|
||
|
||
/**
|
||
* 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 = '';
|
||
for (var key in associativeArray)
|
||
{
|
||
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;
|
||
}
|
||
|
||
return parameterHash;
|
||
},
|
||
|
||
/**
|
||
* 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.
|
||
* From: https://stackoverflow.com/questions/985272/jquery-selecting-text-in-an-element-akin-to-highlighting-with-your-mouse
|
||
*
|
||
* @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)
|
||
{
|
||
// For IE<10: Doesn't support white-space:pre-wrap; so we have to do this...
|
||
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);
|
||
}
|
||
},
|
||
|
||
/**
|
||
* 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);
|
||
}
|
||
},
|
||
|
||
/**
|
||
* 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)
|
||
{
|
||
var markup = '<a href="$1" rel="nofollow">$1</a>';
|
||
element.html(
|
||
element.html().replace(
|
||
/((http|https|ftp):\/\/[\w?=&.\/-;#@~%+-]+(?![\w\s?&.\/;#~%"=-]*>))/ig,
|
||
markup
|
||
)
|
||
);
|
||
element.html(
|
||
element.html().replace(
|
||
/((magnet):[\w?=&.\/-;#@~%+-]+)/ig,
|
||
markup
|
||
)
|
||
);
|
||
},
|
||
|
||
/**
|
||
* minimal sprintf emulation for %s and %d formats
|
||
* From: https://stackoverflow.com/questions/610406/javascript-equivalent-to-printf-string-format#4795914
|
||
*
|
||
* @param string format
|
||
* @param mixed args one or multiple parameters injected into format string
|
||
* @return string
|
||
*/
|
||
sprintf: function()
|
||
{
|
||
var args = arguments;
|
||
if (typeof arguments[0] === 'object')
|
||
{
|
||
args = arguments[0];
|
||
}
|
||
var string = args[0],
|
||
i = 1;
|
||
return string.replace(/%((%)|s|d)/g, function (m) {
|
||
// m is the matched format, e.g. %s, %d
|
||
var val;
|
||
if (m[2]) {
|
||
val = m[2];
|
||
} else {
|
||
val = args[i];
|
||
// A switch statement so that the formatter can be extended.
|
||
switch (m)
|
||
{
|
||
case '%d':
|
||
val = parseFloat(val);
|
||
if (isNaN(val)) {
|
||
val = 0;
|
||
}
|
||
break;
|
||
default:
|
||
// Default is %s
|
||
}
|
||
++i;
|
||
}
|
||
return val;
|
||
});
|
||
},
|
||
|
||
/**
|
||
* 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(';');
|
||
for (var i = 0; i < ca.length; ++i) {
|
||
var c = ca[i];
|
||
while (c.charAt(0) === ' ') c = c.substring(1);
|
||
if (c.indexOf(name) === 0)
|
||
{
|
||
return c.substring(name.length, c.length);
|
||
}
|
||
}
|
||
return '';
|
||
},
|
||
|
||
/**
|
||
* Convert all applicable characters to HTML entities.
|
||
* From: https://github.com/janl/mustache.js/blob/master/mustache.js#L60
|
||
* 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
|
||
*
|
||
* @param string str |