From 8e769996e13ace583d484358959502122eb7395c Mon Sep 17 00:00:00 2001 From: Enstrayed <48845980+Enstrayed@users.noreply.github.com> Date: Sun, 23 Jun 2024 12:54:57 -0700 Subject: [PATCH] working changes for new auth --- Caddyfile | 1 + etydFrontend/_static/etyd.js | 58 ++++++++++++++++++++------ etydFrontend/_static/index.css | 7 +++- etydFrontend/index.html | 75 ++++++++++++---------------------- liberals/auth.js | 36 ++++++++++++++++ routes/etyd.js | 12 ++---- routes/mailjet.js | 7 ++-- 7 files changed, 121 insertions(+), 75 deletions(-) create mode 100644 liberals/auth.js diff --git a/Caddyfile b/Caddyfile index eb42a99..aea8b6c 100644 --- a/Caddyfile +++ b/Caddyfile @@ -10,6 +10,7 @@ } handle @staticpaths { + respond /favicon.ico 204 root ./etydFrontend file_server } diff --git a/etydFrontend/_static/etyd.js b/etydFrontend/_static/etyd.js index 5879b9d..79483e7 100644 --- a/etydFrontend/_static/etyd.js +++ b/etydFrontend/_static/etyd.js @@ -1,11 +1,22 @@ -//Firefox check window.onload = function() { - document.getElementById('resultfeed').value = "hii :3" if (navigator.userAgent.includes("Firefox")) { - document.getElementById('resultfeed').value += `\nClipboard functionality does not work on Firefox.` - document.getElementById('clipboard1').disabled = true - document.getElementById('clipboard2').disabled = true + document.getElementById('resultfeed').value += `\nClipboard buttons only work on Firefox >127.` } + + // Event listeners can only be added after the page is loaded + document.getElementById("actiondropdown").addEventListener("change", function() { + if (document.getElementById("actiondropdown").value === "POST") { + document.getElementById("randomizationtoggle").disabled = false + document.getElementById("valuefield").disabled = false + } else if (document.getElementById("actiondropdown").value === "DELETE") { + document.getElementById("randomizationtoggle").disabled = true + document.getElementById("randomizationtoggle").checked = false + randomUrlTick() + document.getElementById("valuefield").disabled = true + } else { + console.error("UI Code Error: Action dropdown event listener function reached impossible state") + } + }) } function makeRandomHex(amount) { @@ -19,6 +30,8 @@ function makeRandomHex(amount) { return result } + + function randomUrlTick() { if (document.getElementById("randomizationtoggle").checked == true) { document.getElementById("targetfield").disabled = true @@ -29,9 +42,9 @@ function randomUrlTick() { } } -function buttonCopyResult() { - navigator.clipboard.writeText(`${document.location.href}${document.getElementById("urlfield").value}`) -} +// function buttonCopyResult() { +// navigator.clipboard.writeText(`${document.location.href}${document.getElementById("urlfield").value}`) +// } function buttonFillFromClipboard() { navigator.clipboard.readText().then(res => { @@ -39,9 +52,29 @@ function buttonFillFromClipboard() { }) } -function postData() { - fetch("http://nrdesktop:8081/etydwrite", { - method: "POST", +// Changes the buttons text to OK for 500ms for action feedback +// "internal" in this context just means not called from the page +function internalButtonConfirmation(element) { + let normalValue = document.getElementById(element).innerHTML + document.getElementById(element).innerHTML = "Ok" + setTimeout(function() { + document.getElementById(element).innerHTML = normalValue + }, 500) +} + +function buttonCopyUrl() { + navigator.clipboard.writeText(`this doesn't work rn lol`) + internalButtonConfirmation("buttonCopyUrl") +} + +function buttonClearLog() { + document.getElementById("resultfeed").value = "" + internalButtonConfirmation("buttonClearLog") +} + +function submitData() { + fetch(`http://nrdesktop:8081/etyd${document.getElementById("targetfield").value}`, { + method: document.getElementById("actiondropdown").value, mode: "cors", headers: { "Authorization": document.getElementById("authfield").value @@ -57,5 +90,4 @@ function postData() { }).catch(error => { document.getElementById("resultfeed").value += `\nError: ${error}` }) -} - +} \ No newline at end of file diff --git a/etydFrontend/_static/index.css b/etydFrontend/_static/index.css index 66ddd02..b4b4698 100644 --- a/etydFrontend/_static/index.css +++ b/etydFrontend/_static/index.css @@ -11,6 +11,10 @@ body { margin-right: 1em; } +.marginbottom1em { + margin-bottom: 1em; +} + .resultfeed { height: 100%; } @@ -30,7 +34,8 @@ body { input, select, textarea, button { background: none; color: white; - border: 2px solid white; + border: 1px solid white; + padding: 1px 2px; } input:disabled, button:disabled { diff --git a/etydFrontend/index.html b/etydFrontend/index.html index 4b9026d..64e4571 100644 --- a/etydFrontend/index.html +++ b/etydFrontend/index.html @@ -1,3 +1,4 @@ + @@ -7,66 +8,44 @@ etyd.cc -

etyd.cc URL Shortener

-
-
+
+
- -
-
+ + + +
+ + +
-
-
+
+ + +
-
- -
+
+ + + +
-
- - - - -

+
+ + + +
-
- -
- - - -
-
-

Instructions

-

- 1. Enter your API Key in the 'Authorization' field
- 2. Enter the shortened URL you want to act upon under the 'URL' field
- 3. Enter the URL that the user will be redirected to under the 'Value' field
- 4. Change 'Action' depending if you want to create or delete a URL
- 5. Press 'POST Data' to submit the form to the server -

