You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
Drift/server/src/routes/admin.ts

200 lines
3.4 KiB
TypeScript

import isAdmin, { UserJwtRequest } from "@lib/middleware/is-admin"
import { Post } from "@lib/models/Post"
import { User } from "@lib/models/User"
import { File } from "@lib/models/File"
import { Router } from "express"
import { celebrate, Joi } from "celebrate"
export const admin = Router()
admin.use(isAdmin)
admin.get("/is-admin", async (req, res) => {
return res.json({
isAdmin: true
})
})
admin.get("/users", async (req, res, next) => {
try {
const users = await User.findAll({
attributes: {
exclude: ["password"],
include: ["id", "username", "createdAt", "updatedAt"]
},
include: [
{
model: Post,
as: "posts",
attributes: ["id"]
}
]
})
res.json(users)
} catch (e) {
next(e)
}
})
admin.post(
"/users/toggle-role",
celebrate({
body: {
id: Joi.string().required(),
role: Joi.string().required().allow("user", "admin")
}
}),
async (req: UserJwtRequest, res, next) => {
try {
const { id, role } = req.body
if (req.user?.id === id) {
return res.status(400).json({
error: "You can't change your own role"
})
}
const user = await User.findByPk(id)
if (!user) {
return res.status(404).json({
error: "User not found"
})
}
await user.update({
role
})
await user.save()
res.json({
success: true
})
} catch (e) {
next(e)
}
}
)
admin.delete("/users/:id", async (req, res, next) => {
try {
const user = await User.findByPk(req.params.id)
if (!user) {
return res.status(404).json({
error: "User not found"
})
}
// TODO: verify CASCADE is removing files + posts
await user.destroy()
res.json({
success: true
})
} catch (e) {
next(e)
}
})
admin.delete("/posts/:id", async (req, res, next) => {
try {
const post = await Post.findByPk(req.params.id)
if (!post) {
return res.status(404).json({
error: "Post not found"
})
}
await post.destroy()
res.json({
success: true
})
} catch (e) {
next(e)
}
})
admin.get("/posts", async (req, res, next) => {
try {
const posts = await Post.findAll({
attributes: {
exclude: ["content"],
include: ["id", "title", "visibility", "createdAt"]
},
include: [
{
model: File,
as: "files",
attributes: ["id", "title", "createdAt", "html"]
},
{
model: User,
as: "users",
attributes: ["id", "username"]
}
]
})
res.json(posts)
} catch (e) {
next(e)
}
})
admin.get("/post/:id", async (req, res, next) => {
try {
const post = await Post.findByPk(req.params.id, {
attributes: {
exclude: ["content"],
include: ["id", "title", "visibility", "createdAt"]
},
include: [
{
model: File,
as: "files",
attributes: ["id", "title", "sha", "createdAt", "updatedAt", "html"]
},
{
model: User,
as: "users",
attributes: ["id", "username"]
}
]
})
if (!post) {
return res.status(404).json({
message: "Post not found"
})
}
res.json(post)
} catch (e) {
next(e)
}
})
admin.delete("/post/:id", async (req, res, next) => {
try {
const post = await Post.findByPk(req.params.id, {
include: [
{
model: File,
as: "files"
}
]
})
if (!post) {
return res.status(404).json({
message: "Post not found"
})
}
if (post.files?.length)
await Promise.all(post.files.map((file) => file.destroy()))
await post.destroy({ force: true })
res.json({
message: "Post deleted"
})
} catch (e) {
next(e)
}
})