1.2.1: change versioning scheme / avoid unsafe inline javascript

This commit is contained in:
minoplhy 2025-04-12 14:15:32 +07:00
parent 7b5ceb1ce7
commit 61f2c93493
Signed by: minoplhy
GPG Key ID: 41D406044E2434BF
4 changed files with 57 additions and 11 deletions

2
actix/Cargo.lock generated
View File

@ -458,7 +458,7 @@ checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd"
[[package]] [[package]]
name = "chhoto-url" name = "chhoto-url"
version = "1.2.0" version = "1.2.1"
dependencies = [ dependencies = [
"actix-files", "actix-files",
"actix-session", "actix-session",

View File

@ -3,7 +3,7 @@
[package] [package]
name = "chhoto-url" name = "chhoto-url"
version = "1.2.0" version = "1.2.1"
edition = "2021" edition = "2021"
authors = ["Sayantan Santra <sayantan[dot]santra689[at]gmail[dot]com"] authors = ["Sayantan Santra <sayantan[dot]santra689[at]gmail[dot]com"]
license = "mit" license = "mit"

View File

@ -32,8 +32,7 @@
<legend id="logo"><img src="assets/favicon-32.png" width="26px" alt="logo"> Chhoto URL</legend> <legend id="logo"><img src="assets/favicon-32.png" width="26px" alt="logo"> Chhoto URL</legend>
<div class="pure-control-group"> <div class="pure-control-group">
<label for="longUrl">Long URL</label> <label for="longUrl">Long URL</label>
<input type="url" name="longUrl" id="longUrl" placeholder="Please enter a valid URL" <input type="url" name="longUrl" id="longUrl" placeholder="Please enter a valid URL" required />
onblur="addProtocol(this)" required />
</div> </div>
<div class="pure-control-group"> <div class="pure-control-group">
<label for="shortUrl">Short URL (optional)</label> <label for="shortUrl">Short URL (optional)</label>
@ -67,9 +66,9 @@
</div> </div>
<div name="links-div"> <div name="links-div">
<a id="admin-button" href="javascript:getLogin()" hidden>login</a> <a id="admin-button" href="#" hidden>login</a>
&nbsp; &nbsp;
<a id="api-key-button" href="javascript:fetchApiKey()" hidden>API Key</a> <a id="api-key-button" href="#" hidden>API Key</a>
&nbsp; &nbsp;
<a id="version-number" href="https://github.com/minoplhy/chhoto-url" target="_blank" rel="noopener noreferrer" <a id="version-number" href="https://github.com/minoplhy/chhoto-url" target="_blank" rel="noopener noreferrer"
hidden>Source Code</a> hidden>Source Code</a>

View File

@ -30,7 +30,7 @@ const showVersion = async () => {
let version = await getVersion(); let version = await getVersion();
link = document.getElementById("version-number"); link = document.getElementById("version-number");
link.innerText = "v" + version; link.innerText = "v" + version;
link.href = "https://github.com/SinTan1729/chhoto-url/releases/tag/" + version; link.href = "https://github.com/minoplhy/chhoto-url/releases/tag/" + version;
link.hidden = false; link.hidden = false;
} }
@ -38,7 +38,17 @@ const getLogin = async () => {
document.getElementById("container").style.filter = "blur(2px)"; document.getElementById("container").style.filter = "blur(2px)";
document.getElementById("login-dialog").showModal(); document.getElementById("login-dialog").showModal();
document.getElementById("password").focus(); document.getElementById("password").focus();
};
document.addEventListener("DOMContentLoaded", () => {
const adminButton = document.getElementById("admin-button");
if (adminButton) {
adminButton.addEventListener("click", (e) => {
e.preventDefault();
getLogin();
});
} }
});
const refreshData = async () => { const refreshData = async () => {
let res = await fetch(prepSubdir("/api/all")); let res = await fetch(prepSubdir("/api/all"));
@ -65,11 +75,21 @@ const refreshData = async () => {
const displayData = async (data) => { const displayData = async (data) => {
showVersion(); showVersion();
let site = await getSiteUrl(); let site = await getSiteUrl();
admin_button = document.getElementById("admin-button");
const admin_button = document.getElementById("admin-button");
admin_button.innerText = "logout"; admin_button.innerText = "logout";
admin_button.href = "javascript:logOut()"; admin_button.removeAttribute("href");
admin_button.hidden = false; admin_button.hidden = false;
const newButton = admin_button.cloneNode(true);
newButton.href = "#";
admin_button.parentNode.replaceChild(newButton, admin_button);
newButton.addEventListener("click", (e) => {
e.preventDefault();
logOut();
});
apikey_button = document.getElementById("api-key-button"); apikey_button = document.getElementById("api-key-button");
apikey_button.innerText = "API Key" apikey_button.innerText = "API Key"
apikey_button.hidden = false; apikey_button.hidden = false;
@ -105,6 +125,15 @@ const showAlert = async (text, col) => {
controls.appendChild(alertBox); controls.appendChild(alertBox);
} }
document.addEventListener("click", (e) => {
const link = e.target.closest(".copy-short-url");
if (link) {
e.preventDefault();
const shortlink = link.dataset.shortlink;
copyShortUrl(shortlink);
}
});
const TR = (row, site) => { const TR = (row, site) => {
const tr = document.createElement("tr"); const tr = document.createElement("tr");
const longTD = TD(A_LONG(row["longlink"]), "Long URL"); const longTD = TD(A_LONG(row["longlink"]), "Long URL");
@ -153,8 +182,16 @@ const addProtocol = (input) => {
return input; return input;
} }
document.addEventListener("DOMContentLoaded", () => {
const longUrlInput = document.getElementById("longUrl");
longUrlInput.addEventListener("blur", () => {
addProtocol(longUrlInput);
});
});
const A_LONG = (s) => `<a href='${s}'>${s}</a>`; const A_LONG = (s) => `<a href='${s}'>${s}</a>`;
const A_SHORT = (s, t) => `<a href="javascript:copyShortUrl('${s}');">${s}</a>`; const A_SHORT = (s, t) => `<a href="#" class="copy-short-url" data-shortlink="${s}">${s}</a>`;
const A_SHORT_INSECURE = (s, t) => `<a href="${t}/${s}">${s}</a>`; const A_SHORT_INSECURE = (s, t) => `<a href="${t}/${s}">${s}</a>`;
const deleteButton = (shortUrl) => { const deleteButton = (shortUrl) => {
@ -312,6 +349,16 @@ const fetchApiKey = async () => {
} }
} }
document.addEventListener("DOMContentLoaded", () => {
const adminButton = document.getElementById("api-key-button");
if (adminButton) {
adminButton.addEventListener("click", (e) => {
e.preventDefault();
fetchApiKey();
});
}
});
const logOut = async () => { const logOut = async () => {
let reply = await fetch(prepSubdir("/api/logout"), {method: "DELETE"}).then(res => res.text()); let reply = await fetch(prepSubdir("/api/logout"), {method: "DELETE"}).then(res => res.text());
console.log(reply); console.log(reply);