2023-07-02 16:05:02 +00:00
|
|
|
const q = (selector, elem = document) => elem.querySelector(selector);
|
|
|
|
const t = (templateSelector, element) =>
|
|
|
|
q(templateSelector).content.cloneNode(true).querySelector(element);
|
|
|
|
const onReady = (f) => {
|
|
|
|
if (document.readyState === "complete") {
|
|
|
|
f();
|
|
|
|
} else {
|
|
|
|
document.addEventListener("DOMContentLoaded", f);
|
|
|
|
}
|
|
|
|
};
|
2022-07-26 03:59:58 +00:00
|
|
|
|
|
|
|
const populateRedirects = async (redirKey) => {
|
2023-07-02 16:05:02 +00:00
|
|
|
const status = q("main #status-message");
|
|
|
|
|
|
|
|
let redirects;
|
|
|
|
try {
|
|
|
|
redirects = await fetch("/redirects.json", {
|
|
|
|
headers: { authorization: `Bearer ${redirKey}` },
|
|
|
|
})
|
|
|
|
.then((r) => r.json())
|
|
|
|
.catch();
|
|
|
|
} catch (e) {
|
|
|
|
status.textContent =
|
|
|
|
"You are not authorized to fetch the list of redirects.";
|
|
|
|
return;
|
|
|
|
}
|
2022-07-26 03:59:58 +00:00
|
|
|
|
2023-07-02 16:05:02 +00:00
|
|
|
status.style.display = "none";
|
2022-07-26 03:59:58 +00:00
|
|
|
|
2023-07-02 16:05:02 +00:00
|
|
|
const table = t("template#redirect-table", "table");
|
|
|
|
const body = q("tbody", table);
|
|
|
|
q("main").appendChild(table);
|
2022-07-26 03:59:58 +00:00
|
|
|
|
|
|
|
for (const redirect of redirects) {
|
2023-07-02 16:05:02 +00:00
|
|
|
const deleteBody = new URLSearchParams();
|
|
|
|
deleteBody.append("path", redirect.path);
|
|
|
|
|
|
|
|
const row = t("template#redirect-row", "tr");
|
|
|
|
const rowEntries = row.querySelectorAll("td");
|
|
|
|
|
|
|
|
rowEntries[0].querySelector("a").href = `/${redirect.path}`;
|
|
|
|
rowEntries[0].querySelector("pre").textContent = redirect.path;
|
|
|
|
|
|
|
|
rowEntries[1].querySelector("a").href = redirect.target_location;
|
|
|
|
rowEntries[1].querySelector("a").textContent = redirect.target_location;
|
|
|
|
|
|
|
|
rowEntries[2].textContent = redirect.redirect_code;
|
|
|
|
rowEntries[3]
|
|
|
|
.querySelector("button")
|
|
|
|
.addEventListener("click", async (e) => {
|
|
|
|
await fetch("/shorten", {
|
|
|
|
method: "DELETE",
|
|
|
|
headers: {
|
|
|
|
"content-type": "application/x-www-form-urlencoded",
|
|
|
|
authorization: `Bearer ${redirKey}`,
|
|
|
|
},
|
|
|
|
body: deleteBody,
|
|
|
|
});
|
|
|
|
row.remove();
|
|
|
|
});
|
|
|
|
|
|
|
|
body.appendChild(row);
|
2022-07-26 03:59:58 +00:00
|
|
|
}
|
|
|
|
};
|
|
|
|
|
2023-07-02 16:05:02 +00:00
|
|
|
const setupRedirectForm = (redirKey) => {
|
|
|
|
const form = t("template#redirect-form", "form");
|
2022-07-26 03:59:58 +00:00
|
|
|
|
|
|
|
form.addEventListener("submit", async (e) => {
|
|
|
|
e.preventDefault();
|
|
|
|
|
|
|
|
const data = new URLSearchParams();
|
|
|
|
const path = form.querySelector("#path").value;
|
|
|
|
if (path) data.append("path", path);
|
|
|
|
data.append("target", form.querySelector("#url").value);
|
|
|
|
|
|
|
|
const response = await fetch("/shorten", {
|
|
|
|
method: "POST",
|
|
|
|
headers: {
|
|
|
|
"content-type": "application/x-www-form-urlencoded",
|
|
|
|
authorization: `Bearer ${redirKey}`,
|
|
|
|
},
|
|
|
|
body: data,
|
|
|
|
}).then((r) => r.json());
|
|
|
|
|
|
|
|
if (response.error) alert(response.error);
|
|
|
|
|
|
|
|
window.location.reload();
|
|
|
|
});
|
|
|
|
|
|
|
|
q("main").appendChild(form);
|
|
|
|
};
|
|
|
|
|
2023-07-02 16:05:02 +00:00
|
|
|
onReady(async () => {
|
|
|
|
const redirKey = window.localStorage.getItem("char.lt/redirect-key");
|
|
|
|
if (redirKey == null) {
|
|
|
|
// TODO: Show a form entry for setting the redirect key
|
|
|
|
return;
|
|
|
|
}
|
2022-07-26 03:59:58 +00:00
|
|
|
|
2023-07-02 16:05:02 +00:00
|
|
|
await populateRedirects(redirKey);
|
|
|
|
setupRedirectForm(redirKey);
|
2022-07-26 03:59:58 +00:00
|
|
|
});
|