import { NodePgDatabase } from "drizzle-orm/node-postgres"; import { Express } from "express"; import { follows, profiles, updates, users } from "../db/schema.js"; import { and, desc, eq } from "drizzle-orm"; import { getMoods, render } from "./util.js"; import { PgColumn } from "drizzle-orm/pg-core"; import dayjs from "dayjs"; export default async function (app: Express, db: NodePgDatabase) { const { moods } = await getMoods(); app.get("/users/:user", async (req, res) => { const isSelf = req.params.user === req.session["user"]; const user = ( await db .select({ id: users.id, name: users.name, 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) { req.flash("error", `User ${req.params.user} does not exist`); res.redirect("/"); return; } // follows const isFollowing = !!( await db .select() .from(follows) .where( and( eq(follows.followerId, req.session["uid"]), eq(follows.userId, user.id) ) ) .limit(1) )[0]; // 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]; // feed const now = dayjs(); const userMoodFeed = (await db .select({ mood: updates.mood, date: updates.date, desc: updates.description }) .from(updates) .where(eq(updates.user, user.id))).map((e) => { return { user: user.name, mood: moods[e.mood], date: now.to(dayjs(e.date)), desc: e.desc } }); if (!isSelf) { userMood.mood = moods[userMood.mood as number]; } render(db, "user", `${req.params.user}'s Profile`, res, req, { user, isSelf, userMood, userMoodFeed, isFollowing }); }); app.post("/users/:user/edit", async (req, res) => { if (!req.session["loggedIn"]) { res.redirect("/login"); return; } const { uname, mod } = ( await db .select({ uname: users.name, mod: users.moderator }) .from(users) .where(eq(users.name, req.params.user)) )[0]; if ((uname || "") !== req.session["user"] && !mod) { res.redirect("back"); return; } 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; } 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}`); }); }