feat: add message storage and fetching api #21
4 changed files with 61 additions and 12 deletions
|
@ -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));
|
||||||
|
|
|
@ -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()
|
||||||
|
});
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -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,
|
||||||
|
|
12
brainlet/models/Message.js
Normal file
12
brainlet/models/Message.js
Normal 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;
|
Reference in a new issue