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