This repository has been archived on 2022-05-17. You can view files and clone it, but cannot push or open issues or pull requests.
brainlet/api/v1/content.js

149 lines
No EOL
4.5 KiB
JavaScript
Executable file

const User = require('../../models/User');
const Category = require('../../models/Category');
const Post = require('../../models/Post');
const config = require('../../config');
const secret = require('../../secret');
const { authenticateEndpoint } = require('./authfunctions');
const mongoose = require('mongoose');
const { body, query, param, validationResult } = require('express-validator');
const express = require('express');
const app = express.Router();
mongoose.connect(config.mongoUrl, {useNewUrlParser: true, useUnifiedTopology: true});
const rateLimit = require("express-rate-limit");
const createLimiter = rateLimit({
windowMs: 2 * 60 * 1000,
max: 3,
});
app.post('/category/create', [
createLimiter,
body('title').not().isEmpty().trim().isLength({ min: 3, max: 32 }).escape()
], authenticateEndpoint(async (req, res, user) => {
const errors = validationResult(req);
if (!errors.isEmpty()) {
res.status(400).json({ error: true, message: 'ERROR_REQUEST_INVALID_DATA', errors: errors.array() });
return;
}
const title = req.body.title;
const category = await Category.create({
title: title,
creator: user._id,
posts: []
});
res.status(200).json({
error: false,
message: 'SUCCESS_CATEGORY_CREATED',
category: {
title: category.title,
creator: category.creator,
posts: category.posts,
_id: category._id
}
});
}, undefined, config.roleMap.USER));
app.post('/post/create', [
createLimiter,
body('category').not().isEmpty().trim().escape().isLength({ min: 24, max: 24 }),
body('title').not().isEmpty().trim().isLength({ min: 3, max: 32 }).escape(),
body('body').not().isEmpty().trim().isLength({ min: 3, max: 1000 }).escape(),
], authenticateEndpoint(async (req, res, user) => {
const errors = validationResult(req);
if (!errors.isEmpty()) {
res.status(400).json({ error: true, message: 'ERROR_REQUEST_INVALID_DATA', errors: errors.array() });
return;
}
const category = req.body.category;
const title = req.body.title;
const content = req.body.body;
const post = new Post();
post.title = title;
post.body = content;
post.creator = user._id;
post.category = category;
const r = await Category.updateOne({
_id: category
}, {
$push: { posts: post }
});
if (r.n < 1) {
res.status(404).json({
error: true,
message: 'ERROR_CATEGORY_NOT_FOUND'
});
return;
}
res.status(200).json({
error: false,
message: 'SUCCESS_POST_CREATED',
post: {
_id: post._id
}
});
}, undefined, config.roleMap.USER));
app.get('/category/:category/info', [
param('category').not().isEmpty().trim().escape().isLength({ min: 24, max: 24 })
], authenticateEndpoint(async (req, res, user) => {
const errors = validationResult(req);
if (!errors.isEmpty()) {
res.status(400).json({ error: true, message: 'ERROR_REQUEST_INVALID_DATA', errors: errors.array() });
return;
}
const categoryId = req.params.category;
const category = await Category.findById(categoryId).populate('posts.creator', 'username _id');
// TODO: Implement subscribing to a channel and stuff
const users = await User.find().sort({ _id: -1 }).limit(50).select('username _id')
if (!category) {
res.status(404).json({
error: true,
message: 'ERROR_CATEGORY_NOT_FOUND'
});
return;
}
res.status(200).json({
error: false,
message: 'SUCCESS_CATEGORY_DATA_FETCHED',
category: {
title: category.title,
creator: category.creator,
posts: category.posts,
users: users,
usersListLimit: 50
}
});
}));
app.get('/category/list', authenticateEndpoint(async (req, res, user) => {
let count = parseInt(req.query.count);
if (!Number.isInteger(count)) {
count = 10;
}
// TODO: This is probably not efficient
const categories = await Category.find().sort({ _id: -1 }).limit(count).select('-posts -__v').populate('creator', 'username _id');
res.status(200).json({
error: false,
message: 'SUCCESS_CATEGORY_LIST_FETCHED',
categories
});
}));
module.exports = app;