CoastalCommitsPastes/server/src/routes/posts.ts

183 lines
5.5 KiB
TypeScript
Raw Normal View History

2022-03-06 16:46:59 -08:00
import { Router } from 'express'
// import { Movie } from '../models/Post'
import { File } from '../lib/models/File'
import { Post } from '../lib/models/Post';
import jwt, { UserJwtRequest } from '../lib/middleware/jwt';
2022-03-06 16:46:59 -08:00
import * as crypto from "crypto";
import { User } from '../lib/models/User';
import secretKey from '../lib/middleware/secret-key';
import markdown from '../lib/render-markdown';
2022-03-06 16:46:59 -08:00
export const posts = Router()
posts.post('/create', jwt, async (req, res, next) => {
try {
if (!req.body.files) {
throw new Error("Please provide files.")
}
if (!req.body.title) {
throw new Error("Please provide a title.")
}
if (!req.body.userId) {
throw new Error("No user id provided.")
}
if (!req.body.visibility) {
throw new Error("Please provide a visibility.")
}
2022-03-21 18:51:19 -07:00
if (req.body.visibility === 'protected' && !req.body.password) {
throw new Error("Please provide a password.")
}
let hashedPassword: string = ''
if (req.body.visibility === 'protected') {
hashedPassword = crypto.createHash('sha256').update(req.body.password).digest('hex');
}
2022-03-06 16:46:59 -08:00
const newPost = new Post({
title: req.body.title,
visibility: req.body.visibility,
2022-03-21 18:51:19 -07:00
password: hashedPassword,
2022-03-06 16:46:59 -08:00
})
await newPost.save()
await newPost.$add('users', req.body.userId);
const newFiles = await Promise.all(req.body.files.map(async (file) => {
const renderAsMarkdown = ['markdown', 'md', 'mdown', 'mkdn', 'mkd', 'mdwn', 'mdtxt', 'mdtext', 'text', '']
const fileType = () => {
const pathParts = file.title.split(".")
const language = pathParts.length > 1 ? pathParts[pathParts.length - 1] : ""
return language
}
const type = fileType()
let contentToRender: string = (file.content || '');
if (!renderAsMarkdown.includes(type)) {
contentToRender =
`~~~${type}
${file.content}
~~~`
} else {
contentToRender = '\n' + file.content;
}
const html = markdown(contentToRender)
2022-03-06 16:46:59 -08:00
const newFile = new File({
title: file.title,
content: file.content,
sha: crypto.createHash('sha256').update(file.content).digest('hex').toString(),
html
2022-03-06 16:46:59 -08:00
})
await newFile.$set("user", req.body.userId);
await newFile.$set("post", newPost.id);
await newFile.save();
return newFile;
}))
await Promise.all(newFiles.map((file) => {
newPost.$add("files", file.id);
newPost.save();
}))
res.json(newPost);
} catch (e) {
next(e);
}
});
posts.get("/", secretKey, async (req, res, next) => {
try {
const posts = await Post.findAll({
attributes: ["id", "title", "visibility", "createdAt"],
})
res.json(posts);
} catch (e) {
next(e);
}
});
posts.get("/mine", jwt, secretKey, async (req: UserJwtRequest, res, next) => {
if (!req.user) {
return res.status(401).json({ error: "Unauthorized" })
}
try {
const user = await User.findByPk(req.user.id, {
include: [
{
model: Post,
as: "posts",
include: [
{
model: File,
as: "files"
}
]
},
],
})
if (!user) {
return res.status(404).json({ error: "User not found" })
}
return res.json(user.posts?.sort((a, b) => b.createdAt.getTime() - a.createdAt.getTime()))
} catch (error) {
next(error)
}
})
2022-03-21 18:51:19 -07:00
posts.get("/:id", async (req, res, next) => {
2022-03-06 16:46:59 -08:00
try {
const post = await Post.findOne({
where: {
id: req.params.id
},
include: [
{
model: File,
as: "files",
attributes: ["id", "title", "content", "sha", "createdAt", "updatedAt"],
2022-03-06 16:46:59 -08:00
},
{
model: User,
as: "users",
attributes: ["id", "username"],
},
]
})
2022-03-21 18:51:19 -07:00
if (!post) {
throw new Error("Post not found.")
}
2022-03-06 22:16:08 -08:00
2022-03-21 18:51:19 -07:00
if (post.visibility === 'public' || post?.visibility === 'unlisted') {
2022-03-21 18:51:19 -07:00
secretKey(req, res, () => {
res.json(post);
})
} else if (post.visibility === 'private') {
jwt(req as UserJwtRequest, res, () => {
2022-03-06 22:16:08 -08:00
res.json(post);
})
} else if (post.visibility === 'protected') {
2022-03-21 18:51:19 -07:00
const { password } = req.query
if (!password || typeof password !== 'string') {
return jwt(req as UserJwtRequest, res, () => {
res.json(post);
})
}
const hash = crypto.createHash('sha256').update(password).digest('hex').toString()
if (hash !== post.password) {
return res.status(400).json({ error: "Incorrect password." })
}
2022-03-21 18:51:19 -07:00
res.json(post);
2022-03-06 22:16:08 -08:00
}
2022-03-06 16:46:59 -08:00
}
catch (e) {
next(e);
}
});