diff --git a/app/channel-settings/server/methods/saveRoomSettings.js b/app/channel-settings/server/methods/saveRoomSettings.js index 62974e4754eb..5da1e591b523 100644 --- a/app/channel-settings/server/methods/saveRoomSettings.js +++ b/app/channel-settings/server/methods/saveRoomSettings.js @@ -19,6 +19,188 @@ import { saveStreamingOptions } from '../functions/saveStreamingOptions'; import { RoomSettingsEnum, roomTypes } from '../../../utils'; const fields = ['roomAvatar', 'featured', 'roomName', 'roomTopic', 'roomAnnouncement', 'roomCustomFields', 'roomDescription', 'roomType', 'readOnly', 'reactWhenReadOnly', 'systemMessages', 'default', 'joinCode', 'tokenpass', 'streamingOptions', 'retentionEnabled', 'retentionMaxAge', 'retentionExcludePinned', 'retentionFilesOnly', 'retentionIgnoreThreads', 'retentionOverrideGlobal', 'encrypted', 'favorite']; + +const validators = { + default({ userId }) { + if (!hasPermission(userId, 'view-room-administration')) { + throw new Meteor.Error('error-action-not-allowed', 'Viewing room administration is not allowed', { + method: 'saveRoomSettings', + action: 'Viewing_room_administration', + }); + } + }, + featured({ userId }) { + if (!hasPermission(userId, 'view-room-administration')) { + throw new Meteor.Error('error-action-not-allowed', 'Viewing room administration is not allowed', { + method: 'saveRoomSettings', + action: 'Viewing_room_administration', + }); + } + }, + roomType({ userId, room, value }) { + if (value === room.t) { + return; + } + + if (value === 'c' && !hasPermission(userId, 'create-c')) { + throw new Meteor.Error('error-action-not-allowed', 'Changing a private group to a public channel is not allowed', { + method: 'saveRoomSettings', + action: 'Change_Room_Type', + }); + } + + if (value === 'p' && !hasPermission(userId, 'create-p')) { + throw new Meteor.Error('error-action-not-allowed', 'Changing a public channel to a private room is not allowed', { + method: 'saveRoomSettings', + action: 'Change_Room_Type', + }); + } + }, + encrypted({ value, room }) { + if (value !== room.encrypted && !roomTypes.getConfig(room.t).allowRoomSettingChange(room, RoomSettingsEnum.E2E)) { + throw new Meteor.Error('error-action-not-allowed', 'Only groups or direct channels can enable encryption', { + method: 'saveRoomSettings', + action: 'Change_Room_Encrypted', + }); + } + }, + retentionEnabled({ userId, value, room, rid }) { + if (!hasPermission(userId, 'edit-room-retention-policy', rid) && value !== room.retention.enabled) { + throw new Meteor.Error('error-action-not-allowed', 'Editing room retention policy is not allowed', { + method: 'saveRoomSettings', + action: 'Editing_room', + }); + } + }, + retentionMaxAge({ userId, value, room, rid }) { + if (!hasPermission(userId, 'edit-room-retention-policy', rid) && value !== room.retention.maxAge) { + throw new Meteor.Error('error-action-not-allowed', 'Editing room retention policy is not allowed', { + method: 'saveRoomSettings', + action: 'Editing_room', + }); + } + }, + retentionExcludePinned({ userId, value, room, rid }) { + if (!hasPermission(userId, 'edit-room-retention-policy', rid) && value !== room.retention.excludePinned) { + throw new Meteor.Error('error-action-not-allowed', 'Editing room retention policy is not allowed', { + method: 'saveRoomSettings', + action: 'Editing_room', + }); + } + }, + retentionFilesOnly({ userId, value, room, rid }) { + if (!hasPermission(userId, 'edit-room-retention-policy', rid) && value !== room.retention.filesOnly) { + throw new Meteor.Error('error-action-not-allowed', 'Editing room retention policy is not allowed', { + method: 'saveRoomSettings', + action: 'Editing_room', + }); + } + }, + retentionIgnoreThreads({ userId, value, room, rid }) { + if (!hasPermission(userId, 'edit-room-retention-policy', rid) && value !== room.retention.ignoreThreads) { + throw new Meteor.Error('error-action-not-allowed', 'Editing room retention policy is not allowed', { + method: 'saveRoomSettings', + action: 'Editing_room', + }); + } + }, +}; + +const settingSavers = { + roomName({ value, rid, user }) { + saveRoomName(rid, value, user); + }, + roomTopic({ value, room, rid, user }) { + if (value !== room.topic) { + saveRoomTopic(rid, value, user); + } + }, + roomAnnouncement({ value, room, rid, user }) { + if (value !== room.announcement) { + saveRoomAnnouncement(rid, value, user); + } + }, + roomCustomFields({ value, room, rid }) { + if (value !== room.customFields) { + saveRoomCustomFields(rid, value); + } + }, + roomDescription({ value, room, rid, user }) { + if (value !== room.description) { + saveRoomDescription(rid, value, user); + } + }, + roomType({ value, room, rid, user }) { + if (value !== room.t) { + saveRoomType(rid, value, user); + } + }, + tokenpass({ value, rid }) { + check(value, { + require: String, + tokens: [{ + token: String, + balance: String, + }], + }); + saveRoomTokenpass(rid, value); + }, + streamingOptions({ value, rid }) { + saveStreamingOptions(rid, value); + }, + readOnly({ value, room, rid, user }) { + if (value !== room.ro) { + saveRoomReadOnly(rid, value, user); + } + }, + reactWhenReadOnly({ value, room, rid, user }) { + if (value !== room.reactWhenReadOnly) { + saveReactWhenReadOnly(rid, value, user); + } + }, + systemMessages({ value, room, rid, user }) { + if (JSON.stringify(value) !== JSON.stringify(room.sysMes)) { + saveRoomSystemMessages(rid, value, user); + } + }, + joinCode({ value, rid }) { + Rooms.setJoinCodeById(rid, String(value)); + }, + default({ value, rid }) { + Rooms.saveDefaultById(rid, value); + }, + featured({ value, rid }) { + Rooms.saveFeaturedById(rid, value); + }, + retentionEnabled({ value, rid }) { + Rooms.saveRetentionEnabledById(rid, value); + }, + retentionMaxAge({ value, rid }) { + Rooms.saveRetentionMaxAgeById(rid, value); + }, + retentionExcludePinned({ value, rid }) { + Rooms.saveRetentionExcludePinnedById(rid, value); + }, + retentionFilesOnly({ value, rid }) { + Rooms.saveRetentionFilesOnlyById(rid, value); + }, + retentionIgnoreThreads({ value, rid }) { + Rooms.saveRetentionIgnoreThreadsById(rid, value); + }, + retentionOverrideGlobal({ value, rid }) { + Rooms.saveRetentionOverrideGlobalById(rid, value); + }, + encrypted({ value, rid }) { + Rooms.saveEncryptedById(rid, value); + }, + favorite({ value, rid }) { + Rooms.saveFavoriteById(rid, value.favorite, value.defaultValue); + }, + roomAvatar({ value, rid, user }) { + setRoomAvatar(rid, value, user); + }, +}; + Meteor.methods({ saveRoomSettings(rid, settings, value) { const userId = Meteor.userId(); @@ -71,70 +253,19 @@ Meteor.methods({ const user = Meteor.user(); // validations - Object.keys(settings).forEach((setting) => { const value = settings[setting]; - if (settings === 'default' && !hasPermission(userId, 'view-room-administration')) { - throw new Meteor.Error('error-action-not-allowed', 'Viewing room administration is not allowed', { - method: 'saveRoomSettings', - action: 'Viewing_room_administration', - }); - } - if (settings === 'featured' && !hasPermission(userId, 'view-room-administration')) { - throw new Meteor.Error('error-action-not-allowed', 'Viewing room administration is not allowed', { - method: 'saveRoomSettings', - action: 'Viewing_room_administration', - }); - } - if (setting === 'roomType' && value !== room.t && value === 'c' && !hasPermission(userId, 'create-c')) { - throw new Meteor.Error('error-action-not-allowed', 'Changing a private group to a public channel is not allowed', { - method: 'saveRoomSettings', - action: 'Change_Room_Type', - }); - } - if (setting === 'roomType' && value !== room.t && value === 'p' && !hasPermission(userId, 'create-p')) { - throw new Meteor.Error('error-action-not-allowed', 'Changing a public channel to a private room is not allowed', { - method: 'saveRoomSettings', - action: 'Change_Room_Type', - }); - } - if (setting === 'encrypted' && value !== room.encrypted && !roomTypes.getConfig(room.t).allowRoomSettingChange(room, RoomSettingsEnum.E2E)) { - throw new Meteor.Error('error-action-not-allowed', 'Only groups or direct channels can enable encryption', { - method: 'saveRoomSettings', - action: 'Change_Room_Encrypted', - }); - } - if (setting === 'retentionEnabled' && !hasPermission(userId, 'edit-room-retention-policy', rid) && value !== room.retention.enabled) { - throw new Meteor.Error('error-action-not-allowed', 'Editing room retention policy is not allowed', { - method: 'saveRoomSettings', - action: 'Editing_room', - }); - } - if (setting === 'retentionMaxAge' && !hasPermission(userId, 'edit-room-retention-policy', rid) && value !== room.retention.maxAge) { - throw new Meteor.Error('error-action-not-allowed', 'Editing room retention policy is not allowed', { - method: 'saveRoomSettings', - action: 'Editing_room', - }); - } - if (setting === 'retentionExcludePinned' && !hasPermission(userId, 'edit-room-retention-policy', rid) && value !== room.retention.excludePinned) { - throw new Meteor.Error('error-action-not-allowed', 'Editing room retention policy is not allowed', { - method: 'saveRoomSettings', - action: 'Editing_room', - }); - } - if (setting === 'retentionFilesOnly' && !hasPermission(userId, 'edit-room-retention-policy', rid) && value !== room.retention.filesOnly) { - throw new Meteor.Error('error-action-not-allowed', 'Editing room retention policy is not allowed', { - method: 'saveRoomSettings', - action: 'Editing_room', - }); - } - if (setting === 'retentionIgnoreThreads' && !hasPermission(userId, 'edit-room-retention-policy', rid) && value !== room.retention.ignoreThreads) { - throw new Meteor.Error('error-action-not-allowed', 'Editing room retention policy is not allowed', { - method: 'saveRoomSettings', - action: 'Editing_room', + const validator = validators[setting]; + if (validator) { + validator({ + userId, + value, + room, + rid, }); } + if (setting === 'retentionOverrideGlobal') { delete settings.retentionMaxAge; delete settings.retentionExcludePinned; @@ -143,101 +274,18 @@ Meteor.methods({ } }); + // saving data Object.keys(settings).forEach((setting) => { const value = settings[setting]; - switch (setting) { - case 'roomName': - saveRoomName(rid, value, user); - break; - case 'roomTopic': - if (value !== room.topic) { - saveRoomTopic(rid, value, user); - } - break; - case 'roomAnnouncement': - if (value !== room.announcement) { - saveRoomAnnouncement(rid, value, user); - } - break; - case 'roomCustomFields': - if (value !== room.customFields) { - saveRoomCustomFields(rid, value); - } - break; - case 'roomDescription': - if (value !== room.description) { - saveRoomDescription(rid, value, user); - } - break; - case 'roomType': - if (value !== room.t) { - saveRoomType(rid, value, user); - } - break; - case 'tokenpass': - check(value, { - require: String, - tokens: [{ - token: String, - balance: String, - }], - }); - saveRoomTokenpass(rid, value); - break; - case 'streamingOptions': - saveStreamingOptions(rid, value); - break; - case 'readOnly': - if (value !== room.ro) { - saveRoomReadOnly(rid, value, user); - } - break; - case 'reactWhenReadOnly': - if (value !== room.reactWhenReadOnly) { - saveReactWhenReadOnly(rid, value, user); - } - break; - case 'systemMessages': - if (JSON.stringify(value) !== JSON.stringify(room.sysMes)) { - saveRoomSystemMessages(rid, value, user); - } - break; - case 'joinCode': - Rooms.setJoinCodeById(rid, String(value)); - break; - case 'default': - Rooms.saveDefaultById(rid, value); - break; - case 'featured': - Rooms.saveFeaturedById(rid, value); - break; - case 'retentionEnabled': - Rooms.saveRetentionEnabledById(rid, value); - break; - case 'retentionMaxAge': - Rooms.saveRetentionMaxAgeById(rid, value); - break; - case 'retentionExcludePinned': - Rooms.saveRetentionExcludePinnedById(rid, value); - break; - case 'retentionFilesOnly': - Rooms.saveRetentionFilesOnlyById(rid, value); - break; - case 'retentionIgnoreThreads': - Rooms.saveRetentionIgnoreThreadsById(rid, value); - break; - case 'retentionOverrideGlobal': - Rooms.saveRetentionOverrideGlobalById(rid, value); - break; - case 'encrypted': - Rooms.saveEncryptedById(rid, value); - break; - case 'favorite': - Rooms.saveFavoriteById(rid, value.favorite, value.defaultValue); - break; - case 'roomAvatar': - setRoomAvatar(rid, value, user); - break; + + const saver = settingSavers[setting]; + if (saver) { + saver({ + value, + room, + rid, + user, + }); } });