Added Idempotency-Key header and fixed an bug allowing xss in display name

This commit is contained in:
nipos 2018-05-06 16:08:50 +02:00
parent ab0bd55cbc
commit fff7a7d50c
5 changed files with 64 additions and 29 deletions

View File

@ -10,16 +10,17 @@ Follow or Mastodon account and never miss an important update: [@halcyon@social.
## Instances
These instances are publicly accessible and usable by everyone, no matter which Mastodon instance you use.
- https://halcyon.toromino.de - 1.1.4
- https://halcyon.bka.li - 1.1.4
- https://halcyon.toromino.de - 1.1.5
- https://social.dev-wiki.de - 1.1.5
- https://halcyon.bka.li - 1.1.5
- https://itter.photog.social - 1.1.4
- https://halcyon.tilde.team - 1.1.3
- https://itter.photog.social - 1.1.3
- https://social.dev-wiki.de - 1.1.1
- https://halcyon.cybre.space - Outdated
You have your own Halcyon instance and want it to be listed here? Create an issue with the link and we will add it to the list.
## Blog
- Release of Version 1.1.5 - Introduced the new Idempotency-Key Header and fixed an bug allowing XSS with the display name
- Release of Version 1.1.4 - Automatically reconnect on bad connection,now supports desktop notifications,added ... at the end of shortened links
- Release of Version 1.1.3 - New function link previews introduced and bug when replying an toot which already has replies below it fixed (reply to undefined)
- Release of Version 1.1.2 - Privacy modes are now correctly displayed and used for replies,use username if display name doesn't exist,bugs on search page fixed

View File

@ -147,6 +147,24 @@ const datetime ="・" + calendar[posted_time_original.getMonth()] + " " + posted
return datetime;
}
}
function htmlEscape(strings, ...values) {
var handleString = function(str) {
return str.replace(/&/g, '&')
.replace(/>/g, '>')
.replace(/</g, '&lt;')
.replace(/"/g, '&quot;')
.replace(/'/g, '&#039;')
.replace(/`/g, '&#096;');
};
var res = '';
for(var i=0, l=strings.length; i<l; i+=1) {
res += handleString(strings[i]);
if(i < values.length) {
res += handleString(values[i]);
}
}
return res;
}
function resetApp() {
current_id = Number(localStorage.getItem("current_id"));
current_instance = localStorage.getItem("current_instance");
@ -285,3 +303,9 @@ icon: '/assets/images/halcyon_logo.png'
}
}
}
function getRandom() {
var s4 = function() {
return Math.floor((1 + Math.random()) * 0x10000).toString(16).substring(1);
}
return s4() + s4() + '-' + s4() + '-' + s4() + '-' + s4() + '-' + s4() + s4() + s4();
}

View File

@ -279,7 +279,7 @@ const html=(`
<div class="text_ellipsis">
<a href="${status_account_link}">
<span class="displayname emoji_poss">
${status.account.display_name}
${htmlEscape(status.account.display_name)}
</span>
<span class="username">
@${status.account.acct}
@ -313,7 +313,7 @@ ${media_views}
</article>
<footer class="toot_footer"${toot_footer_width}>
<div class="toot_reaction">
<button class="reply_button" tid="${status.id}" acct="@${status.account.acct}" display_name="${status.account.display_name}" privacy="${status.visibility}">
<button class="reply_button" tid="${status.id}" acct="@${status.account.acct}" display_name="${htmlEscape(status.account.display_name)}" privacy="${status.visibility}">
<i class="fa fa-fw fa-reply"></i>
<span class="reaction_count reply_count"></span>
</button>
@ -384,7 +384,7 @@ const html = (`
<li sid="${status.id}" class="toot_entry">
<div class="boost_author_box">
<a href="${status_account_link}">
<span class="emoji_poss"><i class="fa fa-fw fa-retweet"></i>${status.account.display_name} Boosted</span>
<span class="emoji_poss"><i class="fa fa-fw fa-retweet"></i>${htmlEscape(status.account.display_name)} Boosted</span>
</a>
</div>
<div class="toot_entry_body">
@ -398,7 +398,7 @@ const html = (`
<div class="text_ellipsis">
<a href="${status_reblog_account_link}">
<span class="displayname emoji_poss">
${status.reblog.account.display_name}
${htmlEscape(status.reblog.account.display_name)}
</span>
<span class="username">
@${status.reblog.account.acct}
@ -432,7 +432,7 @@ ${media_views}
</article>
<footer class="toot_footer" style="width:320px">
<div class="toot_reaction">
<button class="reply_button" tid="${status.reblog.id}"acct="@${status.reblog.account.acct}" display_name="${status.reblog.account.display_name}" privacy="${status.reblog.visibility}">
<button class="reply_button" tid="${status.reblog.id}"acct="@${status.reblog.account.acct}" display_name="${htmlEscape(status.reblog.account.display_name)}" privacy="${status.reblog.visibility}">
<i class="fa fa-fw fa-reply"></i>
<span class="reaction_count reply_count"></span>
</button>
@ -484,7 +484,7 @@ const html = (`
</a>
<i class="fa fa-fw fa-star font-icon favourite"></i>
<a class="notice_author" href="${notice_author_link}">
<span class="emoji_poss" >${NotificationObj.account.display_name}</span> favourited Your Toot
<span class="emoji_poss" >${htmlEscape(NotificationObj.account.display_name)}</span> favourited Your Toot
</a>
</div>
<div class="notice_entry_body">
@ -493,7 +493,7 @@ const html = (`
<div class="text_ellipsis">
<a href="${toot_author_link}">
<span class="displayname emoji_poss">
${NotificationObj.status.account.display_name}
${htmlEscape(NotificationObj.status.account.display_name)}
</span>
<span class="username">
@${NotificationObj.status.account.acct}
@ -524,7 +524,7 @@ html = (`
</a>
<i class="fa fa-fw fa-retweet font-icon boost"></i>
<a class="notice_author" href="${notice_author_link}">
<span class="emoji_poss" >${NotificationObj.account.display_name}</span> boosted Your Toot
<span class="emoji_poss" >${htmlEscape(NotificationObj.account.display_name)}</span> boosted Your Toot
</a>
</div>
<blockquote class="notice_entry_body">
@ -533,7 +533,7 @@ html = (`
<div class="text_ellipsis">
<a href="${toot_author_link}">
<span class="displayname emoji_poss">
${NotificationObj.status.account.display_name}
${htmlEscape(NotificationObj.status.account.display_name)}
</span>
<span class="username">
@${NotificationObj.status.account.acct}
@ -610,7 +610,7 @@ const html=(`
<div class="text_ellipsis">
<a href="${toot_author_link}">
<span class="displayname emoji_poss">
${NotificationObj.status.account.display_name}
${htmlEscape(NotificationObj.status.account.display_name)}
</span>
<span class="username">
@${NotificationObj.status.account.acct}
@ -644,7 +644,7 @@ ${media_views}
</article>
<footer class="toot_footer"${toot_footer_width}>
<div class="toot_reaction">
<button class="reply_button" tid="${NotificationObj.status.id}" acct="@${NotificationObj.account.acct}" display_name="${NotificationObj.account.display_name}" privacy="${NotificationObj.status.visibility}">
<button class="reply_button" tid="${NotificationObj.status.id}" acct="@${NotificationObj.account.acct}" display_name="${htmlEscape(NotificationObj.account.display_name)}" privacy="${NotificationObj.status.visibility}">
<i class="fa fa-fw fa-reply"></i>
<span class="reaction_count reply_count"></span>
</button>
@ -677,7 +677,7 @@ const html=(`
</a>
<i class="fa fa-fw fa-user font-icon follow"></i>
<a class="notice_author" href="${notice_author_link}">
<span class="emoji_poss">${NotificationObj.account.display_name}</span> followed you
<span class="emoji_poss">${htmlEscape(NotificationObj.account.display_name)}</span> followed you
</a>
</div>
</li>`);
@ -706,7 +706,7 @@ const html = (`
<div class="follows_profile_name_box emoji_poss">
<a class="js_follows_profile_link" href="${profile_link}">
<h2 class="js_follows_profile_displayname">
${AccountObj.display_name}
${htmlEscape(AccountObj.display_name)}
</h2>
<span class="js_follows_profile_username">
@${AccountObj.acct}
@ -781,7 +781,7 @@ const html=(`
</div>
<a href="${status_account_link}">
<span class="displayname emoji_poss">
${status.account.display_name}
${htmlEscape(status.account.display_name)}
</span>
<span class="username">
@${status.account.acct}
@ -816,7 +816,7 @@ ${media_views}
</section>
<footer class="toot_footer"${toot_footer_width}>
<div class="toot_reaction">
<button class="reply_button" tid="${status.id}" acct="@${status.account.acct}" display_name="${status.account.display_name}" privacy="${status.visibility}">
<button class="reply_button" tid="${status.id}" acct="@${status.account.acct}" display_name="${htmlEscape(status.account.display_name)}" privacy="${status.visibility}">
<i class="fa fa-fw fa-reply"></i>
<span class="reaction_count reply_count"></span>
</button>
@ -955,7 +955,7 @@ const html=(`
</div>
<a href="${status_account_link}">
<span class="displayname emoji_poss">
${status.reblog.account.display_name}
${htmlEscape(status.reblog.account.display_name)}
</span>
<span class="username">
@${status.reblog.account.acct}
@ -990,7 +990,7 @@ ${media_views}
</section>
<footer class="toot_footer" style="width:320px">
<div class="toot_reaction">
<button class="reply_button" tid="${status.reblog.id}" acct="@${status.reblog.account.acct}" display_name="${status.reblog.account.display_name}" privacy="${status.reblog.visibility}">
<button class="reply_button" tid="${status.reblog.id}" acct="@${status.reblog.account.acct}" display_name="${htmlEscape(status.reblog.account.display_name)}" privacy="${status.reblog.visibility}">
<i class="fa fa-fw fa-reply"></i>
<span class="reaction_count reply_count"></span>
</button>
@ -1171,7 +1171,7 @@ const html=(`
<header class="toot_header">
<a href="${status_account_link}">
<span class="displayname emoji_poss">
${status.account.display_name}
${htmlEscape(status.account.display_name)}
</span>
<span class="username">
@${status.account.acct}
@ -1204,7 +1204,7 @@ ${media_views}
</article>
<footer class="toot_footer"${toot_footer_width}>
<div class="toot_reaction">
<button class="reply_button" tid="${status.id}" acct="@${status.account.acct}" display_name="${status.account.display_name}" privacy="${status.visibility}">
<button class="reply_button" tid="${status.id}" acct="@${status.account.acct}" display_name="${htmlEscape(status.account.display_name)}" privacy="${status.visibility}">
<i class="fa fa-fw fa-reply"></i>
<span class="reaction_count reply_count"></span>
</button>
@ -1266,7 +1266,7 @@ const html=(`
<div sid="${status.id}" class="toot_entry ${class_options}">
<div class="boost_author_box">
<a href="${status_account_link}">
<span class="emoji_poss"><i class="fa fa-fw fa-retweet"></i>${status.account.display_name} Boosted</span>
<span class="emoji_poss"><i class="fa fa-fw fa-retweet"></i>${htmlEscape(status.account.display_name)} Boosted</span>
</a>
</div>
<div class="toot_entry_body">
@ -1277,7 +1277,7 @@ const html=(`
<header class="toot_header">
<a href="${status_reblog_account_link}">
<span class="displayname emoji_poss">
${status.reblog.account.display_name}
${htmlEscape(status.reblog.account.display_name)}
</span>
<span class="username">
@${status.reblog.account.acct}
@ -1310,7 +1310,7 @@ ${media_views}
</article>
<footer class="toot_footer" style="width:320px">
<div class="toot_reaction">
<button class="reply_button" tid="${status.reblog.id}" acct="@${status.reblog.account.acct}" display_name="${status.reblog.account.display_name}" privacy="${status.reblog.visibility}">
<button class="reply_button" tid="${status.reblog.id}" acct="@${status.reblog.account.acct}" display_name="${htmlEscape(status.reblog.account.display_name)}" privacy="${status.reblog.visibility}">
<i class="fa fa-fw fa-reply"></i>
<span class="reaction_count reply_count"></span>
</button>

View File

@ -150,11 +150,21 @@ callback = arguments[1];
postData = arguments[1];
callback = arguments[2];
}
var requestHeaders = {"Authorization":"Bearer "+config.api_user_token};
if(endpoint == "statuses") {
if(arguments.length == 4) {
var idempotencykey = arguments[3];
}
else {
var idempotencykey = getRandom();
}
requestHeaders["Idempotency-Key"] = idempotencykey;
}
$.ajax({
url: apiBase + endpoint,
type: "POST",
data: postData,
headers: {"Authorization": "Bearer " + config.api_user_token},
headers: requestHeaders,
success: function(data, textStatus) {
if(endpoint == "statuses") {
$(".js_current_toots_count").html(++localStorage.current_statuses_count);
@ -170,7 +180,7 @@ callback(data,textStatus)
},
error: function(xhr, textStatus, errorThrown) {
if(xhr.readyState == 0) {
api.post(endpoint,postData,callback);
api.post(endpoint,postData,callback,idempotencykey);
}
else {
putMessage(`[${xhr.status}] ${xhr.responseJSON['error']}`);

View File

@ -1 +1 @@
1.1.4
1.1.5