From fc6541692daa9264ae1b916b0b32a78f5e40d022 Mon Sep 17 00:00:00 2001 From: Guilherme Gazzo Date: Fri, 31 Mar 2017 12:56:35 -0300 Subject: [PATCH] conversion --- .../client/lib/ChannelSettings.coffee | 31 -- .../client/lib/ChannelSettings.js | 28 ++ .../client/startup/messageTypes.coffee | 38 -- .../client/startup/messageTypes.js | 16 + .../client/startup/tabBar.coffee | 8 - .../client/startup/tabBar.js | 10 + .../client/views/channelSettings.coffee | 307 ------------- .../client/views/channelSettings.js | 425 ++++++++++++++++++ .../rocketchat-channel-settings/package.js | 27 +- .../functions/saveRoomDescription.coffee | 11 - .../server/functions/saveRoomDescription.js | 12 + .../server/functions/saveRoomName.coffee | 29 -- .../server/functions/saveRoomName.js | 36 ++ .../server/functions/saveRoomReadOnly.coffee | 7 - .../server/functions/saveRoomReadOnly.js | 8 + .../functions/saveRoomSystemMessages.coffee | 7 - .../functions/saveRoomSystemMessages.js | 8 + .../server/functions/saveRoomTopic.coffee | 12 - .../server/functions/saveRoomTopic.js | 13 + .../server/functions/saveRoomType.coffee | 26 -- .../server/functions/saveRoomType.js | 44 ++ .../server/methods/saveRoomSettings.coffee | 55 --- .../server/methods/saveRoomSettings.js | 95 ++++ .../server/models/Messages.coffee | 5 - .../server/models/Messages.js | 7 + .../server/models/Rooms.coffee | 55 --- .../server/models/Rooms.js | 65 +++ 27 files changed, 780 insertions(+), 605 deletions(-) delete mode 100644 packages/rocketchat-channel-settings/client/lib/ChannelSettings.coffee create mode 100644 packages/rocketchat-channel-settings/client/lib/ChannelSettings.js delete mode 100644 packages/rocketchat-channel-settings/client/startup/messageTypes.coffee create mode 100644 packages/rocketchat-channel-settings/client/startup/messageTypes.js delete mode 100644 packages/rocketchat-channel-settings/client/startup/tabBar.coffee create mode 100644 packages/rocketchat-channel-settings/client/startup/tabBar.js delete mode 100644 packages/rocketchat-channel-settings/client/views/channelSettings.coffee create mode 100644 packages/rocketchat-channel-settings/client/views/channelSettings.js delete mode 100644 packages/rocketchat-channel-settings/server/functions/saveRoomDescription.coffee create mode 100644 packages/rocketchat-channel-settings/server/functions/saveRoomDescription.js delete mode 100644 packages/rocketchat-channel-settings/server/functions/saveRoomName.coffee create mode 100644 packages/rocketchat-channel-settings/server/functions/saveRoomName.js delete mode 100644 packages/rocketchat-channel-settings/server/functions/saveRoomReadOnly.coffee create mode 100644 packages/rocketchat-channel-settings/server/functions/saveRoomReadOnly.js delete mode 100644 packages/rocketchat-channel-settings/server/functions/saveRoomSystemMessages.coffee create mode 100644 packages/rocketchat-channel-settings/server/functions/saveRoomSystemMessages.js delete mode 100644 packages/rocketchat-channel-settings/server/functions/saveRoomTopic.coffee create mode 100644 packages/rocketchat-channel-settings/server/functions/saveRoomTopic.js delete mode 100644 packages/rocketchat-channel-settings/server/functions/saveRoomType.coffee create mode 100644 packages/rocketchat-channel-settings/server/functions/saveRoomType.js delete mode 100644 packages/rocketchat-channel-settings/server/methods/saveRoomSettings.coffee create mode 100644 packages/rocketchat-channel-settings/server/methods/saveRoomSettings.js delete mode 100644 packages/rocketchat-channel-settings/server/models/Messages.coffee create mode 100644 packages/rocketchat-channel-settings/server/models/Messages.js delete mode 100644 packages/rocketchat-channel-settings/server/models/Rooms.coffee create mode 100644 packages/rocketchat-channel-settings/server/models/Rooms.js diff --git a/packages/rocketchat-channel-settings/client/lib/ChannelSettings.coffee b/packages/rocketchat-channel-settings/client/lib/ChannelSettings.coffee deleted file mode 100644 index 4c723d54bd9..00000000000 --- a/packages/rocketchat-channel-settings/client/lib/ChannelSettings.coffee +++ /dev/null @@ -1,31 +0,0 @@ -RocketChat.ChannelSettings = new class - options = new ReactiveVar {} - - ### - # Adds an option in Channel Settings - # @config (object) - # id: option id (required) - # template (string): template name to render (required) - # validation (function): if option should be displayed - ### - addOption = (config) -> - unless config?.id - return false - - Tracker.nonreactive -> - opts = options.get() - opts[config.id] = config - options.set opts - - getOptions = (currentData, group) -> - allOptions = _.toArray options.get() - allowedOptions = _.compact _.map allOptions, (option) -> - if not option.validation? or option.validation() - option.data = Object.assign (option.data or {}), currentData - return option - allowedOptions = allowedOptions.filter (option) -> - !group or !option.group or option.group?.indexOf(group) > -1 - return _.sortBy allowedOptions, 'order' - - addOption: addOption - getOptions: getOptions diff --git a/packages/rocketchat-channel-settings/client/lib/ChannelSettings.js b/packages/rocketchat-channel-settings/client/lib/ChannelSettings.js new file mode 100644 index 00000000000..2e177ff05be --- /dev/null +++ b/packages/rocketchat-channel-settings/client/lib/ChannelSettings.js @@ -0,0 +1,28 @@ +RocketChat.ChannelSettings = new class { + constructor() { + this.options = new ReactiveVar({}); + } + addOption(config) { + if (!(config && config.id)) { + return false; + } + return Tracker.nonreactive(() => { + const opts = this.options.get(); + opts[config.id] = config; + return this.options.set(opts); + }); + } + + getOptions(currentData, group) { + const allOptions = _.toArray(this.options.get()); + const allowedOptions = _.compact(_.map(allOptions, function(option) { + if ((option.validation == null) || option.validation()) { + option.data = Object.assign(option.data || {}, currentData); + return option; + } + })).filter(function(option) { + return !group || !option.group || option.group.includes(group); + }); + return _.sortBy(allowedOptions, 'order'); + } +}; diff --git a/packages/rocketchat-channel-settings/client/startup/messageTypes.coffee b/packages/rocketchat-channel-settings/client/startup/messageTypes.coffee deleted file mode 100644 index 7911c68604b..00000000000 --- a/packages/rocketchat-channel-settings/client/startup/messageTypes.coffee +++ /dev/null @@ -1,38 +0,0 @@ -Meteor.startup -> - RocketChat.MessageTypes.registerType - id: 'room_changed_privacy' - system: true - message: 'room_changed_privacy' - data: (message) -> - return { - user_by: message.u?.username - room_type: message.msg - } - - RocketChat.MessageTypes.registerType - id: 'room_changed_topic' - system: true - message: 'room_changed_topic' - data: (message) -> - return { - user_by: message.u?.username - room_topic: message.msg - } - - RocketChat.MessageTypes.registerType - id: 'room_changed_announcement' - system: true - message: 'room_changed_announcement' - data: (message) -> - return { - user_by: message.u?.username - room_announcement: message.msg - } - - RocketChat.MessageTypes.registerType - id: 'room_changed_description' - system: true - message: 'room_changed_description' - data: (message) -> - user_by: message.u?.username - room_description: message.msg diff --git a/packages/rocketchat-channel-settings/client/startup/messageTypes.js b/packages/rocketchat-channel-settings/client/startup/messageTypes.js new file mode 100644 index 00000000000..f9d76ce1bcd --- /dev/null +++ b/packages/rocketchat-channel-settings/client/startup/messageTypes.js @@ -0,0 +1,16 @@ +function data(message) { + return { + user_by: message.u && message.u.username, + room_type: message.msg + }; +} +Meteor.startup(function() { + ['room_changed_privacy', 'room_changed_topic', 'room_changed_announcement', 'room_changed_description'].forEach(id => { + RocketChat.MessageTypes.registerType({ + id, + system: true, + message: id, + data + }); + }); +}); diff --git a/packages/rocketchat-channel-settings/client/startup/tabBar.coffee b/packages/rocketchat-channel-settings/client/startup/tabBar.coffee deleted file mode 100644 index 52245c27b6a..00000000000 --- a/packages/rocketchat-channel-settings/client/startup/tabBar.coffee +++ /dev/null @@ -1,8 +0,0 @@ -Meteor.startup -> - RocketChat.TabBar.addButton - groups: ['channel', 'group', 'direct'] - id: 'channel-settings' - i18nTitle: 'Room_Info' - icon: 'icon-info-circled' - template: 'channelSettings' - order: 0 diff --git a/packages/rocketchat-channel-settings/client/startup/tabBar.js b/packages/rocketchat-channel-settings/client/startup/tabBar.js new file mode 100644 index 00000000000..8106391c369 --- /dev/null +++ b/packages/rocketchat-channel-settings/client/startup/tabBar.js @@ -0,0 +1,10 @@ +Meteor.startup(() => { + RocketChat.TabBar.addButton({ + groups: ['channel', 'group', 'direct'], + id: 'channel-settings', + i18nTitle: 'Room_Info', + icon: 'icon-info-circled', + template: 'channelSettings', + order: 0 + }); +}); diff --git a/packages/rocketchat-channel-settings/client/views/channelSettings.coffee b/packages/rocketchat-channel-settings/client/views/channelSettings.coffee deleted file mode 100644 index c32ca638540..00000000000 --- a/packages/rocketchat-channel-settings/client/views/channelSettings.coffee +++ /dev/null @@ -1,307 +0,0 @@ -import toastr from 'toastr' -Template.channelSettings.helpers - toArray: (obj) -> - arr = [] - for key, value of obj - arr.push - $key: key - $value: value - return arr - - valueOf: (obj, key) -> - if key is 't' - if obj[key] is 'c' - return false - - return true - return obj?[key] - - showSetting: (setting, room) -> - if setting.showInDirect is false - return room.t isnt 'd' - return true - - settings: -> - return Template.instance().settings - - getRoom: -> - return ChatRoom.findOne(@rid) - - editing: (field) -> - return Template.instance().editing.get() is field - - isDisabled: (field, room) -> - return Template.instance().settings[field].disabled?(room) or Template.instance().settings[field].processing.get() or !RocketChat.authz.hasAllPermission('edit-room', room._id) - - channelSettings: -> - return RocketChat.ChannelSettings.getOptions(Template.currentData(), 'room') - - unscape: (value) -> - return s.unescapeHTML value - - canDeleteRoom: -> - roomType = ChatRoom.findOne(@rid, { fields: { t: 1 }})?.t - return roomType? and RocketChat.authz.hasAtLeastOnePermission("delete-#{roomType}", @rid) - - readOnly: -> - return ChatRoom.findOne(@rid, { fields: { ro: 1 }})?.ro - has: (v, key) -> - v?[key]? - readOnlyDescription: -> - readOnly = ChatRoom.findOne(@rid, { fields: { ro: 1 }})?.ro - if readOnly is true - return t('True') - else - return t('False') - - - -Template.channelSettings.events - 'click .delete': -> - swal { - title: t('Are_you_sure') - text: t('Delete_Room_Warning') - type: 'warning' - showCancelButton: true - confirmButtonColor: '#DD6B55' - confirmButtonText: t('Yes_delete_it') - cancelButtonText: t('Cancel') - closeOnConfirm: false - html: false - }, => - swal.disableButtons() - - Meteor.call 'eraseRoom', @rid, (error, result) -> - if error - handleError(error) - swal.enableButtons() - else - swal - title: t('Deleted') - text: t('Room_has_been_deleted') - type: 'success' - timer: 2000 - showConfirmButton: false - - 'keydown input[type=text]': (e, t) -> - if e.keyCode is 13 - e.preventDefault() - t.saveSetting() - - 'click [data-edit]': (e, t) -> - e.preventDefault() - if $(e.currentTarget).data('edit') - t.editing.set($(e.currentTarget).data('edit')) - setTimeout (-> t.$('input.editing').focus().select()), 100 - - 'change [type="radio"]': (e, t) -> - t.editing.set($(e.currentTarget).attr('name')) - - 'change [type="checkbox"]': (e, t) -> - t.editing.set($(e.currentTarget).attr('name')) - t.saveSetting() - - 'click .cancel': (e, t) -> - e.preventDefault() - t.editing.set() - - 'click .save': (e, t) -> - e.preventDefault() - t.saveSetting() - -Template.channelSettings.onCreated -> - @editing = new ReactiveVar - - @settings = - name: - type: 'text' - label: 'Name' - canView: (room) => room.t isnt 'd' - canEdit: (room) => RocketChat.authz.hasAllPermission('edit-room', room._id) - save: (value, room) -> - if not RocketChat.authz.hasAllPermission('edit-room', room._id) or room.t not in ['c', 'p'] - return toastr.error t('error-not-allowed') - - try - nameValidation = new RegExp '^' + RocketChat.settings.get('UTF8_Names_Validation') + '$' - catch - nameValidation = new RegExp '^[0-9a-zA-Z-_.]+$' - - if not nameValidation.test value - return toastr.error t('error-invalid-room-name', { room_name: name: value }) - - RocketChat.callbacks.run 'roomNameChanged', { _id: room._id, name: value } - Meteor.call 'saveRoomSettings', room._id, 'roomName', value, (err, result) -> - return handleError err if err - toastr.success TAPi18n.__ 'Room_name_changed_successfully' - - topic: - type: 'markdown' - label: 'Topic' - canView: (room) => true - canEdit: (room) => RocketChat.authz.hasAllPermission('edit-room', room._id) - save: (value, room) -> - Meteor.call 'saveRoomSettings', room._id, 'roomTopic', value, (err, result) -> - return handleError err if err - toastr.success TAPi18n.__ 'Room_topic_changed_successfully' - RocketChat.callbacks.run 'roomTopicChanged', room - - announcement: - type: 'markdown' - label: 'Announcement' - canView: (room) => true - canEdit: (room) => RocketChat.authz.hasAllPermission('edit-room', room._id) - save: (value, room) -> - Meteor.call 'saveRoomSettings', room._id, 'roomAnnouncement', value, (err, result) -> - return handleError err if err - toastr.success TAPi18n.__ 'Room_announcement_changed_successfully' - RocketChat.callbacks.run 'roomAnnouncementChanged', room - - description: - type: 'text' - label: 'Description' - canView: (room) => room.t isnt 'd' - canEdit: (room) => RocketChat.authz.hasAllPermission('edit-room', room._id) - save: (value, room) -> - Meteor.call 'saveRoomSettings', room._id, 'roomDescription', value, (err, result) -> - return handleError err if err - toastr.success TAPi18n.__ 'Room_description_changed_successfully' - - t: - type: 'boolean' - label: 'Private' - isToggle: true - processing: new ReactiveVar(false) - disabled: (room) => - room.default and not RocketChat.authz.hasRole( Meteor.userId(), 'admin') - message: (room) => - #if the user can change but the channel is default - if RocketChat.authz.hasAllPermission('edit-room', room._id) and room.default - # if you are an admin, even so you can change - unless RocketChat.authz.hasRole( Meteor.userId(), 'admin') - return 'Room_type_of_default_rooms_cant_be_changed' - canView: (room) -> - if room.t not in ['c', 'p'] - return false - else if room.t is 'p' and not RocketChat.authz.hasAllPermission('create-c') - return false - else if room.t is 'c' and not RocketChat.authz.hasAllPermission('create-p') - return false - return true - canEdit: (room) => ( RocketChat.authz.hasAllPermission('edit-room', room._id) and not room.default) or RocketChat.authz.hasRole( Meteor.userId(), 'admin') - save: (value, room) -> - saveRoomSettings = => - @processing.set(true) - value = if value then 'p' else 'c' - RocketChat.callbacks.run 'roomTypeChanged', room - Meteor.call 'saveRoomSettings', room._id, 'roomType', value, (err, result) => - return handleError err if err - @processing.set(false) - toastr.success TAPi18n.__ 'Room_type_changed_successfully' - - if room.default - if RocketChat.authz.hasRole Meteor.userId(), 'admin' - swal { - title: t('Room_default_change_to_private_will_be_default_no_more') - type: 'warning' - showCancelButton: true - confirmButtonColor: '#DD6B55' - confirmButtonText: t('Yes') - cancelButtonText: t('Cancel') - closeOnConfirm: true - html: false - }, (confirmed) => - return saveRoomSettings() if confirmed - $(".channel-settings form [name='t']").prop('checked', !!room.type == 'p') - else - saveRoomSettings() - ro: - type: 'boolean' - label: 'Read_only' - isToggle: true - processing: new ReactiveVar(false) - canView: (room) => room.t isnt 'd' - canEdit: (room) => RocketChat.authz.hasAllPermission('set-readonly', room._id) - save: (value, room) -> - @processing.set(true) - Meteor.call 'saveRoomSettings', room._id, 'readOnly', value, (err, result) => - return handleError err if err - @processing.set(false) - toastr.success TAPi18n.__ 'Read_only_changed_successfully' - - reactWhenReadOnly: - type: 'boolean' - label: 'React_when_read_only' - isToggle: true - processing: new ReactiveVar(false) - canView: (room) => room.t isnt 'd' and room.ro - canEdit: (room) => RocketChat.authz.hasAllPermission('set-react-when-readonly', room._id) - save: (value, room) -> - @processing.set(true) - Meteor.call 'saveRoomSettings', room._id, 'reactWhenReadOnly', value, (err, result) => - return handleError err if err - @processing.set(false) - toastr.success TAPi18n.__ 'React_when_read_only_changed_successfully' - - archived: - type: 'boolean' - label: 'Room_archivation_state_true' - isToggle: true, - processing: new ReactiveVar(false) - canView: (room) => room.t isnt 'd' - canEdit: (room) => RocketChat.authz.hasAtLeastOnePermission(['archive-room', 'unarchive-room'], room._id) - save: (value, room) => - swal { - title: t('Are_you_sure') - type: 'warning' - showCancelButton: true - confirmButtonColor: '#DD6B55' - confirmButtonText: if value then t('Yes_archive_it') else t('Yes_unarchive_it') - cancelButtonText: t('Cancel') - closeOnConfirm: false - html: false - }, (confirmed) => - swal.disableButtons() - if (confirmed) - action = if value then 'archiveRoom' else 'unarchiveRoom' - Meteor.call action, room._id, (err, results) => - if err - swal.enableButtons() - handleError err - swal - title: if value then t('Room_archived') else t('Room_has_been_archived') - text: if value then t('Room_has_been_archived') else t('Room_has_been_unarchived') - type: 'success' - timer: 2000 - showConfirmButton: false - RocketChat.callbacks.run action, room - else - $(".channel-settings form [name='archived']").prop('checked', !!room.archived) - - joinCode: - type: 'text' - label: 'Password' - canView: (room) => room.t is 'c' and RocketChat.authz.hasAllPermission('edit-room', room._id) - canEdit: (room) => RocketChat.authz.hasAllPermission('edit-room', room._id) - save: (value, room) -> - Meteor.call 'saveRoomSettings', room._id, 'joinCode', value, (err, result) -> - return handleError err if err - toastr.success TAPi18n.__ 'Room_password_changed_successfully' - RocketChat.callbacks.run 'roomCodeChanged', room - - - @saveSetting = => - room = ChatRoom.findOne @data?.rid - field = @editing.get() - - if @settings[field].type is 'select' - value = @$(".channel-settings form [name=#{field}]:checked").val() - else if @settings[field].type is 'boolean' - value = @$(".channel-settings form [name=#{field}]").is(":checked") - else - value = @$(".channel-settings form [name=#{field}]").val() - - if value isnt room[field] - @settings[field].save(value, room) - - @editing.set() diff --git a/packages/rocketchat-channel-settings/client/views/channelSettings.js b/packages/rocketchat-channel-settings/client/views/channelSettings.js new file mode 100644 index 00000000000..4a8580839a4 --- /dev/null +++ b/packages/rocketchat-channel-settings/client/views/channelSettings.js @@ -0,0 +1,425 @@ +import toastr from 'toastr'; + +Template.channelSettings.helpers({ + toArray(obj) { + return Object.keys(obj).map((key) => { + return { + $key: key, + $value: obj[key] + }; + }); + }, + valueOf(obj, key) { + if (key === 't') { + if (obj[key] === 'c') { + return false; + } + return true; + } + return obj && obj[key]; + }, + showSetting(setting, room) { + if (setting.showInDirect === false) { + return room.t !== 'd'; + } + return true; + }, + settings() { + return Template.instance().settings; + }, + getRoom() { + return ChatRoom.findOne(this.rid); + }, + editing(field) { + return Template.instance().editing.get() === field; + }, + isDisabled(field, room) { + const setting = Template.instance().settings[field]; + return (typeof setting.disabled === 'function' && setting.disabled(room)) || setting.processing.get() || !RocketChat.authz.hasAllPermission('edit-room', room._id); + }, + channelSettings() { + return RocketChat.ChannelSettings.getOptions(Template.currentData(), 'room'); + }, + unscape(value) { + return s.unescapeHTML(value); + }, + canDeleteRoom() { + const room = ChatRoom.findOne(this.rid, { + fields: { + t: 1 + } + }); + const roomType = room && room.t; + return roomType && RocketChat.authz.hasAtLeastOnePermission(`delete-${ roomType }`, this.rid); + }, + readOnly() { + const room = ChatRoom.findOne(this.rid, { + fields: { + ro: 1 + } + }); + return room && room.ro; + }, + has(v, key) { + return !!(v && v[key]); + }, + readOnlyDescription() { + const room = ChatRoom.findOne(this.rid, { + fields: { + ro: 1 + } + }); + return t(room && room.ro ? 'True' : 'False'); + } +}); + +Template.channelSettings.events({ + 'click .delete'() { + return swal({ + title: t('Are_you_sure'), + text: t('Delete_Room_Warning'), + type: 'warning', + showCancelButton: true, + confirmButtonColor: '#DD6B55', + confirmButtonText: t('Yes_delete_it'), + cancelButtonText: t('Cancel'), + closeOnConfirm: false, + html: false + }, () => { + swal.disableButtons(); + Meteor.call('eraseRoom', this.rid, function(error) { + if (error) { + handleError(error); + return swal.enableButtons(); + } + swal({ + title: t('Deleted'), + text: t('Room_has_been_deleted'), + type: 'success', + timer: 2000, + showConfirmButton: false + }); + }); + }); + }, + 'keydown input[type=text]'(e, t) { + if (e.keyCode === 13) { + e.preventDefault(); + t.saveSetting(); + } + }, + 'click [data-edit]'(e, t) { + e.preventDefault(); + if ($(e.currentTarget).data('edit')) { + t.editing.set($(e.currentTarget).data('edit')); + return setTimeout((function() { + return t.$('input.editing').focus().select(); + }), 100); + } + }, + 'change [type="radio"]'(e, t) { + return t.editing.set($(e.currentTarget).attr('name')); + }, + 'change [type="checkbox"]'(e, t) { + t.editing.set($(e.currentTarget).attr('name')); + return t.saveSetting(); + }, + 'click .cancel'(e, t) { + e.preventDefault(); + return t.editing.set(); + }, + 'click .save'(e, t) { + e.preventDefault(); + return t.saveSetting(); + } +}); + +Template.channelSettings.onCreated(function() { + this.editing = new ReactiveVar; + this.settings = { + name: { + type: 'text', + label: 'Name', + canView(room) { + return room.t !== 'd'; + }, + canEdit(room) { + return RocketChat.authz.hasAllPermission('edit-room', room._id); + }, + save(value, room) { + let nameValidation; + if (!RocketChat.authz.hasAllPermission('edit-room', room._id) || (room.t !== 'c' && room.t !== 'p')) { + return toastr.error(t('error-not-allowed')); + } + try { + nameValidation = new RegExp(`^${ RocketChat.settings.get('UTF8_Names_Validation') }$`); + } catch (error1) { + nameValidation = new RegExp('^[0-9a-zA-Z-_.]+$'); + } + if (!nameValidation.test(value)) { + return toastr.error(t('error-invalid-room-name', { + room_name: { + name: value + } + })); + } + Meteor.call('saveRoomSettings', room._id, 'roomName', value, function(err) { + if (err) { + return handleError(err); + } + RocketChat.callbacks.run('roomNameChanged', { + _id: room._id, + name: value + }); + return toastr.success(TAPi18n.__('Room_name_changed_successfully')); + }); + } + }, + topic: { + type: 'markdown', + label: 'Topic', + canView() { + return true; + }, + canEdit(room) { + return RocketChat.authz.hasAllPermission('edit-room', room._id); + }, + save(value, room) { + return Meteor.call('saveRoomSettings', room._id, 'roomTopic', value, function(err) { + if (err) { + return handleError(err); + } + toastr.success(TAPi18n.__('Room_topic_changed_successfully')); + return RocketChat.callbacks.run('roomTopicChanged', room); + }); + } + }, + announcement: { + type: 'markdown', + label: 'Announcement', + canView() { + return true; + }, + canEdit(room) { + return RocketChat.authz.hasAllPermission('edit-room', room._id); + }, + save(value, room) { + return Meteor.call('saveRoomSettings', room._id, 'roomAnnouncement', value, function(err) { + if (err) { + return handleError(err); + } + toastr.success(TAPi18n.__('Room_announcement_changed_successfully')); + return RocketChat.callbacks.run('roomAnnouncementChanged', room); + }); + } + }, + description: { + type: 'text', + label: 'Description', + canView(room) { + return room.t !== 'd'; + }, + canEdit(room) { + return RocketChat.authz.hasAllPermission('edit-room', room._id); + }, + save(value, room) { + return Meteor.call('saveRoomSettings', room._id, 'roomDescription', value, function(err) { + if (err) { + return handleError(err); + } + return toastr.success(TAPi18n.__('Room_description_changed_successfully')); + }); + } + }, + t: { + type: 'boolean', + label: 'Private', + isToggle: true, + processing: new ReactiveVar(false), + disabled(room) { + return room['default'] && !RocketChat.authz.hasRole(Meteor.userId(), 'admin'); + }, + message(room) { + if (RocketChat.authz.hasAllPermission('edit-room', room._id) && room['default']) { + if (!RocketChat.authz.hasRole(Meteor.userId(), 'admin')) { + return 'Room_type_of_default_rooms_cant_be_changed'; + } + } + }, + canView(room) { + let ref; + if ((ref = room.t) !== 'c' && ref !== 'p') { + return false; + } else if (room.t === 'p' && !RocketChat.authz.hasAllPermission('create-c')) { + return false; + } else if (room.t === 'c' && !RocketChat.authz.hasAllPermission('create-p')) { + return false; + } + return true; + }, + canEdit(room) { + return (RocketChat.authz.hasAllPermission('edit-room', room._id) && !room['default']) || RocketChat.authz.hasRole(Meteor.userId(), 'admin'); + }, + save(value, room) { + const saveRoomSettings = () => { + this.processing.set(true); + value = value ? 'p' : 'c'; + RocketChat.callbacks.run('roomTypeChanged', room); + return Meteor.call('saveRoomSettings', room._id, 'roomType', value, (err) => { + if (err) { + return handleError(err); + } + this.processing.set(false); + return toastr.success(TAPi18n.__('Room_type_changed_successfully')); + }); + }; + if (room['default']) { + if (RocketChat.authz.hasRole(Meteor.userId(), 'admin')) { + swal({ + title: t('Room_default_change_to_private_will_be_default_no_more'), + type: 'warning', + showCancelButton: true, + confirmButtonColor: '#DD6B55', + confirmButtonText: t('Yes'), + cancelButtonText: t('Cancel'), + closeOnConfirm: true, + html: false + }, function(confirmed) { + if (confirmed) { + return saveRoomSettings(); + } + }); + } + return $('.channel-settings form [name=\'t\']').prop('checked', !!room.type === 'p'); + } else { + return saveRoomSettings(); + } + } + }, + ro: { + type: 'boolean', + label: 'Read_only', + isToggle: true, + processing: new ReactiveVar(false), + canView(room) { + return room.t !== 'd'; + }, + canEdit(room) { + return RocketChat.authz.hasAllPermission('set-readonly', room._id); + }, + save(value, room) { + this.processing.set(true); + return Meteor.call('saveRoomSettings', room._id, 'readOnly', value, (err) => { + if (err) { + return handleError(err); + } + this.processing.set(false); + return toastr.success(TAPi18n.__('Read_only_changed_successfully')); + }); + } + }, + reactWhenReadOnly: { + type: 'boolean', + label: 'React_when_read_only', + isToggle: true, + processing: new ReactiveVar(false), + canView(room) { + return room.t !== 'd' && room.ro; + }, + canEdit(room) { + return RocketChat.authz.hasAllPermission('set-react-when-readonly', room._id); + }, + save(value, room) { + this.processing.set(true); + return Meteor.call('saveRoomSettings', room._id, 'reactWhenReadOnly', value, (err) => { + if (err) { + return handleError(err); + } + this.processing.set(false); + return toastr.success(TAPi18n.__('React_when_read_only_changed_successfully')); + }); + } + }, + archived: { + type: 'boolean', + label: 'Room_archivation_state_true', + isToggle: true, + processing: new ReactiveVar(false), + canView(room) { + return room.t !== 'd'; + }, + canEdit(room) { + return RocketChat.authz.hasAtLeastOnePermission(['archive-room', 'unarchive-room'], room._id); + }, + save(value, room) { + return swal({ + title: t('Are_you_sure'), + type: 'warning', + showCancelButton: true, + confirmButtonColor: '#DD6B55', + confirmButtonText: value ? t('Yes_archive_it') : t('Yes_unarchive_it'), + cancelButtonText: t('Cancel'), + closeOnConfirm: false, + html: false + }, function(confirmed) { + let action; + swal.disableButtons(); + if (confirmed) { + action = value ? 'archiveRoom' : 'unarchiveRoom'; + return Meteor.call(action, room._id, function(err) { + if (err) { + swal.enableButtons(); + handleError(err); + } + swal({ + title: value ? t('Room_archived') : t('Room_has_been_archived'), + text: value ? t('Room_has_been_archived') : t('Room_has_been_unarchived'), + type: 'success', + timer: 2000, + showConfirmButton: false + }); + return RocketChat.callbacks.run(action, room); + }); + } else { + return $('.channel-settings form [name=\'archived\']').prop('checked', !!room.archived); + } + }); + } + }, + joinCode: { + type: 'text', + label: 'Password', + canView(room) { + return room.t === 'c' && RocketChat.authz.hasAllPermission('edit-room', room._id); + }, + canEdit(room) { + return RocketChat.authz.hasAllPermission('edit-room', room._id); + }, + save(value, room) { + return Meteor.call('saveRoomSettings', room._id, 'joinCode', value, function(err) { + if (err) { + return handleError(err); + } + toastr.success(TAPi18n.__('Room_password_changed_successfully')); + return RocketChat.callbacks.run('roomCodeChanged', room); + }); + } + } + }; + return this.saveSetting = () => { + const room = ChatRoom.findOne(this.data && this.data.rid); + const field = this.editing.get(); + let value; + if (this.settings[field].type === 'select') { + value = this.$(`.channel-settings form [name=${ field }]:checked`).val(); + } else if (this.settings[field].type === 'boolean') { + value = this.$(`.channel-settings form [name=${ field }]`).is(':checked'); + } else { + value = this.$(`.channel-settings form [name=${ field }]`).val(); + } + if (value !== room[field]) { + this.settings[field].save(value, room); + } + return this.editing.set(); + }; +}); diff --git a/packages/rocketchat-channel-settings/package.js b/packages/rocketchat-channel-settings/package.js index 6bfe2c0b87b..6b4a60a42e7 100644 --- a/packages/rocketchat-channel-settings/package.js +++ b/packages/rocketchat-channel-settings/package.js @@ -7,7 +7,6 @@ Package.describe({ Package.onUse(function(api) { api.use([ - 'coffeescript', 'ecmascript', 'reactive-var', 'tracker', @@ -17,27 +16,27 @@ Package.onUse(function(api) { ]); api.addFiles([ - 'client/lib/ChannelSettings.coffee', - 'client/startup/messageTypes.coffee', - 'client/startup/tabBar.coffee', + 'client/lib/ChannelSettings.js', + 'client/startup/messageTypes.js', + 'client/startup/tabBar.js', 'client/startup/trackSettingsChange.js', 'client/views/channelSettings.html', - 'client/views/channelSettings.coffee', + 'client/views/channelSettings.js', 'client/stylesheets/channel-settings.less' ], 'client'); api.addFiles([ 'server/functions/saveReactWhenReadOnly.js', - 'server/functions/saveRoomType.coffee', - 'server/functions/saveRoomTopic.coffee', + 'server/functions/saveRoomType.js', + 'server/functions/saveRoomTopic.js', 'server/functions/saveRoomAnnouncement.js', - 'server/functions/saveRoomName.coffee', - 'server/functions/saveRoomReadOnly.coffee', - 'server/functions/saveRoomDescription.coffee', - 'server/functions/saveRoomSystemMessages.coffee', - 'server/methods/saveRoomSettings.coffee', - 'server/models/Messages.coffee', - 'server/models/Rooms.coffee', + 'server/functions/saveRoomName.js', + 'server/functions/saveRoomReadOnly.js', + 'server/functions/saveRoomDescription.js', + 'server/functions/saveRoomSystemMessages.js', + 'server/methods/saveRoomSettings.js', + 'server/models/Messages.js', + 'server/models/Rooms.js', 'server/startup.js' ], 'server'); }); diff --git a/packages/rocketchat-channel-settings/server/functions/saveRoomDescription.coffee b/packages/rocketchat-channel-settings/server/functions/saveRoomDescription.coffee deleted file mode 100644 index ef63d1715a9..00000000000 --- a/packages/rocketchat-channel-settings/server/functions/saveRoomDescription.coffee +++ /dev/null @@ -1,11 +0,0 @@ -RocketChat.saveRoomDescription = (rid, roomDescription, user) -> - unless Match.test rid, String - throw new Meteor.Error 'invalid-room', 'Invalid room', { function: 'RocketChat.saveRoomDescription' } - - roomDescription = s.escapeHTML(roomDescription) - - update = RocketChat.models.Rooms.setDescriptionById rid, roomDescription - - RocketChat.models.Messages.createRoomSettingsChangedWithTypeRoomIdMessageAndUser 'room_changed_description', rid, roomDescription, user - - return update diff --git a/packages/rocketchat-channel-settings/server/functions/saveRoomDescription.js b/packages/rocketchat-channel-settings/server/functions/saveRoomDescription.js new file mode 100644 index 00000000000..e0b5230b89c --- /dev/null +++ b/packages/rocketchat-channel-settings/server/functions/saveRoomDescription.js @@ -0,0 +1,12 @@ +RocketChat.saveRoomDescription = function(rid, roomDescription, user) { + + if (!Match.test(rid, String)) { + throw new Meteor.Error('invalid-room', 'Invalid room', { + 'function': 'RocketChat.saveRoomDescription' + }); + } + const escapedRoomDescription = s.escapeHTML(roomDescription); + const update = RocketChat.models.Rooms.setDescriptionById(rid, escapedRoomDescription); + RocketChat.models.Messages.createRoomSettingsChangedWithTypeRoomIdMessageAndUser('room_changed_description', rid, escapedRoomDescription, user); + return update; +}; diff --git a/packages/rocketchat-channel-settings/server/functions/saveRoomName.coffee b/packages/rocketchat-channel-settings/server/functions/saveRoomName.coffee deleted file mode 100644 index 6af72ac445d..00000000000 --- a/packages/rocketchat-channel-settings/server/functions/saveRoomName.coffee +++ /dev/null @@ -1,29 +0,0 @@ -RocketChat.saveRoomName = (rid, name, user, sendMessage=true) -> - room = RocketChat.models.Rooms.findOneById rid - - if room.t not in ['c', 'p'] - throw new Meteor.Error 'error-not-allowed', 'Not allowed', { function: 'RocketChat.saveRoomName' } - - try - nameValidation = new RegExp '^' + RocketChat.settings.get('UTF8_Names_Validation') + '$' - catch - nameValidation = new RegExp '^[0-9a-zA-Z-_.]+$' - - if not nameValidation.test name - throw new Meteor.Error 'error-invalid-room-name', name + ' is not a valid room name. Use only letters, numbers, hyphens and underscores', { function: 'RocketChat.saveRoomName', room_name: name } - - - # name = _.slugify name - - if name is room.name - return - - # avoid duplicate names - if RocketChat.models.Rooms.findOneByName name - throw new Meteor.Error 'error-duplicate-channel-name', 'A channel with name \'' + name + '\' exists', { function: 'RocketChat.saveRoomName', channel_name: name } - - update = RocketChat.models.Rooms.setNameById(rid, name) and RocketChat.models.Subscriptions.updateNameAndAlertByRoomId(rid, name) - if update and sendMessage - RocketChat.models.Messages.createRoomRenamedWithRoomIdRoomNameAndUser rid, name, user - - return name diff --git a/packages/rocketchat-channel-settings/server/functions/saveRoomName.js b/packages/rocketchat-channel-settings/server/functions/saveRoomName.js new file mode 100644 index 00000000000..d58d47a55b6 --- /dev/null +++ b/packages/rocketchat-channel-settings/server/functions/saveRoomName.js @@ -0,0 +1,36 @@ + +RocketChat.saveRoomName = function(rid, name, user, sendMessage = true) { + debugger + const room = RocketChat.models.Rooms.findOneById(rid); + if (room.t !== 'c' && room.t !== 'p') { + throw new Meteor.Error('error-not-allowed', 'Not allowed', { + 'function': 'RocketChat.saveRoomName' + }); + } + let nameValidation; + try { + nameValidation = new RegExp(`^${ RocketChat.settings.get('UTF8_Names_Validation') }$`); + } catch (error) { + nameValidation = new RegExp('^[0-9a-zA-Z-_.]+$'); + } + if (!nameValidation.test(name)) { + throw new Meteor.Error('error-invalid-room-name', `${ name } is not a valid room name. Use only letters, numbers, hyphens and underscores`, { + 'function': 'RocketChat.saveRoomName', + room_name: name + }); + } + if (name === room.name) { + return; + } + if (RocketChat.models.Rooms.findOneByName(name)) { + throw new Meteor.Error('error-duplicate-channel-name', `A channel with name '${ name }' exists`, { + 'function': 'RocketChat.saveRoomName', + channel_name: name + }); + } + const update = RocketChat.models.Rooms.setNameById(rid, name) && RocketChat.models.Subscriptions.updateNameAndAlertByRoomId(rid, name); + if (update && sendMessage) { + RocketChat.models.Messages.createRoomRenamedWithRoomIdRoomNameAndUser(rid, name, user); + } + return name; +}; diff --git a/packages/rocketchat-channel-settings/server/functions/saveRoomReadOnly.coffee b/packages/rocketchat-channel-settings/server/functions/saveRoomReadOnly.coffee deleted file mode 100644 index 08f3ae7af69..00000000000 --- a/packages/rocketchat-channel-settings/server/functions/saveRoomReadOnly.coffee +++ /dev/null @@ -1,7 +0,0 @@ -RocketChat.saveRoomReadOnly = (rid, readOnly, user) -> - unless Match.test rid, String - throw new Meteor.Error 'invalid-room', 'Invalid room', { function: 'RocketChat.saveRoomReadOnly' } - - update = RocketChat.models.Rooms.setReadOnlyById rid, readOnly - - return update diff --git a/packages/rocketchat-channel-settings/server/functions/saveRoomReadOnly.js b/packages/rocketchat-channel-settings/server/functions/saveRoomReadOnly.js new file mode 100644 index 00000000000..35d8ccbd138 --- /dev/null +++ b/packages/rocketchat-channel-settings/server/functions/saveRoomReadOnly.js @@ -0,0 +1,8 @@ +RocketChat.saveRoomReadOnly = function(rid, readOnly) { + if (!Match.test(rid, String)) { + throw new Meteor.Error('invalid-room', 'Invalid room', { + 'function': 'RocketChat.saveRoomReadOnly' + }); + } + return RocketChat.models.Rooms.setReadOnlyById(rid, readOnly); +}; diff --git a/packages/rocketchat-channel-settings/server/functions/saveRoomSystemMessages.coffee b/packages/rocketchat-channel-settings/server/functions/saveRoomSystemMessages.coffee deleted file mode 100644 index 3b27991e09a..00000000000 --- a/packages/rocketchat-channel-settings/server/functions/saveRoomSystemMessages.coffee +++ /dev/null @@ -1,7 +0,0 @@ -RocketChat.saveRoomSystemMessages = (rid, systemMessages, user) -> - unless Match.test rid, String - throw new Meteor.Error 'invalid-room', 'Invalid room', { function: 'RocketChat.saveRoomSystemMessages' } - - update = RocketChat.models.Rooms.setSystemMessagesById rid, systemMessages - - return update diff --git a/packages/rocketchat-channel-settings/server/functions/saveRoomSystemMessages.js b/packages/rocketchat-channel-settings/server/functions/saveRoomSystemMessages.js new file mode 100644 index 00000000000..930531793fc --- /dev/null +++ b/packages/rocketchat-channel-settings/server/functions/saveRoomSystemMessages.js @@ -0,0 +1,8 @@ +RocketChat.saveRoomSystemMessages = function(rid, systemMessages) { + if (!Match.test(rid, String)) { + throw new Meteor.Error('invalid-room', 'Invalid room', { + 'function': 'RocketChat.saveRoomSystemMessages' + }); + } + return RocketChat.models.Rooms.setSystemMessagesById(rid, systemMessages); +}; diff --git a/packages/rocketchat-channel-settings/server/functions/saveRoomTopic.coffee b/packages/rocketchat-channel-settings/server/functions/saveRoomTopic.coffee deleted file mode 100644 index ec27c79d4f7..00000000000 --- a/packages/rocketchat-channel-settings/server/functions/saveRoomTopic.coffee +++ /dev/null @@ -1,12 +0,0 @@ -RocketChat.saveRoomTopic = (rid, roomTopic, user, sendMessage=true) -> - unless Match.test rid, String - throw new Meteor.Error 'invalid-room', 'Invalid room', { function: 'RocketChat.saveRoomTopic' } - - roomTopic = s.escapeHTML(roomTopic) - - update = RocketChat.models.Rooms.setTopicById(rid, roomTopic) - - if update and sendMessage - RocketChat.models.Messages.createRoomSettingsChangedWithTypeRoomIdMessageAndUser 'room_changed_topic', rid, roomTopic, user - - return update diff --git a/packages/rocketchat-channel-settings/server/functions/saveRoomTopic.js b/packages/rocketchat-channel-settings/server/functions/saveRoomTopic.js new file mode 100644 index 00000000000..a92909a5c4b --- /dev/null +++ b/packages/rocketchat-channel-settings/server/functions/saveRoomTopic.js @@ -0,0 +1,13 @@ +RocketChat.saveRoomTopic = function(rid, roomTopic, user, sendMessage = true) { + if (!Match.test(rid, String)) { + throw new Meteor.Error('invalid-room', 'Invalid room', { + 'function': 'RocketChat.saveRoomTopic' + }); + } + roomTopic = s.escapeHTML(roomTopic); + const update = RocketChat.models.Rooms.setTopicById(rid, roomTopic); + if (update && sendMessage) { + RocketChat.models.Messages.createRoomSettingsChangedWithTypeRoomIdMessageAndUser('room_changed_topic', rid, roomTopic, user); + } + return update; +}; diff --git a/packages/rocketchat-channel-settings/server/functions/saveRoomType.coffee b/packages/rocketchat-channel-settings/server/functions/saveRoomType.coffee deleted file mode 100644 index 24bbbb8012a..00000000000 --- a/packages/rocketchat-channel-settings/server/functions/saveRoomType.coffee +++ /dev/null @@ -1,26 +0,0 @@ -RocketChat.saveRoomType = (rid, roomType, user, sendMessage=true) -> - unless Match.test rid, String - throw new Meteor.Error 'invalid-room', 'Invalid room', { function: 'RocketChat.saveRoomType' } - - if roomType not in ['c', 'p'] - throw new Meteor.Error 'error-invalid-room-type', 'error-invalid-room-type', { function: 'RocketChat.saveRoomType', type: roomType } - - room = RocketChat.models.Rooms.findOneById(rid); - - if not room? - throw new Meteor.Error 'error-invalid-room', 'error-invalid-room', { function: 'RocketChat.saveRoomType', _id: rid } - - if room.t is 'd' - throw new Meteor.Error 'error-direct-room', 'Can\'t change type of direct rooms', { function: 'RocketChat.saveRoomType' } - - result = RocketChat.models.Rooms.setTypeById(rid, roomType) and RocketChat.models.Subscriptions.updateTypeByRoomId(rid, roomType) - - if result and sendMessage - if roomType is 'c' - message = TAPi18n.__('Channel', { lng: user?.language || RocketChat.settings.get('language') || 'en' }) - else - message = TAPi18n.__('Private_Group', { lng: user?.language || RocketChat.settings.get('language') || 'en' }) - - RocketChat.models.Messages.createRoomSettingsChangedWithTypeRoomIdMessageAndUser 'room_changed_privacy', rid, message, user - - return result diff --git a/packages/rocketchat-channel-settings/server/functions/saveRoomType.js b/packages/rocketchat-channel-settings/server/functions/saveRoomType.js new file mode 100644 index 00000000000..9fd7b7dff5a --- /dev/null +++ b/packages/rocketchat-channel-settings/server/functions/saveRoomType.js @@ -0,0 +1,44 @@ + +RocketChat.saveRoomType = function(rid, roomType, user, sendMessage = true) { + if (sendMessage == null) { + sendMessage = true; + } + if (!Match.test(rid, String)) { + throw new Meteor.Error('invalid-room', 'Invalid room', { + 'function': 'RocketChat.saveRoomType' + }); + } + if (roomType !== 'c' && roomType !== 'p') { + throw new Meteor.Error('error-invalid-room-type', 'error-invalid-room-type', { + 'function': 'RocketChat.saveRoomType', + type: roomType + }); + } + const room = RocketChat.models.Rooms.findOneById(rid); + if (room == null) { + throw new Meteor.Error('error-invalid-room', 'error-invalid-room', { + 'function': 'RocketChat.saveRoomType', + _id: rid + }); + } + if (room.t === 'd') { + throw new Meteor.Error('error-direct-room', 'Can\'t change type of direct rooms', { + 'function': 'RocketChat.saveRoomType' + }); + } + let message; + const result = RocketChat.models.Rooms.setTypeById(rid, roomType) && RocketChat.models.Subscriptions.updateTypeByRoomId(rid, roomType); + if (result && sendMessage) { + if (roomType === 'c') { + message = TAPi18n.__('Channel', { + lng: user && user.language || RocketChat.settings.get('language') || 'en' + }); + } else { + message = TAPi18n.__('Private_Group', { + lng: user && user.language || RocketChat.settings.get('language') || 'en' + }); + } + RocketChat.models.Messages.createRoomSettingsChangedWithTypeRoomIdMessageAndUser('room_changed_privacy', rid, message, user); + } + return result; +}; diff --git a/packages/rocketchat-channel-settings/server/methods/saveRoomSettings.coffee b/packages/rocketchat-channel-settings/server/methods/saveRoomSettings.coffee deleted file mode 100644 index ee85e795076..00000000000 --- a/packages/rocketchat-channel-settings/server/methods/saveRoomSettings.coffee +++ /dev/null @@ -1,55 +0,0 @@ -Meteor.methods - saveRoomSettings: (rid, setting, value) -> - if not Meteor.userId() - throw new Meteor.Error('error-invalid-user', "Invalid user", { function: 'RocketChat.saveRoomName' }) - - unless Match.test rid, String - throw new Meteor.Error 'error-invalid-room', 'Invalid room', { method: 'saveRoomSettings' } - - if setting not in ['roomName', 'roomTopic', 'roomAnnouncement', 'roomDescription', 'roomType', 'readOnly', 'reactWhenReadOnly', 'systemMessages', 'default', 'joinCode'] - throw new Meteor.Error 'error-invalid-settings', 'Invalid settings provided', { method: 'saveRoomSettings' } - - unless RocketChat.authz.hasPermission(Meteor.userId(), 'edit-room', rid) - throw new Meteor.Error 'error-action-not-allowed', 'Editing room is not allowed', { method: 'saveRoomSettings', action: 'Editing_room' } - - if setting is 'default' and not RocketChat.authz.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' } - - room = RocketChat.models.Rooms.findOneById rid - if room? - if setting is 'roomType' and value isnt room.t and value is 'c' and not RocketChat.authz.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 is 'roomType' and value isnt room.t and value is 'p' and not RocketChat.authz.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' } - - switch setting - when 'roomName' - name = RocketChat.saveRoomName rid, value, Meteor.user() - when 'roomTopic' - if value isnt room.topic - RocketChat.saveRoomTopic(rid, value, Meteor.user()) - when 'roomAnnouncement' - if value isnt room.announcement - RocketChat.saveRoomAnnouncement(rid, value, Meteor.user()) - when 'roomDescription' - if value isnt room.description - RocketChat.saveRoomDescription rid, value, Meteor.user() - when 'roomType' - if value isnt room.t - RocketChat.saveRoomType(rid, value, Meteor.user()) - when 'readOnly' - if value isnt room.ro - RocketChat.saveRoomReadOnly rid, value, Meteor.user() - when 'reactWhenReadOnly' - if value isnt room.reactWhenReadOnly - RocketChat.saveReactWhenReadOnly rid, value, Meteor.user() - when 'systemMessages' - if value isnt room.sysMes - RocketChat.saveRoomSystemMessages rid, value, Meteor.user() - when 'joinCode' - RocketChat.models.Rooms.setJoinCodeById rid, String(value) - when 'default' - RocketChat.models.Rooms.saveDefaultById rid, value - - return { result: true, rid: room._id } diff --git a/packages/rocketchat-channel-settings/server/methods/saveRoomSettings.js b/packages/rocketchat-channel-settings/server/methods/saveRoomSettings.js new file mode 100644 index 00000000000..9ca3ad4759a --- /dev/null +++ b/packages/rocketchat-channel-settings/server/methods/saveRoomSettings.js @@ -0,0 +1,95 @@ +Meteor.methods({ + saveRoomSettings(rid, setting, value) { + if (!Meteor.userId()) { + throw new Meteor.Error('error-invalid-user', 'Invalid user', { + 'function': 'RocketChat.saveRoomName' + }); + } + if (!Match.test(rid, String)) { + throw new Meteor.Error('error-invalid-room', 'Invalid room', { + method: 'saveRoomSettings' + }); + } + if (setting !== 'roomName' && setting !== 'roomTopic' && setting !== 'roomAnnouncement' && setting !== 'roomDescription' && setting !== 'roomType' && setting !== 'readOnly' && setting !== 'reactWhenReadOnly' && setting !== 'systemMessages' && setting !== 'default' && setting !== 'joinCode') { + throw new Meteor.Error('error-invalid-settings', 'Invalid settings provided', { + method: 'saveRoomSettings' + }); + } + if (!RocketChat.authz.hasPermission(Meteor.userId(), 'edit-room', rid)) { + throw new Meteor.Error('error-action-not-allowed', 'Editing room is not allowed', { + method: 'saveRoomSettings', + action: 'Editing_room' + }); + } + if (setting === 'default' && !RocketChat.authz.hasPermission(this.userId, 'view-room-administration')) { + throw new Meteor.Error('error-action-not-allowed', 'Viewing room administration is not allowed', { + method: 'saveRoomSettings', + action: 'Viewing_room_administration' + }); + } + const room = RocketChat.models.Rooms.findOneById(rid); + if (room != null) { + if (setting === 'roomType' && value !== room.t && value === 'c' && !RocketChat.authz.hasPermission(this.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' && !RocketChat.authz.hasPermission(this.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' + }); + } + switch (setting) { + case 'roomName': + name = RocketChat.saveRoomName(rid, value, Meteor.user()); + break; + case 'roomTopic': + if (value !== room.topic) { + RocketChat.saveRoomTopic(rid, value, Meteor.user()); + } + break; + case 'roomAnnouncement': + if (value !== room.announcement) { + RocketChat.saveRoomAnnouncement(rid, value, Meteor.user()); + } + break; + case 'roomDescription': + if (value !== room.description) { + RocketChat.saveRoomDescription(rid, value, Meteor.user()); + } + break; + case 'roomType': + if (value !== room.t) { + RocketChat.saveRoomType(rid, value, Meteor.user()); + } + break; + case 'readOnly': + if (value !== room.ro) { + RocketChat.saveRoomReadOnly(rid, value, Meteor.user()); + } + break; + case 'reactWhenReadOnly': + if (value !== room.reactWhenReadOnly) { + RocketChat.saveReactWhenReadOnly(rid, value, Meteor.user()); + } + break; + case 'systemMessages': + if (value !== room.sysMes) { + RocketChat.saveRoomSystemMessages(rid, value, Meteor.user()); + } + break; + case 'joinCode': + RocketChat.models.Rooms.setJoinCodeById(rid, String(value)); + break; + case 'default': + RocketChat.models.Rooms.saveDefaultById(rid, value); + } + } + return { + result: true, + rid: room._id + }; + } +}); diff --git a/packages/rocketchat-channel-settings/server/models/Messages.coffee b/packages/rocketchat-channel-settings/server/models/Messages.coffee deleted file mode 100644 index 9a72fcd32bb..00000000000 --- a/packages/rocketchat-channel-settings/server/models/Messages.coffee +++ /dev/null @@ -1,5 +0,0 @@ -RocketChat.models.Messages.createRoomSettingsChangedWithTypeRoomIdMessageAndUser = (type, roomId, message, user, extraData) -> - return @createWithTypeRoomIdMessageAndUser type, roomId, message, user, extraData - -RocketChat.models.Messages.createRoomRenamedWithRoomIdRoomNameAndUser = (roomId, roomName, user, extraData) -> - return @createWithTypeRoomIdMessageAndUser 'r', roomId, roomName, user, extraData diff --git a/packages/rocketchat-channel-settings/server/models/Messages.js b/packages/rocketchat-channel-settings/server/models/Messages.js new file mode 100644 index 00000000000..6f4e473375b --- /dev/null +++ b/packages/rocketchat-channel-settings/server/models/Messages.js @@ -0,0 +1,7 @@ +RocketChat.models.Messages.createRoomSettingsChangedWithTypeRoomIdMessageAndUser = function(type, roomId, message, user, extraData) { + return this.createWithTypeRoomIdMessageAndUser(type, roomId, message, user, extraData); +}; + +RocketChat.models.Messages.createRoomRenamedWithRoomIdRoomNameAndUser = function(roomId, roomName, user, extraData) { + return this.createWithTypeRoomIdMessageAndUser('r', roomId, roomName, user, extraData); +}; diff --git a/packages/rocketchat-channel-settings/server/models/Rooms.coffee b/packages/rocketchat-channel-settings/server/models/Rooms.coffee deleted file mode 100644 index d277959fe75..00000000000 --- a/packages/rocketchat-channel-settings/server/models/Rooms.coffee +++ /dev/null @@ -1,55 +0,0 @@ -RocketChat.models.Rooms.setDescriptionById = (_id, description) -> - query = - _id: _id - - update = - $set: - description: description - - return @update query, update - -RocketChat.models.Rooms.setReadOnlyById = (_id, readOnly) -> - query = - _id: _id - - update = - $set: - ro: readOnly - - if readOnly - # we want to mute all users without the post-readonly permission - - RocketChat.models.Subscriptions.findByRoomId(_id).forEach (subscription) -> - if not subscription._user? - return - - user = subscription._user - if RocketChat.authz.hasPermission(user._id, 'post-readonly') is false - # create a new array if necessary - update.$set.muted = [] if !update.$set.muted - update.$set.muted.push user.username - else - # remove the muted user array - update.$unset = {muted: ""} - - return @update query, update - -RocketChat.models.Rooms.setAllowReactingWhenReadOnlyById = (_id, allowReacting) -> - query = - _id: _id - - update = - $set: - reactWhenReadOnly: allowReacting - - return @update query, update - -RocketChat.models.Rooms.setSystemMessagesById = (_id, systemMessages) -> - query = - _id: _id - - update = - $set: - sysMes: systemMessages - - return @update query, update diff --git a/packages/rocketchat-channel-settings/server/models/Rooms.js b/packages/rocketchat-channel-settings/server/models/Rooms.js new file mode 100644 index 00000000000..07e81e5ff17 --- /dev/null +++ b/packages/rocketchat-channel-settings/server/models/Rooms.js @@ -0,0 +1,65 @@ +RocketChat.models.Rooms.setDescriptionById = function(_id, description) { + const query = { + _id + }; + const update = { + $set: { + description + } + }; + return this.update(query, update); +}; + +RocketChat.models.Rooms.setReadOnlyById = function(_id, readOnly) { + const query = { + _id + }; + const update = { + $set: { + ro: readOnly + } + }; + if (readOnly) { + RocketChat.models.Subscriptions.findByRoomId(_id).forEach(function(subscription) { + if (subscription._user == null) { + return; + } + const user = subscription._user; + if (RocketChat.authz.hasPermission(user._id, 'post-readonly') === false) { + if (!update.$set.muted) { + update.$set.muted = []; + } + return update.$set.muted.push(user.username); + } + }); + } else { + update.$unset = { + muted: '' + }; + } + return this.update(query, update); +}; + +RocketChat.models.Rooms.setAllowReactingWhenReadOnlyById = function(_id, allowReacting) { + const query = { + _id + }; + const update = { + $set: { + reactWhenReadOnly: allowReacting + } + }; + return this.update(query, update); +}; + +RocketChat.models.Rooms.setSystemMessagesById = function(_id, systemMessages) { + const query = { + _id + }; + const update = { + $set: { + sysMes: systemMessages + } + }; + return this.update(query, update); +};