feat: #11881, limit room names

isekai-main
Barış Soner Uşaklı 2 years ago
parent 8996804829
commit 9349cb63cb

@ -64,6 +64,7 @@
"maximumAboutMeLength": 1000,
"maximumUsersInChatRoom": 0,
"maximumChatMessageLength": 1000,
"maximumChatRoomNameLength": 50,
"maximumProfileImageSize": 256,
"maximumCoverImageSize": 2048,
"profileImageDimension": 200,

@ -4,6 +4,7 @@
"disable-editing": "Disable chat message editing/deletion",
"disable-editing-help": "Administrators and global moderators are exempt from this restriction",
"max-length": "Maximum length of chat messages",
"max-chat-room-name-length": "Maximum length of chat room names",
"max-room-size": "Maximum number of users in chat rooms",
"delay": "Time between chat messages in milliseconds",
"notification-delay": "Notification delay for chat messages. (0 for no delay)",

@ -191,7 +191,7 @@
"chat-room-does-not-exist": "Chat room does not exist.",
"cant-add-users-to-chat-room": "Can't add users to chat room.",
"cant-remove-users-from-chat-room": "Can't remove users from chat room.",
"chat-room-name-too-long": "Chat room name too long.",
"chat-room-name-too-long": "Chat room name too long. Names can't be longer than %1 characters.",
"already-voting-for-this-post": "You have already voted for this post.",
"reputation-system-disabled": "Reputation system is disabled.",

