diff --git a/public/openapi/write.yaml b/public/openapi/write.yaml index 5054499dcd..d08236d274 100644 --- a/public/openapi/write.yaml +++ b/public/openapi/write.yaml @@ -194,6 +194,8 @@ paths: $ref: 'write/chats.yaml' /chats/unread: $ref: 'write/chats/unread.yaml' + /chats/sort: + $ref: 'write/chats/sort.yaml' /chats/{roomId}: $ref: 'write/chats/roomId.yaml' /chats/{roomId}/state: diff --git a/public/openapi/write/chats/sort.yaml b/public/openapi/write/chats/sort.yaml new file mode 100644 index 0000000000..df52c4a605 --- /dev/null +++ b/public/openapi/write/chats/sort.yaml @@ -0,0 +1,33 @@ +put: + tags: + - chats + summary: sort public chat rooms + description: This operation sorts the publicly available chat rooms. This is a privileged function; only superadmins can call it. + requestBody: + required: true + content: + application/json: + schema: + type: object + properties: + roomIds: + type: array + description: A list of room ids. + example: [1] + scores: + type: array + description: A list of sort orders associated with the passed-in `roomIds` + example: [0] + responses: + '200': + description: Public chat rooms successfully re-ordered. + content: + application/json: + schema: + type: object + properties: + status: + $ref: ../../components/schemas/Status.yaml#/Status + response: + type: object + properties: {} \ No newline at end of file diff --git a/public/src/client/chats.js b/public/src/client/chats.js index c45f14d6d7..222960945c 100644 --- a/public/src/client/chats.js +++ b/public/src/client/chats.js @@ -141,7 +141,7 @@ define('forum/chats', [ data.roomIds.push($(el).attr('data-roomid')); data.scores.push(idx); }); - await socket.emit('modules.chats.sortPublicRooms', data); + await api.put('/chats/sort', data); }, }); }); diff --git a/src/api/chats.js b/src/api/chats.js index 91e3dbd2b4..88b0a27d2c 100644 --- a/src/api/chats.js +++ b/src/api/chats.js @@ -84,6 +84,22 @@ chatsAPI.getUnread = async (caller) => { return { count }; }; +chatsAPI.sortPublicRooms = async (caller, { roomIds, scores }) => { + [roomIds, scores].forEach((arr) => { + if (!Array.isArray(arr) || !arr.every(value => isFinite(value))) { + throw new Error('[[error:invalid-data]]'); + } + }); + + const isAdmin = await user.isAdministrator(caller.uid); + if (!isAdmin) { + throw new Error('[[error:no-privileges]]'); + } + + await db.sortedSetAdd(`chat:rooms:public:order`, scores, roomIds); + require('../cache').del(`chat:rooms:public:order:all`); +}; + chatsAPI.get = async (caller, { uid, roomId }) => await messaging.loadRoom(caller.uid, { uid, roomId }); chatsAPI.post = async (caller, data) => { diff --git a/src/controllers/write/categories.js b/src/controllers/write/categories.js index 80ee961fbf..bb4ec84090 100644 --- a/src/controllers/write/categories.js +++ b/src/controllers/write/categories.js @@ -68,7 +68,6 @@ Categories.setWatchState = async (req, res) => { } else if (Object.keys(categories.watchStates).includes(state)) { state = categories.watchStates[state]; // convert to integer for backend processing } else { - console.log('throwing', cid, uid, state); throw new Error('[[error:invalid-data]]'); } diff --git a/src/controllers/write/chats.js b/src/controllers/write/chats.js index 87b1de3023..86ab6012ee 100644 --- a/src/controllers/write/chats.js +++ b/src/controllers/write/chats.js @@ -32,6 +32,13 @@ Chats.create = async (req, res) => { // currently only returns unread count, but open-ended for future additions if warranted. Chats.getUnread = async (req, res) => helpers.formatApiResponse(200, res, await api.chats.getUnread(req)); +Chats.sortPublicRooms = async (req, res) => { + const { roomIds, scores } = req.body; + await api.chats.sortPublicRooms(req, { roomIds, scores }); + + helpers.formatApiResponse(200, res); +}; + Chats.exists = async (req, res) => { // yes, this is fine. Room existence is checked via middleware :) helpers.formatApiResponse(200, res); diff --git a/src/routes/write/chats.js b/src/routes/write/chats.js index 5a42bcdc51..73ee54815a 100644 --- a/src/routes/write/chats.js +++ b/src/routes/write/chats.js @@ -14,6 +14,7 @@ module.exports = function () { setupApiRoute(router, 'post', '/', [...middlewares, middleware.checkRequired.bind(null, ['uids'])], controllers.write.chats.create); setupApiRoute(router, 'get', '/unread', [...middlewares], controllers.write.chats.getUnread); + setupApiRoute(router, 'put', '/sort', [...middlewares, middleware.checkRequired.bind(null, ['roomIds', 'scores'])], controllers.write.chats.sortPublicRooms); setupApiRoute(router, 'head', '/:roomId', [...middlewares, middleware.assert.room], controllers.write.chats.exists); setupApiRoute(router, 'get', '/:roomId', [...middlewares, middleware.assert.room], controllers.write.chats.get); diff --git a/src/socket.io/modules.js b/src/socket.io/modules.js index 0636fc23d5..9901b25c82 100644 --- a/src/socket.io/modules.js +++ b/src/socket.io/modules.js @@ -147,15 +147,13 @@ async function joinLeave(socket, roomIds, method, prefix = 'chat_room') { } SocketModules.chats.sortPublicRooms = async function (socket, data) { - if (!data || !Array.isArray(data.scores) || !Array.isArray(data.roomIds)) { + sockets.warnDeprecated(socket, 'PUT /api/v3/chats/sort'); + + if (!data) { throw new Error('[[error:invalid-data]]'); } - const isAdmin = await user.isAdministrator(socket.uid); - if (!isAdmin) { - throw new Error('[[error:no-privileges]]'); - } - await db.sortedSetAdd(`chat:rooms:public:order`, data.scores, data.roomIds); - require('../cache').del(`chat:rooms:public:order:all`); + + await api.chats.sortPublicRooms(socket, data); }; SocketModules.chats.searchMembers = async function (socket, data) {