mirror of
https://git.sr.ht/~roxwize/mipilin
synced 2025-01-30 18:53:36 +00:00
admining
Signed-off-by: roxwize <rae@roxwize.xyz>
This commit is contained in:
parent
65c29b0564
commit
ccc894dc33
10 changed files with 111 additions and 41 deletions
7
main.ts
7
main.ts
|
@ -59,7 +59,12 @@ object-src 'none'; base-uri 'none';"
|
|||
return next();
|
||||
});
|
||||
app.use((req, res, next) => {
|
||||
console.log(`${req.ip.padEnd(24)} ${req.method.padStart(8)} ${req.path}`);
|
||||
let s = "";
|
||||
for (const [k, v] of Object.entries(req.query))
|
||||
s += `${k}=${v}&`;
|
||||
s = s.slice(0, -1);
|
||||
|
||||
console.log(`${req.ip.padEnd(24)} ${req.method.padStart(8)} ${req.path}${s ? "?" + s : ""}`);
|
||||
return next();
|
||||
})
|
||||
|
||||
|
|
|
@ -8,7 +8,13 @@ import {
|
|||
users
|
||||
} from "../db/schema.js";
|
||||
import { and, desc, eq, ne } from "drizzle-orm";
|
||||
import { getMoods, render, render404, UserStatus, validateUrl } from "./util.js";
|
||||
import {
|
||||
getMoods,
|
||||
render,
|
||||
render404,
|
||||
UserStatus,
|
||||
validateUrl
|
||||
} from "./util.js";
|
||||
import { PgColumn } from "drizzle-orm/pg-core";
|
||||
import dayjs from "dayjs";
|
||||
|
||||
|
@ -84,9 +90,13 @@ export default async function (app: Express, db: NodePgDatabase) {
|
|||
})
|
||||
.from(journalEntries)
|
||||
.where(
|
||||
user.id === req.session["uid"] || req.session["status"] & UserStatus.MODERATOR
|
||||
user.id === req.session["uid"] ||
|
||||
req.session["status"] & UserStatus.MODERATOR
|
||||
? eq(journalEntries.user, user.id)
|
||||
: and(eq(journalEntries.user, user.id), ne(journalEntries.visibility, 0))
|
||||
: and(
|
||||
eq(journalEntries.user, user.id),
|
||||
ne(journalEntries.visibility, 0)
|
||||
)
|
||||
)
|
||||
.orderBy(desc(journalEntries.date))
|
||||
.limit(5)
|
||||
|
@ -139,11 +149,6 @@ export default async function (app: Express, db: NodePgDatabase) {
|
|||
res.redirect("/login");
|
||||
return;
|
||||
}
|
||||
if (!validateUrl(req.body.website)) {
|
||||
req.flash("error", "The website URL provided is invalid or malformed.");
|
||||
res.redirect(req.get("Referrer") || "/");
|
||||
return;
|
||||
}
|
||||
const { uname } = (
|
||||
await db
|
||||
.select({ uname: users.name })
|
||||
|
@ -154,20 +159,50 @@ export default async function (app: Express, db: NodePgDatabase) {
|
|||
(uname || "") !== req.session["user"] &&
|
||||
!(req.session["status"] & UserStatus.MODERATOR)
|
||||
) {
|
||||
res.redirect(req.get("Referrer") || "/");
|
||||
render404(db, res, req);
|
||||
return;
|
||||
}
|
||||
|
||||
await db
|
||||
.update(profiles)
|
||||
.set({
|
||||
// @ts-expect-error
|
||||
bio: req.body.bio,
|
||||
website: req.body.website
|
||||
})
|
||||
.where(eq(profiles.user, req.session["uid"]));
|
||||
req.flash("success", "Profile updated!");
|
||||
res.redirect("/dashboard");
|
||||
if (req.query.param && (req.session["status"] & UserStatus.MODERATOR)) {
|
||||
switch (req.query.param) {
|
||||
case "status":
|
||||
if (!req.query.status) {
|
||||
req.flash("error", "No status parameter specified.");
|
||||
res.redirect(req.get("Referrer") || "/");
|
||||
return;
|
||||
}
|
||||
await db.update(users).set({
|
||||
// @ts-expect-error
|
||||
status: parseInt(req.query.status)
|
||||
}).where(eq(users.name, req.params.user));
|
||||
break;
|
||||
default:
|
||||
render404(db, res, req);
|
||||
return;
|
||||
}
|
||||
} else {
|
||||
if (!validateUrl(req.body.website)) {
|
||||
req.flash(
|
||||
"error",
|
||||
"The website URL provided is invalid or malformed."
|
||||
);
|
||||
res.redirect(req.get("Referrer") || "/");
|
||||
return;
|
||||
}
|
||||
await db
|
||||
.update(profiles)
|
||||
.set({
|
||||
// @ts-expect-error
|
||||
bio: req.body.bio,
|
||||
website: req.body.website
|
||||
})
|
||||
.where(eq(profiles.user, req.session["uid"]));
|
||||
req.flash("success", "Profile updated!");
|
||||
res.redirect("/dashboard");
|
||||
return;
|
||||
}
|
||||
req.flash("success", "Updated");
|
||||
res.redirect(req.get("Referrer") || "/");
|
||||
});
|
||||
app.post("/users/:user/follow", async (req, res) => {
|
||||
if (!req.session["loggedIn"]) {
|
||||
|
|
20
static/js/admin.js
Normal file
20
static/js/admin.js
Normal file
|
@ -0,0 +1,20 @@
|
|||
const e_user_selected = document.getElementById("user-selected");
|
||||
let current;
|
||||
|
||||
document.querySelectorAll("#users tr").forEach((el) => {
|
||||
el.addEventListener("click", () => {
|
||||
current = el.querySelector("td:nth-child(2)").textContent;
|
||||
e_user_selected.textContent = current;
|
||||
});
|
||||
});
|
||||
|
||||
document.querySelectorAll("button").forEach((el) => {
|
||||
el.addEventListener("click", (ev) => {
|
||||
if (!current) {
|
||||
ev.preventDefault();
|
||||
return;
|
||||
};
|
||||
const e = el.parentElement;
|
||||
e.setAttribute("action", el.parentElement.dataset.url.replaceAll("{}", current));
|
||||
});
|
||||
});
|
|
@ -1,14 +0,0 @@
|
|||
mixin feed(feed, hideUser)
|
||||
if feed.length > 0
|
||||
#feed
|
||||
for update of feed
|
||||
.feed-update
|
||||
div
|
||||
a(href=`/users/${update.user}`)
|
||||
if !hideUser
|
||||
| #{update.user}
|
||||
strong= update.mood
|
||||
div= update.desc || "[no mood description provided]"
|
||||
div(title=update.date.toLocaleString())= update.relativeDate
|
||||
else
|
||||
span [no updates]
|
|
@ -1,3 +1,18 @@
|
|||
mixin feed(feed, hideUser)
|
||||
if feed.length > 0
|
||||
#feed
|
||||
for update of feed
|
||||
.feed-update
|
||||
div
|
||||
a(href=`/users/${update.user}`)
|
||||
if !hideUser
|
||||
| #{update.user}
|
||||
strong= update.mood
|
||||
div= update.desc || "[no mood description provided]"
|
||||
div(title=update.date.toLocaleString())= update.relativeDate
|
||||
else
|
||||
span [no updates]
|
||||
|
||||
mixin invite_code_expiration(code)
|
||||
- const timestamp = code.expires.getTime()
|
||||
if timestamp === 0
|
||||
|
|
|
@ -5,7 +5,10 @@ block content
|
|||
h1 Admin Panel
|
||||
p Don't Be Evil
|
||||
h2 Users
|
||||
table
|
||||
p
|
||||
| Selected:
|
||||
strong#user-selected [none]
|
||||
table#users
|
||||
tbody
|
||||
tr
|
||||
th UID
|
||||
|
@ -17,7 +20,13 @@ block content
|
|||
td
|
||||
a(href=`/users/${user.uname}`)= user.uname
|
||||
td= user.status.toString(2).padStart(4, "0")
|
||||
h2 Invite codes
|
||||
br
|
||||
form(action="#", method="post", data-url="/users/{}/edit?param=status&status=4")
|
||||
button#btn-trust Trust
|
||||
button#btn-ban Ban
|
||||
form(action="#", method="post", data-url="/users/{}/edit?param=status&status=0")
|
||||
button#btn-reset Revoke all stati
|
||||
h2(style="margin-top:1em;") Invite codes
|
||||
p Well Rae. You've made quite a The Closed Beta.
|
||||
form(action="/codes/delete", method="post")
|
||||
table
|
||||
|
@ -41,3 +50,4 @@ block content
|
|||
form(action="/codes/create", method="post")
|
||||
input(type="datetime-local", name="expiration")
|
||||
button(type="submit") Create
|
||||
script(src="/js/admin.js", nonce=nonce)
|
||||
|
|
|
@ -39,7 +39,7 @@ block content
|
|||
| /
|
||||
a(href="#invite-codes") Invite codes
|
||||
p This is where you "MIPILIN"! That is all you need to know!!!
|
||||
p If onlookers notice your actions and inquire about what you are doing, you MUST tell them that you are mipilining all over the place, and then PROMPTLY SCROLL DOWN AND GENERATE AN INVITE CODE SO THAT THEY CAN MIPILIN TOO. If you do not do this I will cry.
|
||||
p If onlookers notice your actions and inquire about what you are doing, you MUST tell them that you are mipilining all over the place, and then PROMPTLY SCROLL DOWN AND GENERATE AN INVITE CODE SO THAT THEY CAN MIPILIN TOO.
|
||||
form#dashboard-update-form(action="/update/mood", method="post", onsubmit="disable(this);")
|
||||
select(name="mood", required)
|
||||
//- Maybe put the index of the mood in the value of the option element
|
||||
|
@ -50,7 +50,6 @@ block content
|
|||
button(type="submit") Update
|
||||
|
||||
h1#feed(style="margin-top:0.5em;") Feed
|
||||
include _feed.pug
|
||||
+feed(recentUpdates)
|
||||
|
||||
h1#invite-codes(style="margin-top:1em;") Invite codes
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
extends site.pug
|
||||
include _util.pug
|
||||
|
||||
block head
|
||||
style
|
||||
|
@ -46,5 +47,4 @@ block content
|
|||
| .
|
||||
h1 Global Feed
|
||||
p Look at how all these people are doing!!!
|
||||
include _feed.pug
|
||||
+feed(feedUpdates)
|
||||
|
|
|
@ -35,7 +35,7 @@ html(lang="en")
|
|||
| You should log in! It's FUN!!
|
||||
span#ticker-marquee
|
||||
marquee
|
||||
| The beta is still a thing that is happening! If something fucks up plz let me know! <3
|
||||
| The beta is still a thing that is happening! If something fucks up plz let me know! <3
|
||||
#page
|
||||
block page
|
||||
#content
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
extends site.pug
|
||||
include _util.pug
|
||||
|
||||
//- Display mood here but keep yourself dry (i.e. dont request user mood if the profile being viewed is the profile of the currently logged-in user)
|
||||
block content
|
||||
|
@ -47,5 +48,4 @@ block content
|
|||
div [no entries]
|
||||
br
|
||||
h2 Recent mood updates
|
||||
include _feed.pug
|
||||
+feed(userMoodFeed, true)
|
||||
|
|
Loading…
Reference in a new issue