feat: add message storage and fetching api #21

Merged
hippoz merged 4 commits from message-history into master 2021-10-03 21:20:29 +03:00
4 changed files with 61 additions and 12 deletions
Showing only changes of commit 495bd71f36 - Show all commits

View file

@ -1,6 +1,7 @@
const User = require("../../models/User"); const User = require("../../models/User");
const Channel = require("../../models/Channel"); const Channel = require("../../models/Channel");
const Post = require("../../models/Post"); const Post = require("../../models/Post");
const Message = require("../../models/Message");
const config = require("../../config"); const config = require("../../config");
const { authenticateEndpoint } = require("./../../common/auth/authfunctions"); const { authenticateEndpoint } = require("./../../common/auth/authfunctions");
@ -38,7 +39,7 @@ app.post("/channel/create", [
res.status(200).json({ res.status(200).json({
error: false, error: false,
message: "SUCCESS_CATEGORY_CREATED", message: "SUCCESS_CHANNEL_CREATED",
channel: channel.getPublicObject() channel: channel.getPublicObject()
}); });
}, undefined, config.roleMap.USER)); }, undefined, config.roleMap.USER));
@ -76,7 +77,7 @@ app.post("/post/create", [
if (r.n < 1) { if (r.n < 1) {
res.status(404).json({ res.status(404).json({
error: true, error: true,
message: "ERROR_CATEGORY_NOT_FOUND" message: "ERROR_CHANNEL_NOT_FOUND"
}); });
return; return;
} }
@ -90,6 +91,33 @@ app.post("/post/create", [
}); });
}, undefined, config.roleMap.USER)); }, undefined, config.roleMap.USER));
app.get("/channel/:channel/messages", [
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;
}
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", [ app.get("/channel/:channel/info", [
param("channel").not().isEmpty().trim().escape().isLength({ min: 24, max: 24 }) param("channel").not().isEmpty().trim().escape().isLength({ min: 24, max: 24 })
], authenticateEndpoint(async (req, res) => { ], authenticateEndpoint(async (req, res) => {
@ -99,23 +127,21 @@ app.get("/channel/:channel/info", [
return; return;
} }
const channelId = req.params.channel; const channel = await Channel.findById(req.params.channel).populate("posts.creator", User.getPulicFields());
const channel = await Channel.findById(channelId).populate("posts.creator", User.getPulicFields());
// TODO: Implement subscribing to a channel and stuff
const users = await User.find().sort({ _id: -1 }).limit(50).select(User.getPulicFields()); const users = await User.find().sort({ _id: -1 }).limit(50).select(User.getPulicFields());
if (!channel) { if (!channel) {
res.status(404).json({ res.status(404).json({
error: true, error: true,
message: "ERROR_CATEGORY_NOT_FOUND" message: "ERROR_CHANNEL_NOT_FOUND"
}); });
return; return;
} }
res.status(200).json({ res.status(200).json({
error: false, error: false,
message: "SUCCESS_CATEGORY_DATA_FETCHED", message: "SUCCESS_CHANNEL_DATA_FETCHED",
channel: channel.getPublicObject(), channel: channel.getPublicObject(),
userInfo: { userInfo: {
userListLimit: 50, userListLimit: 50,
@ -135,7 +161,7 @@ app.get("/channel/list", authenticateEndpoint(async (req, res) => {
res.status(200).json({ res.status(200).json({
error: false, error: false,
message: "SUCCESS_CATEGORY_LIST_FETCHED", message: "SUCCESS_CHANNEL_LIST_FETCHED",
channels channels
}); });
}, undefined, config.roleMap.USER)); }, undefined, config.roleMap.USER));

View file

@ -5,6 +5,7 @@ const { policies, gatewayPingInterval, gatewayPingCheckInterval, clientFacingPin
const { experiments } = require("../../../experiments"); const { experiments } = require("../../../experiments");
const User = require("../../../models/User"); const User = require("../../../models/User");
const Channel = require("../../../models/Channel"); const Channel = require("../../../models/Channel");
const Message = require("../../../models/Message");
const { parseMessage, packet } = require("./messageparser"); const { parseMessage, packet } = require("./messageparser");
const { checkToken } = require("../../../common/auth/authfunctions"); const { checkToken } = require("../../../common/auth/authfunctions");
@ -20,10 +21,11 @@ const wsCloseCodes = {
}; };
const attributes = { const attributes = {
PRESENCE_UPDATES: "PRESENCE_UPDATES" PRESENCE_UPDATES: "PRESENCE_UPDATES",
SAVE_MESSAGES: "SAVE_MESSAGES"
}; };
const supportedAttributes = [attributes.PRESENCE_UPDATES]; const supportedAttributes = [attributes.PRESENCE_UPDATES, attributes.SAVE_MESSAGES];
class GatewaySession { class GatewaySession {
constructor() { constructor() {
@ -243,6 +245,15 @@ class GatewayHandler {
_id: uuid.v4() _id: uuid.v4()
}); });
}); });
if (session.hasAttribute(attributes.SAVE_MESSAGES)) {
await Message.create({
author: session.user._id,
channel: data.channel._id,
content: messageContent,
createdAt: new Date().getTime()
});
}
} }
} }

View file

@ -10,7 +10,6 @@ module.exports = {
// "https://example.com" // "https://example.com"
"http://localhost:3005", // Allow the server itself (provided it's listening on 3005) "http://localhost:3005", // Allow the server itself (provided it's listening on 3005)
//"http://localhost:3000" // Optionally allow the react app development server (which listens on 3000 by default)
], ],
policies: { policies: {
// Currently, policies apply to all users - no matter the role. // Currently, policies apply to all users - no matter the role.
@ -19,7 +18,7 @@ module.exports = {
allowAccountCreation: true, allowAccountCreation: true,
allowLogin: true, allowLogin: true,
allowGatewayConnection: true, allowGatewayConnection: true,
perUserMaxGatewayConnections: 4, perUserMaxGatewayConnections: 4
}, },
/* /*
--- Adding a special code requirement for account creation --- Adding a special code requirement for account creation
@ -36,6 +35,7 @@ module.exports = {
gatewayPingInterval: 15000, gatewayPingInterval: 15000,
gatewayPingCheckInterval: 4500, gatewayPingCheckInterval: 4500,
clientFacingPingInterval: 14750, clientFacingPingInterval: 14750,
unsafeStoreMessages: false,
bcryptRounds: 10, bcryptRounds: 10,
roleMap: { roleMap: {
"BANNED": 0, "BANNED": 0,

View file

@ -0,0 +1,12 @@
const mongoose = require("mongoose");
const messageSchema = new mongoose.Schema({
author: {type: mongoose.Schema.Types.ObjectId, ref: "User"},
channel: {type: mongoose.Schema.Types.ObjectId, ref: "Channel"},
content: String,
createdAt: Number
});
const Message = mongoose.model("Message", messageSchema);
module.exports = Message;