enable csp headers

This commit is contained in:
Izalia Mae 2024-03-15 19:47:05 -04:00
parent b068f4f91e
commit 3114e48371
12 changed files with 193 additions and 43 deletions

View file

@ -130,7 +130,7 @@ class Application(web.Application):
data = [ data = [
"default-src 'none'", "default-src 'none'",
f"script-src 'nonce-{request['hash']}'", f"script-src 'nonce-{request['hash']}'",
f"style-src 'nonce-{request['hash']}'", f"style-src 'self' 'nonce-{request['hash']}'",
"form-action 'self'", "form-action 'self'",
"connect-src 'self'", "connect-src 'self'",
"img-src 'self'", "img-src 'self'",
@ -287,8 +287,8 @@ async def handle_response_headers(request: web.Request, handler: Callable) -> Re
resp.headers['Server'] = 'ActivityRelay' resp.headers['Server'] = 'ActivityRelay'
# Still have to figure out how csp headers work # Still have to figure out how csp headers work
# if resp.content_type == 'text/html': if resp.content_type == 'text/html':
# resp.headers['Content-Security-Policy'] = Application.DEFAULT.get_csp(request) resp.headers['Content-Security-Policy'] = Application.DEFAULT.get_csp(request)
if not request.app['dev'] and request.path.endswith(('.css', '.js')): if not request.app['dev'] and request.path.endswith(('.css', '.js')):
# cache for 2 weeks # cache for 2 weeks

View file

@ -2,7 +2,7 @@
-set page="Domain Bans" -set page="Domain Bans"
-block head -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 -block content
%details.section %details.section
@ -17,7 +17,7 @@
%label(for="new-note") << Admin Note %label(for="new-note") << Admin Note
%textarea(id="new-note") << {{""}} %textarea(id="new-note") << {{""}}
%input(type="button" value="Ban Domain" onclick="ban();") %input#new-ban(type="button" value="Ban Domain")
%fieldset.section %fieldset.section
%legend << Domain Bans %legend << Domain Bans
@ -44,10 +44,10 @@
%label.note(for="{{ban.domain}}-note") << Note %label.note(for="{{ban.domain}}-note") << Note
%textarea.note(id="{{ban.domain}}-note") << {{ban.note or ""}} %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 %td.date
=ban.created.strftime("%Y-%m-%d") =ban.created.strftime("%Y-%m-%d")
%td.remove %td.remove
%a(href="#" onclick="unban('{{ban.domain}}')" title="Unban domain") << &#10006; %a(href="#" title="Unban domain") << &#10006;

View file

@ -2,7 +2,7 @@
-set page="Instances" -set page="Instances"
-block head -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 -block content
%details.section %details.section
@ -20,7 +20,7 @@
%label(for="new-software") << Software %label(for="new-software") << Software
%input(id="new-software" placeholder="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 -if requests
%fieldset.section.requests %fieldset.section.requests
@ -48,10 +48,10 @@
=request.created.strftime("%Y-%m-%d") =request.created.strftime("%Y-%m-%d")
%td.approve %td.approve
%a(href="#" onclick="req_response('{{request.domain}}', true)" title="Approve Request") << &check; %a(href="#" title="Approve Request") << &check;
%td.deny %td.deny
%a(href="#" onclick="req_response('{{request.domain}}', false)" title="Deny Request") << &#10006; %a(href="#" title="Deny Request") << &#10006;
%fieldset.section.instances %fieldset.section.instances
%legend << Instances %legend << Instances
@ -78,4 +78,4 @@
=instance.created.strftime("%Y-%m-%d") =instance.created.strftime("%Y-%m-%d")
%td.remove %td.remove
%a(href="#" onclick="del_instance('{{instance.domain}}')" title="Remove Instance") << &#10006; %a(href="#" title="Remove Instance") << &#10006;

View file

@ -2,7 +2,7 @@
-set page="Software Bans" -set page="Software Bans"
-block head -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 -block content
%details.section %details.section
@ -17,13 +17,13 @@
%label(for="new-note") << Admin Note %label(for="new-note") << Admin Note
%textarea(id="new-note") << {{""}} %textarea(id="new-note") << {{""}}
%input(type="submit" value="Ban Software" onclick="ban()") %input#new-ban(type="button" value="Ban Software")
%fieldset.section %fieldset.section
%legend << Software Bans %legend << Software Bans
.data-table .data-table
%table %table#bans
%thead %thead
%tr %tr
%td.name << Name %td.name << Name
@ -44,10 +44,10 @@
%label.note(for="{{ban.name}}-note") << Note %label.note(for="{{ban.name}}-note") << Note
%textarea.note(id="{{ban.name}}-note") << {{ban.note or ""}} %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 %td.date
=ban.created.strftime("%Y-%m-%d") =ban.created.strftime("%Y-%m-%d")
%td.remove %td.remove
%a(href="#" onclick="unban('{{ban.name}}')" title="Unban name") << &#10006; %a(href="#" title="Unban name") << &#10006;

View file

@ -2,7 +2,7 @@
-set page="Users" -set page="Users"
-block head -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 -block content
%details.section %details.section
@ -20,7 +20,7 @@
%label(for="new-handle") << Handle %label(for="new-handle") << Handle
%input(id="new-handle" type="email" placeholder="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 %fieldset.section
%legend << Users %legend << Users
@ -47,4 +47,4 @@
=user.created.strftime("%Y-%m-%d") =user.created.strftime("%Y-%m-%d")
%td.remove %td.remove
%a(href="#" onclick="del_user('{{user.username}}')" title="Remove User") << &#10006; %a(href="#" title="Remove User") << &#10006;

View file

@ -2,7 +2,7 @@
-set page="Whitelist" -set page="Whitelist"
-block head -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 -block content
%details.section %details.section
@ -11,7 +11,7 @@
%label(for="new-domain") << Domain %label(for="new-domain") << Domain
%input(type="domain" id="new-domain" placeholder="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 %fieldset.data-table.section
%legend << Whitelist %legend << Whitelist
@ -33,4 +33,4 @@
=item.created.strftime("%Y-%m-%d") =item.created.strftime("%Y-%m-%d")
%td.remove %td.remove
%a(href="#" onclick="del_whitelist('{{item.domain}}')" title="Remove whitlisted domain") << &#10006; %a(href="#" title="Remove whitlisted domain") << &#10006;

View file

@ -30,6 +30,8 @@ function append_table_row(table, row_name, row) {
index += 1; index += 1;
} }
} }
return table_row;
} }

