I think the API is done.

This commit is contained in:
MeowcaTheoRange 2023-07-13 14:33:16 -05:00
parent 588868a26b
commit 2864193fd9
7 changed files with 122 additions and 21 deletions

View file

@ -27,7 +27,7 @@ export function SubmitUserToServerUser(
): Omit<Partial<ServerUser>, "_id"> {
let serverUser: Omit<Partial<ServerUser>, "_id"> = {
...submitUser,
flairs: [],
flairs: undefined,
code: submitUser.code || "",
updatedDate: new Date()
};

View file

@ -1,7 +1,8 @@
import { Levels, Permissions } from "@/permissions";
import { ServerUser } from "@/types/user";
import { ObjectId } from "mongodb";
export function getLevel(user: ServerUser) {
export function getLevel(user: Partial<ServerUser> & { flairs: ObjectId[] }) {
let highestLevel = "USER";
for (let level of Permissions) {
if (user.flairs.some(oid => level.values.includes(oid.toString())))

View file

@ -11,11 +11,8 @@ import {
import { changeTroll, getSingleTroll } from "@/lib/trollcall/troll";
import { getSingleUser } from "@/lib/trollcall/user";
import { PartialTrollSchema, SubmitTroll } from "@/types/client/troll";
import { Router } from "express";
import { NextApiRequest, NextApiResponse } from "next";
export const trollRouter = Router();
export default async function handler(
req: NextApiRequest,
res: NextApiResponse
@ -46,7 +43,6 @@ export default async function handler(
name: query.user
});
if (checkUser == null) return res.status(404).end();
// Make sure to reverse methods so that way other owners can edit this troll
if (!compareCredentials(checkUser, cookies)) {
const thisUser = await getSingleUser({
name: cookies.TROLLCALL_NAME
@ -59,7 +55,7 @@ export default async function handler(
}
const editingTroll = await getSingleTroll({
"name.0": query.troll,
"owners": checkUser._id
"owners.0": checkUser._id
});
if (editingTroll == null) return res.status(404).end();
const serverTroll = SubmitTrollToServerTroll(validatedTroll);

View file

@ -0,0 +1,36 @@
import {
compareCredentials,
compareLevels,
getLevel
} from "@/lib/trollcall/perms";
import { getSingleTroll } from "@/lib/trollcall/troll";
import { getSingleUser } from "@/lib/trollcall/user";
import { NextApiRequest, NextApiResponse } from "next";
export default async function handler(
req: NextApiRequest,
res: NextApiResponse
) {
const { query, cookies, method, body } = req;
if (method === "GET") {
const user = await getSingleUser({
name: query.user
});
if (user == null) return res.status(404).end();
if (!compareCredentials(user, cookies)) {
const thisUser = await getSingleUser({
name: cookies.TROLLCALL_NAME
});
if (thisUser == null || !compareCredentials(thisUser, cookies))
return res.status(403).end();
if (!compareLevels(getLevel(thisUser), "MODERATOR"))
return res.status(403).end();
}
const troll = await getSingleTroll({
"name.0": query.troll,
"owners.0": user._id
});
if (troll == null) return res.status(404).end();
res.json(troll);
}
}

View file

@ -39,6 +39,7 @@ export default async function handler(
name: query.user
});
if (checkExistingUser == null) return res.status(404).end();
let isModerator = false;
if (!compareCredentials(checkExistingUser, cookies)) {
const thisUser = await getSingleUser({
name: cookies.TROLLCALL_NAME
@ -47,27 +48,33 @@ export default async function handler(
return res.status(403).end();
if (!compareLevels(getLevel(thisUser), "MODERATOR"))
return res.status(403).end();
isModerator = true;
}
const serverUser = SubmitUserToServerUser(validatedUser);
if (serverUser.code === "")
serverUser.code = checkExistingUser.code || nanoid(16);
if (!compareLevels(getLevel(checkExistingUser), "SUPPORTER"))
serverUser.bgimage = null;
const bothUsers = MergeServerUsers(checkExistingUser, serverUser);
const newUser = await changeUser(bothUsers);
if (newUser == null) return res.status(503).end();
// Give cookies, redundant style
res.setHeader("Set-Cookie", [
serialize("TROLLCALL_NAME", newUser.name, {
path: "/",
maxAge: 31540000
}),
serialize("TROLLCALL_CODE", newUser.code, {
path: "/",
maxAge: 31540000
}),
serialize("TROLLCALL_PFP", newUser.pfp ?? "", {
path: "/",
maxAge: 31540000
})
]).json(newUser);
if (!isModerator)
// don't set cookies if moderator is changing credentials
res.setHeader("Set-Cookie", [
serialize("TROLLCALL_NAME", newUser.name, {
path: "/",
maxAge: 31540000
}),
serialize("TROLLCALL_CODE", newUser.code, {
path: "/",
maxAge: 31540000
}),
serialize("TROLLCALL_PFP", newUser.pfp ?? "", {
path: "/",
maxAge: 31540000
})
]).json(newUser);
else res.json(newUser);
} else return res.status(405).end();
}

View file

@ -1,4 +1,5 @@
import { SubmitUserToServerUser } from "@/lib/trollcall/convert/user";
import { compareLevels, getLevel } from "@/lib/trollcall/perms";
import { createUser, getSingleUser } from "@/lib/trollcall/user";
import { SubmitUserSchema } from "@/types/client/user";
import { ServerUser } from "@/types/user";
@ -30,6 +31,8 @@ export default async function handler(
"_id"
>;
if (serverUser.code === "") serverUser.code = nanoid(16);
if (!compareLevels(getLevel(serverUser), "SUPPORTER"))
serverUser.bgimage = null;
const newUser = await createUser(serverUser);
if (newUser == null) return res.status(503).end();
// Give cookies

View file

@ -14,8 +14,40 @@ export const SubmitUserSchema = yup
description: yup.string().max(10000).ensure(),
url: yup.string().notRequired().url(),
trueSign: yup.string().required().oneOf(TrueSignKeys),
pronouns: yup
.array()
.of(
yup
.tuple([
yup
.string()
.required()
.matches(/^[A-z]+$/, "Letters only")
.min(1)
.max(10)
.lowercase(), // she, he, they
yup
.string()
.required()
.matches(/^[A-z]+$/, "Letters only")
.min(1)
.max(10)
.lowercase(), // her, him, them
yup
.string()
.required()
.matches(/^[A-z]+$/, "Letters only")
.min(1)
.max(10)
.lowercase() // hers, his, theirs
])
.required()
)
.required()
.min(1),
color: ColorSchema.required(),
pfp: yup.string().notRequired().url(),
bgimage: yup.string().notRequired().url(),
code: yup.string().notRequired().max(256, "Too secure!!")
// flairs: yup.array().of(ClientFlairSchema).required(),
})
@ -40,12 +72,38 @@ export const PartialUserSchema = yup
return v === "" ? null : v;
})
.oneOf(TrueSignKeys),
pronouns: yup
.array()
.of(
yup.tuple([
yup
.string()
.matches(/^[A-z]+$/, "Letters only")
.min(1)
.max(10)
.lowercase(), // she, he, they
yup
.string()
.matches(/^[A-z]+$/, "Letters only")
.min(1)
.max(10)
.lowercase(), // her, him, them
yup
.string()
.matches(/^[A-z]+$/, "Letters only")
.min(1)
.max(10)
.lowercase() // hers, his, theirs
])
)
.min(1),
color: yup.tuple([
yup.number().min(0).max(255),
yup.number().min(0).max(255),
yup.number().min(0).max(255)
]),
pfp: yup.string().url(),
bgimage: yup.string().url(),
code: yup.string().max(256, "Too secure!!")
// flairs: yup.array().of(ClientFlairSchema).required(),
})