diff --git a/brainlet/api/v1/content.js b/brainlet/api/v1/content.js index a73dcc4..03bae5b 100755 --- a/brainlet/api/v1/content.js +++ b/brainlet/api/v1/content.js @@ -94,6 +94,16 @@ app.post("/post/create", [ 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() }); diff --git a/brainlet/api/v2/gateway/index.js b/brainlet/api/v2/gateway/index.js index ca3f40a..3c3ba59 100644 --- a/brainlet/api/v2/gateway/index.js +++ b/brainlet/api/v2/gateway/index.js @@ -1,5 +1,6 @@ const websockets = require("ws"); -const uuid = require("uuid"); +const { v4 } = require("uuid"); +const mongoose = require("mongoose"); const { policies, gatewayPingInterval, gatewayPingCheckInterval, clientFacingPingInterval } = require("../../../config"); const { experiments } = require("../../../experiments"); @@ -18,21 +19,21 @@ const wsCloseCodes = { NOT_AUTHORIZED: [4006, "Not authorized"], FLOODING: [4007, "Flooding"], NO_PING: [4008, "No ping"], + UNSUPPORTED_ATTRIBUTE: [4009, "Unsupported attribute."], }; const attributes = { PRESENCE_UPDATES: "PRESENCE_UPDATES", - SAVE_MESSAGES: "SAVE_MESSAGES" }; -const supportedAttributes = [attributes.PRESENCE_UPDATES, attributes.SAVE_MESSAGES]; +const supportedAttributes = [attributes.PRESENCE_UPDATES]; class GatewaySession { constructor() { this.authenticated = false; this.user = null; this.token = null; - this.sessionId = uuid.v4(); + this.sessionId = v4(); this.attributes = []; // Specific to websocket sessions @@ -110,7 +111,7 @@ class GatewayHandler { const session = new GatewaySession(); session.setWebsocketClient(ws); - session.send("HELLO", { pingInterval: clientFacingPingInterval }); + session.send("HELLO", { pingInterval: clientFacingPingInterval, supportedAttributes }); return session; } @@ -177,8 +178,9 @@ class GatewayHandler { if (data.attributes) { if (!Array.isArray(data.attributes) || data.attributes.length > 8) return {error: wsCloseCodes.PAYLOAD_ERROR}; - for (let i = 0; i < data.attributes; i++) { - if (!supportedAttributes.includes(data[i])) return {error: wsCloseCodes.PAYLOAD_ERROR}; + for (let i = 0; i < data.attributes.length; i++) { + if (!supportedAttributes.includes(data.attributes[i])) + return {error: wsCloseCodes.UNSUPPORTED_ATTRIBUTE}; } session.attributes = data.attributes; } @@ -232,7 +234,20 @@ class GatewayHandler { // Check if the user is in that channel before broadcasting the message if (!session.channels.includes(data.channel._id)) return {error: wsCloseCodes.NOT_AUTHORIZED}; - this.eachInChannel({channelId: data.channel._id}, ({ session: remoteSession }) => { + this.eachInChannel({channelId: data.channel._id}, async ({ session: remoteSession }) => { + let id; + if (policies.allowSavingMessages) { + const message = await Message.create({ + author: session.user._id, + channel: data.channel._id, + content: messageContent, + createdAt: new Date().getTime() + }); + id = message._id; + } else { + id = new mongoose.Types.ObjectId(); + } + remoteSession.send("EVENT_CREATE_MESSAGE", { content: messageContent, channel: { @@ -242,18 +257,9 @@ class GatewayHandler { _id: session.user._id, username: session.user.username }, - _id: uuid.v4() + _id: id }); }); - - if (session.hasAttribute(attributes.SAVE_MESSAGES)) { - await Message.create({ - author: session.user._id, - channel: data.channel._id, - content: messageContent, - createdAt: new Date().getTime() - }); - } } } diff --git a/brainlet/config.js b/brainlet/config.js index d689a76..df0cb3d 100755 --- a/brainlet/config.js +++ b/brainlet/config.js @@ -18,6 +18,9 @@ module.exports = { allowAccountCreation: true, allowLogin: true, allowGatewayConnection: true, + // The policy below will make all messages sent over the gateway to be in plain text saved to the database. + // This is experimental and dangerous, and, as such, should generally not be used. + allowSavingMessages: true, perUserMaxGatewayConnections: 4 }, /* @@ -35,7 +38,6 @@ module.exports = { gatewayPingInterval: 15000, gatewayPingCheckInterval: 4500, clientFacingPingInterval: 14750, - unsafeStoreMessages: false, bcryptRounds: 10, roleMap: { "BANNED": 0,