+ const channelId = sanitise(data);
+ const messageId = sanitise(row.message_id);
+ return `
Loading...
@@ -98,7 +103,8 @@ async function initContentTable() {
orderable: false,
className: "p-0",
render: function(data, type, row) {
- return `
`
+ const embedColour = sanitise(row.subscription.embed_colour);
+ return `
`
}
}
]
@@ -166,17 +172,18 @@ async function deleteSelectedContent() {
const rows = contentTable.rows(".selected").data().toArray();
const names = rows.map(row => { return row.title });
const namesString = arrayToHtmlList(names, true).prop("outerHTML");
- const multiple = names.length > 1;
+ const isMany = names.length > 1;
- await confirmDeleteModal(
- `Confirm ${multiple ? "Multiple Deletions" : "Deletion"}`,
- `Do you wish to permanently delete ${multiple ? "these" : "this"}
${names.length} content${multiple ? "s" : ""}?
${namesString}`,
+ await confirmationModal(
+ `Delete ${isMany ? "Many Tracked Contents" : "a Tracked Content"}`,
+ `Do you wish to permanently delete ${isMany ? "these" : "this"}
${names.length} Tracked Content${isMany ? "s" : ""}?
${namesString}`,
+ "danger",
async () => {
rows.forEach(async row => { await deleteTrackedContent(row.id) });
showToast(
"danger",
- `Deleted ${names.length} Content${multiple ? "s" : ""}`,
+ `Deleted ${names.length} Content${isMany ? "s" : ""}`,
`${arrayToHtmlList(names, false).prop("outerHTML")}`,
12000
);
diff --git a/apps/static/js/home/filters.js b/apps/static/js/home/filters.js
index b28191d..c5ca0f1 100644
--- a/apps/static/js/home/filters.js
+++ b/apps/static/js/home/filters.js
@@ -40,7 +40,8 @@ async function initFiltersTable() {
title: "Name",
data: "name",
render: function(data, type, row) {
- return `
`
+ const name = sanitise(data);
+ return `
`
}
},
{
@@ -55,7 +56,7 @@ async function initFiltersTable() {
case 5: return "Fuzzy Match";
default:
console.error(`unknown matching algorithm '${data}'`);
- return data;
+ return sanitise(data);
}
}
},
@@ -252,12 +253,14 @@ $(document).on("selectedServerChange", async function() {
$("#deleteEditFilter").on("click", async function() {
const filterId = parseInt($("#filterId").val());
const filter = filtersTable.row(function(idx, row) { return row.id === filterId }).data();
+ const filterName = sanitise(filter.name);
$("#filterFormModal").modal("hide");
- await confirmDeleteModal(
- "Confirm Deletion",
- `Do you wish to permanently delete
${filter.name}?`, // FIX: potential xss attack
+ await confirmationModal(
+ "Delete a Filter",
+ `Do you wish to permanently delete
${filterName}?`,
+ "danger",
async () => {
await deleteFilter(filterId);
await loadFilters(getCurrentlyActiveServer().guild_id);
@@ -265,7 +268,7 @@ $("#deleteEditFilter").on("click", async function() {
showToast(
"danger",
"Deleted a Filter",
- filter.name, // FIX: potential xss attack
+ filterName,
12000
);
},
@@ -279,27 +282,29 @@ async function deleteSelectedFilters() {
const rows = filtersTable.rows(".selected").data().toArray();
const names = rows.map(row => row.name);
const namesString = arrayToHtmlList(names, true).prop("outerHTML");
- const multiple = names.length > 1;
+ const isMany = names.length > 1;
- await confirmDeleteModal(
- `Confirm ${multiple ? "Multiple Deletions" : "Deletion"}`,
- `Do you wish to permanently delete ${multiple ? "these" : "this"}
${names.length} filter${multiple ? "s" : ""}?
${namesString}`,
+ await confirmationModal(
+ `Delete ${isMany ? "Many Filters" : "a Filter"}`,
+ `Do you wish to permanently delete ${isMany ? "these" : "this"}
${names.length} filter${isMany ? "s" : ""}?
${namesString}`,
+ "danger",
async () => {
rows.forEach(async row => { await deleteFilter(row.id) });
-
+
showToast(
"danger",
- `Delete ${names.length} Subscription${multiple ? "s" : ""}`,
+ `Delete ${names.length} Subscription${isMany ? "s" : ""}`,
`${arrayToHtmlList(names, false).prop("outerHTML")}`,
12000
);
-
+
// Multi-deletion can take time, this timeout ensures the refresh is accurate
setTimeout(async () => {
await loadFilters(getCurrentlyActiveServer().guild_id);
}, 600);
},
null
+
);
}
diff --git a/apps/static/js/home/index.js b/apps/static/js/home/index.js
index 8e00c97..4a6f07f 100644
--- a/apps/static/js/home/index.js
+++ b/apps/static/js/home/index.js
@@ -155,23 +155,33 @@ $(document).ready(function() {
});
});
-async function confirmDeleteModal(title, description, acceptFunc, declineFunc) {
- let $modal = $("#confirmDeleteModal");
+async function confirmationModal(title, bodyText, style, acceptFunc, declineFunc) {
+ let $modal = $("#confirmationModal");
+
+ // Ensure valid style and apply it to the confirm button
+ if (!["danger", "success", "warning", "info", "primary", "secondary"].includes(style)) {
+ throw new Error(`${style} is not a valid style`);
+ }
+ $modal.find(".modal-confirm-btn").addClass(`btn-${style}`);
+
$modal.find(".modal-title").text(title);
- $modal.find(".modal-body > p").html(description);
- $modal.find(".confirm-delete-btn").off("click").on("click", async function(e) {
+ $modal.find(".modal-body > p").html(bodyText);
+
+ $modal.find(".modal-confirm-btn").off("click").on("click", async function(e) {
await acceptFunc()
$modal.modal("hide");
});
- $modal.find(".dismiss-delete-btn").off("click").on("click", async function(e) {
+
+ $modal.find(".modal-dismiss-btn").off("click").on("click", async function(e) {
if (declineFunc) await declineFunc();
$modal.modal("hide");
});
+
$modal.modal("show");
}
function arrayToHtmlList(array, bold=false) {
- $ul = $("
");
+ $ul = $("").addClass("mb-0");
array.forEach(item => {
let $li = $("- ");
diff --git a/apps/static/js/home/servers.js b/apps/static/js/home/servers.js
index 3c18363..2312e4d 100644
--- a/apps/static/js/home/servers.js
+++ b/apps/static/js/home/servers.js
@@ -35,7 +35,7 @@ function addToLoadedServers(server, selectNew=true) {
loadedServers[id] = server;
// Display the loaded server
- addServerTemplate(id, server.guild_id, server.name, server.icon, server.permissions, server.owner);
+ addServerTemplate(id, sanitise(server.guild_id), sanitise(server.name), sanitise(server.icon), sanitise(server.permissions), sanitise(server.owner));
// Select the newly added server
if (selectNew) {
@@ -90,10 +90,10 @@ async function loadServerOptions() {
servers.forEach(server => {
$("#serverOptions").append($("