2024-11-14 03:51:08 +00:00
|
|
|
import { NodePgDatabase } from "drizzle-orm/node-postgres";
|
|
|
|
import { Express } from "express";
|
2024-12-26 21:24:04 +00:00
|
|
|
import {
|
|
|
|
follows,
|
|
|
|
journalEntries,
|
|
|
|
profiles,
|
|
|
|
updates,
|
|
|
|
users
|
|
|
|
} from "../db/schema.js";
|
2024-11-14 03:51:08 +00:00
|
|
|
import { and, desc, eq } from "drizzle-orm";
|
2024-12-26 21:24:04 +00:00
|
|
|
import { getMoods, render, render404, UserStatus } from "./util.js";
|
2024-11-14 03:51:08 +00:00
|
|
|
import { PgColumn } from "drizzle-orm/pg-core";
|
2024-11-17 19:16:27 +00:00
|
|
|
import dayjs from "dayjs";
|
2024-11-14 03:51:08 +00:00
|
|
|
|
|
|
|
export default async function (app: Express, db: NodePgDatabase) {
|
2024-12-26 21:24:04 +00:00
|
|
|
const { moods } = await getMoods();
|
|
|
|
app.get("/users/:user", async (req, res) => {
|
|
|
|
const isSelf = req.params.user === req.session["user"];
|
2024-11-14 03:51:08 +00:00
|
|
|
|
2024-12-26 21:24:04 +00:00
|
|
|
const user: {
|
|
|
|
id: number;
|
|
|
|
name: string;
|
|
|
|
registered: Date;
|
|
|
|
relativeRegistered?: string;
|
|
|
|
bio: string;
|
|
|
|
website: string;
|
|
|
|
} = (
|
|
|
|
await db
|
|
|
|
.select({
|
|
|
|
id: users.id,
|
|
|
|
name: users.name,
|
|
|
|
registered: users.registered,
|
|
|
|
bio: profiles.bio,
|
|
|
|
website: profiles.website
|
|
|
|
})
|
|
|
|
.from(users)
|
|
|
|
.where(eq(users.name, req.params.user))
|
|
|
|
.leftJoin(profiles, eq(profiles.user, users.id))
|
|
|
|
)[0];
|
|
|
|
if (!user) {
|
|
|
|
render404(db, res, req);
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
user.relativeRegistered = dayjs(user.registered).fromNow();
|
2024-11-14 03:51:08 +00:00
|
|
|
|
2024-12-26 21:24:04 +00:00
|
|
|
// follows
|
|
|
|
const isFollowing = !!(
|
|
|
|
await db
|
|
|
|
.select()
|
|
|
|
.from(follows)
|
|
|
|
.where(
|
|
|
|
and(
|
|
|
|
eq(follows.followerId, req.session["uid"]),
|
|
|
|
eq(follows.userId, user.id)
|
|
|
|
)
|
|
|
|
)
|
|
|
|
.limit(1)
|
|
|
|
)[0];
|
2024-11-14 03:51:08 +00:00
|
|
|
|
2024-12-26 21:24:04 +00:00
|
|
|
// mood
|
|
|
|
let moodSelection: { [k: string]: PgColumn } = {
|
|
|
|
desc: updates.description,
|
|
|
|
date: updates.date
|
|
|
|
};
|
|
|
|
if (!isSelf) moodSelection.mood = updates.mood;
|
|
|
|
const userMood: { [k: string]: string | number | Date } = (
|
|
|
|
await db
|
|
|
|
.select(moodSelection)
|
|
|
|
.from(updates)
|
|
|
|
.where(eq(updates.user, user.id))
|
|
|
|
.orderBy(desc(updates.date))
|
|
|
|
.limit(1)
|
|
|
|
)[0];
|
2024-11-14 03:51:08 +00:00
|
|
|
|
2024-12-26 21:24:04 +00:00
|
|
|
// journal entries
|
|
|
|
const now = dayjs();
|
|
|
|
const userJournalEntries = (
|
|
|
|
await db
|
|
|
|
.select({
|
|
|
|
id: journalEntries.id,
|
|
|
|
title: journalEntries.title,
|
|
|
|
date: journalEntries.date
|
|
|
|
})
|
|
|
|
.from(journalEntries)
|
|
|
|
.where(eq(journalEntries.user, user.id))
|
|
|
|
.orderBy(desc(journalEntries.date))
|
|
|
|
.limit(5)
|
|
|
|
).map((e) => {
|
|
|
|
return {
|
|
|
|
id: e.id,
|
|
|
|
title: e.title,
|
|
|
|
date: e.date,
|
|
|
|
relativeDate: now.to(e.date)
|
|
|
|
};
|
|
|
|
});
|
2024-11-17 19:16:27 +00:00
|
|
|
|
2024-12-26 21:24:04 +00:00
|
|
|
// feed
|
|
|
|
const userMoodFeed = (
|
|
|
|
await db
|
|
|
|
.select({
|
|
|
|
mood: updates.mood,
|
|
|
|
date: updates.date,
|
|
|
|
desc: updates.description
|
|
|
|
})
|
|
|
|
.from(updates)
|
|
|
|
.where(eq(updates.user, user.id))
|
|
|
|
.orderBy(desc(updates.date))
|
|
|
|
).map((e) => {
|
|
|
|
return {
|
|
|
|
user: user.name,
|
|
|
|
mood: moods[e.mood],
|
|
|
|
date: e.date,
|
|
|
|
relativeDate: now.to(dayjs(e.date)),
|
|
|
|
desc: e.desc
|
|
|
|
};
|
|
|
|
});
|
2024-11-14 03:51:08 +00:00
|
|
|
|
2024-12-26 21:24:04 +00:00
|
|
|
if (!isSelf) {
|
|
|
|
userMood.mood = moods[userMood.mood as number];
|
|
|
|
}
|
|
|
|
|
|
|
|
render(db, "user", `${req.params.user}'s profile`, res, req, {
|
|
|
|
user,
|
|
|
|
isSelf,
|
|
|
|
userMood,
|
|
|
|
userMoodFeed,
|
|
|
|
userJournalEntries,
|
|
|
|
isFollowing
|
|
|
|
});
|
2024-11-14 03:51:08 +00:00
|
|
|
});
|
2024-12-26 21:24:04 +00:00
|
|
|
app.post("/users/:user/edit", async (req, res) => {
|
|
|
|
if (!req.session["loggedIn"]) {
|
|
|
|
res.redirect("/login");
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
const { uname } = (
|
|
|
|
await db
|
|
|
|
.select({ uname: users.name })
|
|
|
|
.from(users)
|
|
|
|
.where(eq(users.name, req.params.user))
|
|
|
|
)[0];
|
|
|
|
if (
|
|
|
|
(uname || "") !== req.session["user"] &&
|
|
|
|
!(req.session["status"] & UserStatus.MODERATOR)
|
|
|
|
) {
|
|
|
|
res.redirect("back");
|
|
|
|
return;
|
|
|
|
}
|
2024-11-14 03:51:08 +00:00
|
|
|
|
2024-12-26 21:24:04 +00:00
|
|
|
await db //! no sanitization here either BROOOOOOO
|
|
|
|
.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");
|
|
|
|
});
|
|
|
|
app.post("/users/:user/follow", async (req, res) => {
|
|
|
|
if (!req.session["loggedIn"]) {
|
|
|
|
res.redirect("/login");
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
if (req.session["user"] === req.params.user) {
|
|
|
|
req.flash("error", "Can't Follow Yourself Dummy");
|
|
|
|
res.redirect(`/users/${req.params.user}`);
|
|
|
|
return;
|
|
|
|
}
|
2024-11-14 03:51:08 +00:00
|
|
|
|
2024-12-26 21:24:04 +00:00
|
|
|
const { uid } = (
|
|
|
|
await db
|
|
|
|
.select({ uid: users.id })
|
|
|
|
.from(users)
|
|
|
|
.where(eq(users.name, req.params.user))
|
|
|
|
)[0];
|
|
|
|
if (!uid) {
|
|
|
|
req.flash(
|
|
|
|
"error",
|
|
|
|
"It looks like you're trying to follow a user that doesn't exist anymore."
|
|
|
|
);
|
|
|
|
res.redirect("/");
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
const isFollowing = !!(
|
|
|
|
await db
|
|
|
|
.select()
|
|
|
|
.from(follows)
|
|
|
|
.where(
|
|
|
|
and(
|
|
|
|
eq(follows.followerId, req.session["uid"]),
|
|
|
|
eq(follows.userId, uid)
|
|
|
|
)
|
|
|
|
)
|
|
|
|
.limit(1)
|
|
|
|
)[0];
|
|
|
|
if (isFollowing) {
|
|
|
|
// unfollow
|
|
|
|
await db
|
|
|
|
.delete(follows)
|
|
|
|
.where(
|
|
|
|
and(
|
|
|
|
eq(follows.followerId, req.session["uid"]),
|
|
|
|
eq(follows.userId, uid)
|
|
|
|
)
|
|
|
|
);
|
|
|
|
} else {
|
|
|
|
await db.insert(follows).values({
|
|
|
|
userId: uid,
|
|
|
|
followerId: req.session["uid"]
|
|
|
|
});
|
|
|
|
}
|
|
|
|
res.redirect(`/users/${req.params.user}`);
|
|
|
|
});
|
2024-11-14 03:51:08 +00:00
|
|
|
}
|