From bc06ef87bba3733265e922cf73c6ad66a98cbdbb Mon Sep 17 00:00:00 2001 From: Richard Hansen Date: Fri, 8 Apr 2022 14:35:12 -0400 Subject: [PATCH] chat: Move HTTP API handlers to `chat.js` --- src/node/chat.js | 73 ++++++++++++++++++++++++++++++++++- src/node/db/API.js | 95 +--------------------------------------------- 2 files changed, 72 insertions(+), 96 deletions(-) diff --git a/src/node/chat.js b/src/node/chat.js index 62f0f0fb3..e14fdb2f6 100644 --- a/src/node/chat.js +++ b/src/node/chat.js @@ -1,6 +1,7 @@ 'use strict'; const ChatMessage = require('../static/js/ChatMessage'); +const CustomError = require('./utils/customError'); const api = require('./db/API'); const assert = require('assert').strict; const authorManager = require('./db/AuthorManager'); @@ -185,9 +186,77 @@ exports.socketio = (hookName, {io}) => { socketio = io; }; +const getPadSafe = async (padId) => { + if (typeof padId !== 'string') throw new CustomError('padID is not a string', 'apierror'); + if (!padManager.isValidPadId(padId)) throw new CustomError('padID is not valid', 'apierror'); + if (!await padManager.doesPadExist(padId)) throw new CustomError('pad not found', 'apierror'); + return await padManager.getPad(padId); +}; + api.registerChatHandlers({ - getChatMessages, - sendChatMessageToPadClients, + /** + * appendChatMessage(padId, text, authorId, time), creates a chat message for the pad id, + * time is a timestamp + * + * Example returns: + * + * {code: 0, message:"ok", data: null} + * {code: 1, message:"padID does not exist", data: null} + */ + appendChatMessage: async (padId, text, authorId, time) => { + if (typeof text !== 'string') throw new CustomError('text is not a string', 'apierror'); + if (time === undefined || !Number.isInteger(Number.parseFloat(time))) time = Date.now(); + await sendChatMessageToPadClients(new ChatMessage(text, authorId, time), padId); + }, + + /** + * getChatHead(padId) returns the chatHead (last number of the last chat-message) of the pad + * + * Example returns: + * + * {code: 0, message:"ok", data: {chatHead: 42}} + * {code: 1, message:"padID does not exist", data: null} + */ + getChatHead: async (padId) => { + const pad = await getPadSafe(padId); + const {chatHead = -1} = pad; + return {chatHead}; + }, + + /** + * getChatHistory(padId, start, end), returns a part of or the whole chat-history of this pad + * + * Example returns: + * + * {"code":0,"message":"ok","data":{"messages":[ + * {"text":"foo","authorID":"a.foo","time":1359199533759,"userName":"test"}, + * {"text":"bar","authorID":"a.foo","time":1359199534622,"userName":"test"} + * ]}} + * + * {code: 1, message:"start is higher or equal to the current chatHead", data: null} + * + * {code: 1, message:"padID does not exist", data: null} + */ + getChatHistory: async (padId, start, end) => { + if (start && end) { + if (start < 0) throw new CustomError('start is below zero', 'apierror'); + if (end < 0) throw new CustomError('end is below zero', 'apierror'); + if (start > end) throw new CustomError('start is higher than end', 'apierror'); + } + const pad = await getPadSafe(padId); + const {chatHead = -1} = pad; + if (!start || !end) { + start = 0; + end = chatHead; + } + if (start > chatHead) { + throw new CustomError('start is higher than the current chatHead', 'apierror'); + } + if (end > chatHead) { + throw new CustomError('end is higher than the current chatHead', 'apierror'); + } + return {messages: await getChatMessages(pad, start, end)}; + }, }); pad.registerLegacyChatMethodHandlers({ diff --git a/src/node/db/API.js b/src/node/db/API.js index c2c51547f..b10aae06a 100644 --- a/src/node/db/API.js +++ b/src/node/db/API.js @@ -20,7 +20,6 @@ */ const Changeset = require('../../static/js/Changeset'); -const ChatMessage = require('../../static/js/ChatMessage'); const CustomError = require('../utils/customError'); const padManager = require('./PadManager'); const padMessageHandler = require('../handler/PadMessageHandler'); @@ -289,85 +288,7 @@ exports.setHTML = async (padID, html, authorId = '') => { * CHAT FUNCTIONS * **************** */ -let chat = null; -exports.registerChatHandlers = (handlers) => chat = handlers; - -/** -getChatHistory(padId, start, end), returns a part of or the whole chat-history of this pad - -Example returns: - -{"code":0,"message":"ok","data":{"messages":[ - {"text":"foo","authorID":"a.foo","time":1359199533759,"userName":"test"}, - {"text":"bar","authorID":"a.foo","time":1359199534622,"userName":"test"} -]}} - -{code: 1, message:"start is higher or equal to the current chatHead", data: null} - -{code: 1, message:"padID does not exist", data: null} -*/ -exports.getChatHistory = async (padID, start, end) => { - if (start && end) { - if (start < 0) { - throw new CustomError('start is below zero', 'apierror'); - } - if (end < 0) { - throw new CustomError('end is below zero', 'apierror'); - } - if (start > end) { - throw new CustomError('start is higher than end', 'apierror'); - } - } - - // get the pad - const pad = await getPadSafe(padID, true); - - const chatHead = pad.chatHead; - - // fall back to getting the whole chat-history if a parameter is missing - if (!start || !end) { - start = 0; - end = pad.chatHead; - } - - if (start > chatHead) { - throw new CustomError('start is higher than the current chatHead', 'apierror'); - } - if (end > chatHead) { - throw new CustomError('end is higher than the current chatHead', 'apierror'); - } - - // the the whole message-log and return it to the client - const messages = await chat.getChatMessages(pad, start, end); - - return {messages}; -}; - -/** -appendChatMessage(padID, text, authorID, time), creates a chat message for the pad id, -time is a timestamp - -Example returns: - -{code: 0, message:"ok", data: null} -{code: 1, message:"padID does not exist", data: null} -*/ -exports.appendChatMessage = async (padID, text, authorID, time) => { - // text is required - if (typeof text !== 'string') { - throw new CustomError('text is not a string', 'apierror'); - } - - // if time is not an integer value set time to current timestamp - if (time === undefined || !isInt(time)) { - time = Date.now(); - } - - // @TODO - missing getPadSafe() call ? - - // save chat message to database and send message to all connected clients - await chat.sendChatMessageToPadClients(new ChatMessage(text, authorID, time), padID); -}; +exports.registerChatHandlers = (handlers) => Object.assign(exports, handlers); /* *************** * PAD FUNCTIONS * @@ -735,20 +656,6 @@ Example returns: exports.checkToken = async () => { }; -/** -getChatHead(padID) returns the chatHead (last number of the last chat-message) of the pad - -Example returns: - -{code: 0, message:"ok", data: {chatHead: 42}} -{code: 1, message:"padID does not exist", data: null} -*/ -exports.getChatHead = async (padID) => { - // get the pad - const pad = await getPadSafe(padID, true); - return {chatHead: pad.chatHead}; -}; - /** createDiffHTML(padID, startRev, endRev) returns an object of diffs from 2 points in a pad