Security update: no script attributes
This commit is contained in:
parent
8f14f77576
commit
21ce55f1cd
6 changed files with 134 additions and 66 deletions
|
@ -98,20 +98,21 @@ th, td {
|
|||
#nav > div[data-active] img.active {
|
||||
display: none;
|
||||
}
|
||||
#nav > div[data-active="home"] [role="home"] img.inactive,
|
||||
#nav > div[data-active="explore"] [role="explore"] img.inactive,
|
||||
#nav > div[data-active="notifications"] [role="notifications"] img.inactive,
|
||||
#nav > div[data-active="settings"] [role="settings"] img.inactive,
|
||||
#nav > div[data-active="messages"] [role="dm"] img.inactive {
|
||||
#nav > div[data-active="home"] [data-view="friends"] img.inactive,
|
||||
#nav > div[data-active="explore"] [data-view="explore"] img.inactive,
|
||||
#nav > div[data-active="notifications"] [data-view="notifications"] img.inactive,
|
||||
#nav > div[data-active="settings"] [data-view="settings"] img.inactive,
|
||||
#nav > div[data-active="messages"] [data-view="dm"] img.inactive {
|
||||
display: none;
|
||||
}
|
||||
#nav > div[data-active="home"] [role="home"] img.active,
|
||||
#nav > div[data-active="explore"] [role="explore"] img.active,
|
||||
#nav > div[data-active="notifications"] [role="notifications"] img.active,
|
||||
#nav > div[data-active="settings"] [role="settings"] img.active,
|
||||
#nav > div[data-active="messages"] [role="dm"] img.active {
|
||||
#nav > div[data-active="home"] [data-view="friends"] img.active,
|
||||
#nav > div[data-active="explore"] [data-view="explore"] img.active,
|
||||
#nav > div[data-active="notifications"] [data-view="notifications"] img.active,
|
||||
#nav > div[data-active="settings"] [data-view="settings"] img.active,
|
||||
#nav > div[data-active="messages"] [data-view="dm"] img.active {
|
||||
display: block;
|
||||
}
|
||||
|
||||
#app-icon-logo > img {
|
||||
width: 36px;
|
||||
height: 36px;
|
||||
|
@ -145,26 +146,26 @@ button.nav > img.icon {
|
|||
width: 28px;
|
||||
height: 28px;
|
||||
}
|
||||
#gnav button[role="open-gnav"] {
|
||||
#gnav button[action="toggle-gnav"] {
|
||||
z-index: var(--zGlobal);
|
||||
padding: 15px;
|
||||
}
|
||||
#gnav.open button[role="home"] {
|
||||
#gnav.open button[data-view="friends"] {
|
||||
top: -375px;
|
||||
}
|
||||
#gnav.open button[role="explore"] {
|
||||
#gnav.open button[data-view="explore"] {
|
||||
top: -300px;
|
||||
}
|
||||
#gnav.open button[role="dm"] {
|
||||
#gnav.open button[data-view="dm"] {
|
||||
top: -225px;
|
||||
}
|
||||
#gnav.open button[role="notifications"] {
|
||||
#gnav.open button[data-view="notifications"] {
|
||||
top: -150px;
|
||||
}
|
||||
#gnav.open button[role="notifications"] .new-notifications {
|
||||
#gnav.open button[data-view="notifications"] .new-notifications {
|
||||
right: 9px;
|
||||
}
|
||||
#gnav.open button[role="settings"] {
|
||||
#gnav.open button[data-view="settings"] {
|
||||
top: -75px;
|
||||
}
|
||||
|
||||
|
@ -282,9 +283,6 @@ button.nav > img.icon {
|
|||
.event-content > .info {
|
||||
display: inline-block;
|
||||
}
|
||||
.event-content > .info button[role="view-event"] {
|
||||
margin-left: 10px;
|
||||
}
|
||||
.username, .thread-id {
|
||||
font-weight: 800;
|
||||
font-size: var(--fsReduced);
|
||||
|
|
54
index.html
54
index.html
|
@ -5,7 +5,7 @@
|
|||
<meta name="viewport" content="width=device-width, initial-scale=1">
|
||||
<meta name="theme-color" content="#0f0f0f"/>
|
||||
<meta http-equiv="Content-Security-Policy"
|
||||
content="default-src 'none'; manifest-src 'self'; connect-src 'self' ws: wss:; script-src 'self'; script-src-elem 'self'; script-src-attr 'unsafe-inline'; style-src 'self' fonts.googleapis.com; img-src http: https: data:; media-src *; font-src 'self' fonts.gstatic.com; child-src 'none';" />
|
||||
content="default-src 'none'; manifest-src 'self'; connect-src 'self' ws: wss:; script-src 'self'; script-src-elem 'self'; script-src-attr 'none'; style-src 'self' fonts.googleapis.com; img-src http: https: data:; media-src *; font-src 'self' fonts.gstatic.com; child-src 'none';" />
|
||||
<title>Yo, Sup</title>
|
||||
<link rel="manifest" href="pwa/manifest.json"/>
|
||||
<link rel="icon" href="icon/icon.svg" type="image/svg+xml"/>
|
||||
|
@ -47,13 +47,13 @@
|
|||
<img class="icon svg" src="icon/logo-inverted.svg"/>
|
||||
</h1>
|
||||
<p>The blue bird experience for Nostr.</p>
|
||||
<button class="action" onclick="signin()">
|
||||
<button class="action" action="sign-in">
|
||||
Sign In with Key
|
||||
<img src="./icon/key.svg" class="icon svg small invert"/>
|
||||
</button>
|
||||
<br/>
|
||||
<br/>
|
||||
<button class="btn-text" onclick="open_faqs()">
|
||||
<button class="btn-text" action="open-faqs">
|
||||
What's Nostr?
|
||||
</button>
|
||||
</div>
|
||||
|
@ -61,25 +61,25 @@
|
|||
</div>
|
||||
|
||||
<div id="container-app" class="hide">
|
||||
<nav id="gnav" class="">
|
||||
<button class="icon" role="open-gnav" title="Open Menu" onclick="toggle_gnav(this)">
|
||||
<nav id="gnav">
|
||||
<button class="icon" action="toggle-gnav" title="Open Menu">
|
||||
<img class="icon svg invert" src="icon/logo.svg"/>
|
||||
</button>
|
||||
<button class="icon" role="home" title="Home" onclick="switch_view('friends')">
|
||||
<button class="icon" action="open-view" data-view="friends" title="Home">
|
||||
<img class="icon svg invert" src="icon/home.svg"/>
|
||||
</button>
|
||||
<button class="icon" role="explore" title="Explore" onclick="switch_view('explore')">
|
||||
<button class="icon" action="open-view" data-view="explore" title="Explore">
|
||||
<img class="icon svg invert" src="icon/explore.svg"/>
|
||||
</button>
|
||||
<button class="icon" role="dm" title="Direct Messages" onclick="switch_view('dm')">
|
||||
<button class="icon" action="open-view" data-view="dm" title="Direct Messages">
|
||||
<img class="icon svg invert" src="icon/messages.svg"/>
|
||||
<div class="new-notifications hide" role="dm"></div>
|
||||
</button>
|
||||
<button class="icon" role="notifications" title="Notifications" onclick="switch_view('notifications')">
|
||||
<button class="icon" action="open-view" data-view="notifications" title="Notifications">
|
||||
<img class="icon svg invert" src="icon/notifications.svg"/>
|
||||
<div class="new-notifications hide" role="activity"></div>
|
||||
</button>
|
||||
<button class="icon" role="settings" title="Settings" onclick="switch_view('settings')">
|
||||
<button class="icon" action="open-view" data-view="settings" title="Settings">
|
||||
<img class="icon svg invert" src="icon/settings.svg"/>
|
||||
</button>
|
||||
</nav>
|
||||
|
@ -90,29 +90,29 @@
|
|||
<div id="app-icon-logo">
|
||||
<img class="icon svg" title="Damus" src="icon/logo-inverted.svg"/>
|
||||
</div>
|
||||
<button role="home" class="nav icon"
|
||||
title="Home" onclick="switch_view('friends')">
|
||||
<button action="open-view" data-view="friends" class="nav icon"
|
||||
title="Home">
|
||||
<img class="icon svg inactive" src="icon/home.svg"/>
|
||||
<img class="icon svg active" src="icon/home-active.svg"/>
|
||||
</button>
|
||||
<button role="explore" class="nav icon"
|
||||
title="Explore" onclick="switch_view('explore')"> <img class="icon svg inactive" src="icon/explore.svg"/>
|
||||
<button action="open-view" data-view="explore" class="nav icon"
|
||||
title="Explore"> <img class="icon svg inactive" src="icon/explore.svg"/>
|
||||
<img class="icon svg active" src="icon/explore-active.svg"/>
|
||||
</button>
|
||||
<button role="dm" class="nav icon"
|
||||
title="Direct Messages" onclick="switch_view('dm')">
|
||||
<button action="open-view" data-view="dm" class="nav icon"
|
||||
title="Direct Messages">
|
||||
<img class="icon svg inactive" src="icon/messages.svg"/>
|
||||
<img class="icon svg active" src="icon/messages-active.svg"/>
|
||||
<div class="new-notifications hide" role="dm"></div>
|
||||
</button>
|
||||
<button role="notifications" class="nav icon"
|
||||
title="Notifications" onclick="switch_view('notifications')">
|
||||
<button action="open-view" data-view="notifications"
|
||||
class="nav icon" title="Notifications">
|
||||
<img class="icon svg inactive" src="icon/notifications.svg"/>
|
||||
<img class="icon svg active" src="icon/notifications-active.svg"/>
|
||||
<div class="new-notifications hide" role="activity"></div>
|
||||
</button>
|
||||
<button role="settings" title="Settings" class="nav icon"
|
||||
onclick="switch_view('settings')">
|
||||
<button action="open-view" data-view="settings"
|
||||
title="Settings" class="nav icon">
|
||||
<img class="icon svg inactive" src="icon/settings.svg"/>
|
||||
<img class="icon svg active" src="icon/settings-active.svg"/>
|
||||
</button>
|
||||
|
@ -172,7 +172,7 @@
|
|||
</div>
|
||||
</div>
|
||||
<div id="show-new" class="show-new bottom-border hide">
|
||||
<button onclick="show_new()">
|
||||
<button action="show-timeline-new">
|
||||
Show New (<span role="count">0</span>)</button>
|
||||
</div>
|
||||
<div id="dms-not-available" class="hide">
|
||||
|
@ -248,7 +248,7 @@
|
|||
|
||||
<div class="modal closed" id="media-preview">
|
||||
<div class="media-container">
|
||||
<img onclick="close_media_preview()" src=""/>
|
||||
<img action="close-media" src=""/>
|
||||
</div>
|
||||
<!-- TODO add loader to media preview -->
|
||||
</div>
|
||||
|
@ -257,7 +257,7 @@
|
|||
<div id="reply-modal-content" class="modal-content">
|
||||
<header>
|
||||
<label>Reply To</label>
|
||||
<button class="icon" onclick="close_modal(this)">
|
||||
<button class="icon" action="close-modal">
|
||||
<img class="icon svg" src="icon/close-modal.svg"/>
|
||||
</button>
|
||||
</header>
|
||||
|
@ -276,7 +276,7 @@
|
|||
<div class="modal-content">
|
||||
<header>
|
||||
<label>Update Profile</label>
|
||||
<button class="icon" onclick="close_modal(this)">
|
||||
<button class="icon" action="close-modal">
|
||||
<img class="icon svg" src="icon/close-modal.svg"/>
|
||||
</button>
|
||||
</header>
|
||||
|
@ -285,7 +285,7 @@
|
|||
<input type="text" class="block w100" name="picture" placeholder="Picture URL"/>
|
||||
<input type="text" class="block w100" name="nip05" placeholder="nip05"/>
|
||||
<textarea name="about" class="block w100" placeholder="A bit about you."></textarea>
|
||||
<button class="action float-right" onclick="click_update_profile()">
|
||||
<button class="action float-right" action="open-profile-editor">
|
||||
Update
|
||||
</button>
|
||||
</div>
|
||||
|
@ -295,7 +295,7 @@
|
|||
<div class="modal-content">
|
||||
<header>
|
||||
<label>Event Details</label>
|
||||
<button class="icon modal-floating-close-btn" onclick="close_modal(this)">
|
||||
<button class="icon modal-floating-close-btn" action="close-modal">
|
||||
<img class="icon svg" src="icon/close-modal.svg"/>
|
||||
</button>
|
||||
</header>
|
||||
|
@ -306,7 +306,7 @@
|
|||
</div>
|
||||
|
||||
<div id="faqs" class="modal scrollable closed">
|
||||
<button class="icon modal-floating-close-btn" onclick="close_modal(this)">
|
||||
<button class="icon modal-floating-close-btn" action="close-modal">
|
||||
<img class="icon svg" src="icon/close-modal.svg"/>
|
||||
</button>
|
||||
<div class="page-content">
|
||||
|
|
|
@ -19,6 +19,7 @@ const SID_FRIENDS = "friends";
|
|||
// https://developer.mozilla.org/en-US/docs/Web/API/Window/DOMContentLoaded_event
|
||||
addEventListener('DOMContentLoaded', (ev) => {
|
||||
damus_web_init();
|
||||
document.addEventListener("click", onclick_any);
|
||||
});
|
||||
|
||||
async function damus_web_init() {
|
||||
|
@ -295,4 +296,3 @@ function fetch_friends_history(friends, pool, relay) {
|
|||
limit: 500,
|
||||
}], relay);
|
||||
}
|
||||
|
||||
|
|
|
@ -11,7 +11,7 @@ function linkify(text="", show_media=false) {
|
|||
if (show_media && is_img_url(parsed.pathname)) {
|
||||
markup = html`
|
||||
<img class="inline-img clickable" src="${url}"
|
||||
onclick="open_media_preview('${url}', 'image')"/>`;
|
||||
action="open-media" data-type="image"/>`;
|
||||
} else if (show_media && is_video_url(parsed.pathname)) {
|
||||
markup = html`
|
||||
<video controls class="inline-img" />
|
||||
|
|
|
@ -13,8 +13,8 @@ function render_replying_to(model, ev) {
|
|||
if (!replying_to) {
|
||||
return html`<span class="replying-to small-txt">
|
||||
replying in thread
|
||||
<span class="thread-id clickable"
|
||||
onclick="open_thread('${ev.refs.reply}')">
|
||||
<span class="thread-id clickable" action="open-thread"
|
||||
data-thread-id="${ev.refs.reply}">
|
||||
${fmt_pubkey(ev.refs.reply)}</span></span>`;
|
||||
} else {
|
||||
pubkeys = [replying_to.pubkey];
|
||||
|
@ -156,9 +156,9 @@ function render_event_body(model, ev, opts) {
|
|||
function render_react_onclick(our_pubkey, reacting_to, emoji, reactions) {
|
||||
const reaction = reactions[our_pubkey]
|
||||
if (!reaction) {
|
||||
return html`onclick="send_reply('${emoji}', '${reacting_to}')"`
|
||||
return html`action="reply" data-emoji="${emoji}" data-to="${reacting_to}"`;
|
||||
} else {
|
||||
return html`onclick="delete_post('${reaction.id}')"`
|
||||
return html`action="delete" data-evid="${reaction.id}"`;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -196,14 +196,15 @@ function render_action_bar(model, ev, opts={}) {
|
|||
const reaction_id = reaction ? reaction.id : "";
|
||||
let str = html`<div class="action-bar">`;
|
||||
if (!shared && event_can_reply(ev)) {
|
||||
str += html`<button class="icon" title="Reply" onclick="reply_author('${ev.id}')">
|
||||
str += html`
|
||||
<button class="icon" title="Reply" action="reply-author" data-evid="${ev.id}">
|
||||
<img class="icon svg small" src="icon/event-reply.svg"/>
|
||||
</button>
|
||||
<button class="icon" title="Reply All" onclick="reply_all('${ev.id}')">
|
||||
<button class="icon" title="Reply All" action="reply-all" data-evid="${ev.id}">
|
||||
<img class="icon svg small" src="icon/event-reply-all.svg"/>
|
||||
</button>
|
||||
<button class="icon react heart ${ab(liked, 'liked', '')}"
|
||||
onclick="click_toggle_like(this)"
|
||||
action="react-like"
|
||||
data-reaction-id="${reaction_id}"
|
||||
data-reacting-to="${ev.id}"
|
||||
title="$${ab(liked, 'Unlike', 'Like')}">
|
||||
|
@ -212,27 +213,29 @@ function render_action_bar(model, ev, opts={}) {
|
|||
</button>`;
|
||||
}
|
||||
if (!shared) {
|
||||
str += html`<button class="icon" title="Share" data-evid="${ev.id}" onclick="click_share(this)">
|
||||
str += html`<button class="icon" title="Share" data-evid="${ev.id}"
|
||||
action="share">
|
||||
<img class="icon svg small" src="icon/event-share.svg"/>
|
||||
</button>`;
|
||||
}
|
||||
str += `
|
||||
<button class="icon" title="View Thread" role="view-thread"
|
||||
onclick="open_thread('${thread_root}')">
|
||||
<button class="icon" title="View Thread" action="open-thread"
|
||||
data-thread-id="${thread_root}">
|
||||
<img class="icon svg small" src="icon/open-thread.svg"/>
|
||||
</button>
|
||||
<button class="icon" title="View Replies" role="view-replies"
|
||||
onclick="open_thread('${ev.id}')">
|
||||
<button class="icon" title="View Replies" action="open-thread"
|
||||
data-thread-id="${ev.id}">
|
||||
<img class="icon svg small" src="icon/open-thread-here.svg"/>
|
||||
</button>
|
||||
<button class="icon" title="View Event JSON" role="view-event-json"
|
||||
onclick="on_click_show_event_details('${ev.id}')">
|
||||
<button class="icon" title="View Event JSON" action="show-event-json"
|
||||
data-evid="${ev.id}">
|
||||
<img class="icon svg small" src="icon/event-details.svg"/>
|
||||
</button>`;
|
||||
if (can_delete) {
|
||||
const delete_id = shared ? shared.share_evid : ev.id;
|
||||
str += html`
|
||||
<button class="icon" title="Delete" onclick="delete_post_confirm('${delete_id}')">
|
||||
<button class="icon" title="Delete" action="confirm-delete"
|
||||
data-evid="${delete_id}">
|
||||
<img class="icon svg small" src="icon/event-delete.svg"/>
|
||||
</button>`
|
||||
}
|
||||
|
@ -275,14 +278,14 @@ function render_name(pk, profile, prefix="") {
|
|||
|
||||
function render_profile_img(profile, noclick=false) {
|
||||
const name = fmt_name(profile);
|
||||
let str = html`class="pfp clickable" onclick="open_profile('${profile.pubkey}')"`;
|
||||
let str = html`class="pfp clickable" action="open-profile"`;
|
||||
if (noclick)
|
||||
str = "class='pfp'";
|
||||
return html`<img
|
||||
$${str}
|
||||
data-pubkey="${profile.pubkey}"
|
||||
title="${name}"
|
||||
onerror="this.onerror=null;this.src='${IMG_NO_USER}';"
|
||||
src="${get_profile_pic(profile)}"/>`
|
||||
//onerror="this.onerror=null;this.src='${IMG_NO_USER}';"
|
||||
}
|
||||
|
||||
|
|
|
@ -566,3 +566,70 @@ function onclick_toggle_cw(ev) {
|
|||
const input = el.parentElement.querySelector("input.cw");
|
||||
input.classList.toggle("hide", !isOn);
|
||||
}
|
||||
|
||||
function onclick_any(ev) {
|
||||
const el = ev.target;
|
||||
const action = el.getAttribute("action");
|
||||
switch (action) {
|
||||
case "open-faqs":
|
||||
open_faqs();
|
||||
break;
|
||||
case "toggle-gnav":
|
||||
toggle_gnav(el);
|
||||
break;
|
||||
case "sign-in":
|
||||
signin();
|
||||
break;
|
||||
case "open-view":
|
||||
switch_view(el.dataset.view);
|
||||
break;
|
||||
case "close-media":
|
||||
close_media_preview();
|
||||
break;
|
||||
case "close-modal":
|
||||
close_modal(el);
|
||||
break;
|
||||
case "open-profile":
|
||||
open_profile(el.dataset.pubkey);
|
||||
break;
|
||||
case "open-profile-editor":
|
||||
click_update_profile();
|
||||
break;
|
||||
case "show-timeline-new":
|
||||
show_new();
|
||||
break;
|
||||
case "open-thread":
|
||||
open_trhead(el.dataset.threadId);
|
||||
break;
|
||||
case "reply":
|
||||
send_reply(el.dataset.emoji, el.dataset.to);
|
||||
break;
|
||||
case "delete":
|
||||
delete_post(el.dataset.evid);
|
||||
break;
|
||||
case "reply-author":
|
||||
reply_author(el.dataset.evid);
|
||||
break;
|
||||
case "reply-all":
|
||||
reply_all(el.dataset.evid);
|
||||
break;
|
||||
case "react-like":
|
||||
click_toggle_like(el);
|
||||
break;
|
||||
case "share":
|
||||
click_share(el);
|
||||
break;
|
||||
case "open-thread":
|
||||
open_thread(el.dataset.threadId);
|
||||
break;
|
||||
case "open-media":
|
||||
open_media_preview(el.src, el.dataset.type);
|
||||
break;
|
||||
case "show-event-json":
|
||||
on_click_show_event_details(el.dataset.evid);
|
||||
break;
|
||||
case "confirm-delete":
|
||||
delete_post_confirm(el.dataset.evid);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue