From 3114e4837110ccb6c4398d69d4525315cac036bd Mon Sep 17 00:00:00 2001 From: Izalia Mae Date: Fri, 15 Mar 2024 19:47:05 -0400 Subject: [PATCH] enable csp headers --- relay/application.py | 6 +-- relay/frontend/page/admin-domain_bans.haml | 8 +-- relay/frontend/page/admin-instances.haml | 10 ++-- relay/frontend/page/admin-software_bans.haml | 10 ++-- relay/frontend/page/admin-users.haml | 6 +-- relay/frontend/page/admin-whitelist.haml | 6 +-- relay/frontend/static/api.js | 2 + relay/frontend/static/domain_ban.js | 39 ++++++++++++-- relay/frontend/static/instance.js | 56 ++++++++++++++++++-- relay/frontend/static/software_ban.js | 36 ++++++++++--- relay/frontend/static/user.js | 30 +++++++++-- relay/frontend/static/whitelist.js | 27 +++++++++- 12 files changed, 193 insertions(+), 43 deletions(-) diff --git a/relay/application.py b/relay/application.py index b3da393..58668a8 100644 --- a/relay/application.py +++ b/relay/application.py @@ -130,7 +130,7 @@ class Application(web.Application): data = [ "default-src 'none'", f"script-src 'nonce-{request['hash']}'", - f"style-src 'nonce-{request['hash']}'", + f"style-src 'self' 'nonce-{request['hash']}'", "form-action 'self'", "connect-src 'self'", "img-src 'self'", @@ -287,8 +287,8 @@ async def handle_response_headers(request: web.Request, handler: Callable) -> Re resp.headers['Server'] = 'ActivityRelay' # Still have to figure out how csp headers work - # if resp.content_type == 'text/html': - # resp.headers['Content-Security-Policy'] = Application.DEFAULT.get_csp(request) + if resp.content_type == 'text/html': + resp.headers['Content-Security-Policy'] = Application.DEFAULT.get_csp(request) if not request.app['dev'] and request.path.endswith(('.css', '.js')): # cache for 2 weeks diff --git a/relay/frontend/page/admin-domain_bans.haml b/relay/frontend/page/admin-domain_bans.haml index a9fdbe0..19ae4ae 100644 --- a/relay/frontend/page/admin-domain_bans.haml +++ b/relay/frontend/page/admin-domain_bans.haml @@ -2,7 +2,7 @@ -set page="Domain Bans" -block head - %script(type="application/javascript" src="/static/domain_ban.js" nonce="{{view.request['hash']}}") + %script(type="application/javascript" src="/static/domain_ban.js" nonce="{{view.request['hash']}}" defer) -block content %details.section @@ -17,7 +17,7 @@ %label(for="new-note") << Admin Note %textarea(id="new-note") << {{""}} - %input(type="button" value="Ban Domain" onclick="ban();") + %input#new-ban(type="button" value="Ban Domain") %fieldset.section %legend << Domain Bans @@ -44,10 +44,10 @@ %label.note(for="{{ban.domain}}-note") << Note %textarea.note(id="{{ban.domain}}-note") << {{ban.note or ""}} - %input(type="button" value="Update" onclick="update_ban('{{ban.domain}}')") + %input.update-ban(type="button" value="Update") %td.date =ban.created.strftime("%Y-%m-%d") %td.remove - %a(href="#" onclick="unban('{{ban.domain}}')" title="Unban domain") << ✖ + %a(href="#" title="Unban domain") << ✖ diff --git a/relay/frontend/page/admin-instances.haml b/relay/frontend/page/admin-instances.haml index fcb0630..2e43f48 100644 --- a/relay/frontend/page/admin-instances.haml +++ b/relay/frontend/page/admin-instances.haml @@ -2,7 +2,7 @@ -set page="Instances" -block head - %script(type="application/javascript" src="/static/instance.js" nonce="{{view.request['hash']}}") + %script(type="application/javascript" src="/static/instance.js" nonce="{{view.request['hash']}}" defer) -block content %details.section @@ -20,7 +20,7 @@ %label(for="new-software") << Software %input(id="new-software" placeholder="software") - %input(type="button" value="Add Instance", onclick="add_instance()") + %input#add-instance(type="button" value="Add Instance") -if requests %fieldset.section.requests @@ -48,10 +48,10 @@ =request.created.strftime("%Y-%m-%d") %td.approve - %a(href="#" onclick="req_response('{{request.domain}}', true)" title="Approve Request") << ✓ + %a(href="#" title="Approve Request") << ✓ %td.deny - %a(href="#" onclick="req_response('{{request.domain}}', false)" title="Deny Request") << ✖ + %a(href="#" title="Deny Request") << ✖ %fieldset.section.instances %legend << Instances @@ -78,4 +78,4 @@ =instance.created.strftime("%Y-%m-%d") %td.remove - %a(href="#" onclick="del_instance('{{instance.domain}}')" title="Remove Instance") << ✖ + %a(href="#" title="Remove Instance") << ✖ diff --git a/relay/frontend/page/admin-software_bans.haml b/relay/frontend/page/admin-software_bans.haml index 00f4043..9bda3be 100644 --- a/relay/frontend/page/admin-software_bans.haml +++ b/relay/frontend/page/admin-software_bans.haml @@ -2,7 +2,7 @@ -set page="Software Bans" -block head - %script(type="application/javascript" src="/static/software_ban.js" nonce="{{view.request['hash']}}") + %script(type="application/javascript" src="/static/software_ban.js" nonce="{{view.request['hash']}}" defer) -block content %details.section @@ -17,13 +17,13 @@ %label(for="new-note") << Admin Note %textarea(id="new-note") << {{""}} - %input(type="submit" value="Ban Software" onclick="ban()") + %input#new-ban(type="button" value="Ban Software") %fieldset.section %legend << Software Bans .data-table - %table + %table#bans %thead %tr %td.name << Name @@ -44,10 +44,10 @@ %label.note(for="{{ban.name}}-note") << Note %textarea.note(id="{{ban.name}}-note") << {{ban.note or ""}} - %input(type="button" value="Update" onclick="update_ban('{{ban.name}}')") + %input.update-ban(type="button" value="Update") %td.date =ban.created.strftime("%Y-%m-%d") %td.remove - %a(href="#" onclick="unban('{{ban.name}}')" title="Unban name") << ✖ + %a(href="#" title="Unban name") << ✖ diff --git a/relay/frontend/page/admin-users.haml b/relay/frontend/page/admin-users.haml index f872dfb..2043ba8 100644 --- a/relay/frontend/page/admin-users.haml +++ b/relay/frontend/page/admin-users.haml @@ -2,7 +2,7 @@ -set page="Users" -block head - %script(type="application/javascript" src="/static/user.js" nonce="{{view.request['hash']}}") + %script(type="application/javascript" src="/static/user.js" nonce="{{view.request['hash']}}" defer) -block content %details.section @@ -20,7 +20,7 @@ %label(for="new-handle") << Handle %input(id="new-handle" type="email" placeholder="handle") - %input(type="button" value="Add User" onclick="add_user()") + %input#new-user(type="button" value="Add User") %fieldset.section %legend << Users @@ -47,4 +47,4 @@ =user.created.strftime("%Y-%m-%d") %td.remove - %a(href="#" onclick="del_user('{{user.username}}')" title="Remove User") << ✖ + %a(href="#" title="Remove User") << ✖ diff --git a/relay/frontend/page/admin-whitelist.haml b/relay/frontend/page/admin-whitelist.haml index 77fad7a..f494aef 100644 --- a/relay/frontend/page/admin-whitelist.haml +++ b/relay/frontend/page/admin-whitelist.haml @@ -2,7 +2,7 @@ -set page="Whitelist" -block head - %script(type="application/javascript" src="/static/whitelist.js" nonce="{{view.request['hash']}}") + %script(type="application/javascript" src="/static/whitelist.js" nonce="{{view.request['hash']}}" defer) -block content %details.section @@ -11,7 +11,7 @@ %label(for="new-domain") << Domain %input(type="domain" id="new-domain" placeholder="Domain") - %input(type="button" value="Add Domain", onclick="add_whitelist()") + %input#new-item(type="button" value="Add Domain") %fieldset.data-table.section %legend << Whitelist @@ -33,4 +33,4 @@ =item.created.strftime("%Y-%m-%d") %td.remove - %a(href="#" onclick="del_whitelist('{{item.domain}}')" title="Remove whitlisted domain") << ✖ + %a(href="#" title="Remove whitlisted domain") << ✖ diff --git a/relay/frontend/static/api.js b/relay/frontend/static/api.js index e5a3c9b..d064d7b 100644 --- a/relay/frontend/static/api.js +++ b/relay/frontend/static/api.js @@ -30,6 +30,8 @@ function append_table_row(table, row_name, row) { index += 1; } } + + return table_row; } diff --git a/relay/frontend/static/domain_ban.js b/relay/frontend/static/domain_ban.js index 443ccce..e84bf52 100644 --- a/relay/frontend/static/domain_ban.js +++ b/relay/frontend/static/domain_ban.js @@ -6,13 +6,25 @@ function create_ban_object(domain, reason, note) { text += `\n`; text += `\n`; text += `\n`; - text += ``; + text += ``; text += ''; return text; } +function add_row_listeners(row) { + row.querySelector(".update-ban").addEventListener("click", async (event) => { + await update_ban(row.id); + }); + + row.querySelector(".remove a").addEventListener("click", async (event) => { + event.preventDefault(); + await unban(row.id); + }); +} + + async function ban() { var table = document.querySelector("table"); var elems = { @@ -23,8 +35,8 @@ async function ban() { var values = { domain: elems.domain.value.trim(), - reason: elems.reason.value, - note: elems.note.value + reason: elems.reason.value.trim(), + note: elems.note.value.trim() } if (values.domain === "") { @@ -40,12 +52,16 @@ async function ban() { return } - append_table_row(document.getElementById("instances"), ban.domain, { + var row = append_table_row(document.querySelector("table"), ban.domain, { domain: create_ban_object(ban.domain, ban.reason, ban.note), date: get_date_string(ban.created), - remove: `` + remove: `` }); + console.log(row.querySelector(".update-ban")); + console.log(row.querySelector(".remove a")); + add_row_listeners(row); + elems.domain.value = null; elems.reason.value = null; elems.note.value = null; @@ -91,3 +107,16 @@ async function unban(domain) { document.getElementById(domain).remove(); } + + +document.querySelector("#new-ban").addEventListener("click", async (event) => { + await ban(); +}); + +for (var row of document.querySelector("fieldset.section table").rows) { + if (!row.querySelector(".update-ban")) { + continue; + } + + add_row_listeners(row); +} diff --git a/relay/frontend/static/instance.js b/relay/frontend/static/instance.js index 6b822d1..8987b25 100644 --- a/relay/frontend/static/instance.js +++ b/relay/frontend/static/instance.js @@ -1,3 +1,24 @@ +function add_instance_listeners(row) { + row.querySelector(".remove a").addEventListener("click", async (event) => { + event.preventDefault(); + await del_instance(row.id); + }); +} + + +function add_request_listeners(row) { + row.querySelector(".approve a").addEventListener("click", async (event) => { + event.preventDefault(); + await req_response(row.id, true); + }); + + row.querySelector(".deny a").addEventListener("click", async (event) => { + event.preventDefault(); + await req_response(row.id, false); + }); +} + + async function add_instance() { var elems = { actor: document.getElementById("new-actor"), @@ -26,13 +47,15 @@ async function add_instance() { return } - append_table_row(document.getElementById("instances"), instance.domain, { + row = append_table_row(document.getElementById("instances"), instance.domain, { domain: `${instance.domain}`, software: instance.software, date: get_date_string(instance.created), - remove: `` + remove: `` }); + add_instance_listeners(row); + elems.actor.value = null; elems.inbox.value = null; elems.followid.value = null; @@ -82,12 +105,37 @@ async function req_response(domain, accept) { instances = await request("GET", `v1/instance`, null); instances.forEach((instance) => { if (instance.domain === domain) { - append_table_row(document.getElementById("instances"), instance.domain, { + row = append_table_row(document.getElementById("instances"), instance.domain, { domain: `${instance.domain}`, software: instance.software, date: get_date_string(instance.created), - remove: `` + remove: `` }); + + add_instance_listeners(row); } }); } + + +document.querySelector("#add-instance").addEventListener("click", async (event) => { + await add_instance(); +}) + +for (var row of document.querySelector("#instances").rows) { + if (!row.querySelector(".remove a")) { + continue; + } + + add_instance_listeners(row); +} + +if (document.querySelector("#requests")) { + for (var row of document.querySelector("#requests").rows) { + if (!row.querySelector(".approve a")) { + continue; + } + + add_request_listeners(row); + } +} diff --git a/relay/frontend/static/software_ban.js b/relay/frontend/static/software_ban.js index b316df9..510f796 100644 --- a/relay/frontend/static/software_ban.js +++ b/relay/frontend/static/software_ban.js @@ -6,17 +6,26 @@ function create_ban_object(name, reason, note) { text += `\n`; text += `\n`; text += `\n`; - text += ``; + text += ``; text += ''; return text; } -async function ban() { - var table = document.querySelector("table"); - var row = table.insertRow(-1); +function add_row_listeners(row) { + row.querySelector(".update-ban").addEventListener("click", async (event) => { + await update_ban(row.id); + }); + row.querySelector(".remove a").addEventListener("click", async (event) => { + event.preventDefault(); + await unban(row.id); + }); +} + + +async function ban() { var elems = { name: document.getElementById("new-name"), reason: document.getElementById("new-reason"), @@ -42,12 +51,14 @@ async function ban() { return } - append_table_row(document.getElementById("instances"), ban.name, { + var row = append_table_row(document.getElementById("bans"), ban.name, { name: create_ban_object(ban.name, ban.reason, ban.note), date: get_date_string(ban.created), - remove: `` + remove: `` }); + add_row_listeners(row); + elems.name.value = null; elems.reason.value = null; elems.note.value = null; @@ -93,3 +104,16 @@ async function unban(name) { document.getElementById(name).remove(); } + + +document.querySelector("#new-ban").addEventListener("click", async (event) => { + await ban(); +}); + +for (var row of document.querySelector("#bans").rows) { + if (!row.querySelector(".update-ban")) { + continue; + } + + add_row_listeners(row); +} diff --git a/relay/frontend/static/user.js b/relay/frontend/static/user.js index 3d23b2b..6f63334 100644 --- a/relay/frontend/static/user.js +++ b/relay/frontend/static/user.js @@ -1,3 +1,12 @@ +function add_row_listeners(row) { + console.log(row); + row.querySelector(".remove a").addEventListener("click", async (event) => { + event.preventDefault(); + await del_user(row.id); + }); +} + + async function add_user() { var elems = { username: document.getElementById("new-username"), @@ -31,13 +40,15 @@ async function add_user() { return } - append_table_row(document.getElementById("users"), user.username, { + var row = append_table_row(document.querySelector("fieldset.section table"), user.username, { domain: user.username, - handle: user.handle, + handle: user.handle ? self.handle : "n/a", date: get_date_string(user.created), - remove: `` + remove: `` }); + add_row_listeners(row); + elems.username.value = null; elems.password.value = null; elems.password2.value = null; @@ -58,3 +69,16 @@ async function del_user(username) { document.getElementById(username).remove(); } + + +document.querySelector("#new-user").addEventListener("click", async (event) => { + await add_user(); +}); + +for (var row of document.querySelector("#users").rows) { + if (!row.querySelector(".remove a")) { + continue; + } + + add_row_listeners(row); +} diff --git a/relay/frontend/static/whitelist.js b/relay/frontend/static/whitelist.js index 71f883c..e04204d 100644 --- a/relay/frontend/static/whitelist.js +++ b/relay/frontend/static/whitelist.js @@ -1,3 +1,11 @@ +function add_row_listeners(row) { + row.querySelector(".remove a").addEventListener("click", async (event) => { + event.preventDefault(); + await del_whitelist(row.id); + }); +} + + async function add_whitelist() { var domain_elem = document.getElementById("new-domain"); var domain = domain_elem.value.trim(); @@ -15,12 +23,14 @@ async function add_whitelist() { return } - append_table_row(document.getElementById("whitelist"), item.domain, { + var row = append_table_row(document.getElementById("whitelist"), item.domain, { domain: item.domain, date: get_date_string(item.created), - remove: `` + remove: `` }); + add_row_listeners(row); + domain_elem.value = null; document.querySelector("details.section").open = false; } @@ -37,3 +47,16 @@ async function del_whitelist(domain) { document.getElementById(domain).remove(); } + + +document.querySelector("#new-item").addEventListener("click", async (event) => { + await add_whitelist(); +}); + +for (var row of document.querySelector("fieldset.section table").rows) { + if (!row.querySelector(".remove a")) { + continue; + } + + add_row_listeners(row); +}