brainlet/api/v1/content.js

129 lines
4 KiB
JavaScript
Executable file

const User = require("../../models/User");
const Channel = require("../../models/Channel");
const Message = require("../../models/Message");
const config = require("../../config");
const { authenticateEndpoint } = require("./../../common/auth/authfunctions");
const mongoose = require("mongoose");
const { body, param, validationResult } = require("express-validator");
const express = require("express");
const rateLimit = require("express-rate-limit");
const app = express.Router();
const createLimiter = rateLimit({
windowMs: 2 * 60 * 1000,
max: 10,
});
mongoose.connect(config.mongoUrl, {useNewUrlParser: true, useUnifiedTopology: true});
app.post("/channel/create", [
createLimiter,
body("title").not().isEmpty().trim().isLength({ min: 3, max: 32 }).escape()
], authenticateEndpoint(async (req, res, user) => {
if (!config.policies.allowChannelCreation) return res.status(403).json({ error: true, message: "ERROR_FORBIDDEN_BY_POLICY" });
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 channel = await Channel.create({
title: title,
creator: user._id
});
res.status(200).json({
error: false,
message: "SUCCESS_CHANNEL_CREATED",
channel: channel.getPublicObject()
});
}, undefined, config.roleMap.USER));
app.get("/channel/:channel/messages", [
param("channel").not().isEmpty().trim().escape().isLength({ min: 24, max: 24 })
], authenticateEndpoint(async (req, res) => {
if (!config.policies.allowSavingMessages) {
// TODO: hack
res.status(200).json({
error: false,
message: "SUCCESS_CHANNEL_MESSAGES_FETCHED",
channelMessages: []
});
return;
}
const errors = validationResult(req);
if (!errors.isEmpty()) {
res.status(400).json({ error: true, message: "ERROR_REQUEST_INVALID_DATA", errors: errors.array() });
return;
}
let idSearch = {};
if (req.query.before) {
idSearch = { _id: { $lt: req.query.before } };
}
const messages = await Message.find({ channel: req.params.channel, ...idSearch })
.sort({ _id: -1 })
.limit(50)
.select("-__v -channel")
.populate("author", "_id username");
res.status(200).json({
error: false,
message: "SUCCESS_CHANNEL_MESSAGES_FETCHED",
channelMessages: messages
});
}, undefined, config.roleMap.USER));
app.get("/channel/:channel/info", [
param("channel").not().isEmpty().trim().escape().isLength({ min: 24, max: 24 })
], authenticateEndpoint(async (req, res) => {
const errors = validationResult(req);
if (!errors.isEmpty()) {
res.status(400).json({ error: true, message: "ERROR_REQUEST_INVALID_DATA", errors: errors.array() });
return;
}
const channel = await Channel.findById(req.params.channel);
const users = await User.find().sort({ _id: -1 }).limit(50).select(User.getPulicFields());
if (!channel) {
res.status(404).json({
error: true,
message: "ERROR_CHANNEL_NOT_FOUND"
});
return;
}
res.status(200).json({
error: false,
message: "SUCCESS_CHANNEL_DATA_FETCHED",
channel: channel.getPublicObject(),
userInfo: {
userListLimit: 50,
users: users
}
});
}, undefined, config.roleMap.USER));
app.get("/channel/list", authenticateEndpoint(async (req, res) => {
let count = parseInt(req.query.count);
if (!Number.isInteger(count)) {
count = 10;
}
// TODO: This is probably not efficient
const channels = await Channel.find().lean().sort({ _id: -1 }).limit(count).select("-__v").populate("creator", User.getPulicFields());
res.status(200).json({
error: false,
message: "SUCCESS_CHANNEL_LIST_FETCHED",
channels
});
}, undefined, config.roleMap.USER));
module.exports = app;