-
- -
-

Status Code Reference

-

- 400: Bad Request - You will see this if you try and delete a non-existent URL
- 401: Unauthorized - Did you enter your API key?
- 409: Conflict - The entered URL already exists, tick 'Random' and try again
- 500: Internal Server Error - If this happens something has gone very wrong
- 502: Bad Gateway - If you see this the backend is down/unreachable by Caddy
-

-
diff --git a/liberals/auth.js b/liberals/auth.js new file mode 100644 index 0000000..115523c --- /dev/null +++ b/liberals/auth.js @@ -0,0 +1,36 @@ +const { globalConfig } = require("../index.js") + +async function checkToken(token,scope) { + return await fetch(`http://${globalConfig.couchdb.host}/auth/sessions`, { + headers: { + "Authorization": `Basic ${btoa(globalConfig.couchdb.authorization)}` + } + }).then(fetchRes => { + + // CouchDB should only ever return 200/304 for success so this should work + // https://docs.couchdb.org/en/stable/api/document/common.html#get--db-docid + if (fetchRes.status !== 200 || fetchRes.status !== 304) { + console.log(`ERROR: auth.js: Database request returned ${fetchRes.status}`) + return false + } else { + + return fetchRes.json().then(dbRes => { + + if (dbRes.sessions[token] == undefined) { // If the token is not on the sessions list then reject + return false + } else if (dbRes.sessions[token].scopes.includes(scope)) { // If the token is on the seesions list and includes the scope then accept + return true + } else { // Otherwise reject + return false + } + + }) + } + + }).catch(error => { + console.log("ERROR: auth.js: " + error) + return false + }) +} + +module.exports = {checkToken} \ No newline at end of file diff --git a/routes/etyd.js b/routes/etyd.js index ca39d10..87ed09a 100644 --- a/routes/etyd.js +++ b/routes/etyd.js @@ -1,5 +1,5 @@ const { app, globalConfig } = require("../index.js") // Get globals from index -const { checkAuthorization } = require("../liberals/authorization.js") +const { checkToken } = require("../liberals/auth.js") app.get("/etyd*", (rreq,rres) => { fetch(`http://${globalConfig.couchdb.host}/etyd${rreq.path.replace("/etyd","")}`, { @@ -30,9 +30,8 @@ app.delete("/etyd*", (rreq,rres) => { if (rreq.get("Authorization") === undefined) { rres.sendStatus(400) } else { - checkAuthorization(globalConfig.etyd.authKeysDoc,rreq.get("Authorization")).then(authRes => { + checkToken(rreq.get("Authorization"),"etyd").then(authRes => { if (authRes === false) { - console.log(`${rreq.get("cf-connecting-ip")} DELETE ${rreq.path} returned 401`) // Log unauthorized requests rres.sendStatus(401) } else if (authRes === true) { // Authorization successful @@ -82,14 +81,12 @@ app.post("/etyd*", (rreq,rres) => { if (rreq.get("Authorization") === undefined) { rres.sendStatus(400) } else { - checkAuthorization(globalConfig.etyd.authKeysDoc,rreq.get("Authorization")).then(authRes => { + checkToken(rreq.get("Authorization"),"etyd").then(authRes => { if (authRes === false) { - console.log(`${rreq.get("cf-connecting-ip")} POST ${rreq.path} returned 401`) // Log unauthorized requests rres.sendStatus(401) } else if (authRes === true) { // Authorization successful if (rreq.body["url"] == undefined) { - console.log(`${rreq.get("cf-connecting-ip")} POST ${rreq.path} returned 400 KEY: ${rreq.get("Authorization")}`) rres.sendStatus(400) } else { fetch(`http://${globalConfig.couchdb.host}/etyd${rreq.path.replace("/etyd", "")}`, { @@ -106,12 +103,10 @@ app.post("/etyd*", (rreq,rres) => { switch(dbRes.status) { case 409: - console.log(`${rreq.get("cf-connecting-ip")} POST ${rreq.path} returned 409 KEY: ${rreq.get("Authorization")}`) rres.sendStatus(409) break; case 201: - console.log(`${rreq.get("cf-connecting-ip")} POST ${rreq.path} returned 200 KEY: ${rreq.get("Authorization")}`) rres.status(200).send(rreq.path.replace("/etyd", "")) break; @@ -132,5 +127,4 @@ app.post("/etyd*", (rreq,rres) => { }) - module.exports = {app} // export routes to be imported by index for execution \ No newline at end of file diff --git a/routes/mailjet.js b/routes/mailjet.js index b26e9d5..19d5e35 100644 --- a/routes/mailjet.js +++ b/routes/mailjet.js @@ -1,9 +1,9 @@ const { app, globalConfig } = require("../index.js") // Get globals from index -const { checkAuthorization } = require("../liberals/authorization.js") +const { checkToken } = require("../liberals/auth.js") app.post("/sendemail", (rreq,rres) => { - checkAuthorization(globalConfig.mailjet.authKeysDoc,rreq.get("Authorization")).then(authRes => { + checkToken(rreq.get("Authorization"),"mailjet").then(authRes => { if (authRes === false) { // If the supplied authorization is invalid or an error occured console.log(`${rreq.get("cf-connecting-ip")} POST /sendemail returned 401`) // Log the request @@ -21,8 +21,7 @@ app.post("/sendemail", (rreq,rres) => { "Messages": [ { "From": { - "Email": globalConfig.mailjet.senderAddress, - "Name": globalConfig.mailjet.senderName, + "Email": globalConfig.mailjet.senderAddress }, "To": [ {