add YOURLS API samples for extractUrl validation
This commit is contained in:
parent
fd82b937a9
commit
405479642f
6 changed files with 130 additions and 17 deletions
|
@ -113,8 +113,8 @@ exports.jscBase64String = function() {
|
||||||
};
|
};
|
||||||
|
|
||||||
// provides a random URL schema supported by the whatwg-url library
|
// provides a random URL schema supported by the whatwg-url library
|
||||||
exports.jscSchemas = function() {
|
exports.jscSchemas = function(withFtp = true) {
|
||||||
return jsc.elements(schemas);
|
return jsc.elements(withFtp ? schemas : schemas.slice(1));
|
||||||
};
|
};
|
||||||
|
|
||||||
// provides a random supported language string
|
// provides a random supported language string
|
||||||
|
|
|
@ -2117,7 +2117,7 @@ jQuery.PrivateBin = (function($, RawDeflate) {
|
||||||
response = JSON.stringify(response);
|
response = JSON.stringify(response);
|
||||||
}
|
}
|
||||||
if (typeof response === 'string' && response.length > 0) {
|
if (typeof response === 'string' && response.length > 0) {
|
||||||
const shortUrlMatcher = /https?:\/\/[^\s]+/g;
|
const shortUrlMatcher = /https?:\/\/[^\s"<]+/g; // JSON API will have URL in quotes, XML in tags
|
||||||
const shortUrl = (response.match(shortUrlMatcher) || []).filter(function(urlRegExMatch) {
|
const shortUrl = (response.match(shortUrlMatcher) || []).filter(function(urlRegExMatch) {
|
||||||
if (typeof URL.canParse === 'function') {
|
if (typeof URL.canParse === 'function') {
|
||||||
return URL.canParse(urlRegExMatch);
|
return URL.canParse(urlRegExMatch);
|
||||||
|
@ -2129,7 +2129,7 @@ jQuery.PrivateBin = (function($, RawDeflate) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}).sort(function(a, b) {
|
}).sort(function(a, b) {
|
||||||
return a.length - b.length;
|
return a.length - b.length; // shortest first
|
||||||
})[0];
|
})[0];
|
||||||
if (typeof shortUrl === 'string' && shortUrl.length > 0) {
|
if (typeof shortUrl === 'string' && shortUrl.length > 0) {
|
||||||
// we disable the button to avoid calling shortener again
|
// we disable the button to avoid calling shortener again
|
||||||
|
|
|
@ -259,16 +259,16 @@ describe('Helper', function () {
|
||||||
this.timeout(30000);
|
this.timeout(30000);
|
||||||
jsc.property(
|
jsc.property(
|
||||||
'returns the URL without query & fragment',
|
'returns the URL without query & fragment',
|
||||||
jsc.elements(['http', 'https']),
|
common.jscSchemas(false),
|
||||||
jsc.nearray(common.jscA2zString()),
|
common.jscUrl(),
|
||||||
jsc.array(common.jscA2zString()),
|
function (schema, url) {
|
||||||
jsc.array(common.jscQueryString()),
|
url.schema = schema;
|
||||||
'string',
|
const fullUrl = common.urlToString(url);
|
||||||
function (schema, address, path, query, fragment) {
|
delete(url.query);
|
||||||
|
delete(url.fragment);
|
||||||
$.PrivateBin.Helper.reset();
|
$.PrivateBin.Helper.reset();
|
||||||
var path = path.join('') + (path.length > 0 ? '/' : ''),
|
const expected = common.urlToString(url),
|
||||||
expected = schema + '://' + address.join('') + '/' + path,
|
clean = jsdom('', {url: fullUrl}),
|
||||||
clean = jsdom('', {url: expected + '?' + query.join('') + '#' + fragment}),
|
|
||||||
result = $.PrivateBin.Helper.baseUri();
|
result = $.PrivateBin.Helper.baseUri();
|
||||||
clean();
|
clean();
|
||||||
return expected === result;
|
return expected === result;
|
||||||
|
|
|
@ -1,6 +1,23 @@
|
||||||
'use strict';
|
'use strict';
|
||||||
var common = require('../common');
|
var common = require('../common');
|
||||||
|
|
||||||
|
function urlStrings(schema, longUrl, shortUrl) {
|
||||||
|
longUrl.schema = schema;
|
||||||
|
shortUrl.schema = schema;
|
||||||
|
let longUrlString = common.urlToString(longUrl),
|
||||||
|
shortUrlString = common.urlToString(shortUrl);
|
||||||
|
// ensure the two random URLs actually are sorted as expected
|
||||||
|
if (longUrlString.length <= shortUrlString.length) {
|
||||||
|
if (longUrlString.length === shortUrlString.length) {
|
||||||
|
longUrl.address.unshift('a');
|
||||||
|
longUrlString = common.urlToString(longUrl);
|
||||||
|
} else {
|
||||||
|
[longUrlString, shortUrlString] = [shortUrlString, longUrlString];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return [longUrlString, shortUrlString];
|
||||||
|
}
|
||||||
|
|
||||||
describe('PasteStatus', function () {
|
describe('PasteStatus', function () {
|
||||||
describe('createPasteNotification', function () {
|
describe('createPasteNotification', function () {
|
||||||
this.timeout(30000);
|
this.timeout(30000);
|
||||||
|
@ -28,8 +45,8 @@ describe('PasteStatus', function () {
|
||||||
this.timeout(30000);
|
this.timeout(30000);
|
||||||
|
|
||||||
jsc.property(
|
jsc.property(
|
||||||
'extracts and updates URLs found in given response',
|
'extracts and updates IDN URLs found in given response',
|
||||||
jsc.elements(['http','https']),
|
common.jscSchemas(false),
|
||||||
'nestring',
|
'nestring',
|
||||||
common.jscUrl(),
|
common.jscUrl(),
|
||||||
function (schema, domain, url) {
|
function (schema, domain, url) {
|
||||||
|
@ -58,6 +75,102 @@ describe('PasteStatus', function () {
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
|
|
||||||
|
// YOURLS API samples from: https://yourls.org/readme.html#API;apireturn
|
||||||
|
jsc.property(
|
||||||
|
'extracts and updates URLs found in YOURLS API JSON response',
|
||||||
|
common.jscSchemas(false),
|
||||||
|
common.jscUrl(),
|
||||||
|
common.jscUrl(false),
|
||||||
|
function (schema, longUrl, shortUrl) {
|
||||||
|
const [longUrlString, shortUrlString] = urlStrings(schema, longUrl, shortUrl),
|
||||||
|
yourlsResponse = {
|
||||||
|
url: {
|
||||||
|
keyword: longUrl.address.join(''),
|
||||||
|
url: longUrlString,
|
||||||
|
title: "example title",
|
||||||
|
date: "2014-10-24 16:01:39",
|
||||||
|
ip: "127.0.0.1"
|
||||||
|
},
|
||||||
|
status: "success",
|
||||||
|
message: longUrlString + " added to database",
|
||||||
|
title: "example title",
|
||||||
|
shorturl: shortUrlString,
|
||||||
|
statusCode: 200
|
||||||
|
},
|
||||||
|
clean = jsdom();
|
||||||
|
|
||||||
|
$('body').html('<div><div id="pastelink"></div></div>');
|
||||||
|
$.PrivateBin.PasteStatus.init();
|
||||||
|
$.PrivateBin.PasteStatus.createPasteNotification('', '');
|
||||||
|
$.PrivateBin.PasteStatus.extractUrl(JSON.stringify(yourlsResponse, undefined, 4));
|
||||||
|
|
||||||
|
const result = $('#pasteurl')[0].href;
|
||||||
|
clean();
|
||||||
|
|
||||||
|
return result === shortUrlString;
|
||||||
|
}
|
||||||
|
);
|
||||||
|
jsc.property(
|
||||||
|
'extracts and updates URLs found in YOURLS API XML response',
|
||||||
|
common.jscSchemas(false),
|
||||||
|
common.jscUrl(),
|
||||||
|
common.jscUrl(false),
|
||||||
|
function (schema, longUrl, shortUrl) {
|
||||||
|
const [longUrlString, shortUrlString] = urlStrings(schema, longUrl, shortUrl),
|
||||||
|
yourlsResponse = '<result>\n' +
|
||||||
|
' <keyword>' + longUrl.address.join('') + '</keyword>\n' +
|
||||||
|
' <shorturl>' + shortUrlString + '</shorturl>\n' +
|
||||||
|
' <longurl>' + longUrlString + '</longurl>\n' +
|
||||||
|
' <message>success</message>\n' +
|
||||||
|
' <statusCode>200</statusCode>\n' +
|
||||||
|
'</result>',
|
||||||
|
clean = jsdom();
|
||||||
|
|
||||||
|
$('body').html('<div><div id="pastelink"></div></div>');
|
||||||
|
$.PrivateBin.PasteStatus.init();
|
||||||
|
$.PrivateBin.PasteStatus.createPasteNotification('', '');
|
||||||
|
$.PrivateBin.PasteStatus.extractUrl(yourlsResponse);
|
||||||
|
|
||||||
|
const result = $('#pasteurl')[0].href;
|
||||||
|
clean();
|
||||||
|
|
||||||
|
return result === shortUrlString;
|
||||||
|
}
|
||||||
|
);
|
||||||
|
jsc.property(
|
||||||
|
'extracts and updates URLs found in YOURLS proxy HTML response',
|
||||||
|
common.jscSchemas(false),
|
||||||
|
common.jscUrl(),
|
||||||
|
common.jscUrl(false),
|
||||||
|
function (schema, longUrl, shortUrl) {
|
||||||
|
const [longUrlString, shortUrlString] = urlStrings(schema, longUrl, shortUrl),
|
||||||
|
yourlsResponse = '<!DOCTYPE html>\n' +
|
||||||
|
'<html lang="en">\n' +
|
||||||
|
'\t<head>\n' +
|
||||||
|
'\t\t<meta charset="utf-8" />\n' +
|
||||||
|
'\t\t<meta http-equiv="Content-Security-Policy" content="default-src \'none\'; base-uri \'self\'; form-action \'none\'; manifest-src \'self\'; connect-src * blob:; script-src \'self\' \'unsafe-eval\'; style-src \'self\'; font-src \'self\'; frame-ancestors \'none\'; img-src \'self\' data: blob:; media-src blob:; object-src blob:; sandbox allow-same-origin allow-scripts allow-forms allow-popups allow-modals allow-downloads">\n' +
|
||||||
|
'\t\t<meta name="robots" content="noindex" />\n' +
|
||||||
|
'\t\t<meta name="google" content="notranslate">\n' +
|
||||||
|
'\t\t<title>PrivateBin</title>\n' +
|
||||||
|
'\t</head>\n' +
|
||||||
|
'\t<body>\n' +
|
||||||
|
'\t\t<p>Your paste is <a id="pasteurl" href="' + shortUrlString + '">' + shortUrlString + '</a> <span id="copyhint">(Hit [Ctrl]+[c] to copy)</span></p>\n' +
|
||||||
|
'\t</body>\n' +
|
||||||
|
'</html>',
|
||||||
|
clean = jsdom();
|
||||||
|
|
||||||
|
$('body').html('<div><div id="pastelink"></div></div>');
|
||||||
|
$.PrivateBin.PasteStatus.init();
|
||||||
|
$.PrivateBin.PasteStatus.createPasteNotification('', '');
|
||||||
|
$.PrivateBin.PasteStatus.extractUrl(yourlsResponse);
|
||||||
|
|
||||||
|
const result = $('#pasteurl')[0].href;
|
||||||
|
clean();
|
||||||
|
|
||||||
|
return result === shortUrlString;
|
||||||
|
}
|
||||||
|
);
|
||||||
});
|
});
|
||||||
|
|
||||||
describe('showRemainingTime', function () {
|
describe('showRemainingTime', function () {
|
||||||
|
|
|
@ -73,7 +73,7 @@ endif;
|
||||||
?>
|
?>
|
||||||
<script type="text/javascript" data-cfasync="false" src="js/purify-3.0.6.js" integrity="sha512-N3y6/HOk3pbsw3lFh4O8CKKEVwu1B2CF8kinhjURf8Yqa5OfSUt+/arozxFW+TUPOPw3TsDCRT/0u7BGRTEVUw==" crossorigin="anonymous"></script>
|
<script type="text/javascript" data-cfasync="false" src="js/purify-3.0.6.js" integrity="sha512-N3y6/HOk3pbsw3lFh4O8CKKEVwu1B2CF8kinhjURf8Yqa5OfSUt+/arozxFW+TUPOPw3TsDCRT/0u7BGRTEVUw==" crossorigin="anonymous"></script>
|
||||||
<script type="text/javascript" data-cfasync="false" src="js/legacy.js?<?php echo rawurlencode($VERSION); ?>" integrity="sha512-LYos+qXHIRqFf5ZPNphvtTB0cgzHUizu2wwcOwcwz/VIpRv9lpcBgPYz4uq6jx0INwCAj6Fbnl5HoKiLufS2jg==" crossorigin="anonymous"></script>
|
<script type="text/javascript" data-cfasync="false" src="js/legacy.js?<?php echo rawurlencode($VERSION); ?>" integrity="sha512-LYos+qXHIRqFf5ZPNphvtTB0cgzHUizu2wwcOwcwz/VIpRv9lpcBgPYz4uq6jx0INwCAj6Fbnl5HoKiLufS2jg==" crossorigin="anonymous"></script>
|
||||||
<script type="text/javascript" data-cfasync="false" src="js/privatebin.js?<?php echo rawurlencode($VERSION); ?>" integrity="sha512-m/JO/NGsP+FEHPACdYe60BFkURk+NVCBaMsIUOUC5J1EnVE2XgVKF6Z+YSDd+9M4ISu0SivYxCZBEl8qW8u1Jg==" crossorigin="anonymous"></script>
|
<script type="text/javascript" data-cfasync="false" src="js/privatebin.js?<?php echo rawurlencode($VERSION); ?>" integrity="sha512-pR0TsQjCcheBGUbJyi6WxjhuX0AvGFg/R/NTMBZd1Sz22lDydBVIRy2y2ik8qTr9P/XRKj3QTkLrZC3ZF1NMyA==" crossorigin="anonymous"></script>
|
||||||
<!-- icon -->
|
<!-- icon -->
|
||||||
<link rel="apple-touch-icon" href="<?php echo I18n::encode($BASEPATH); ?>img/apple-touch-icon.png" sizes="180x180" />
|
<link rel="apple-touch-icon" href="<?php echo I18n::encode($BASEPATH); ?>img/apple-touch-icon.png" sizes="180x180" />
|
||||||
<link rel="icon" type="image/png" href="img/favicon-32x32.png" sizes="32x32" />
|
<link rel="icon" type="image/png" href="img/favicon-32x32.png" sizes="32x32" />
|
||||||
|
|
|
@ -51,7 +51,7 @@ endif;
|
||||||
?>
|
?>
|
||||||
<script type="text/javascript" data-cfasync="false" src="js/purify-3.0.6.js" integrity="sha512-N3y6/HOk3pbsw3lFh4O8CKKEVwu1B2CF8kinhjURf8Yqa5OfSUt+/arozxFW+TUPOPw3TsDCRT/0u7BGRTEVUw==" crossorigin="anonymous"></script>
|
<script type="text/javascript" data-cfasync="false" src="js/purify-3.0.6.js" integrity="sha512-N3y6/HOk3pbsw3lFh4O8CKKEVwu1B2CF8kinhjURf8Yqa5OfSUt+/arozxFW+TUPOPw3TsDCRT/0u7BGRTEVUw==" crossorigin="anonymous"></script>
|
||||||
<script type="text/javascript" data-cfasync="false" src="js/legacy.js?<?php echo rawurlencode($VERSION); ?>" integrity="sha512-LYos+qXHIRqFf5ZPNphvtTB0cgzHUizu2wwcOwcwz/VIpRv9lpcBgPYz4uq6jx0INwCAj6Fbnl5HoKiLufS2jg==" crossorigin="anonymous"></script>
|
<script type="text/javascript" data-cfasync="false" src="js/legacy.js?<?php echo rawurlencode($VERSION); ?>" integrity="sha512-LYos+qXHIRqFf5ZPNphvtTB0cgzHUizu2wwcOwcwz/VIpRv9lpcBgPYz4uq6jx0INwCAj6Fbnl5HoKiLufS2jg==" crossorigin="anonymous"></script>
|
||||||
<script type="text/javascript" data-cfasync="false" src="js/privatebin.js?<?php echo rawurlencode($VERSION); ?>" integrity="sha512-m/JO/NGsP+FEHPACdYe60BFkURk+NVCBaMsIUOUC5J1EnVE2XgVKF6Z+YSDd+9M4ISu0SivYxCZBEl8qW8u1Jg==" crossorigin="anonymous"></script>
|
<script type="text/javascript" data-cfasync="false" src="js/privatebin.js?<?php echo rawurlencode($VERSION); ?>" integrity="sha512-pR0TsQjCcheBGUbJyi6WxjhuX0AvGFg/R/NTMBZd1Sz22lDydBVIRy2y2ik8qTr9P/XRKj3QTkLrZC3ZF1NMyA==" crossorigin="anonymous"></script>
|
||||||
<!-- icon -->
|
<!-- icon -->
|
||||||
<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" />
|
||||||
|
|
Loading…
Reference in a new issue