2015-12-15 14:10:32 +02:00
|
|
|
'use strict';
|
|
|
|
|
|
2024-10-10 13:04:07 -04:00
|
|
|
const db = require('../database');
|
2020-01-23 22:19:15 -05:00
|
|
|
const meta = require('../meta');
|
|
|
|
|
const user = require('../user');
|
2020-07-07 17:31:05 -04:00
|
|
|
const plugins = require('../plugins');
|
2025-10-22 12:51:50 -04:00
|
|
|
const activitypub = require('../activitypub');
|
2020-10-13 22:42:50 -04:00
|
|
|
const privileges = require('../privileges');
|
2024-10-15 11:27:54 -04:00
|
|
|
const utils = require('../utils');
|
2015-12-15 14:10:32 +02:00
|
|
|
|
2020-01-23 22:19:15 -05:00
|
|
|
const sockets = require('../socket.io');
|
2015-12-15 14:10:32 +02:00
|
|
|
|
|
|
|
|
|
2016-10-13 11:43:39 +02:00
|
|
|
module.exports = function (Messaging) {
|
2019-07-22 11:18:13 -04:00
|
|
|
Messaging.editMessage = async (uid, mid, roomId, content) => {
|
2020-07-06 16:27:07 -04:00
|
|
|
await Messaging.checkContent(content);
|
2024-10-10 13:04:07 -04:00
|
|
|
const isPublic = parseInt(await db.getObjectField(`chat:room:${roomId}`, 'public'), 10) === 1;
|
2019-07-22 11:18:13 -04:00
|
|
|
const raw = await Messaging.getMessageField(mid, 'content');
|
|
|
|
|
if (raw === content) {
|
|
|
|
|
return;
|
|
|
|
|
}
|
2020-07-07 17:31:05 -04:00
|
|
|
|
2020-11-20 16:06:26 -05:00
|
|
|
const payload = await plugins.hooks.fire('filter:messaging.edit', {
|
2019-07-22 11:18:13 -04:00
|
|
|
content: content,
|
|
|
|
|
edited: Date.now(),
|
|
|
|
|
});
|
2015-12-15 14:10:32 +02:00
|
|
|
|
2020-07-07 17:31:05 -04:00
|
|
|
if (!String(payload.content).trim()) {
|
|
|
|
|
throw new Error('[[error:invalid-chat-message]]');
|
|
|
|
|
}
|
|
|
|
|
await Messaging.setMessageFields(mid, payload);
|
|
|
|
|
|
2019-07-22 11:18:13 -04:00
|
|
|
// Propagate this change to users in the room
|
2023-07-12 13:03:54 -04:00
|
|
|
const messages = await Messaging.getMessagesData([mid], uid, roomId, true);
|
2023-08-28 12:10:42 -04:00
|
|
|
if (messages[0]) {
|
|
|
|
|
const roomName = messages[0].deleted ? `uid_${uid}` : `chat_room_${roomId}`;
|
|
|
|
|
sockets.in(roomName).emit('event:chats.edit', {
|
|
|
|
|
messages: messages,
|
|
|
|
|
});
|
2024-10-10 13:04:07 -04:00
|
|
|
|
2024-10-15 11:27:54 -04:00
|
|
|
if (!isPublic && utils.isNumber(messages[0].fromuid)) {
|
2025-10-22 12:51:50 -04:00
|
|
|
activitypub.out.update.privateNote(messages[0].fromuid, messages[0]);
|
2024-10-10 13:04:07 -04:00
|
|
|
}
|
2023-08-28 12:10:42 -04:00
|
|
|
}
|
|
|
|
|
|
2023-07-27 17:32:35 -04:00
|
|
|
plugins.hooks.fire('action:messaging.edit', {
|
|
|
|
|
message: { ...messages[0], content: payload.content },
|
|
|
|
|
});
|
2017-12-11 10:53:29 -05:00
|
|
|
};
|
|
|
|
|
|
2019-07-22 11:18:13 -04:00
|
|
|
const canEditDelete = async (messageId, uid, type) => {
|
|
|
|
|
let durationConfig = '';
|
2017-12-11 10:53:29 -05:00
|
|
|
if (type === 'edit') {
|
|
|
|
|
durationConfig = 'chatEditDuration';
|
|
|
|
|
} else if (type === 'delete') {
|
|
|
|
|
durationConfig = 'chatDeleteDuration';
|
|
|
|
|
}
|
|
|
|
|
|
2021-12-20 11:30:43 -05:00
|
|
|
const exists = await Messaging.messageExists(messageId);
|
|
|
|
|
if (!exists) {
|
|
|
|
|
throw new Error('[[error:invalid-mid]]');
|
|
|
|
|
}
|
|
|
|
|
|
2020-12-28 10:20:52 -05:00
|
|
|
const isAdminOrGlobalMod = await user.isAdminOrGlobalMod(uid);
|
|
|
|
|
|
2018-10-21 16:47:51 -04:00
|
|
|
if (meta.config.disableChat) {
|
2019-07-22 11:18:13 -04:00
|
|
|
throw new Error('[[error:chat-disabled]]');
|
2020-12-28 10:20:52 -05:00
|
|
|
} else if (!isAdminOrGlobalMod && meta.config.disableChatMessageEditing) {
|
2019-07-22 11:18:13 -04:00
|
|
|
throw new Error('[[error:chat-message-editing-disabled]]');
|
2015-12-15 14:10:32 +02:00
|
|
|
}
|
|
|
|
|
|
2020-10-13 22:42:50 -04:00
|
|
|
const userData = await user.getUserFields(uid, ['banned']);
|
2019-07-22 11:18:13 -04:00
|
|
|
if (userData.banned) {
|
|
|
|
|
throw new Error('[[error:user-banned]]');
|
|
|
|
|
}
|
2020-12-28 10:20:52 -05:00
|
|
|
|
2023-10-17 13:19:25 -04:00
|
|
|
const canChat = await privileges.global.can(['chat', 'chat:privileged'], uid);
|
|
|
|
|
if (!canChat.includes(true)) {
|
2020-10-13 22:42:50 -04:00
|
|
|
throw new Error('[[error:no-privileges]]');
|
2019-07-22 11:18:13 -04:00
|
|
|
}
|
2015-12-15 14:10:32 +02:00
|
|
|
|
2020-12-28 10:20:52 -05:00
|
|
|
const messageData = await Messaging.getMessageFields(messageId, ['fromuid', 'timestamp', 'system']);
|
|
|
|
|
if (isAdminOrGlobalMod && !messageData.system) {
|
2019-07-22 11:18:13 -04:00
|
|
|
return;
|
|
|
|
|
}
|
2020-12-28 10:20:52 -05:00
|
|
|
|
2020-01-23 22:19:15 -05:00
|
|
|
const chatConfigDuration = meta.config[durationConfig];
|
2019-07-22 11:18:13 -04:00
|
|
|
if (chatConfigDuration && Date.now() - messageData.timestamp > chatConfigDuration * 1000) {
|
2021-02-03 23:59:08 -07:00
|
|
|
throw new Error(`[[error:chat-${type}-duration-expired, ${meta.config[durationConfig]}]]`);
|
2019-07-22 11:18:13 -04:00
|
|
|
}
|
|
|
|
|
|
2024-10-17 11:23:08 -04:00
|
|
|
if (String(messageData.fromuid) === String(uid) && !messageData.system) {
|
2019-07-22 11:18:13 -04:00
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
2021-02-03 23:59:08 -07:00
|
|
|
throw new Error(`[[error:cant-${type}-chat-message]]`);
|
2019-07-22 11:18:13 -04:00
|
|
|
};
|
2017-12-11 10:53:29 -05:00
|
|
|
|
2019-07-22 11:18:13 -04:00
|
|
|
Messaging.canEdit = async (messageId, uid) => await canEditDelete(messageId, uid, 'edit');
|
|
|
|
|
Messaging.canDelete = async (messageId, uid) => await canEditDelete(messageId, uid, 'delete');
|
2023-08-28 15:57:30 -04:00
|
|
|
|
|
|
|
|
Messaging.canPin = async (roomId, uid) => {
|
|
|
|
|
const [isAdmin, isGlobalMod, inRoom, isRoomOwner] = await Promise.all([
|
|
|
|
|
user.isAdministrator(uid),
|
|
|
|
|
user.isGlobalModerator(uid),
|
|
|
|
|
Messaging.isUserInRoom(uid, roomId),
|
|
|
|
|
Messaging.isRoomOwner(uid, roomId),
|
|
|
|
|
]);
|
|
|
|
|
if (!isAdmin && !isGlobalMod && (!inRoom || !isRoomOwner)) {
|
|
|
|
|
throw new Error('[[error:no-privileges]]');
|
|
|
|
|
}
|
|
|
|
|
};
|
2017-02-18 02:30:48 -07:00
|
|
|
};
|