fix raw file viewing, rm password from settings, add admin api

This commit is contained in:
Max Leiter 2022-11-13 23:28:51 -08:00
parent 97cff7eb53
commit 0627ab7396
7 changed files with 142 additions and 19 deletions

View file

@ -45,10 +45,6 @@
align-items: center; align-items: center;
} }
.header .title .badges > * {
width: min-content;
}
.header .buttons { .header .buttons {
display: flex; display: flex;
justify-content: center; justify-content: center;

View file

@ -29,10 +29,10 @@ const getPost = async (id: string) => {
return notFound() return notFound()
} }
const isAuthor = user?.id === post?.authorId const isAuthorOrAdmin = user?.id === post?.authorId || user?.role === "admin"
if (post.visibility === "public") { if (post.visibility === "public") {
return { post, isAuthor } return { post, isAuthor: isAuthorOrAdmin }
} }
// must be authed to see unlisted/private // must be authed to see unlisted/private
@ -43,19 +43,19 @@ const getPost = async (id: string) => {
return notFound() return notFound()
} }
if (post.visibility === "private" && !isAuthor) { if (post.visibility === "private" && !isAuthorOrAdmin) {
return notFound() return notFound()
} }
if (post.visibility === "protected" && !isAuthor) { if (post.visibility === "protected" && !isAuthorOrAdmin) {
return { return {
post, post,
isProtected: true, isProtected: true,
isAuthor isAuthor: isAuthorOrAdmin
} }
} }
return { post, isAuthor } return { post, isAuthor: isAuthorOrAdmin }
} }
const PostView = async ({ const PostView = async ({
@ -67,8 +67,14 @@ const PostView = async ({
}) => { }) => {
const { post, isProtected, isAuthor } = await getPost(params.id) const { post, isProtected, isAuthor } = await getPost(params.id)
// TODO: serialize dates in prisma middleware instead of passing as JSON // TODO: serialize dates in prisma middleware instead of passing as JSON
const stringifiedPost = JSON.stringify(post); const stringifiedPost = JSON.stringify(post)
return <PostPage isAuthor={isAuthor} isProtected={isProtected} post={stringifiedPost} /> return (
<PostPage
isAuthor={isAuthor}
isProtected={isProtected}
post={stringifiedPost}
/>
)
} }
// export const getServerSideProps: GetServerSideProps = async ({ // export const getServerSideProps: GetServerSideProps = async ({

View file

@ -24,10 +24,7 @@
.badges { .badges {
flex-direction: column; flex-direction: column;
align-items: flex-start; align-items: flex-start;
} margin-top: var(--gap-half);
.badges > * {
width: min-content;
} }
.title { .title {

View file

@ -26,9 +26,9 @@ export default async function SettingsPage() {
<SettingsGroup title="Profile"> <SettingsGroup title="Profile">
<Profile user={user} /> <Profile user={user} />
</SettingsGroup> </SettingsGroup>
<SettingsGroup title="Password"> {/* <SettingsGroup title="Password">
<Password /> <Password />
</SettingsGroup> </SettingsGroup> */}
</div> </div>
) )
} }

View file

@ -23,7 +23,7 @@ const nextConfig = {
return [ return [
{ {
source: "/file/raw/:id", source: "/file/raw/:id",
destination: `/api/raw/:id` destination: `/api/file/raw/:id`
}, },
{ {
source: "/home", source: "/home",

View file

@ -0,0 +1,121 @@
// ts nextjs api handler
import { withMethods } from "@lib/api-middleware/with-methods"
import { parseQueryParam } from "@lib/server/parse-query-param"
import { NextApiRequest, NextApiResponse } from "next"
import { prisma } from "lib/server/prisma"
import { getSession } from "next-auth/react"
const actions = [
"user",
"post",
"users",
"posts",
"set-role",
"delete-user",
"delete-post"
] as const
const handler = async (req: NextApiRequest, res: NextApiResponse) => {
const { action: requestedAction } = req.query
const action = parseQueryParam(requestedAction) as typeof actions[number]
if (!action || !actions.includes(action)) {
res.status(400).json({ error: "Invalid action" })
return
}
const session = await getSession({ req })
const id = session?.user?.id
// get admin from db
const isAdmin = await prisma.user
.findUnique({
where: {
id
},
select: {
role: true
}
})
.then((user) => user?.role === "admin")
if (!isAdmin) {
return res.status(403).json({ error: "Not authorized" })
}
switch (req.method) {
case "GET":
switch (action) {
case "users":
const users = await prisma.user.findMany()
return res.status(200).json(users)
case "posts":
const posts = await prisma.post.findMany()
return res.status(200).json(posts)
case "user":
const { id: userId } = req.query
const user = await prisma.user.findUnique({
where: {
id: parseQueryParam(userId)
}
})
return res.status(200).json(user)
case "post":
const { id: postId } = req.query
const post = await prisma.post.findUnique({
where: {
id: parseQueryParam(postId)
}
})
return res.status(200).json(post)
}
break
case "PATCH":
switch (action) {
case "set-role":
const { userId, role } = req.body
if (!userId || !role || role !== "admin" || role !== "user") {
return res.status(400).json({ error: "Invalid request" })
}
const user = await prisma.user.update({
where: { id: userId },
data: {
role: role
}
})
return res.status(200).json(user)
}
break
case "DELETE":
switch (action) {
case "delete-user":
const { userId } = req.body
if (!userId) {
return res.status(400).json({ error: "Invalid request" })
}
const user = await prisma.user.delete({
where: { id: userId }
})
return res.status(200).json(user)
case "delete-post":
const { postId } = req.body
if (!postId) {
return res.status(400).json({ error: "Invalid request" })
}
const post = await prisma.post.delete({
where: { id: postId }
})
return res.status(200).json(post)
}
break
}
}
export default withMethods(["GET", "PATCH", "DELETE"], handler)

View file

@ -141,6 +141,9 @@ async function handleDelete(req: NextApiRequest, res: NextApiResponse<any>) {
await prisma.post.delete({ await prisma.post.delete({
where: { where: {
id id
},
include: {
files: true
} }
}) })