View file

@ -6,13 +6,25 @@ function create_ban_object(domain, reason, note) {
text += `<textarea id="${domain}-reason" class="reason">${reason}</textarea>\n`; text += `<textarea id="${domain}-reason" class="reason">${reason}</textarea>\n`;
text += `<label for="${domain}-note" class="note">Note</label>\n`; text += `<label for="${domain}-note" class="note">Note</label>\n`;
text += `<textarea id="${domain}-note" class="note">${note}</textarea>\n`; text += `<textarea id="${domain}-note" class="note">${note}</textarea>\n`;
text += `<input type="button" value="Update" onclick="update_ban(\"${domain}\"")">`; text += `<input class="update-ban" type="button" value="Update">`;
text += '</details>'; text += '</details>';
return 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() { async function ban() {
var table = document.querySelector("table"); var table = document.querySelector("table");
var elems = { var elems = {
@ -23,8 +35,8 @@ async function ban() {
var values = { var values = {
domain: elems.domain.value.trim(), domain: elems.domain.value.trim(),
reason: elems.reason.value, reason: elems.reason.value.trim(),
note: elems.note.value note: elems.note.value.trim()
} }
if (values.domain === "") { if (values.domain === "") {
@ -40,12 +52,16 @@ async function ban() {
return 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), domain: create_ban_object(ban.domain, ban.reason, ban.note),
date: get_date_string(ban.created), date: get_date_string(ban.created),
remove: `<a href="#" onclick="unban('${ban.domain}')" title="Unban domain">&#10006;</a>` remove: `<a href="#" title="Unban domain">&#10006;</a>`
}); });
console.log(row.querySelector(".update-ban"));
console.log(row.querySelector(".remove a"));
add_row_listeners(row);
elems.domain.value = null; elems.domain.value = null;
elems.reason.value = null; elems.reason.value = null;
elems.note.value = null; elems.note.value = null;
@ -91,3 +107,16 @@ async function unban(domain) {
document.getElementById(domain).remove(); 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);
}

View file

@ -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() { async function add_instance() {
var elems = { var elems = {
actor: document.getElementById("new-actor"), actor: document.getElementById("new-actor"),
@ -26,13 +47,15 @@ async function add_instance() {
return return
} }
append_table_row(document.getElementById("instances"), instance.domain, { row = append_table_row(document.getElementById("instances"), instance.domain, {
domain: `<a href="https://${instance.domain}/" target="_new">${instance.domain}</a>`, domain: `<a href="https://${instance.domain}/" target="_new">${instance.domain}</a>`,
software: instance.software, software: instance.software,
date: get_date_string(instance.created), date: get_date_string(instance.created),
remove: `<a href="#" onclick="del_instance('${instance.domain}')" title="Remove Instance">&#10006;</a>` remove: `<a href="#" title="Remove Instance">&#10006;</a>`
}); });
add_instance_listeners(row);
elems.actor.value = null; elems.actor.value = null;
elems.inbox.value = null; elems.inbox.value = null;
elems.followid.value = null; elems.followid.value = null;
@ -82,12 +105,37 @@ async function req_response(domain, accept) {
instances = await request("GET", `v1/instance`, null); instances = await request("GET", `v1/instance`, null);
instances.forEach((instance) => { instances.forEach((instance) => {
if (instance.domain === domain) { if (instance.domain === domain) {
append_table_row(document.getElementById("instances"), instance.domain, { row = append_table_row(document.getElementById("instances"), instance.domain, {
domain: `<a href="https://${instance.domain}/" target="_new">${instance.domain}</a>`, domain: `<a href="https://${instance.domain}/" target="_new">${instance.domain}</a>`,
software: instance.software, software: instance.software,
date: get_date_string(instance.created), date: get_date_string(instance.created),
remove: `<a href="#" onclick="del_instance('${instance.domain}')" title="Remove Instance">&#10006;</a>` remove: `<a href="#" title="Remove Instance">&#10006;</a>`
}); });
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);
}
}

View file

@ -6,17 +6,26 @@ function create_ban_object(name, reason, note) {
text += `<textarea id="${name}-reason" class="reason">${reason}</textarea>\n`; text += `<textarea id="${name}-reason" class="reason">${reason}</textarea>\n`;
text += `<label for="${name}-note" class="note">Note</label>\n`; text += `<label for="${name}-note" class="note">Note</label>\n`;
text += `<textarea id="${name}-note" class="note">${note}</textarea>\n`; text += `<textarea id="${name}-note" class="note">${note}</textarea>\n`;
text += `<input type="button" value="Update" onclick="update_ban(\"${name}\"")">`; text += `<input class="update-ban" type="button" value="Update">`;
text += '</details>'; text += '</details>';
return text; return text;
} }
async function ban() { function add_row_listeners(row) {
var table = document.querySelector("table"); row.querySelector(".update-ban").addEventListener("click", async (event) => {
var row = table.insertRow(-1); await update_ban(row.id);
});
row.querySelector(".remove a").addEventListener("click", async (event) => {
event.preventDefault();
await unban(row.id);
});
}
async function ban() {
var elems = { var elems = {
name: document.getElementById("new-name"), name: document.getElementById("new-name"),
reason: document.getElementById("new-reason"), reason: document.getElementById("new-reason"),
@ -42,12 +51,14 @@ async function ban() {
return 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), name: create_ban_object(ban.name, ban.reason, ban.note),
date: get_date_string(ban.created), date: get_date_string(ban.created),
remove: `<a href="#" onclick="unban('${ban.domain}')" title="Unban software">&#10006;</a>` remove: `<a href="#" title="Unban software">&#10006;</a>`
}); });
add_row_listeners(row);
elems.name.value = null; elems.name.value = null;
elems.reason.value = null; elems.reason.value = null;
elems.note.value = null; elems.note.value = null;
@ -93,3 +104,16 @@ async function unban(name) {
document.getElementById(name).remove(); 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);
}

View file

@ -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() { async function add_user() {
var elems = { var elems = {
username: document.getElementById("new-username"), username: document.getElementById("new-username"),
@ -31,13 +40,15 @@ async function add_user() {
return return
} }
append_table_row(document.getElementById("users"), user.username, { var row = append_table_row(document.querySelector("fieldset.section table"), user.username, {
domain: user.username, domain: user.username,
handle: user.handle, handle: user.handle ? self.handle : "n/a",
date: get_date_string(user.created), date: get_date_string(user.created),
remove: `<a href="#" onclick="del_user('${user.username}')" title="Delete User">&#10006;</a>` remove: `<a href="#" title="Delete User">&#10006;</a>`
}); });
add_row_listeners(row);
elems.username.value = null; elems.username.value = null;
elems.password.value = null; elems.password.value = null;
elems.password2.value = null; elems.password2.value = null;
@ -58,3 +69,16 @@ async function del_user(username) {
document.getElementById(username).remove(); 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);
}

View file

@ -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() { async function add_whitelist() {
var domain_elem = document.getElementById("new-domain"); var domain_elem = document.getElementById("new-domain");
var domain = domain_elem.value.trim(); var domain = domain_elem.value.trim();
@ -15,12 +23,14 @@ async function add_whitelist() {
return return
} }
append_table_row(document.getElementById("whitelist"), item.domain, { var row = append_table_row(document.getElementById("whitelist"), item.domain, {
domain: item.domain, domain: item.domain,
date: get_date_string(item.created), date: get_date_string(item.created),
remove: `<a href="#" onclick="del_whitelist('${item.domain}')" title="Remove whitelisted domain">&#10006;</a>` remove: `<a href="#" title="Remove whitelisted domain">&#10006;</a>`
}); });
add_row_listeners(row);
domain_elem.value = null; domain_elem.value = null;
document.querySelector("details.section").open = false; document.querySelector("details.section").open = false;
} }
@ -37,3 +47,16 @@ async function del_whitelist(domain) {
document.getElementById(domain).remove(); 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);
}