Files
NodeBB/src/socket.io/modules.js
2023-11-20 13:06:26 -05:00

226 lines
6.2 KiB
JavaScript

'use strict';
/**
* v4 note — all methods here are deprecated and can be removed except for:
* - SocketModules.chats.(enter|leave)(Public)? => related to socket.io rooms
*/
const Messaging = require('../messaging');
const utils = require('../utils');
const user = require('../user');
const groups = require('../groups');
const api = require('../api');
const sockets = require('.');
const SocketModules = module.exports;
SocketModules.chats = {};
SocketModules.settings = {};
/* Chat */
SocketModules.chats.getRaw = async function (socket, data) {
sockets.warnDeprecated(socket, 'GET /api/v3/chats/:roomId/messages/:mid/raw');
if (!data || !data.hasOwnProperty('mid')) {
throw new Error('[[error:invalid-data]]');
}
const roomId = await Messaging.getMessageField(data.mid, 'roomId');
const { content } = await api.chats.getRawMessage(socket, {
mid: data.mid,
roomId,
});
return content;
};
SocketModules.chats.isDnD = async function (socket, uid) {
sockets.warnDeprecated(socket, 'GET /api/v3/users/:uid/status OR HEAD /api/v3/users/:uid/status/:status');
const { status } = await api.users.getStatus(socket, { uid });
return status === 'dnd';
};
SocketModules.chats.canMessage = async function (socket, roomId) {
sockets.warnDeprecated(socket);
await Messaging.canMessageRoom(socket.uid, roomId);
};
SocketModules.chats.markAllRead = async function (socket) {
sockets.warnDeprecated(socket);
await Messaging.markAllRead(socket.uid);
Messaging.pushUnreadCount(socket.uid);
};
SocketModules.chats.getRecentChats = async function (socket, data) {
sockets.warnDeprecated(socket, 'GET /api/v3/chats');
if (!data || !utils.isNumber(data.after) || !utils.isNumber(data.uid)) {
throw new Error('[[error:invalid-data]]');
}
const start = parseInt(data.after, 10);
const stop = start + 9;
const { uid } = data;
return api.chats.list(socket, { uid, start, stop });
};
SocketModules.chats.hasPrivateChat = async function (socket, uid) {
sockets.warnDeprecated(socket, 'GET /api/v3/users/:uid/chat');
if (socket.uid <= 0 || uid <= 0) {
throw new Error('[[error:invalid-data]]');
}
// despite the `has` prefix, this method actually did return the roomId.
const { roomId } = await api.users.getPrivateRoomId(socket, { uid });
return roomId;
};
SocketModules.chats.getIP = async function (socket, mid) {
sockets.warnDeprecated(socket, 'GET /api/v3/chats/:roomId/messages/:mid/ip');
const { ip } = await api.chats.getIpAddress(socket, { mid });
return ip;
};
SocketModules.chats.getUnreadCount = async function (socket) {
sockets.warnDeprecated(socket, 'GET /api/v3/chats/unread');
const { count } = await api.chats.getUnread(socket);
return count;
};
SocketModules.chats.enter = async function (socket, roomIds) {
await joinLeave(socket, roomIds, 'join');
};
SocketModules.chats.leave = async function (socket, roomIds) {
await joinLeave(socket, roomIds, 'leave');
};
SocketModules.chats.enterPublic = async function (socket, roomIds) {
await joinLeave(socket, roomIds, 'join', 'chat_room_public');
};
SocketModules.chats.leavePublic = async function (socket, roomIds) {
await joinLeave(socket, roomIds, 'leave', 'chat_room_public');
};
async function joinLeave(socket, roomIds, method, prefix = 'chat_room') {
if (!(socket.uid > 0)) {
throw new Error('[[error:not-allowed]]');
}
if (!Array.isArray(roomIds)) {
roomIds = [roomIds];
}
if (roomIds.length) {
const [isAdmin, inRooms, roomData] = await Promise.all([
user.isAdministrator(socket.uid),
Messaging.isUserInRoom(socket.uid, roomIds),
Messaging.getRoomsData(roomIds, ['public', 'groups']),
]);
await Promise.all(roomIds.map(async (roomId, idx) => {
const isPublic = roomData[idx] && roomData[idx].public;
const roomGroups = roomData[idx] && roomData[idx].groups;
if (isAdmin ||
(
inRooms[idx] &&
(!isPublic || !roomGroups.length || await groups.isMemberOfAny(socket.uid, roomGroups))
)
) {
socket[method](`${prefix}_${roomId}`);
}
}));
}
}
SocketModules.chats.sortPublicRooms = async function (socket, data) {
sockets.warnDeprecated(socket, 'PUT /api/v3/chats/sort');
if (!data) {
throw new Error('[[error:invalid-data]]');
}
await api.chats.sortPublicRooms(socket, data);
};
SocketModules.chats.searchMembers = async function (socket, data) {
sockets.warnDeprecated(socket, 'GET /api/v3/search/chats/:roomId/users?query=');
if (!data || !data.roomId) {
throw new Error('[[error:invalid-data]]');
}
// parameter renamed; backwards compatibility
data.query = data.username;
delete data.username;
return await api.search.roomUsers(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]]');
}
await api.chats.toggleOwner(socket, data);
};
SocketModules.chats.setNotificationSetting = async (socket, data) => {
sockets.warnDeprecated(socket, 'PUT/DELETE /api/v3/chats/:roomId/watch');
if (!data || !utils.isNumber(data.value) || !data.roomId) {
throw new Error('[[error:invalid-data]]');
}
await api.chats.watch(socket, data);
};
SocketModules.chats.searchMessages = async (socket, data) => {
sockets.warnDeprecated(socket, 'GET /api/v3/search/chats/:roomId/messages');
if (!data || !utils.isNumber(data.roomId) || !data.content) {
throw new Error('[[error:invalid-data]]');
}
// parameter renamed; backwards compatibility
data.query = data.content;
delete data.content;
return await api.search.roomMessages(socket, data);
};
SocketModules.chats.loadPinnedMessages = async (socket, data) => {
sockets.warnDeprecated(socket, 'GET /api/v3/chats/:roomId/messages/pinned');
if (!data || !data.roomId || !utils.isNumber(data.start)) {
throw new Error('[[error:invalid-data]]');
}
const { messages } = await api.chats.getPinnedMessages(socket, data);
return messages;
};
SocketModules.chats.typing = async (socket, data) => {
sockets.warnDeprecated(socket, 'PUT /api/v3/chats/:roomId/typing');
if (!data) {
throw new Error('[[error:invalid-data]]');
}
// `username` is now inferred from caller uid
delete data.username;
await api.chats.toggleTyping(socket, data);
};
require('../promisify')(SocketModules);