500 Callback-Token-${fetchRes1.error}`)
+ } else { // Assumed success
+ fetch(globalConfig.oidc.userinfoUrl, { // Call userinfo endpoint at IdP using token provided during previous step
+ headers: { "Authorization": `Bearer ${fetchRes1.access_token}`}
+ }).then(fetchRes2 => {
+ if (fetchRes2.ok === false) { // Fetch to userinfo endpoint succeded but resulted in error (usually 401)
+ logRequest(rres,rreq,500,`Callback-Userinfo-${fetchRes2.status}`)
+ rres.status(500).send(`An error occured during login, a token was not created.500 Callback-Userinfo-${fetchRes2.status}`)
+ } else {
+ fetchRes2.json().then(fetchRes2 => {
+ rres.send(fetchRes2)
+ })
+ }
+ }).catch(fetchErr2 => { // Fetch to userinfo endpoint failed for some other reason
+ logRequest(rres,rreq,500,`Callback-Fetch2-${fetchErr2}`)
+ rres.status(500).send(`An error occured during login, a token was not created.500 Callback-Fetch2-${fetchErr2}`)
+ })
+ }
+ })
+ }).catch(fetchErr1 => { // Fetch to token endpoint failed for some other reason
+ logRequest(rres,rreq,500,`Callback-Fetch1-${fetchErr1}`)
+ rres.status(500).send(`An error occured during login, a token was not created.500 Callback-Fetch1-${fetchErr1}`)
+ })
})
app.post("/api/auth/token", (rreq,rres) => {
diff --git a/routes/debug.js b/routes/debug.js
index c155ad5..c5c350e 100644
--- a/routes/debug.js
+++ b/routes/debug.js
@@ -12,4 +12,8 @@ app.get("/api/debugtokencheck", (rreq,rres) => {
})
})
+app.get("/api/debugurl", (rreq,rres) => {
+ rres.send(`${rreq.protocol}://${rreq.get("Host")}`)
+})
+
export { app }
\ No newline at end of file
--
2.49.1
From c868c9bc09821966baa69e1aa0ba31192559202a Mon Sep 17 00:00:00 2001
From: Enstrayed <48845980+Enstrayed@users.noreply.github.com>
Date: Sun, 20 Apr 2025 20:15:02 -0700
Subject: [PATCH 07/12] groundwork for writing new tokens to db
---
liberals/misc.js | 34 +++++++++++++++++++++++++++++++++-
routes/auth.js | 27 ++++++++++++++++++---------
2 files changed, 51 insertions(+), 10 deletions(-)
diff --git a/liberals/misc.js b/liberals/misc.js
index b12a8f6..5fafd90 100644
--- a/liberals/misc.js
+++ b/liberals/misc.js
@@ -20,4 +20,36 @@ function randomStringBase62(length) {
return returnstring
}
-export { randomStringBase16, randomStringBase62 }
\ No newline at end of file
+function getHumanReadableUserAgent(useragent) {
+ let formattedua = useragent.replace(/[\/()]/g," ").split(" ")
+ let os = ""
+ let browser = ""
+
+ if (formattedua.includes("Windows")) {
+ os += "Windows"
+ } else if (formattedua.includes("Macintosh")) {
+ os += "macOS"
+ } else if (formattedua.includes("iPhone")) {
+ os += "iOS"
+ } else if (formattedua.includes("Android")) {
+ os += "Android"
+ } else if (formattedua.includes("Linux")) {
+ os += "Linux"
+ } else {
+ os += "Other"
+ }
+
+ if (formattedua.includes("Firefox")) {
+ browser += "Firefox"
+ } else if (formattedua.includes("Chrome")) {
+ browser += "Chrome"
+ } else if (formattedua.includes("Safari")) {
+ browser += "Safari"
+ } else {
+ browser += "Other"
+ }
+
+ return `${os} ${browser}`
+}
+
+export { randomStringBase16, randomStringBase62, getHumanReadableUserAgent }
\ No newline at end of file
diff --git a/routes/auth.js b/routes/auth.js
index b78b00e..cec9dc7 100644
--- a/routes/auth.js
+++ b/routes/auth.js
@@ -1,6 +1,7 @@
import { app, db, globalConfig } from "../index.js" // Get globals from index
import { checkTokenNew } from "../liberals/auth.js"
import { logRequest } from "../liberals/logging.js"
+import { randomStringBase62, getHumanReadableUserAgent } from "../liberals/misc.js"
app.get("/api/auth/whoami", (rreq,rres) => {
rres.send("Non functional endpoint")
@@ -18,30 +19,38 @@ app.get("/api/auth/callback", (rreq,rres) => {
}).then(fetchRes1 => {
fetchRes1.json().then(fetchRes1 => { // Convert response to JSON then continue
if (fetchRes1.error) { // Fetch to token endpoint succeded but resulted in error, usually because the provided code is invalid
- logRequest(rres,rreq,500,`Callback-Token-${fetchRes1.error}`)
- rres.status(500).send(`An error occured during login, a token was not created.500 Callback-Token-${fetchRes1.error}`)
+ localError500(`Callback-Token-${fetchRes1.error}`)
} else { // Assumed success
fetch(globalConfig.oidc.userinfoUrl, { // Call userinfo endpoint at IdP using token provided during previous step
headers: { "Authorization": `Bearer ${fetchRes1.access_token}`}
}).then(fetchRes2 => {
if (fetchRes2.ok === false) { // Fetch to userinfo endpoint succeded but resulted in error (usually 401)
- logRequest(rres,rreq,500,`Callback-Userinfo-${fetchRes2.status}`)
- rres.status(500).send(`An error occured during login, a token was not created.500 Callback-Userinfo-${fetchRes2.status}`)
+ localError500(`Callback-Userinfo-${fetchRes2.status}`)
} else {
fetchRes2.json().then(fetchRes2 => {
- rres.send(fetchRes2)
+ let newToken = randomStringBase62(64)
+ let newExpiration = Date.now() + 86400
+ let newComment = `Login token for ${getHumanReadableUserAgent(rreq.get("User-Agent"))} on ${rreq.get("cf-connecting-ip") ?? rreq.ip}`
+ db`select * from users where oidc_username = ${fetchRes2.username};`.then(dbRes1 => {
+ db`insert into sessions (token,owner,scopes,expires,comment) values (${newToken},${dbRes1[0]?.id},${fetchRes2.enstrayedapi_scopes},${newExpiration},${newComment})`.then(dbRes2 => {
+ rres.send(dbRes2)
+ })
+ })
})
}
}).catch(fetchErr2 => { // Fetch to userinfo endpoint failed for some other reason
- logRequest(rres,rreq,500,`Callback-Fetch2-${fetchErr2}`)
- rres.status(500).send(`An error occured during login, a token was not created.500 Callback-Fetch2-${fetchErr2}`)
+ localError500(`Callback-Fetch2-${fetchErr2}`)
})
}
})
}).catch(fetchErr1 => { // Fetch to token endpoint failed for some other reason
- logRequest(rres,rreq,500,`Callback-Fetch1-${fetchErr1}`)
- rres.status(500).send(`An error occured during login, a token was not created.500 Callback-Fetch1-${fetchErr1}`)
+ localError500(`Callback-Fetch-${fetchErr1}`)
})
+
+ function localError500(code) {
+ logRequest(rres,rreq,500,code)
+ rres.status(500).send(`An error occured during login, a token was not created.500 ${code}`)
+ }
})
app.post("/api/auth/token", (rreq,rres) => {
--
2.49.1
From 2ad8d04c9961922a21d43ffb74d26cdf6e16b13d Mon Sep 17 00:00:00 2001
From: Enstrayed <48845980+Enstrayed@users.noreply.github.com>
Date: Tue, 22 Apr 2025 09:22:54 -0700
Subject: [PATCH 08/12] readme will need rewritten later
---
README.md | 53 ++---------------------------------------------------
1 file changed, 2 insertions(+), 51 deletions(-)
diff --git a/README.md b/README.md
index f3b9c36..903d3f7 100644
--- a/README.md
+++ b/README.md
@@ -8,49 +8,12 @@ This file contains documentation relevant for development and deployment, but no
If you would like to report a bug or security issue, please open a GitHub issue. If you are the operator of a service this application accesses, use the contact information provided during registration with your service to contact me directly.
## Configuration
-The configuration is downloaded from CouchDB on startup, however two environment variables must be set to specify the URL of the CouchDB server and the credentials for accessing it:
-| Variable | Required? | Purpose |
-|--------------|----------------------|-----------------------------------------------------------------------------------------------------|
-| `API_PORT` | No, defaults to 8081 | Sets the port the server will listen on |
-| `API_DBHOST` | Yes | Complete URL of the CouchDB instance, including port and protocol |
-| `API_DBCRED` | Yes | Credentials to access the CouchDB instance, in Basic Authentication format e.g. `username:password` |
-Retrieves, creates or deletes entries for the etyd.cc URL shortener. Replace * in the URL for the target of the request.
diff --git a/website/static/posts.css b/website/static/posts.css index 3df6078..656b127 100644 --- a/website/static/posts.css +++ b/website/static/posts.css @@ -50,9 +50,10 @@ h2 { align-items: center; margin-top: 2rem; gap: 1em; + flex-wrap: wrap; } -.inlineheader > span { +.inlineheader > div > span { padding: 0.2rem; color: white; background-color: #f06445; diff --git a/website/static/snow-leopard.svg b/website/static/snow-leopard.svg new file mode 100644 index 0000000..4eb629f --- /dev/null +++ b/website/static/snow-leopard.svg @@ -0,0 +1,20 @@ + + + \ No newline at end of file -- 2.49.1 From e59162ae04424105b37f74857d6e9ec82e404e01 Mon Sep 17 00:00:00 2001 From: Enstrayed <48845980+Enstrayed@users.noreply.github.com> Date: Sat, 26 Apr 2025 06:35:37 -0700 Subject: [PATCH 10/12] new index & icons --- liberals/libnowplaying.js | 4 +- routes/frontpage.js | 4 +- website/idea.txt | 9 --- website/static/bs.ico | Bin 16958 -> 0 bytes website/static/icons/external.svg | 4 ++ website/static/icons/github.svg | 3 + website/static/icons/link.svg | 4 ++ website/static/icons/post.svg | 4 ++ website/static/icons/twitter.svg | 3 + website/static/newindex.css | 79 ++++++++++++++++++++++++ website/static/orange-globe.svg | 3 + website/static/snow-leopard.ico | Bin 0 -> 7753 bytes website/static/snow-leopard.png | Bin 0 -> 7837 bytes website/static/snow-leopard.svg | 2 +- website/templates/newindextemplate.html | 66 ++++++++++++++++++++ 15 files changed, 171 insertions(+), 14 deletions(-) delete mode 100644 website/idea.txt delete mode 100644 website/static/bs.ico create mode 100644 website/static/icons/external.svg create mode 100644 website/static/icons/github.svg create mode 100644 website/static/icons/link.svg create mode 100644 website/static/icons/post.svg create mode 100644 website/static/icons/twitter.svg create mode 100644 website/static/newindex.css create mode 100644 website/static/orange-globe.svg create mode 100644 website/static/snow-leopard.ico create mode 100644 website/static/snow-leopard.png create mode 100644 website/templates/newindextemplate.html diff --git a/liberals/libnowplaying.js b/liberals/libnowplaying.js index 0bfb6a2..3876e18 100644 --- a/liberals/libnowplaying.js +++ b/liberals/libnowplaying.js @@ -27,7 +27,7 @@ async function queryLastfm() { "artUrl": response.recenttracks.track[0].image[3]["#text"], "link": response.recenttracks.track[0].url }, - "html": `I'm listening to
from ${response.recenttracks.track[0].album["#text"]}
View on Last.fmc49}HpX18yzPTSct`&l>N(yxE>
zZ~DWZKGo-6Nx%E_OI^A9rUv1hrRe;*=-g%PbE@pSq~_rV^zHA^zkLXfzDJMpCcDi~
z;G&P|;~%Q2=aFi 9Fbwqoa)U%%3^x{DK;wKD-yUrQ}h*U1&^!x|UIUBtphmpk};r_TLE
zp)hlQmdka_&C@wanp-|eF_u8S8|2}24J
zP6@Brlp~NsLqjAi-y03bzorj2utHlV*5dQOZXKd9G6Y^7?u5PXt%Q4VE;s;CDV@@T
zpDh*L>2YQ^{zYac*oi+>_VwO{E+Gmc;JVz!joUP~MjqziZAyyyBdX=r2zNrE)VG_^
zXf<_pSy1_N<33Hbq!C1p;o*cc;RLk*yA~dYuCL?a%;WEcmGMOiHhMv9S(?H^1!!X2
zRb|1O7qZj!4gx@qhYTUb6&XN*xj{cePHxF*r~8HlqSEZ`?JKzAbqN=$Mc+q}>GIwE
z>9cgwe)~NESokv=?j%Box7QE!S$_d56Nyj-oKKK6(1seOMc^^Q_msd;IY(Cw8!HJY
zhGaNLqtT3z)>fS0Wqfkn&Jep*7D;AZ;xZ7Ai>y**W$mm`TCYU|@fYnjX;2}SX!b5_
z{m*hwJ^e(eu4$d?BwOT(4XWZeu$hyOFM53QL{=Kd1A!q!s_tsmS+_;gCQ1G2Dn=Wm
zu
3sRFtyly05mzl~oiG^RzWT(b`JGJ46de=!^605Xs%PaMWh=|-QR(g_{+&cxD
zl?y$jYqCf4JMR(5{QP{VDy#85;GiJFAIDtuNxjLz=Zyc8B;Zt>i#KQa#cO$B0{(4r
zFQh@LbN=(I)a4B<=Qtd5b$L!r$iny;{hv4@kKnFDYS93QqiIZy-RR|VNZ>|eJCm4>
zVF9#bp{E}