1
0
Fork 0
mirror of https://git.sr.ht/~roxwize/mipilin synced 2025-01-31 02:53:36 +00:00
mipilin/routes/users.ts

224 lines
6.8 KiB
TypeScript
Raw Normal View History

import { NodePgDatabase } from "drizzle-orm/node-postgres";
import { Express } from "express";
import {
follows,
journalEntries,
profiles,
updates,
users
} from "../db/schema.js";
import { and, desc, eq, ne } from "drizzle-orm";
import { getMoods, render, render404, UserStatus, validateUrl } 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: {
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();
// 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];
// journal entries
const now = dayjs();
const userJournalEntries = (
await db
.select({
id: journalEntries.id,
title: journalEntries.title,
date: journalEntries.date,
visibility: journalEntries.visibility
})
.from(journalEntries)
.where(
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))
)
.orderBy(desc(journalEntries.date))
.limit(5)
).map((e) => {
return {
id: e.id,
title: e.title,
date: e.date,
visibility: e.visibility,
relativeDate: now.to(e.date)
};
});
// 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
};
});
if (!isSelf && userMood) {
userMood.mood = moods[userMood.mood as number];
}
render(db, "user", `${req.params.user}'s profile`, res, req, {
user,
isSelf,
userMood,
userMoodFeed,
userJournalEntries,
isFollowing
});
});
app.post("/users/:user/edit", async (req, res) => {
if (!req.session["loggedIn"]) {
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 })
.from(users)
.where(eq(users.name, req.params.user))
)[0];
if (
(uname || "") !== req.session["user"] &&
!(req.session["status"] & UserStatus.MODERATOR)
) {
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");
});
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) {
render404(db, res, req);
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(req.get("Referrer") || "/");
});
}