From e30fdc732cdbed3ffe2cec33abc55421a36a2973 Mon Sep 17 00:00:00 2001 From: Marcelo Schmidt Date: Tue, 24 Nov 2015 13:42:17 -0200 Subject: [PATCH] Adapting #1145 for merging --- client/methods/saveRoomName.coffee | 3 +- .../server/functions/setUsername.coffee | 7 ++++- .../server/methods/setUsername.coffee | 7 ++++- .../server/startup/settings.coffee | 3 ++ packages/rocketchat-mentions/client.coffee | 6 ++-- packages/rocketchat-mentions/server.coffee | 6 ++-- server/lib/accounts.coffee | 2 +- server/methods/createChannel.coffee | 7 ++++- server/methods/createPrivateGroup.coffee | 7 ++++- server/methods/getUsernameSuggestion.coffee | 24 +++++++++++++--- server/methods/saveRoomName.coffee | 10 +++++-- .../publications/channelAutocomplete.coffee | 8 +++--- server/restapi/restapi.coffee | 28 +++++++++++++------ 13 files changed, 89 insertions(+), 29 deletions(-) diff --git a/client/methods/saveRoomName.coffee b/client/methods/saveRoomName.coffee index 659b8a35a8e..d2f6ff68477 100644 --- a/client/methods/saveRoomName.coffee +++ b/client/methods/saveRoomName.coffee @@ -8,7 +8,8 @@ Meteor.methods if room.u._id isnt Meteor.userId() or room.t not in ['c', 'p'] throw new Meteor.Error 403, t('Not allowed') - # name = _.slugify name + if RocketChat.settings.get 'UTF8_Names_slugify' + name = _.slugify name if name is room.name return diff --git a/packages/rocketchat-lib/server/functions/setUsername.coffee b/packages/rocketchat-lib/server/functions/setUsername.coffee index e5f4af3db7d..409fb6d161a 100644 --- a/packages/rocketchat-lib/server/functions/setUsername.coffee +++ b/packages/rocketchat-lib/server/functions/setUsername.coffee @@ -3,7 +3,12 @@ RocketChat.setUsername = (user, username) -> if not user or not username return false - if not /^[0-9a-zA-Z-_.\u00C0-\u017F\u4e00-\u9fa5]+$/.test username + try + nameValidation = new RegExp '^' + RocketChat.settings.get('UTF8_Names_Validation') + '$' + catch + nameValidation = new RegExp '^[0-9a-zA-Z-_.]+$' + + if not nameValidation.test username return false # User already has desired username, return diff --git a/packages/rocketchat-lib/server/methods/setUsername.coffee b/packages/rocketchat-lib/server/methods/setUsername.coffee index 4df9f4b8d63..6fed25d40de 100644 --- a/packages/rocketchat-lib/server/methods/setUsername.coffee +++ b/packages/rocketchat-lib/server/methods/setUsername.coffee @@ -13,7 +13,12 @@ Meteor.methods if user.username is username return username - if not /^[0-9a-zA-Z-_.\u00C0-\u017F\u4e00-\u9fa5]+$/.test username + try + nameValidation = new RegExp '^' + RocketChat.settings.get('UTF8_Names_Validation') + '$' + catch + nameValidation = new RegExp '^[0-9a-zA-Z-_.]+$' + + if not nameValidation.test username throw new Meteor.Error 'username-invalid', "#{username} is not a valid username, use only letters, numbers, dots and dashes" if not RocketChat.checkUsernameAvailability username diff --git a/packages/rocketchat-lib/server/startup/settings.coffee b/packages/rocketchat-lib/server/startup/settings.coffee index f1985261ece..4bff3c27114 100644 --- a/packages/rocketchat-lib/server/startup/settings.coffee +++ b/packages/rocketchat-lib/server/startup/settings.coffee @@ -54,6 +54,9 @@ RocketChat.settings.add 'Allow_Invalid_SelfSigned_Certs', false, { type: 'boolea RocketChat.settings.add 'Disable_Favorite_Rooms', false, { type: 'boolean', group: 'General' } RocketChat.settings.add 'CDN_PREFIX', '', { type: 'string', group: 'General' } +RocketChat.settings.add 'UTF8_Names_Validation', '[0-9a-zA-Z-_.]+', { type: 'string', group: 'General', section: 'UTF8', public: true } +RocketChat.settings.add 'UTF8_Names_Slugify', true, { type: 'boolean', group: 'General', section: 'UTF8', public: true } + RocketChat.settings.addGroup 'API' RocketChat.settings.add 'API_Analytics', '', { type: 'string', group: 'API', public: true } RocketChat.settings.add 'API_Embed', true, { type: 'boolean', group: 'API', public: true } diff --git a/packages/rocketchat-mentions/client.coffee b/packages/rocketchat-mentions/client.coffee index 6bb5a982dca..7a480267454 100644 --- a/packages/rocketchat-mentions/client.coffee +++ b/packages/rocketchat-mentions/client.coffee @@ -10,7 +10,8 @@ class MentionsClient mentions = [] - message.msg.replace /(?:^|\s|\n)(?:@)([0-9a-zA-Z-_.\u00C0-\u017F\u4e00-\u9fa5]+)/g, (match, mention) -> + msgMentionRegex = new RegExp '(?:^|\s|\n)(?:@)(' + RocketChat.settings.get('UTF8_Names_Validation') + ')', 'g' + message.msg.replace msgMentionRegex, (match, mention) -> mentions.push mention me = Meteor.user()?.username @@ -33,7 +34,8 @@ class MentionsClient return match.replace mention, "#{mention}" channels = [] - message.msg.replace /(?:^|\s|\n)(?:#)([A-Za-z0-9-_.\u00C0-\u017F\u4e00-\u9fa5]+)/g, (match, mention) -> + msgChannelRegex = new RegExp '(?:^|\s|\n)(?:#)(' + RocketChat.settings.get('UTF8_Names_Validation') + ')', 'g' + message.msg.replace msgChannelRegex, (match, mention) -> channels.push mention if channels.length isnt 0 diff --git a/packages/rocketchat-mentions/server.coffee b/packages/rocketchat-mentions/server.coffee index 04c42e511fc..75f364f3f77 100644 --- a/packages/rocketchat-mentions/server.coffee +++ b/packages/rocketchat-mentions/server.coffee @@ -7,7 +7,8 @@ class MentionsServer constructor: (message) -> # If message starts with /me, replace it for text formatting mentions = [] - message.msg.replace /(?:^|\s|\n)(?:@)([A-Za-z0-9-_.\u00C0-\u017F\u4e00-\u9fa5]+)/g, (match, mention) -> + msgMentionRegex = new RegExp '(?:^|\s|\n)(?:@)(' + RocketChat.settings.get('UTF8_Names_Validation') + ')', 'g' + message.msg.replace msgMentionRegex, (match, mention) -> mentions.push mention if mentions.length isnt 0 mentions = _.unique mentions @@ -25,7 +26,8 @@ class MentionsServer message.mentions = verifiedMentions channels = [] - message.msg.replace /(?:^|\s|\n)(?:#)([A-Za-z0-9-_.\u00C0-\u017F\u4e00-\u9fa5]+)/g, (match, mention) -> + msgChannelRegex = new RegExp '(?:^|\s|\n)(?:#)(' + RocketChat.settings.get('UTF8_Names_Validation') + ')', 'g' + message.msg.replace msgChannelRegex, (match, mention) -> channels.push mention if channels.length isnt 0 diff --git a/server/lib/accounts.coffee b/server/lib/accounts.coffee index 4a62d083d86..6489faee0b3 100644 --- a/server/lib/accounts.coffee +++ b/server/lib/accounts.coffee @@ -88,7 +88,7 @@ Accounts.validateLoginAttempt (login) -> if login.allowed isnt true return login.allowed - if login.user?.active isnt true and login.user?.active != '1' + if !!login.user?.active isnt true throw new Meteor.Error 'inactive-user', TAPi18n.__ 'User_is_not_activated' return false diff --git a/server/methods/createChannel.coffee b/server/methods/createChannel.coffee index 9dd9a22f8a4..3c8319079d3 100644 --- a/server/methods/createChannel.coffee +++ b/server/methods/createChannel.coffee @@ -3,7 +3,12 @@ Meteor.methods if not Meteor.userId() throw new Meteor.Error 'invalid-user', "[methods] createChannel -> Invalid user" - if not /^[0-9a-zA-Z-_\u00C0-\u017F\u4e00-\u9fa5]+$/.test name + 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 'name-invalid' if RocketChat.authz.hasPermission(Meteor.userId(), 'create-c') isnt true diff --git a/server/methods/createPrivateGroup.coffee b/server/methods/createPrivateGroup.coffee index 6994f4b1b34..22080081372 100644 --- a/server/methods/createPrivateGroup.coffee +++ b/server/methods/createPrivateGroup.coffee @@ -8,7 +8,12 @@ Meteor.methods console.log '[methods] createPrivateGroup -> '.green, 'userId:', Meteor.userId(), 'arguments:', arguments - if not /^[0-9a-zA-Z-_\u00C0-\u017F\u4e00-\u9fa5]+$/.test name + 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 'name-invalid' now = new Date() diff --git a/server/methods/getUsernameSuggestion.coffee b/server/methods/getUsernameSuggestion.coffee index f9732af56db..927adb09aad 100644 --- a/server/methods/getUsernameSuggestion.coffee +++ b/server/methods/getUsernameSuggestion.coffee @@ -15,25 +15,41 @@ usernameIsAvaliable = (username) -> usernames = [] username = undefined - usernames.push user.name + if RocketChat.settings.get 'UTF8_Names_slugify' + usernames.push slug user.name + else + usernames.push user.name nameParts = user?.name?.split() if nameParts.length > 1 first = nameParts[0] last = nameParts[nameParts.length - 1] + if RocketChat.settings.get 'UTF8_Names_slugify' + usernames.push slug first[0] + last + usernames.push slug first + last[0] + else usernames.push first[0] + last usernames.push first + last[0] if user.profile?.name? - usernames.push user.profile.name + if RocketChat.settings.get 'UTF8_Names_slugify' + usernames.push slug user.profile.name + else + usernames.push user.profile.name if user.services? for serviceName, service of user.services if service.name? - usernames.push service.name + if RocketChat.settings.get 'UTF8_Names_slugify' + usernames.push slug service.name + else + usernames.push service.name else if service.username? - usernames.push service.username + if RocketChat.settings.get 'UTF8_Names_slugify' + usernames.push slug service.username + else + usernames.push service.username if user.emails?.length > 0 for email in user.emails when email.address? and email.verified is true diff --git a/server/methods/saveRoomName.coffee b/server/methods/saveRoomName.coffee index 02425c803f0..16756afec35 100644 --- a/server/methods/saveRoomName.coffee +++ b/server/methods/saveRoomName.coffee @@ -12,10 +12,16 @@ Meteor.methods #if room.u._id isnt Meteor.userId() and not hasPermission throw new Meteor.Error 403, 'Not allowed' - if not /^[0-9a-zA-Z-_\u00C0-\u017F\u4e00-\u9fa5]+$/.test name + 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 'name-invalid' - ##remove name = _.slugify name + if RocketChat.settings.get 'UTF8_Names_slugify' + name = _.slugify name if name is room.name return diff --git a/server/publications/channelAutocomplete.coffee b/server/publications/channelAutocomplete.coffee index 7cdd182e69b..eebbea4bc8f 100644 --- a/server/publications/channelAutocomplete.coffee +++ b/server/publications/channelAutocomplete.coffee @@ -13,12 +13,12 @@ Meteor.publish 'channelAutocomplete', (name) -> limit: 5 cursorHandle = RocketChat.models.Rooms.findByNameContainingAndTypes(name, ['c'], options).observeChanges - added: (_id, record) -> - pub.added('channel-autocomplete', _id, record) if _id? + added: (_id, record) -> + pub.added('channel-autocomplete', _id, record) changed: (_id, record) -> - pub.changed('channel-autocomplete', _id, record) if _id? + pub.changed('channel-autocomplete', _id, record) removed: (_id, record) -> - pub.removed('channel-autocomplete', _id, record) if _id? + pub.removed('channel-autocomplete', _id, record) @ready() @onStop -> cursorHandle.stop() diff --git a/server/restapi/restapi.coffee b/server/restapi/restapi.coffee index eef079bc8e0..24931bdd942 100644 --- a/server/restapi/restapi.coffee +++ b/server/restapi/restapi.coffee @@ -20,7 +20,7 @@ Api.addRoute 'rooms/:id/join', authRequired: true, Meteor.runAsUser this.userId, () => Meteor.call('joinRoom', @urlParams.id) status: 'success' # need to handle error - + # leave a room Api.addRoute 'rooms/:id/leave', authRequired: true, post: -> @@ -60,7 +60,12 @@ Api.testapiValidateUsers = (users) -> if user.name? if user.email? if user.pass? - if /^[0-9a-zA-Z-_\u00C0-\u017F\u4e00-\u9fa5]+$/i.test user.name + try + nameValidation = new RegExp '^' + RocketChat.settings.get('UTF8_Names_Validation') + '$', 'i' + catch + nameValidation = new RegExp '^[0-9a-zA-Z-_.]+$', 'i' + + if nameValidation.test user.name if /\b[A-Z0-9._%+-]+@[A-Z0-9.-]+\.[A-Z]+\b/i.test user.email continue throw new Meteor.Error 'invalid-user-record', "[restapi] bulk/register -> record #" + i + " is invalid" @@ -101,7 +106,7 @@ Api.addRoute 'bulk/register', authRequired: true, # restivus 0.8.4 does not support alanning:roles using groups #roleRequired: ['testagent', 'adminautomation'] action: -> - if RocketChat.authz.hasPermission(@userId, 'bulk-register-user') + if RocketChat.authz.hasPermission(@userId, 'bulk-register-user') try Api.testapiValidateUsers @bodyParams.users @@ -120,7 +125,7 @@ Api.addRoute 'bulk/register', authRequired: true, body: status: 'fail', message: e.name + ' :: ' + e.message else console.log '[restapi] bulk/register -> '.red, "User does not have 'bulk-register-user' permission" - statusCode: 403 + statusCode: 403 body: status: 'error', message: 'You do not have permission to do this' @@ -132,7 +137,12 @@ Api.testapiValidateRooms = (rooms) -> if room.name? if room.members? if room.members.length > 1 - if /^[0-9a-zA-Z-_\u00C0-\u017F\u4e00-\u9fa5]+$/i.test room.name + try + nameValidation = new RegExp '^' + RocketChat.settings.get('UTF8_Names_Validation') + '$', 'i' + catch + nameValidation = new RegExp '^[0-9a-zA-Z-_.]+$', 'i' + + if nameValidation.test room.name continue throw new Meteor.Error 'invalid-room-record', "[restapi] bulk/createRoom -> record #" + i + " is invalid" return @@ -143,7 +153,7 @@ Api.testapiValidateRooms = (rooms) -> @apiName createRoom @apiGroup TestAndAdminAutomation @apiVersion 0.0.1 -@apiParam {json} rooms An array of rooms in the body of the POST. 'name' is room name, 'members' is array of usernames +@apiParam {json} rooms An array of rooms in the body of the POST. 'name' is room name, 'members' is array of usernames @apiParamExample {json} POST Request Body example: { 'rooms':[ {'name': 'room1', @@ -173,9 +183,9 @@ Api.addRoute 'bulk/createRoom', authRequired: true, # restivus 0.8.4 does not support alanning:roles using groups #roleRequired: ['testagent', 'adminautomation'] action: -> - # user must also have create-c permission because + # user must also have create-c permission because # createChannel method requires it - if RocketChat.authz.hasPermission(@userId, 'bulk-create-c') + if RocketChat.authz.hasPermission(@userId, 'bulk-create-c') try this.response.setTimeout (1000 * @bodyParams.rooms.length) Api.testapiValidateRooms @bodyParams.rooms @@ -188,7 +198,7 @@ Api.addRoute 'bulk/createRoom', authRequired: true, body: status: 'fail', message: e.name + ' :: ' + e.message else console.log '[restapi] bulk/createRoom -> '.red, "User does not have 'bulk-create-c' permission" - statusCode: 403 + statusCode: 403 body: status: 'error', message: 'You do not have permission to do this'