@ -396,29 +396,30 @@ define('forum/chats', [
});
};
Chats.addRenameHandler = function (roomId, buttonEl, roomName) {
let modal;
buttonEl.on('click', function () {
app.parseAndTranslate('modals/rename-room', {
name: roomName || ajaxify.data.roomName,
}, function (html) {
modal = bootbox.dialog({
title: '[[modules:chat.rename-room]]',
message: html,
onEscape: true,
buttons: {
save: {
label: '[[global:save]]',
className: 'btn-primary',
callback: function () {
api.put(`/chats/${roomId}`, {
name: modal.find('#roomName').val(),
}).catch(alerts.error);
},
Chats.addRenameHandler = function (roomId, buttonEl) {
buttonEl.on('click', async function () {
const { roomName } = await api.get(`/chats/${roomId}`);
const html = await app.parseAndTranslate('modals/rename-room', {
name: roomName,
});
const modal = bootbox.dialog({
title: '[[modules:chat.rename-room]]',
message: html,
onEscape: true,
buttons: {
save: {
label: '[[global:save]]',
className: 'btn-primary',
callback: function () {
api.put(`/chats/${roomId}`, {
name: modal.find('#roomName').val(),
}).then(() => {
modal.modal('hide');
}).catch(alerts.error);
return false;
},
},
});
},
});
});
};
@ -586,7 +587,15 @@ define('forum/chats', [
if (roomEl.length) {
const titleEl = roomEl.find('[component="chat/room/title"]');
ajaxify.data.roomName = data.newName;
titleEl.text(data.newName);
titleEl.translateText(data.newName ? data.newName : ajaxify.data.usernames);
}
const titleEl = $(`[component="chat/main-wrapper"][data-roomid="${data.roomId}"] [component="chat/header/title"]`);
if (titleEl.length) {
titleEl.html(
data.newName ?
`<i class="fa ${ajaxify.data.icon} text-muted"></i> ${data.newName}` :
ajaxify.data.chatWithMessage
);
}
});

@ -232,9 +232,18 @@ define('chat', [
};
module.onRoomRename = function (data) {
const newTitle = $('<div></div>').html(data.newName).text();
const modal = module.getModal(data.roomId);
modal.find('[component="chat/room/name"]').text(newTitle);
const titleEl = modal.find('[component="chat/room/name"]');
const icon = titleEl.attr('data-icon');
if (titleEl.length) {
titleEl.html(
data.newName ?
`<i class="fa ${icon} text-muted"></i> ${data.newName}` :
data.chatWithMessage
);
}
const newTitle = $('<div></div>').html(data.newName).text();
taskbar.update('chat', modal.attr('data-uuid'), {
title: newTitle,
});
@ -347,7 +356,7 @@ define('chat', [
});
Chats.addActionHandlers(chatModal.find('[component="chat/messages"]'), roomId);
Chats.addRenameHandler(roomId, chatModal.find('[data-action="rename"]'), data.roomName);
Chats.addRenameHandler(roomId, chatModal.find('[data-action="rename"]'));
Chats.addLeaveHandler(roomId, chatModal.find('[data-action="leave"]'));
Chats.addDeleteHandler(roomId, chatModal.find('[data-action="delete"]'));
Chats.addSendHandlers(roomId, chatModal.find('.chat-input'), chatModal.find('[data-action="send"]'));

@ -103,17 +103,10 @@ chatsAPI.update = async (caller, data) => {
}
if (data.hasOwnProperty('name')) {
if (!data.name) {
if (!data.name && data.name !== '') {
throw new Error('[[error:invalid-data]]');
}
await messaging.renameRoom(caller.uid, data.roomId, data.name);
const ioRoom = require('../socket.io').in(`chat_room_${data.roomId}`);
if (ioRoom) {
ioRoom.emit('event:chats.roomRename', {
roomId: data.roomId,
newName: validator.escape(String(data.name)),
});
}
}
const [roomData, isAdmin] = await Promise.all([
messaging.getRoomData(data.roomId),
@ -130,9 +123,20 @@ chatsAPI.update = async (caller, data) => {
if (data.hasOwnProperty('notificationSetting') && isAdmin) {
await db.setObjectField(`chat:room:${data.roomId}`, 'notificationSetting', data.notificationSetting);
}
return messaging.loadRoom(caller.uid, {
const loadedRoom = await messaging.loadRoom(caller.uid, {
roomId: data.roomId,
});
if (data.hasOwnProperty('name')) {
const ioRoom = require('../socket.io').in(`chat_room_${data.roomId}`);
if (ioRoom) {
ioRoom.emit('event:chats.roomRename', {
roomId: data.roomId,
newName: validator.escape(String(data.name)),
chatWithMessage: loadedRoom.chatWithMessage,
});
}
}
return loadedRoom;
};
chatsAPI.rename = async (caller, data) => {

@ -213,8 +213,8 @@ Messaging.getRecentChats = async (callerUid, uid, start, stop) => {
});
room.users = room.users.filter(user => user && parseInt(user.uid, 10));
room.lastUser = room.users[0];
room.usernames = Messaging.generateUsernames(room.users, uid);
room.chatWithMessage = await Messaging.generateChatWithMessage(room.users, uid, results.settings.userLang);
room.usernames = Messaging.generateUsernames(room, uid);
room.chatWithMessage = await Messaging.generateChatWithMessage(room, uid, results.settings.userLang);
}
}));
@ -228,21 +228,21 @@ Messaging.getRecentChats = async (callerUid, uid, start, stop) => {
});
};
Messaging.generateUsernames = function (users, excludeUid) {
users = users.filter(u => u && parseInt(u.uid, 10) !== excludeUid);
Messaging.generateUsernames = function (room, excludeUid) {
const users = room.users.filter(u => u && parseInt(u.uid, 10) !== excludeUid);
const usernames = users.map(u => u.username);
if (users.length > 3) {
return translator.compile(
'modules:chat.usernames-and-x-others',
usernames.slice(0, 2).join(', '),
usernames.length - 2
room.userCount - 2
);
}
return usernames.join(', ');
};
Messaging.generateChatWithMessage = async function (users, callerUid, userLang) {
users = users.filter(u => u && parseInt(u.uid, 10) !== callerUid);
Messaging.generateChatWithMessage = async function (room, callerUid, userLang) {
const users = room.users.filter(u => u && parseInt(u.uid, 10) !== callerUid);
const usernames = users.map(u => `<a href="${relative_path}/uid/${u.uid}">${u.username}</a>`);
let compiled = '';
if (!users.length) {
@ -252,7 +252,7 @@ Messaging.generateChatWithMessage = async function (users, callerUid, userLang)
compiled = translator.compile(
'modules:chat.chat-with-usernames-and-x-others',
usernames.slice(0, 2).join(', '),
usernames.length - 2
room.userCount - 2
);
} else {
compiled = translator.compile(

@ -78,6 +78,10 @@ module.exports = function (Messaging) {
if (Array.isArray(data)) { // old usage second param used to be toUids
data = { uids: data };
}
if (data.hasOwnProperty('roomName')) {
checkRoomName(data.roomName);
}
const now = Date.now();
const roomId = await db.incrObjectField('global', 'nextChatRoomId');
const room = {
@ -87,7 +91,7 @@ module.exports = function (Messaging) {
};
if (data.hasOwnProperty('roomName') && data.roomName) {
room.roomName = String(data.roomName);
room.roomName = String(data.roomName).trim();
}
if (Array.isArray(data.groups) && data.groups.length) {
room.groups = JSON.stringify(data.groups);
@ -397,13 +401,8 @@ module.exports = function (Messaging) {
};
Messaging.renameRoom = async function (uid, roomId, newName) {
if (!newName) {
throw new Error('[[error:invalid-data]]');
}
newName = newName.trim();
if (newName.length > 75) {
throw new Error('[[error:chat-room-name-too-long]]');
}
newName = String(newName).trim();
checkRoomName(newName);
const payload = await plugins.hooks.fire('filter:chat.renameRoom', {
uid: uid,
@ -424,6 +423,15 @@ module.exports = function (Messaging) {
});
};
function checkRoomName(roomName) {
if (!roomName && roomName !== '') {
throw new Error('[[error:invalid-room-name]]');
}
if (roomName.length > meta.config.maximumChatRoomNameLength) {
throw new Error(`[[error:chat-room-name-too-long, ${meta.config.maximumChatRoomNameLength}]]`);
}
}
Messaging.canReply = async (roomId, uid) => {
const inRoom = await db.isSortedSetMember(`chat:room:${roomId}:uids`, uid);
const data = await plugins.hooks.fire('filter:messaging.canReply', { uid: uid, roomId: roomId, inRoom: inRoom, canReply: inRoom });
@ -517,8 +525,8 @@ module.exports = function (Messaging) {
room.canReply = canReply;
room.groupChat = room.hasOwnProperty('groupChat') ? room.groupChat : users.length > 2;
room.icon = Messaging.getRoomIcon(room);
room.usernames = Messaging.generateUsernames(users, uid);
room.chatWithMessage = await Messaging.generateChatWithMessage(users, uid, settings.userLang);
room.usernames = Messaging.generateUsernames(room, uid);
room.chatWithMessage = await Messaging.generateChatWithMessage(room, uid, settings.userLang);
room.maximumUsersInChatRoom = meta.config.maximumUsersInChatRoom;
room.maximumChatMessageLength = meta.config.maximumChatMessageLength;
room.showUserInput = !room.maximumUsersInChatRoom || room.maximumUsersInChatRoom > 2;

@ -31,6 +31,11 @@
<input id="chatDeleteDuration" type="text" class="form-control" value="0" data-field="chatDeleteDuration">
</div>
<div class="mb-3">
<label class="form-label" for="maximumChatRoomNameLength">[[admin/settings/chat:max-chat-room-name-length]]</label>
<input id="maximumChatRoomNameLength" type="text" class="form-control" value="50" data-field="maximumChatRoomNameLength">
</div>
<div class="mb-3">
<label class="form-label" for="maximumChatMessageLength">[[admin/settings/chat:max-length]]</label>
<input id="maximumChatMessageLength" type="text" class="form-control" value="1000" data-field="maximumChatMessageLength">

Loading…
Cancel
Save