diff --git a/public/openapi/write.yaml b/public/openapi/write.yaml index 6e5904cbf2..819caf9e29 100644 --- a/public/openapi/write.yaml +++ b/public/openapi/write.yaml @@ -204,6 +204,8 @@ paths: $ref: 'write/chats/roomId/users.yaml' /chats/{roomId}/users/{uid}: $ref: 'write/chats/roomId/users/uid.yaml' + /chats/{roomId}/owners/{uid}: + $ref: 'write/chats/roomId/owners/uid.yaml' /chats/{roomId}/messages: $ref: 'write/chats/roomId/messages.yaml' /chats/{roomId}/messages/{mid}: diff --git a/public/openapi/write/chats/roomId/owners/uid.yaml b/public/openapi/write/chats/roomId/owners/uid.yaml new file mode 100644 index 0000000000..f09df7e122 --- /dev/null +++ b/public/openapi/write/chats/roomId/owners/uid.yaml @@ -0,0 +1,62 @@ +put: + tags: + - chats + summary: add owner to room + description: This operation adds a user as a room owner. + parameters: + - in: path + name: roomId + schema: + type: number + required: true + description: a valid chat room id + example: 1 + - in: path + name: uid + schema: + type: number + required: true + description: a valid user id + example: 4 + responses: + '200': + description: user successfully added as room owner. + content: + application/json: + schema: + type: object + properties: + status: + $ref: ../../../../components/schemas/Status.yaml#/Status + response: {} +delete: + tags: + - chats + summary: remove owner from room + description: This operation removes a user as a room owner. + parameters: + - in: path + name: roomId + schema: + type: number + required: true + description: a valid chat room id + example: 1 + - in: path + name: uid + schema: + type: number + required: true + description: a valid user id + example: 4 + responses: + '200': + description: user successfully removed as room owner. + content: + application/json: + schema: + type: object + properties: + status: + $ref: ../../../../components/schemas/Status.yaml#/Status + response: {} \ No newline at end of file diff --git a/public/src/client/chats/manage.js b/public/src/client/chats/manage.js index a69cafc4f4..fce6db3505 100644 --- a/public/src/client/chats/manage.js +++ b/public/src/client/chats/manage.js @@ -112,11 +112,11 @@ define('forum/chats/manage', [ function addToggleOwnerHandler(roomId, modal) { modal.on('click', '[data-action="toggleOwner"]', async function () { const uid = parseInt(this.getAttribute('data-uid'), 10); - const $this = $(this); - await socket.emit('modules.chats.toggleOwner', { roomId: roomId, uid: uid }); - $this.parents('[data-uid]') - .find('[component="chat/manage/user/owner/icon"]') - .toggleClass('hidden'); + const iconEl = modal.get(0).querySelector(`[component="chat/manage/user/list"] > [data-uid="${uid}"] [component="chat/manage/user/owner/icon"]`); + const current = !iconEl.classList.contains('hidden'); + + await api[current ? 'del' : 'put'](`/chats/${roomId}/owners/${uid}`); + iconEl.classList.toggle('hidden'); }); } diff --git a/src/api/chats.js b/src/api/chats.js index 88b0a27d2c..e0d1429803 100644 --- a/src/api/chats.js +++ b/src/api/chats.js @@ -269,6 +269,20 @@ chatsAPI.kick = async (caller, data) => { return chatsAPI.users(caller, data); }; +chatsAPI.toggleOwner = async (caller, { roomId, uid, state }) => { + const [isAdmin, inRoom, isRoomOwner] = await Promise.all([ + user.isAdministrator(caller.uid), + messaging.isUserInRoom(caller.uid, roomId), + messaging.isRoomOwner(caller.uid, roomId), + ]); + + if (!isAdmin && (!inRoom || !isRoomOwner)) { + throw new Error('[[error:no-privileges]]'); + } + + return await messaging.toggleOwner(uid, roomId, state); +}; + chatsAPI.listMessages = async (caller, { uid, roomId, start, direction = null }) => { const count = 50; let stop = start + count - 1; diff --git a/src/controllers/write/chats.js b/src/controllers/write/chats.js index 86ab6012ee..04f87b3efd 100644 --- a/src/controllers/write/chats.js +++ b/src/controllers/write/chats.js @@ -126,6 +126,12 @@ Chats.kickUser = async (req, res) => { helpers.formatApiResponse(200, res, users); }; +Chats.toggleOwner = async (req, res) => { + const state = req.method === 'PUT'; + await api.chats.toggleOwner(req, { state, ...req.params }); + helpers.formatApiResponse(200, res); +}; + Chats.messages = {}; Chats.messages.list = async (req, res) => { const uid = req.query.uid || req.uid; diff --git a/src/routes/write/chats.js b/src/routes/write/chats.js index 73ee54815a..4e73ee0f37 100644 --- a/src/routes/write/chats.js +++ b/src/routes/write/chats.js @@ -29,6 +29,9 @@ module.exports = function () { setupApiRoute(router, 'delete', '/:roomId/users', [...middlewares, middleware.assert.room, middleware.checkRequired.bind(null, ['uids'])], controllers.write.chats.kick); setupApiRoute(router, 'delete', '/:roomId/users/:uid', [...middlewares, middleware.assert.room, middleware.assert.user], controllers.write.chats.kickUser); + setupApiRoute(router, 'put', '/:roomId/owners/:uid', [...middlewares, middleware.assert.room, middleware.assert.user], controllers.write.chats.toggleOwner); + setupApiRoute(router, 'delete', '/:roomId/owners/:uid', [...middlewares, middleware.assert.room, middleware.assert.user], controllers.write.chats.toggleOwner); + setupApiRoute(router, 'get', '/:roomId/messages', [...middlewares, middleware.assert.room], controllers.write.chats.messages.list); setupApiRoute(router, 'get', '/:roomId/messages/:mid', [...middlewares, middleware.assert.room, middleware.assert.message], controllers.write.chats.messages.get); setupApiRoute(router, 'put', '/:roomId/messages/:mid', [...middlewares, middleware.assert.room, middleware.assert.message], controllers.write.chats.messages.edit); diff --git a/src/socket.io/modules.js b/src/socket.io/modules.js index 910713d9cf..699a6850fc 100644 --- a/src/socket.io/modules.js +++ b/src/socket.io/modules.js @@ -170,20 +170,13 @@ SocketModules.chats.searchMembers = async function (socket, data) { }; SocketModules.chats.toggleOwner = async (socket, data) => { + sockets.warnDeprecated(socket, 'PUT/DELETE /api/v3/chats/:roomId/owners/:uid'); + if (!data || !data.uid || !data.roomId) { throw new Error('[[error:invalid-data]]'); } - const [isAdmin, inRoom, isRoomOwner] = await Promise.all([ - user.isAdministrator(socket.uid), - Messaging.isUserInRoom(socket.uid, data.roomId), - Messaging.isRoomOwner(socket.uid, data.roomId), - ]); - if (!isAdmin && (!inRoom || !isRoomOwner)) { - throw new Error('[[error:no-privileges]]'); - } - - await Messaging.toggleOwner(data.uid, data.roomId); + await api.chats.toggleOwner(socket, data); }; SocketModules.chats.setNotificationSetting = async (socket, data) => {