From 04a374729be01cdd0a72ad2823afb3a0f191d123 Mon Sep 17 00:00:00 2001 From: Martin Schoeler Date: Mon, 24 Apr 2017 15:04:48 -0300 Subject: [PATCH 01/19] Convert Mailer Package to Js --- .../rocketchat-mailer/client/router.coffee | 10 --- packages/rocketchat-mailer/client/router.js | 16 ++++ .../rocketchat-mailer/client/startup.coffee | 5 -- packages/rocketchat-mailer/client/startup.js | 7 ++ .../client/views/mailer.coffee | 25 ------ .../rocketchat-mailer/client/views/mailer.js | 31 +++++++ .../client/views/mailerUnsubscribe.coffee | 2 - .../client/views/mailerUnsubscribe.js | 3 + packages/rocketchat-mailer/lib/Mailer.js | 1 + packages/rocketchat-mailer/package.js | 23 +++--- .../server/functions/sendMail.coffee | 63 --------------- .../server/functions/sendMail.js | 80 +++++++++++++++++++ .../server/functions/unsubscribe.coffee | 4 - .../server/functions/unsubscribe.js | 7 ++ .../server/methods/sendMail.coffee | 16 ---- .../server/methods/sendMail.js | 25 ++++++ .../server/methods/unsubscribe.coffee | 10 --- .../server/methods/unsubscribe.js | 14 ++++ .../server/models/Users.coffee | 17 ---- .../rocketchat-mailer/server/models/Users.js | 14 ++++ .../rocketchat-mailer/server/startup.coffee | 2 - packages/rocketchat-mailer/server/startup.js | 8 ++ 22 files changed, 217 insertions(+), 166 deletions(-) delete mode 100644 packages/rocketchat-mailer/client/router.coffee create mode 100644 packages/rocketchat-mailer/client/router.js delete mode 100644 packages/rocketchat-mailer/client/startup.coffee create mode 100644 packages/rocketchat-mailer/client/startup.js delete mode 100644 packages/rocketchat-mailer/client/views/mailer.coffee create mode 100644 packages/rocketchat-mailer/client/views/mailer.js delete mode 100644 packages/rocketchat-mailer/client/views/mailerUnsubscribe.coffee create mode 100644 packages/rocketchat-mailer/client/views/mailerUnsubscribe.js create mode 100644 packages/rocketchat-mailer/lib/Mailer.js delete mode 100644 packages/rocketchat-mailer/server/functions/sendMail.coffee create mode 100644 packages/rocketchat-mailer/server/functions/sendMail.js delete mode 100644 packages/rocketchat-mailer/server/functions/unsubscribe.coffee create mode 100644 packages/rocketchat-mailer/server/functions/unsubscribe.js delete mode 100644 packages/rocketchat-mailer/server/methods/sendMail.coffee create mode 100644 packages/rocketchat-mailer/server/methods/sendMail.js delete mode 100644 packages/rocketchat-mailer/server/methods/unsubscribe.coffee create mode 100644 packages/rocketchat-mailer/server/methods/unsubscribe.js delete mode 100644 packages/rocketchat-mailer/server/models/Users.coffee create mode 100644 packages/rocketchat-mailer/server/models/Users.js delete mode 100644 packages/rocketchat-mailer/server/startup.coffee create mode 100644 packages/rocketchat-mailer/server/startup.js diff --git a/packages/rocketchat-mailer/client/router.coffee b/packages/rocketchat-mailer/client/router.coffee deleted file mode 100644 index 0314ec8fd1ea..000000000000 --- a/packages/rocketchat-mailer/client/router.coffee +++ /dev/null @@ -1,10 +0,0 @@ -FlowRouter.route '/mailer', - name: 'mailer' - action: -> - BlazeLayout.render 'main', {center: 'mailer'} - -FlowRouter.route '/mailer/unsubscribe/:_id/:createdAt', - name: 'mailer-unsubscribe' - action: (params) -> - Meteor.call 'Mailer:unsubscribe', params._id, params.createdAt - BlazeLayout.render 'mailerUnsubscribe' diff --git a/packages/rocketchat-mailer/client/router.js b/packages/rocketchat-mailer/client/router.js new file mode 100644 index 000000000000..e2a9e6728035 --- /dev/null +++ b/packages/rocketchat-mailer/client/router.js @@ -0,0 +1,16 @@ +FlowRouter.route('/mailer', { + name: 'mailer', + action() { + return BlazeLayout.render('main', { + center: 'mailer' + }); + } +}); + +FlowRouter.route('/mailer/unsubscribe/:_id/:createdAt', { + name: 'mailer-unsubscribe', + action(params) { + Meteor.call('Mailer:unsubscribe', params._id, params.createdAt); + return BlazeLayout.render('mailerUnsubscribe'); + } +}); diff --git a/packages/rocketchat-mailer/client/startup.coffee b/packages/rocketchat-mailer/client/startup.coffee deleted file mode 100644 index 9b4dd0847261..000000000000 --- a/packages/rocketchat-mailer/client/startup.coffee +++ /dev/null @@ -1,5 +0,0 @@ -RocketChat.AdminBox.addOption - href: 'mailer' - i18nLabel: 'Mailer' - permissionGranted: -> - return RocketChat.authz.hasAllPermission('access-mailer') diff --git a/packages/rocketchat-mailer/client/startup.js b/packages/rocketchat-mailer/client/startup.js new file mode 100644 index 000000000000..728ebddf8c10 --- /dev/null +++ b/packages/rocketchat-mailer/client/startup.js @@ -0,0 +1,7 @@ +RocketChat.AdminBox.addOption({ + href: 'mailer', + i18nLabel: 'Mailer', + permissionGranted() { + return RocketChat.authz.hasAllPermission('access-mailer'); + } +}); diff --git a/packages/rocketchat-mailer/client/views/mailer.coffee b/packages/rocketchat-mailer/client/views/mailer.coffee deleted file mode 100644 index 9f484b5a5e34..000000000000 --- a/packages/rocketchat-mailer/client/views/mailer.coffee +++ /dev/null @@ -1,25 +0,0 @@ -import toastr from 'toastr' -Template.mailer.helpers - fromEmail: -> - return RocketChat.settings.get 'From_Email' - -Template.mailer.events - 'click .send': (e, t) -> - e.preventDefault() - from = $(t.find('[name=from]')).val() - subject = $(t.find('[name=subject]')).val() - body = $(t.find('[name=body]')).val() - dryrun = $(t.find('[name=dryrun]:checked')).val() - query = $(t.find('[name=query]')).val() - - unless from - toastr.error TAPi18n.__('error-invalid-from-address') - return - - if body.indexOf('[unsubscribe]') is -1 - toastr.error TAPi18n.__('error-missing-unsubscribe-link') - return - - Meteor.call 'Mailer.sendMail', from, subject, body, dryrun, query, (err) -> - return handleError(err) if err - toastr.success TAPi18n.__('The_emails_are_being_sent') diff --git a/packages/rocketchat-mailer/client/views/mailer.js b/packages/rocketchat-mailer/client/views/mailer.js new file mode 100644 index 000000000000..731df5aaa3ec --- /dev/null +++ b/packages/rocketchat-mailer/client/views/mailer.js @@ -0,0 +1,31 @@ +import toastr from 'toastr'; +Template.mailer.helpers({ + fromEmail() { + return RocketChat.settings.get('From_Email'); + } +}); + +Template.mailer.events({ + 'click .send'(e, t) { + e.preventDefault(); + const from = $(t.find('[name=from]')).val(); + const subject = $(t.find('[name=subject]')).val(); + const body = $(t.find('[name=body]')).val(); + const dryrun = $(t.find('[name=dryrun]:checked')).val(); + const query = $(t.find('[name=query]')).val(); + if (!from) { + toastr.error(TAPi18n.__('error-invalid-from-address')); + return; + } + if (body.indexOf('[unsubscribe]') === -1) { + toastr.error(TAPi18n.__('error-missing-unsubscribe-link')); + return; + } + return Meteor.call('Mailer.sendMail', from, subject, body, dryrun, query, function(err) { + if (err) { + return handleError(err); + } + return toastr.success(TAPi18n.__('The_emails_are_being_sent')); + }); + } +}); diff --git a/packages/rocketchat-mailer/client/views/mailerUnsubscribe.coffee b/packages/rocketchat-mailer/client/views/mailerUnsubscribe.coffee deleted file mode 100644 index d8a7a1840e01..000000000000 --- a/packages/rocketchat-mailer/client/views/mailerUnsubscribe.coffee +++ /dev/null @@ -1,2 +0,0 @@ -Template.mailerUnsubscribe.onRendered -> - $('#initial-page-loading').remove() diff --git a/packages/rocketchat-mailer/client/views/mailerUnsubscribe.js b/packages/rocketchat-mailer/client/views/mailerUnsubscribe.js new file mode 100644 index 000000000000..8012c4deb519 --- /dev/null +++ b/packages/rocketchat-mailer/client/views/mailerUnsubscribe.js @@ -0,0 +1,3 @@ +Template.mailerUnsubscribe.onRendered(function() { + return $('#initial-page-loading').remove(); +}); diff --git a/packages/rocketchat-mailer/lib/Mailer.js b/packages/rocketchat-mailer/lib/Mailer.js new file mode 100644 index 000000000000..e7e30cfebe4a --- /dev/null +++ b/packages/rocketchat-mailer/lib/Mailer.js @@ -0,0 +1 @@ +Mailer = {};//eslint-disable-line diff --git a/packages/rocketchat-mailer/package.js b/packages/rocketchat-mailer/package.js index 30da5c981e53..ffe0a7e317dc 100644 --- a/packages/rocketchat-mailer/package.js +++ b/packages/rocketchat-mailer/package.js @@ -7,7 +7,6 @@ Package.describe({ Package.onUse(function(api) { api.use([ 'ecmascript', - 'coffeescript', 'ddp-rate-limiter', 'kadira:flow-router', 'rocketchat:lib', @@ -16,24 +15,24 @@ Package.onUse(function(api) { api.use('templating', 'client'); - api.addFiles('lib/Mailer.coffee'); + api.addFiles('lib/Mailer.js'); api.addFiles([ - 'client/startup.coffee', - 'client/router.coffee', + 'client/startup.js', + 'client/router.js', 'client/views/mailer.html', - 'client/views/mailer.coffee', + 'client/views/mailer.js', 'client/views/mailerUnsubscribe.html', - 'client/views/mailerUnsubscribe.coffee' + 'client/views/mailerUnsubscribe.js' ], 'client'); api.addFiles([ - 'server/startup.coffee', - 'server/models/Users.coffee', - 'server/functions/sendMail.coffee', - 'server/functions/unsubscribe.coffee', - 'server/methods/sendMail.coffee', - 'server/methods/unsubscribe.coffee' + 'server/startup.js', + 'server/models/Users.js', + 'server/functions/sendMail.js', + 'server/functions/unsubscribe.js', + 'server/methods/sendMail.js', + 'server/methods/unsubscribe.js' ], 'server'); api.export('Mailer'); diff --git a/packages/rocketchat-mailer/server/functions/sendMail.coffee b/packages/rocketchat-mailer/server/functions/sendMail.coffee deleted file mode 100644 index d6fa86beb87f..000000000000 --- a/packages/rocketchat-mailer/server/functions/sendMail.coffee +++ /dev/null @@ -1,63 +0,0 @@ -Mailer.sendMail = (from, subject, body, dryrun, query) -> - - rfcMailPatternWithName = /^(?:.*<)?([a-zA-Z0-9.!#$%&'*+\/=?^_`{|}~-]+@[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?(?:\.[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?)*)(?:>?)$/ - # rfcMailPattern = /^[a-zA-Z0-9.!#$%&'*+\/=?^_`{|}~-]+@[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?(?:\.[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?)*$/ - - unless rfcMailPatternWithName.test from - throw new Meteor.Error 'error-invalid-from-address', 'Invalid from address', { function: 'Mailer.sendMail' } - - if body.indexOf('[unsubscribe]') is -1 - throw new Meteor.Error 'error-missing-unsubscribe-link', 'You must provide the [unsubscribe] link.', { function: 'Mailer.sendMail' } - - header = RocketChat.placeholders.replace(RocketChat.settings.get('Email_Header') || ''); - footer = RocketChat.placeholders.replace(RocketChat.settings.get('Email_Footer') || ''); - - userQuery = { "mailer.unsubscribed": { $exists: 0 } } - if query - userQuery = { $and: [ userQuery, EJSON.parse(query) ] } - - if dryrun - Meteor.users.find({ "emails.address": from }).forEach (user) -> - # Meteor.users.find({ "username": /\.rocket\.team/ }).forEach (user) -> - email = user.emails?[0]?.address - - html = RocketChat.placeholders.replace(body, { - unsubscribe: Meteor.absoluteUrl(FlowRouter.path('mailer/unsubscribe/:_id/:createdAt', { _id: user._id, createdAt: user.createdAt.getTime() })), - name: user.name, - email: email - }); - - email = "#{user.name} <#{email}>" - - if rfcMailPatternWithName.test email - Meteor.defer -> - Email.send - to: email - from: from - subject: subject - html: header + html + footer - - console.log 'Sending email to ' + email - - else - Meteor.users.find({ "mailer.unsubscribed": { $exists: 0 } }).forEach (user) -> - # Meteor.users.find({ "username": /\.rocket\.team/ }).forEach (user) -> - email = user.emails?[0]?.address - - html = RocketChat.placeholders.replace(body, { - unsubscribe: Meteor.absoluteUrl(FlowRouter.path('mailer/unsubscribe/:_id/:createdAt', { _id: user._id, createdAt: user.createdAt.getTime() })), - name: user.name, - email: email - }); - - email = "#{user.name} <#{email}>" - - if rfcMailPatternWithName.test email - Meteor.defer -> - Email.send - to: email - from: from - subject: subject - html: header + html + footer - - console.log 'Sending email to ' + email diff --git a/packages/rocketchat-mailer/server/functions/sendMail.js b/packages/rocketchat-mailer/server/functions/sendMail.js new file mode 100644 index 000000000000..b8cd2e9b49be --- /dev/null +++ b/packages/rocketchat-mailer/server/functions/sendMail.js @@ -0,0 +1,80 @@ +/*globals Mailer */ +Mailer.sendMail = function(from, subject, body, dryrun, query) { + + const rfcMailPatternWithName = /^(?:.*<)?([a-zA-Z0-9.!#$%&'*+\/=?^_`{|}~-]+@[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?(?:\.[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?)*)(?:>?)$/; + if (!rfcMailPatternWithName.test(from)) { + throw new Meteor.Error('error-invalid-from-address', 'Invalid from address', { + 'function': 'Mailer.sendMail' + }); + } + if (body.indexOf('[unsubscribe]') === -1) { + throw new Meteor.Error('error-missing-unsubscribe-link', 'You must provide the [unsubscribe] link.', { + 'function': 'Mailer.sendMail' + }); + } + const header = RocketChat.placeholders.replace(RocketChat.settings.get('Email_Header') || ''); + const footer = RocketChat.placeholders.replace(RocketChat.settings.get('Email_Footer') || ''); + + let userQuery = { 'mailer.unsubscribed': { $exists: 0 } }; + if (query) { + userQuery = { $and: [ userQuery, EJSON.parse(query) ] }; + } + + if (dryrun) { + return Meteor.users.find({ + 'emails.address': from + }).forEach((user) => { + let email = undefined; + if (user.emails && user.emails[0] && user.emails[0].address) { + email = user.emails[0].address; + } + const html = RocketChat.placeholders.replace(body, { + unsubscribe: Meteor.absoluteUrl(FlowRouter.path('mailer/unsubscribe/:_id/:createdAt', { + _id: user._id, + createdAt: user.createdAt.getTime() + })), + name: user.name, + email + }); + email = `${ user.name } <${ email }>`; + if (rfcMailPatternWithName.test(email)) { + Meteor.defer(function() { + return Email.send({ + to: email, + from, + subject, + html: header + html + footer + }); + }); + return console.log(`Sending email to ${ email }`); + } + }); + } else { + return Meteor.users.find(userQuery).forEach(function(user) { + let email = undefined; + if (user.emails && user.emails[0] && user.emails[0].address) { + email = user.emails[0].address; + } + const html = RocketChat.placeholders.replace(body, { + unsubscribe: Meteor.absoluteUrl(FlowRouter.path('mailer/unsubscribe/:_id/:createdAt', { + _id: user._id, + createdAt: user.createdAt.getTime() + })), + name: user.name, + email + }); + email = `${ user.name } <${ email }>`; + if (rfcMailPatternWithName.test(email)) { + Meteor.defer(function() { + return Email.send({ + to: email, + from, + subject, + html: header + html + footer + }); + }); + return console.log(`Sending email to ${ email }`); + } + }); + } +}; diff --git a/packages/rocketchat-mailer/server/functions/unsubscribe.coffee b/packages/rocketchat-mailer/server/functions/unsubscribe.coffee deleted file mode 100644 index 955a0ec95fb3..000000000000 --- a/packages/rocketchat-mailer/server/functions/unsubscribe.coffee +++ /dev/null @@ -1,4 +0,0 @@ -Mailer.unsubscribe = (_id, createdAt) -> - if _id and createdAt - return RocketChat.models.Users.RocketMailUnsubscribe(_id, createdAt) == 1 - return false diff --git a/packages/rocketchat-mailer/server/functions/unsubscribe.js b/packages/rocketchat-mailer/server/functions/unsubscribe.js new file mode 100644 index 000000000000..4e0bbc838ad9 --- /dev/null +++ b/packages/rocketchat-mailer/server/functions/unsubscribe.js @@ -0,0 +1,7 @@ +/* globals Mailer */ +Mailer.unsubscribe = function(_id, createdAt) { + if (_id && createdAt) { + return RocketChat.models.Users.rocketMailUnsubscribe(_id, createdAt) === 1; + } + return false; +}; diff --git a/packages/rocketchat-mailer/server/methods/sendMail.coffee b/packages/rocketchat-mailer/server/methods/sendMail.coffee deleted file mode 100644 index 17b8946353f5..000000000000 --- a/packages/rocketchat-mailer/server/methods/sendMail.coffee +++ /dev/null @@ -1,16 +0,0 @@ -Meteor.methods - 'Mailer.sendMail': (from, subject, body, dryrun, query) -> - if not Meteor.userId() - throw new Meteor.Error 'error-invalid-user', "Invalid user", { method: 'Mailer.sendMail' } - - unless RocketChat.authz.hasRole( Meteor.userId(), 'admin') is true - throw new Meteor.Error 'error-not-allowed', 'Not allowed', { method: 'Mailer.sendMail' } - - return Mailer.sendMail from, subject, body, dryrun, query - -# Limit setting username once per minute -# DDPRateLimiter.addRule -# type: 'method' -# name: 'Mailer.sendMail' -# connectionId: -> return true -# , 1, 60000 diff --git a/packages/rocketchat-mailer/server/methods/sendMail.js b/packages/rocketchat-mailer/server/methods/sendMail.js new file mode 100644 index 000000000000..c45b394b01b2 --- /dev/null +++ b/packages/rocketchat-mailer/server/methods/sendMail.js @@ -0,0 +1,25 @@ +/*globals Mailer */ +Meteor.methods({ + 'Mailer.sendMail'(from, subject, body, dryrun, query) { + const userId = Meteor.userId(); + if (!userId) { + throw new Meteor.Error('error-invalid-user', 'Invalid user', { + method: 'Mailer.sendMail' + }); + } + if (RocketChat.authz.hasRole(userId, 'admin') !== true) { + throw new Meteor.Error('error-not-allowed', 'Not allowed', { + method: 'Mailer.sendMail' + }); + } + return Mailer.sendMail(from, subject, body, dryrun, query); + } +}); + + +//Limit setting username once per minute +//DDPRateLimiter.addRule +// type: 'method' +// name: 'Mailer.sendMail' +// connectionId: -> return true +// , 1, 60000 diff --git a/packages/rocketchat-mailer/server/methods/unsubscribe.coffee b/packages/rocketchat-mailer/server/methods/unsubscribe.coffee deleted file mode 100644 index 88e5d7a1494b..000000000000 --- a/packages/rocketchat-mailer/server/methods/unsubscribe.coffee +++ /dev/null @@ -1,10 +0,0 @@ -Meteor.methods - 'Mailer:unsubscribe': (_id, createdAt) -> - return Mailer.unsubscribe _id, createdAt - -# Limit setting username once per minute -DDPRateLimiter.addRule - type: 'method' - name: 'Mailer:unsubscribe' - connectionId: -> return true -, 1, 60000 diff --git a/packages/rocketchat-mailer/server/methods/unsubscribe.js b/packages/rocketchat-mailer/server/methods/unsubscribe.js new file mode 100644 index 000000000000..914c80e7b143 --- /dev/null +++ b/packages/rocketchat-mailer/server/methods/unsubscribe.js @@ -0,0 +1,14 @@ +/*globals Mailer */ +Meteor.methods({ + 'Mailer:unsubscribe'(_id, createdAt) { + return Mailer.unsubscribe(_id, createdAt); + } +}); + +DDPRateLimiter.addRule({ + type: 'method', + name: 'Mailer:unsubscribe', + connectionId() { + return true; + } +}, 1, 60000); diff --git a/packages/rocketchat-mailer/server/models/Users.coffee b/packages/rocketchat-mailer/server/models/Users.coffee deleted file mode 100644 index 7622b890d480..000000000000 --- a/packages/rocketchat-mailer/server/models/Users.coffee +++ /dev/null @@ -1,17 +0,0 @@ -# Extends model Users - -RocketChat.models.Users.RocketMailUnsubscribe = (_id, createdAt) -> - - query = - _id: _id - createdAt: new Date(parseInt createdAt) - - update = - $set: - "mailer.unsubscribed": true - - affectedRows = @update query, update - - console.log '[Mailer:Unsubscribe]', _id, createdAt, new Date(parseInt createdAt), affectedRows - - return affectedRows diff --git a/packages/rocketchat-mailer/server/models/Users.js b/packages/rocketchat-mailer/server/models/Users.js new file mode 100644 index 000000000000..9649db1972ff --- /dev/null +++ b/packages/rocketchat-mailer/server/models/Users.js @@ -0,0 +1,14 @@ +RocketChat.models.Users.rocketMailUnsubscribe = function(_id, createdAt) { + const query = { + _id, + createdAt: new Date(parseInt(createdAt)) + }; + const update = { + $set: { + 'mailer.unsubscribed': true + } + }; + const affectedRows = this.update(query, update); + console.log('[Mailer:Unsubscribe]', _id, createdAt, new Date(parseInt(createdAt)), affectedRows); + return affectedRows; +}; diff --git a/packages/rocketchat-mailer/server/startup.coffee b/packages/rocketchat-mailer/server/startup.coffee deleted file mode 100644 index acf55f73c49d..000000000000 --- a/packages/rocketchat-mailer/server/startup.coffee +++ /dev/null @@ -1,2 +0,0 @@ -Meteor.startup -> - RocketChat.models.Permissions.upsert( 'access-mailer', { $setOnInsert : { _id: 'access-mailer', roles : ['admin'] } }) diff --git a/packages/rocketchat-mailer/server/startup.js b/packages/rocketchat-mailer/server/startup.js new file mode 100644 index 000000000000..e1ef976a18fd --- /dev/null +++ b/packages/rocketchat-mailer/server/startup.js @@ -0,0 +1,8 @@ +Meteor.startup(function() { + return RocketChat.models.Permissions.upsert('access-mailer', { + $setOnInsert: { + _id: 'access-mailer', + roles: ['admin'] + } + }); +}); From 9a469b5130281263c7fd0e398d4e68a92b33eceb Mon Sep 17 00:00:00 2001 From: Martin Schoeler Date: Mon, 24 Apr 2017 15:20:33 -0300 Subject: [PATCH 02/19] remove last coffee from mailer --- packages/rocketchat-mailer/lib/Mailer.coffee | 1 - 1 file changed, 1 deletion(-) delete mode 100644 packages/rocketchat-mailer/lib/Mailer.coffee diff --git a/packages/rocketchat-mailer/lib/Mailer.coffee b/packages/rocketchat-mailer/lib/Mailer.coffee deleted file mode 100644 index 8158d6d741d1..000000000000 --- a/packages/rocketchat-mailer/lib/Mailer.coffee +++ /dev/null @@ -1 +0,0 @@ -Mailer = {} From 94e1ed5a43e1cf161b54ec73dff8b42cc03d1226 Mon Sep 17 00:00:00 2001 From: Bradley Hilton Date: Tue, 25 Apr 2017 13:10:35 -0500 Subject: [PATCH 03/19] Fix #6787, run the user update function in the api as the calling user --- packages/rocketchat-api/server/v1/users.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/rocketchat-api/server/v1/users.js b/packages/rocketchat-api/server/v1/users.js index e808a0ff10b6..64db0074cc44 100644 --- a/packages/rocketchat-api/server/v1/users.js +++ b/packages/rocketchat-api/server/v1/users.js @@ -248,7 +248,7 @@ RocketChat.API.v1.addRoute('users.update', { authRequired: true }, { const userData = _.extend({ _id: this.bodyParams.userId }, this.bodyParams.data); - RocketChat.saveUser(this.userId, userData); + Meteor.runAsUser(this.userId, () => RocketChat.saveUser(this.userId, userData)); if (this.bodyParams.data.customFields) { RocketChat.saveCustomFields(this.bodyParams.userId, this.bodyParams.data.customFields); From cfe5068fecd3aacb611f48295bd0e44ee542b1dc Mon Sep 17 00:00:00 2001 From: Rodrigo Nascimento Date: Tue, 25 Apr 2017 15:45:26 -0300 Subject: [PATCH 04/19] [NEW] Option to allow to signup as anonymous --- .../server/functions/canAccessRoom.js | 2 +- .../server/startup.js | 13 +++++----- packages/rocketchat-i18n/i18n/en.i18n.json | 7 +++-- .../rocketchat-lib/client/lib/openRoom.coffee | 2 +- .../server/methods/getRoomRoles.js | 2 +- .../rocketchat-lib/server/startup/settings.js | 15 ++++++++++- .../startup/defaultRoomTypes.js | 2 +- packages/rocketchat-ui-master/client/main.js | 4 +-- .../client/messageBox.coffee | 16 ++++++++++-- .../client/messageBox.html | 7 +++-- .../client/accountBox.js | 4 +-- packages/rocketchat-ui/client/lib/accounts.js | 1 + .../rocketchat-ui/client/lib/collections.js | 2 +- .../client/views/app/room.coffee | 2 +- server/methods/afterVerifyEmail.js | 20 ++++++++++++++ server/methods/canAccessRoom.js | 2 +- server/methods/getUsernameSuggestion.js | 2 +- server/methods/loadHistory.js | 4 +-- server/methods/registerUser.js | 26 ++++++++++++++----- server/methods/saveUserProfile.js | 24 +++++++++-------- server/publications/room.js | 4 +-- server/publications/spotlight.js | 2 +- server/startup/migrations/v093.js | 12 +++++++++ 23 files changed, 128 insertions(+), 47 deletions(-) create mode 100644 server/methods/afterVerifyEmail.js create mode 100644 server/startup/migrations/v093.js diff --git a/packages/rocketchat-authorization/server/functions/canAccessRoom.js b/packages/rocketchat-authorization/server/functions/canAccessRoom.js index faf4164698f5..82a6b761c1bb 100644 --- a/packages/rocketchat-authorization/server/functions/canAccessRoom.js +++ b/packages/rocketchat-authorization/server/functions/canAccessRoom.js @@ -2,7 +2,7 @@ RocketChat.authz.roomAccessValidators = [ function(room, user = {}) { if (room.t === 'c') { - if (!user._id && RocketChat.settings.get('Accounts_AllowAnonymousAccess') === true) { + if (!user._id && RocketChat.settings.get('Accounts_AllowAnonymousRead') === true) { return true; } diff --git a/packages/rocketchat-authorization/server/startup.js b/packages/rocketchat-authorization/server/startup.js index cf4ac5c7bd72..8715666f4eeb 100644 --- a/packages/rocketchat-authorization/server/startup.js +++ b/packages/rocketchat-authorization/server/startup.js @@ -46,20 +46,20 @@ Meteor.startup(function() { { _id: 'set-moderator', roles : ['admin', 'owner'] }, { _id: 'set-owner', roles : ['admin', 'owner'] }, { _id: 'unarchive-room', roles : ['admin'] }, - { _id: 'view-c-room', roles : ['admin', 'user', 'bot'] }, - { _id: 'view-d-room', roles : ['admin', 'user', 'bot'] }, + { _id: 'view-c-room', roles : ['admin', 'user', 'bot', 'anonymous'] }, + { _id: 'view-d-room', roles : ['admin', 'user', 'bot', 'anonymous'] }, { _id: 'view-full-other-user-info', roles : ['admin'] }, - { _id: 'view-history', roles : ['admin', 'user'] }, + { _id: 'view-history', roles : ['admin', 'user', 'anonymous'] }, { _id: 'view-joined-room', roles : ['guest', 'bot'] }, { _id: 'view-join-code', roles : ['admin'] }, { _id: 'view-logs', roles : ['admin'] }, { _id: 'view-other-user-channels', roles : ['admin'] }, - { _id: 'view-p-room', roles : ['admin', 'user'] }, + { _id: 'view-p-room', roles : ['admin', 'user', 'anonymous'] }, { _id: 'view-privileged-setting', roles : ['admin'] }, { _id: 'view-room-administration', roles : ['admin'] }, { _id: 'view-statistics', roles : ['admin'] }, { _id: 'view-user-administration', roles : ['admin'] }, - { _id: 'preview-c-room', roles : ['admin', 'user'] } + { _id: 'preview-c-room', roles : ['admin', 'user', 'anonymous'] } ]; for (const permission of permissions) { @@ -74,7 +74,8 @@ Meteor.startup(function() { { name: 'owner', scope: 'Subscriptions', description: 'Owner' }, { name: 'user', scope: 'Users', description: '' }, { name: 'bot', scope: 'Users', description: '' }, - { name: 'guest', scope: 'Users', description: '' } + { name: 'guest', scope: 'Users', description: '' }, + { name: 'anonymous', scope: 'Users', description: '' } ]; for (const role of defaultRoles) { diff --git a/packages/rocketchat-i18n/i18n/en.i18n.json b/packages/rocketchat-i18n/i18n/en.i18n.json index 3c3fef7b1187..c21b26ab8543 100644 --- a/packages/rocketchat-i18n/i18n/en.i18n.json +++ b/packages/rocketchat-i18n/i18n/en.i18n.json @@ -17,7 +17,8 @@ "Accessing_permissions": "Accessing permissions", "Account_SID": "Account SID", "Accounts": "Accounts", - "Accounts_AllowAnonymousAccess": "Allow anonymous access", + "Accounts_AllowAnonymousRead": "Allow anonymous read", + "Accounts_AllowAnonymousWrite": "Allow anonymous write", "Accounts_AllowDeleteOwnAccount": "Allow users to delete own account", "Accounts_AllowedDomainsList": "Allowed Domains List", "Accounts_AllowedDomainsList_Description": "Comma-separated list of allowed domains", @@ -35,6 +36,7 @@ "Accounts_BlockedUsernameList": "Blocked Username List", "Accounts_BlockedUsernameList_Description": "Comma-separated list of blocked usernames (case-insensitive)", "Accounts_CustomFields_Description": "Should be a valid JSON where keys are the field names containing a dictionary of field settings. Example:
{\n \"role\": {\n  \"type\": \"select\",\n  \"defaultValue\": \"student\",\n  \"options\": [\"teacher\", \"student\"],\n  \"required\": true,\n  \"modifyRecordField\": {\n   \"array\": true,\n   \"field\": \"roles\"\n  }\n },\n \"twitter\": {\n  \"type\": \"text\",\n  \"required\": true,\n  \"minLength\": 2,\n  \"maxLength\": 10\n }\n} ", + "Accounts_DefaultUsernamePrefixSuggestion": "Default username prefix suggestion", "Accounts_denyUnverifiedEmail": "Deny unverified email", "Accounts_EmailVerification": "Email Verification", "Accounts_EmailVerification_Description": "Make sure you have correct SMTP settings to use this feature", @@ -1124,6 +1126,7 @@ "or": "or", "Open_your_authentication_app_and_enter_the_code": "Open your authentication app and enter the code. You can also use one of your backup codes.", "Order": "Order", + "Or_talk_as_anonymous": "Or talk as anonymous", "OS_Arch": "OS Arch", "OS_Cpus": "OS CPU Count", "OS_Freemem": "OS Free Memory", @@ -1228,7 +1231,6 @@ "Register": "Register a new account", "Registration": "Registration", "Registration_Succeeded": "Registration Succeeded", - "Register_or_login_to_send_messages": "Register or login to send messages", "Registration_via_Admin": "Registration via Admin", "Regular_Expressions": "Regular Expressions", "Release": "Release", @@ -1363,6 +1365,7 @@ "Showing_archived_results": "

Showing %s archived results

", "Showing_online_users": "Showing: __total_showing__, Online: __online__, Total: __total__ users", "Showing_results": "

Showing %s results

", + "Sign_in_to_start_talking": "Sign in to start talking", "since_creation": "since %s", "Site_Name": "Site Name", "Site_Url": "Site URL", diff --git a/packages/rocketchat-lib/client/lib/openRoom.coffee b/packages/rocketchat-lib/client/lib/openRoom.coffee index 33e023abf9c9..3130cd82a3e0 100644 --- a/packages/rocketchat-lib/client/lib/openRoom.coffee +++ b/packages/rocketchat-lib/client/lib/openRoom.coffee @@ -6,7 +6,7 @@ currentTracker = undefined Meteor.defer -> currentTracker = Tracker.autorun (c) -> user = Meteor.user() - if (user? and not user.username?) or (not user? and RocketChat.settings.get('Accounts_AllowAnonymousAccess') is false) + if (user? and not user.username?) or (not user? and RocketChat.settings.get('Accounts_AllowAnonymousRead') is false) BlazeLayout.render 'main' return diff --git a/packages/rocketchat-lib/server/methods/getRoomRoles.js b/packages/rocketchat-lib/server/methods/getRoomRoles.js index e35fdb3e33e9..4c7dc6c105f3 100644 --- a/packages/rocketchat-lib/server/methods/getRoomRoles.js +++ b/packages/rocketchat-lib/server/methods/getRoomRoles.js @@ -3,7 +3,7 @@ Meteor.methods({ check(rid, String); - if (!Meteor.userId() && RocketChat.settings.get('Accounts_AllowAnonymousAccess') === false) { + if (!Meteor.userId() && RocketChat.settings.get('Accounts_AllowAnonymousRead') === false) { throw new Meteor.Error('error-invalid-user', 'Invalid user', { method: 'getRoomRoles' }); } diff --git a/packages/rocketchat-lib/server/startup/settings.js b/packages/rocketchat-lib/server/startup/settings.js index b67af0cd860f..f222176bb388 100644 --- a/packages/rocketchat-lib/server/startup/settings.js +++ b/packages/rocketchat-lib/server/startup/settings.js @@ -8,10 +8,18 @@ RocketChat.settings.add('uniqueID', process.env.DEPLOYMENT_ID || Random.id(), { // if you add a node to the i18n.json with the same setting name but with `_Description` it will automatically work. RocketChat.settings.addGroup('Accounts', function() { - this.add('Accounts_AllowAnonymousAccess', false, { + this.add('Accounts_AllowAnonymousRead', false, { type: 'boolean', public: true }); + this.add('Accounts_AllowAnonymousWrite', false, { + type: 'boolean', + public: true, + enableQuery: { + _id: 'Accounts_AllowAnonymousRead', + value: true + } + }); this.add('Accounts_AllowDeleteOwnAccount', false, { type: 'boolean', 'public': true, @@ -62,7 +70,11 @@ RocketChat.settings.addGroup('Accounts', function() { type: 'boolean', 'public': true }); + this.section('Registration', function() { + this.add('Accounts_DefaultUsernamePrefixSuggestion', 'user', { + type: 'string' + }); this.add('Accounts_RequireNameForSignUp', true, { type: 'boolean', 'public': true @@ -145,6 +157,7 @@ RocketChat.settings.addGroup('Accounts', function() { i18nLabel: 'Custom_Fields' }); }); + this.section('Avatar', function() { this.add('Accounts_AvatarResize', true, { type: 'boolean' diff --git a/packages/rocketchat-lib/startup/defaultRoomTypes.js b/packages/rocketchat-lib/startup/defaultRoomTypes.js index 692ddb876528..40fe79c9daf1 100644 --- a/packages/rocketchat-lib/startup/defaultRoomTypes.js +++ b/packages/rocketchat-lib/startup/defaultRoomTypes.js @@ -28,7 +28,7 @@ RocketChat.roomTypes.add('c', 10, { }, condition() { - return RocketChat.authz.hasAtLeastOnePermission(['view-c-room', 'view-joined-room']) || RocketChat.settings.get('Accounts_AllowAnonymousAccess') === true; + return RocketChat.authz.hasAtLeastOnePermission(['view-c-room', 'view-joined-room']) || RocketChat.settings.get('Accounts_AllowAnonymousRead') === true; }, showJoinLink(roomId) { diff --git a/packages/rocketchat-ui-master/client/main.js b/packages/rocketchat-ui-master/client/main.js index ba187b5e9686..9e91eea36872 100644 --- a/packages/rocketchat-ui-master/client/main.js +++ b/packages/rocketchat-ui-master/client/main.js @@ -110,7 +110,7 @@ Template.main.helpers({ return RocketChat.settings.get('Site_Name'); }, logged() { - if (Meteor.userId() != null || (RocketChat.settings.get('Accounts_AllowAnonymousAccess') === true && Session.get('forceLogin') !== true)) { + if (Meteor.userId() != null || (RocketChat.settings.get('Accounts_AllowAnonymousRead') === true && Session.get('forceLogin') !== true)) { $('html').addClass('noscroll').removeClass('scroll'); return true; } else { @@ -134,7 +134,7 @@ Template.main.helpers({ return ready; }, hasUsername() { - return (Meteor.userId() != null && Meteor.user().username != null) || (Meteor.userId() == null && RocketChat.settings.get('Accounts_AllowAnonymousAccess') === true); + return (Meteor.userId() != null && Meteor.user().username != null) || (Meteor.userId() == null && RocketChat.settings.get('Accounts_AllowAnonymousRead') === true); }, requirePasswordChange() { const user = Meteor.user(); diff --git a/packages/rocketchat-ui-message/client/messageBox.coffee b/packages/rocketchat-ui-message/client/messageBox.coffee index 0052f3046146..2587fda0c301 100644 --- a/packages/rocketchat-ui-message/client/messageBox.coffee +++ b/packages/rocketchat-ui-message/client/messageBox.coffee @@ -124,8 +124,11 @@ Template.messageBox.helpers showSandstorm: -> return Meteor.settings.public.sandstorm && !Meteor.isCordova - isAnonymous: -> - return not Meteor.userId()? and RocketChat.settings.get('Accounts_AllowAnonymousAccess') is true + anonymousRead: -> + return not Meteor.userId()? and RocketChat.settings.get('Accounts_AllowAnonymousRead') is true + + anonymousWrite: -> + return not Meteor.userId()? and RocketChat.settings.get('Accounts_AllowAnonymousRead') is true and RocketChat.settings.get('Accounts_AllowAnonymousWrite') is true firefoxPasteUpload = (fn) -> user = navigator.userAgent.match(/Firefox\/(\d+)\.\d/) @@ -186,6 +189,15 @@ Template.messageBox.events event.preventDefault() Session.set('forceLogin', true) + 'click .register-anonymous': (event) -> + event.stopPropagation() + event.preventDefault() + + Meteor.call 'registerUser', {}, (error, loginData) -> + if loginData && loginData.token + Meteor.loginWithToken loginData.token + + 'focus .input-message': (event, instance) -> KonchatNotification.removeRoomNotification @_id chatMessages[@_id].input = instance.find('.input-message') diff --git a/packages/rocketchat-ui-message/client/messageBox.html b/packages/rocketchat-ui-message/client/messageBox.html index 02e98fe5a107..d8f6c14df522 100644 --- a/packages/rocketchat-ui-message/client/messageBox.html +++ b/packages/rocketchat-ui-message/client/messageBox.html @@ -143,9 +143,12 @@ {{/if}} - {{#if isAnonymous}} + {{#if anonymousRead}}
- + + {{#if anonymousWrite}} + + {{/if}}
{{/if}} {{/with}} diff --git a/packages/rocketchat-ui-sidenav/client/accountBox.js b/packages/rocketchat-ui-sidenav/client/accountBox.js index d8dacd1406b2..aecbaea264a4 100644 --- a/packages/rocketchat-ui-sidenav/client/accountBox.js +++ b/packages/rocketchat-ui-sidenav/client/accountBox.js @@ -1,6 +1,6 @@ Template.accountBox.helpers({ myUserInfo() { - if (Meteor.user() == null && RocketChat.settings.get('Accounts_AllowAnonymousAccess')) { + if (Meteor.user() == null && RocketChat.settings.get('Accounts_AllowAnonymousRead')) { return { name: t('Anonymous'), status: 'online', @@ -50,7 +50,7 @@ Template.accountBox.events({ }, 'click .account-box'() { - if (Meteor.userId() == null && RocketChat.settings.get('Accounts_AllowAnonymousAccess')) { + if (Meteor.userId() == null && RocketChat.settings.get('Accounts_AllowAnonymousRead')) { return; } diff --git a/packages/rocketchat-ui/client/lib/accounts.js b/packages/rocketchat-ui/client/lib/accounts.js index 8d220aefcd81..5045fbff9dcc 100644 --- a/packages/rocketchat-ui/client/lib/accounts.js +++ b/packages/rocketchat-ui/client/lib/accounts.js @@ -3,6 +3,7 @@ Accounts.onEmailVerificationLink(function(token, done) { Accounts.verifyEmail(token, function(error) { if (error == null) { toastr.success(t('Email_verified')); + Meteor.call('afterVerifyEmail'); } return done(); }); diff --git a/packages/rocketchat-ui/client/lib/collections.js b/packages/rocketchat-ui/client/lib/collections.js index 06b777c5ee6c..3d95243fbce0 100644 --- a/packages/rocketchat-ui/client/lib/collections.js +++ b/packages/rocketchat-ui/client/lib/collections.js @@ -17,7 +17,7 @@ RocketChat.models.Messages = _.extend({}, RocketChat.models.Messages, this.ChatM Meteor.startup(() => { Tracker.autorun(() => { - if (!Meteor.userId() && RocketChat.settings.get('Accounts_AllowAnonymousAccess') === true) { + if (!Meteor.userId() && RocketChat.settings.get('Accounts_AllowAnonymousRead') === true) { this.CachedChatRoom.init(); this.CachedChatSubscription.ready.set(true); } diff --git a/packages/rocketchat-ui/client/views/app/room.coffee b/packages/rocketchat-ui/client/views/app/room.coffee index 05f1646ef9ce..edd6c1b8a5dc 100644 --- a/packages/rocketchat-ui/client/views/app/room.coffee +++ b/packages/rocketchat-ui/client/views/app/room.coffee @@ -181,7 +181,7 @@ Template.room.helpers if room.t isnt 'c' return true - if RocketChat.settings.get('Accounts_AllowAnonymousAccess') is true + if RocketChat.settings.get('Accounts_AllowAnonymousRead') is true return true if RocketChat.authz.hasAllPermission('preview-c-room') diff --git a/server/methods/afterVerifyEmail.js b/server/methods/afterVerifyEmail.js new file mode 100644 index 000000000000..7b92f596167b --- /dev/null +++ b/server/methods/afterVerifyEmail.js @@ -0,0 +1,20 @@ +Meteor.methods({ + afterVerifyEmail() { + const userId = Meteor.userId(); + + if (!userId) { + throw new Meteor.Error('error-invalid-user', 'Invalid user', { + method: 'afterVerifyEmail' + }); + } + + const user = RocketChat.models.Users.findOneById(userId); + + const verifiedEmail = _.find(user.emails, (email) => email.verified); + + if (verifiedEmail) { + RocketChat.models.Roles.addUserRoles(user._id, 'user'); + RocketChat.models.Roles.removeUserRoles(user._id, 'anonymous'); + } + } +}); diff --git a/server/methods/canAccessRoom.js b/server/methods/canAccessRoom.js index 8c4a04ad98a9..dbb1d468b448 100644 --- a/server/methods/canAccessRoom.js +++ b/server/methods/canAccessRoom.js @@ -5,7 +5,7 @@ Meteor.methods({ let user; - if (!userId && RocketChat.settings.get('Accounts_AllowAnonymousAccess') === false) { + if (!userId && RocketChat.settings.get('Accounts_AllowAnonymousRead') === false) { throw new Meteor.Error('error-invalid-user', 'Invalid user', { method: 'canAccessRoom' }); diff --git a/server/methods/getUsernameSuggestion.js b/server/methods/getUsernameSuggestion.js index 30440f151397..265342330055 100644 --- a/server/methods/getUsernameSuggestion.js +++ b/server/methods/getUsernameSuggestion.js @@ -92,7 +92,7 @@ function generateSuggestion(user) { } if (usernames.length === 0 || usernames[0].length === 0) { - usernames.push('user'); + usernames.push(RocketChat.settings.get('Accounts_DefaultUsernamePrefixSuggestion')); } let index = 0; diff --git a/server/methods/loadHistory.js b/server/methods/loadHistory.js index 82f9d01590bb..01d1720ec5c0 100644 --- a/server/methods/loadHistory.js +++ b/server/methods/loadHistory.js @@ -21,7 +21,7 @@ Meteor.methods({ loadHistory(rid, end, limit = 20, ls) { check(rid, String); - if (!Meteor.userId() && RocketChat.settings.get('Accounts_AllowAnonymousAccess') === false) { + if (!Meteor.userId() && RocketChat.settings.get('Accounts_AllowAnonymousRead') === false) { throw new Meteor.Error('error-invalid-user', 'Invalid user', { method: 'loadHistory' }); @@ -34,7 +34,7 @@ Meteor.methods({ return false; } - const canAnonymous = RocketChat.settings.get('Accounts_AllowAnonymousAccess'); + const canAnonymous = RocketChat.settings.get('Accounts_AllowAnonymousRead'); const canPreview = RocketChat.authz.hasPermission(fromId, 'preview-c-room'); if (room.t === 'c' && !canAnonymous && !canPreview && room.usernames.indexOf(room.username) === -1) { return false; diff --git a/server/methods/registerUser.js b/server/methods/registerUser.js index a4e45bf0fa87..17c0ceb71b14 100644 --- a/server/methods/registerUser.js +++ b/server/methods/registerUser.js @@ -1,11 +1,25 @@ Meteor.methods({ registerUser(formData) { - check(formData, Match.ObjectIncluding({ - email: String, - pass: String, - name: String, - secretURL: Match.Optional(String) - })); + const AllowAnonymousRead = RocketChat.settings.get('Accounts_AllowAnonymousRead'); + const AllowAnonymousWrite = RocketChat.settings.get('Accounts_AllowAnonymousWrite'); + if (AllowAnonymousRead === true && AllowAnonymousWrite === true && formData.email == null) { + const userId = Accounts.insertUserDoc({}, { + globalRoles: [ + 'anonymous' + ] + }); + + const { id, token } = Accounts._loginUser(this, userId); + + return { id, token }; + } else { + check(formData, Match.ObjectIncluding({ + email: String, + pass: String, + name: String, + secretURL: Match.Optional(String) + })); + } if (RocketChat.settings.get('Accounts_RegistrationForm') === 'Disabled') { throw new Meteor.Error('error-user-registration-disabled', 'User registration is disabled', { method: 'registerUser' }); diff --git a/server/methods/saveUserProfile.js b/server/methods/saveUserProfile.js index a70d7aab30f5..7f78f1c99e39 100644 --- a/server/methods/saveUserProfile.js +++ b/server/methods/saveUserProfile.js @@ -31,17 +31,6 @@ Meteor.methods({ } return true; } - if ((settings.newPassword) && RocketChat.settings.get('Accounts_AllowPasswordChange') === true) { - if (!checkPassword(user, settings.typedPassword)) { - throw new Meteor.Error('error-invalid-password', 'Invalid password', { - method: 'saveUserProfile' - }); - } - - Accounts.setPassword(Meteor.userId(), settings.newPassword, { - logout: false - }); - } if (settings.realname) { RocketChat.setRealName(Meteor.userId(), settings.realname); @@ -61,6 +50,19 @@ Meteor.methods({ Meteor.call('setEmail', settings.email); } + // Should be the last chack to prevent error when trying to check password for users without password + if ((settings.newPassword) && RocketChat.settings.get('Accounts_AllowPasswordChange') === true) { + if (!checkPassword(user, settings.typedPassword)) { + throw new Meteor.Error('error-invalid-password', 'Invalid password', { + method: 'saveUserProfile' + }); + } + + Accounts.setPassword(Meteor.userId(), settings.newPassword, { + logout: false + }); + } + RocketChat.models.Users.setProfile(Meteor.userId(), {}); RocketChat.saveCustomFields(Meteor.userId(), customFields); diff --git a/server/publications/room.js b/server/publications/room.js index 8ca4f3248a97..76a2f29ed1b8 100644 --- a/server/publications/room.js +++ b/server/publications/room.js @@ -40,7 +40,7 @@ const roomMap = (record) => { Meteor.methods({ 'rooms/get'(updatedAt) { if (!Meteor.userId()) { - if (RocketChat.settings.get('Accounts_AllowAnonymousAccess') === true) { + if (RocketChat.settings.get('Accounts_AllowAnonymousRead') === true) { return RocketChat.models.Rooms.findByDefaultAndTypes(true, ['c'], options).fetch(); } return []; @@ -59,7 +59,7 @@ Meteor.methods({ }, getRoomByTypeAndName(type, name) { - if (!Meteor.userId() && RocketChat.settings.get('Accounts_AllowAnonymousAccess') === false) { + if (!Meteor.userId() && RocketChat.settings.get('Accounts_AllowAnonymousRead') === false) { throw new Meteor.Error('error-invalid-user', 'Invalid user', { method: 'getRoomByTypeAndName' }); } diff --git a/server/publications/spotlight.js b/server/publications/spotlight.js index ceccb8f4c9e6..babbe04290c0 100644 --- a/server/publications/spotlight.js +++ b/server/publications/spotlight.js @@ -19,7 +19,7 @@ Meteor.methods({ const regex = new RegExp(s.trim(s.escapeRegExp(text)), 'i'); if (this.userId == null) { - if (RocketChat.settings.get('Accounts_AllowAnonymousAccess') === true) { + if (RocketChat.settings.get('Accounts_AllowAnonymousRead') === true) { result.rooms = RocketChat.models.Rooms.findByNameAndTypeNotDefault(regex, 'c', roomOptions).fetch(); } return result; diff --git a/server/startup/migrations/v093.js b/server/startup/migrations/v093.js new file mode 100644 index 000000000000..4ee2ed8f34b3 --- /dev/null +++ b/server/startup/migrations/v093.js @@ -0,0 +1,12 @@ +RocketChat.Migrations.add({ + version: 93, + up() { + + if (RocketChat && RocketChat.models && RocketChat.models.Settings) { + const setting = RocketChat.models.Settings.findOne({ _id: 'Accounts_AllowAnonymousAccess' }); + if (setting && setting.value === true) { + RocketChat.models.Settings.update({ _id: 'Accounts_AllowAnonymousRead' }, { $set: { value: setting.value } }); + } + } + } +}); From 7b636a7bc36d8b656d96d907d515e1eb065c8666 Mon Sep 17 00:00:00 2001 From: Diego Sampaio Date: Tue, 25 Apr 2017 17:33:39 -0300 Subject: [PATCH 05/19] Try to directly install screen share extension --- packages/rocketchat-webrtc/WebRTCClass.coffee | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/packages/rocketchat-webrtc/WebRTCClass.coffee b/packages/rocketchat-webrtc/WebRTCClass.coffee index be46fdb70b83..a957e411d7cc 100644 --- a/packages/rocketchat-webrtc/WebRTCClass.coffee +++ b/packages/rocketchat-webrtc/WebRTCClass.coffee @@ -377,8 +377,13 @@ class WebRTCClass , (isConfirm) => if isConfirm if @navigator is 'chrome' - chrome.webstore.install undefined, refresh, -> - window.open('https://chrome.google.com/webstore/detail/rocketchat-screen-share/nocfbnnmjnndkbipkabodnheejiegccf') + url = 'https://chrome.google.com/webstore/detail/rocketchat-screen-share/nocfbnnmjnndkbipkabodnheejiegccf' + try + chrome.webstore.install url, refresh, -> + window.open(url) + refresh() + catch e + window.open(url) refresh() else if @navigator is 'firefox' window.open('https://addons.mozilla.org/en-GB/firefox/addon/rocketchat-screen-share/') From e6004426bee9e7f14e9a994ccd7c536c5d162436 Mon Sep 17 00:00:00 2001 From: Diego Sampaio Date: Tue, 25 Apr 2017 17:34:48 -0300 Subject: [PATCH 06/19] Wait for iframe setting to start sending postMessages --- .../rocketchat-ui/client/lib/fireEvent.js | 24 ++++++++++++------- 1 file changed, 15 insertions(+), 9 deletions(-) diff --git a/packages/rocketchat-ui/client/lib/fireEvent.js b/packages/rocketchat-ui/client/lib/fireEvent.js index 4238ca12b395..3a1ae3fe6c10 100644 --- a/packages/rocketchat-ui/client/lib/fireEvent.js +++ b/packages/rocketchat-ui/client/lib/fireEvent.js @@ -1,10 +1,16 @@ -window.fireGlobalEvent = (eventName, params) => { - window.dispatchEvent(new CustomEvent(eventName, {detail: params})); - - if (RocketChat.settings.get('Iframe_Integration_send_enable') === true) { - parent.postMessage({ - eventName, - data: params - }, RocketChat.settings.get('Iframe_Integration_send_target_origin')); - } +window.fireGlobalEvent = function _fireGlobalEvent(eventName, params) { + Tracker.autorun((computation) => { + const enabled = RocketChat.settings.get('Iframe_Integration_send_enable'); + if (enabled === undefined) { + return; + } + computation.stop(); + if (enabled) { + window.dispatchEvent(new CustomEvent(eventName, {detail: params})); + parent.postMessage({ + eventName, + data: params + }, RocketChat.settings.get('Iframe_Integration_send_target_origin')); + } + }); }; From 070a0089db1da25a06ba4da72b03a9f3f3851415 Mon Sep 17 00:00:00 2001 From: Diego Sampaio Date: Tue, 25 Apr 2017 17:35:04 -0300 Subject: [PATCH 07/19] Hide users tryping if on iframe --- packages/rocketchat-theme/client/imports/base.less | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/rocketchat-theme/client/imports/base.less b/packages/rocketchat-theme/client/imports/base.less index c06687ef4d9b..308dff9e5b59 100644 --- a/packages/rocketchat-theme/client/imports/base.less +++ b/packages/rocketchat-theme/client/imports/base.less @@ -4996,7 +4996,7 @@ a + br.only-after-a { border-width: 0; } - .stream-info { + .users-typing { display: none; } From 350eff47d35f1c3c027881a58ad5f067ed5951ff Mon Sep 17 00:00:00 2001 From: Bradley Hilton Date: Tue, 25 Apr 2017 17:16:04 -0500 Subject: [PATCH 08/19] Quoted and replied messages should retain the alias when displaying the message. --- packages/rocketchat-oembed/server/jumpToMessage.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/rocketchat-oembed/server/jumpToMessage.js b/packages/rocketchat-oembed/server/jumpToMessage.js index 0f674e461bfa..2cb673cb3a9b 100644 --- a/packages/rocketchat-oembed/server/jumpToMessage.js +++ b/packages/rocketchat-oembed/server/jumpToMessage.js @@ -17,7 +17,7 @@ RocketChat.callbacks.add('beforeSaveMessage', (msg) => { msg.attachments.push({ 'text' : jumpToMessage.msg, 'translations': jumpToMessage.translations, - 'author_name' : jumpToMessage.u.username, + 'author_name' : jumpToMessage.alias || jumpToMessage.u.username, 'author_icon' : getAvatarUrlFromUsername(jumpToMessage.u.username), 'message_link' : item.url, 'attachments' : jumpToMessage.attachments || [], From 77c9b80e4931614946f4afcb98c63321d71dad5b Mon Sep 17 00:00:00 2001 From: Gabriel Engel Date: Tue, 25 Apr 2017 23:21:18 -0300 Subject: [PATCH 09/19] Fixed :smile: test --- tests/end-to-end/ui/07-emoji.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/end-to-end/ui/07-emoji.js b/tests/end-to-end/ui/07-emoji.js index 39e27f94669f..2038bc8c4629 100644 --- a/tests/end-to-end/ui/07-emoji.js +++ b/tests/end-to-end/ui/07-emoji.js @@ -127,7 +127,7 @@ describe('emoji', ()=> { }); it('the value on the message input should be the same as the emoji clicked', ()=> { - mainContent.messageInput.getValue().should.equal(':smile:'); + mainContent.messageInput.getValue().should.equal(':smile: '); }); it('send the emoji', ()=> { From 620803ddeb7c835a394951be52092ba1d0971b7f Mon Sep 17 00:00:00 2001 From: Antony Gelberg Date: Wed, 26 Apr 2017 16:13:51 +0300 Subject: [PATCH 10/19] [FIX] Improve and correct Iframe Integration help text (#6793) * Improve and correct Iframe Integration help text * Improve and correct Iframe Integration help text --- packages/rocketchat-i18n/i18n/en.i18n.json | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/packages/rocketchat-i18n/i18n/en.i18n.json b/packages/rocketchat-i18n/i18n/en.i18n.json index 3c3fef7b1187..9bdb5ece9c2b 100644 --- a/packages/rocketchat-i18n/i18n/en.i18n.json +++ b/packages/rocketchat-i18n/i18n/en.i18n.json @@ -668,11 +668,11 @@ "Iframe_Integration_receive_enable": "Enable Receive", "Iframe_Integration_receive_enable_Description": "Allow parent window to send commands to Rocket.Chat.", "Iframe_Integration_receive_origin": "Receive origins", - "Iframe_Integration_receive_origin_Description": "Only pages with given origin will be able to send commands or `*` for all origins. You can use multiple values separated by `,`. Example `http://localhost,https://localhost`", + "Iframe_Integration_receive_origin_Description": "Origins with protocol prefix, separated by commas, which are allowed to receive commands e.g. 'https://localhost, http://localhost', or * to allow receiving from anywhere.", "Iframe_Integration_send_enable": "Enable Send", "Iframe_Integration_send_enable_Description": "Send events to parent window", "Iframe_Integration_send_target_origin": "Send target origin", - "Iframe_Integration_send_target_origin_Description": "Only pages with given origin will be able to listen to events or `*` for all origins. Example `http://localhost`", + "Iframe_Integration_send_target_origin_Description": "Origin with protocol prefix, which commands are sent to e.g. 'https://localhost', or * to allow sending to anywhere.", "Importer_Archived": "Archived", "Importer_CSV_Information": "The CSV importer requires a specific format, please read the documentation for how to structure your zip file:", "Importer_HipChatEnterprise_Information": "The file uploaded must be a decrypted tar.gz, please read the documentation for further information:", From 9b4a7d2e3e40ebf2d183bc80c2d239448de6dff6 Mon Sep 17 00:00:00 2001 From: Simon Eric Scholl Date: Wed, 26 Apr 2017 15:15:13 +0200 Subject: [PATCH 11/19] fix german translation (#6790) --- packages/rocketchat-i18n/i18n/de.i18n.json | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/packages/rocketchat-i18n/i18n/de.i18n.json b/packages/rocketchat-i18n/i18n/de.i18n.json index 18f8dd6d08c7..3e319b51c4cb 100644 --- a/packages/rocketchat-i18n/i18n/de.i18n.json +++ b/packages/rocketchat-i18n/i18n/de.i18n.json @@ -1072,7 +1072,7 @@ "Selected_agents": "Ausgewählte Agenten", "Send": "Senden", "Send_a_message": "Eine Nachricht schicken", - "Send_a_test_mail_to_my_user": "Eine Test-E-Mail an die Benutzer senden", + "Send_a_test_mail_to_my_user": "Eine Test-E-Mail an mich senden", "Send_a_test_push_to_my_user": "Eine Test-Push-Nachricht an mich senden", "Send_confirmation_email": "Bestätigungsmail versenden", "Send_data_into_RocketChat_in_realtime": "Daten in Rocket.Chat in Echtzeit senden.", @@ -1089,7 +1089,7 @@ "Sending": "Senden...", "Service": "Service", "Set_as_moderator": "Zum Moderator ernennen", - "Set_as_owner": "zum Besitzer machen", + "Set_as_owner": "Zum Besitzer machen", "Settings": "Einstellungen", "Settings_updated": "Die Einstellungen wurden aktualisiert.", "Share_Location_Title": "Standort teilen?", @@ -1376,4 +1376,4 @@ "your_message_optional": "ihre optionale Nachricht", "Your_password_is_wrong": "Falsches Passwort", "Your_push_was_sent_to_s_devices": "Die Push-Nachricht wurde an %s Geräte gesendet." -} \ No newline at end of file +} From ea1179048a71c6f15a08a1bcc5e7900f8785464b Mon Sep 17 00:00:00 2001 From: V S van beek Date: Wed, 26 Apr 2017 15:57:25 +0200 Subject: [PATCH 12/19] Missing useful fields in admin user list #5110 --- packages/rocketchat-ui-admin/client/users/adminUsers.html | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/packages/rocketchat-ui-admin/client/users/adminUsers.html b/packages/rocketchat-ui-admin/client/users/adminUsers.html index bf7827daadfb..87f4821ae5ff 100644 --- a/packages/rocketchat-ui-admin/client/users/adminUsers.html +++ b/packages/rocketchat-ui-admin/client/users/adminUsers.html @@ -29,6 +29,8 @@

{{_ "Name"}} {{_ "Username"}} {{_ "Email"}} + {{_ "Roles"}} + {{_ "Status"}} @@ -42,10 +44,13 @@

{{name}} {{username}} {{emailAddress}} + {{roles}} + {{status}} {{/each}} + {{#if hasMore}} {{/if}} From bbe2a2e3404eef3b5023bf5ea1c821fd28aab9aa Mon Sep 17 00:00:00 2001 From: V S van beek Date: Wed, 26 Apr 2017 16:18:10 +0200 Subject: [PATCH 13/19] Missing useful fields in admin user list #5110 --- .../.npm/package/npm-shrinkwrap.json | 4 ++-- packages/rocketchat-ui-admin/client/users/adminUsers.html | 1 + 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/packages/rocketchat-google-natural-language/.npm/package/npm-shrinkwrap.json b/packages/rocketchat-google-natural-language/.npm/package/npm-shrinkwrap.json index e89b775dfaf7..a34613259049 100644 --- a/packages/rocketchat-google-natural-language/.npm/package/npm-shrinkwrap.json +++ b/packages/rocketchat-google-natural-language/.npm/package/npm-shrinkwrap.json @@ -268,8 +268,8 @@ "from": "generate-object-property@>=1.1.0 <2.0.0" }, "getpass": { - "version": "0.1.6", - "resolved": "https://registry.npmjs.org/getpass/-/getpass-0.1.6.tgz", + "version": "0.1.7", + "resolved": "https://registry.npmjs.org/getpass/-/getpass-0.1.7.tgz", "from": "getpass@>=0.1.1 <0.2.0", "dependencies": { "assert-plus": { diff --git a/packages/rocketchat-ui-admin/client/users/adminUsers.html b/packages/rocketchat-ui-admin/client/users/adminUsers.html index 87f4821ae5ff..46e17936f746 100644 --- a/packages/rocketchat-ui-admin/client/users/adminUsers.html +++ b/packages/rocketchat-ui-admin/client/users/adminUsers.html @@ -63,3 +63,4 @@

{{/with}} + From 45a74d6bcd7222101e59ddf85160814d88ac3931 Mon Sep 17 00:00:00 2001 From: Guilherme Gazzo Date: Wed, 26 Apr 2017 13:05:21 -0300 Subject: [PATCH 14/19] create a method 'create token' --- packages/rocketchat-api/server/v1/users.js | 11 ++ .../server/startup.js | 1 + packages/rocketchat-lib/package.js | 1 + .../server/methods/createToken.js | 13 +++ tests/end-to-end/api/01-users.js | 107 +++++++++++++++++- 5 files changed, 132 insertions(+), 1 deletion(-) create mode 100644 packages/rocketchat-lib/server/methods/createToken.js diff --git a/packages/rocketchat-api/server/v1/users.js b/packages/rocketchat-api/server/v1/users.js index e808a0ff10b6..3dc3c38773ba 100644 --- a/packages/rocketchat-api/server/v1/users.js +++ b/packages/rocketchat-api/server/v1/users.js @@ -263,3 +263,14 @@ RocketChat.API.v1.addRoute('users.update', { authRequired: true }, { return RocketChat.API.v1.success({ user: RocketChat.models.Users.findOneById(this.bodyParams.userId, { fields: RocketChat.API.v1.defaultFieldsToExclude }) }); } }); + +RocketChat.API.v1.addRoute('users.createToken', { authRequired: true }, { + post() { + const user = this.getUserFromParams(); + let data; + Meteor.runAsUser(this.userId, () => { + data = Meteor.call('createToken', {user}); + }); + return data ? RocketChat.API.v1.success({data}) : RocketChat.API.v1.unauthorized(); + } +}); diff --git a/packages/rocketchat-authorization/server/startup.js b/packages/rocketchat-authorization/server/startup.js index cf4ac5c7bd72..af9678861630 100644 --- a/packages/rocketchat-authorization/server/startup.js +++ b/packages/rocketchat-authorization/server/startup.js @@ -46,6 +46,7 @@ Meteor.startup(function() { { _id: 'set-moderator', roles : ['admin', 'owner'] }, { _id: 'set-owner', roles : ['admin', 'owner'] }, { _id: 'unarchive-room', roles : ['admin'] }, + { _id: 'user-generate-access-token', roles : ['admin'] }, { _id: 'view-c-room', roles : ['admin', 'user', 'bot'] }, { _id: 'view-d-room', roles : ['admin', 'user', 'bot'] }, { _id: 'view-full-other-user-info', roles : ['admin'] }, diff --git a/packages/rocketchat-lib/package.js b/packages/rocketchat-lib/package.js index 8902fce8f259..b09e0428bd3d 100644 --- a/packages/rocketchat-lib/package.js +++ b/packages/rocketchat-lib/package.js @@ -134,6 +134,7 @@ Package.onUse(function(api) { api.addFiles('server/methods/checkRegistrationSecretURL.js', 'server'); api.addFiles('server/methods/cleanChannelHistory.js', 'server'); api.addFiles('server/methods/createChannel.js', 'server'); + api.addFiles('server/methods/createToken.js', 'server'); api.addFiles('server/methods/createPrivateGroup.js', 'server'); api.addFiles('server/methods/deleteMessage.js', 'server'); api.addFiles('server/methods/deleteUserOwnAccount.js', 'server'); diff --git a/packages/rocketchat-lib/server/methods/createToken.js b/packages/rocketchat-lib/server/methods/createToken.js new file mode 100644 index 000000000000..6ea2e4ec649d --- /dev/null +++ b/packages/rocketchat-lib/server/methods/createToken.js @@ -0,0 +1,13 @@ +Meteor.methods({ + createToken({user}) { + if (Meteor.userId() !== user._id && !RocketChat.authz.hasPermission(Meteor.userId(), 'user-generate-access-token')) { + throw new Meteor.Error('error-not-authorized', 'Not authorized', { method: 'createToken' }); + } + const token = Accounts._generateStampedLoginToken(); + Accounts._insertLoginToken(user._id, token); + return { + userId: user._id, + authToken: token.token + }; + } +}); diff --git a/tests/end-to-end/api/01-users.js b/tests/end-to-end/api/01-users.js index e5fa8fc3eb08..17621b246095 100644 --- a/tests/end-to-end/api/01-users.js +++ b/tests/end-to-end/api/01-users.js @@ -5,7 +5,6 @@ import {getCredentials, api, login, request, credentials, apiEmail, apiUsername, targetUser, log} from '../../data/api-data.js'; import {adminEmail, password} from '../../data/user.js'; import {imgURL} from '../../data/interactions.js'; -import supertest from 'supertest'; describe('Users', function() { this.retries(0); @@ -143,4 +142,110 @@ describe('Users', function() { }) .end(done); }); + + describe('/users.createToken', () => { + let user; + beforeEach((done) => { + const username = `user.test.${ Date.now() }`; + const email = `${ username }@rocket.chat`; + request.post(api('users.create')) + .set(credentials) + .send({ email, name: username, username, password }) + .end((err, res) => { + user = res.body.user; + done(); + }); + }); + + let userCredentials; + beforeEach((done) => { + request.post(api('login')) + .send({ + user: user.username, + password + }) + .expect('Content-Type', 'application/json') + .expect(200) + .expect((res) => { + userCredentials = {}; + userCredentials['X-Auth-Token'] = res.body.data.authToken; + userCredentials['X-User-Id'] = res.body.data.userId; + }) + .end(done); + }); + afterEach(done => { + request.post(api('users.delete')).set(credentials).send({ + userId: user._id + }).end(done); + user = undefined; + }); + + describe('logged as admin', () => { + it('should return the user id and a new token', (done) => { + request.post(api('users.createToken')) + .set(credentials) + .send({ + username: user.username + }) + .expect('Content-Type', 'application/json') + .expect(200) + .expect((res) => { + expect(res.body).to.have.property('success', true); + expect(res.body).to.have.deep.property('data.userId', user._id); + expect(res.body).to.have.deep.property('data.authToken'); + }) + .end(done); + }); + }); + + describe('logged as itself', () => { + it('should return the user id and a new token', (done) => { + request.post(api('users.createToken')) + .set(userCredentials) + .send({ + username: user.username + }) + .expect('Content-Type', 'application/json') + .expect(200) + .expect((res) => { + expect(res.body).to.have.property('success', true); + expect(res.body).to.have.deep.property('data.userId', user._id); + expect(res.body).to.have.deep.property('data.authToken'); + }) + .end(done); + }); + }); + + describe('As an user not allowed', () => { + it('should return 401 unauthorized', (done) => { + request.post(api('users.createToken')) + .set(userCredentials) + .send({ + username: 'rocket.cat' + }) + .expect('Content-Type', 'application/json') + .expect(400) + .expect((res) => { + expect(res.body).to.have.property('errorType'); + expect(res.body).to.have.property('error'); + }) + .end(done); + }); + }); + + describe('Not logged in', () => { + it('should return 401 unauthorized', (done) => { + request.post(api('users.createToken')) + .send({ + username: user.username + }) + .expect('Content-Type', 'application/json') + .expect(401) + .expect((res) => { + expect(res.body).to.have.property('message'); + }) + .end(done); + }); + }); + }); }); From de4b10a90edaaf737a00db431a6735a465a68c77 Mon Sep 17 00:00:00 2001 From: Rodrigo Nascimento Date: Wed, 26 Apr 2017 13:55:35 -0300 Subject: [PATCH 15/19] AccountBox: Show username instead of name when name is not available --- packages/rocketchat-ui-sidenav/client/accountBox.js | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/packages/rocketchat-ui-sidenav/client/accountBox.js b/packages/rocketchat-ui-sidenav/client/accountBox.js index aecbaea264a4..9825f9e1d68f 100644 --- a/packages/rocketchat-ui-sidenav/client/accountBox.js +++ b/packages/rocketchat-ui-sidenav/client/accountBox.js @@ -3,6 +3,7 @@ Template.accountBox.helpers({ if (Meteor.user() == null && RocketChat.settings.get('Accounts_AllowAnonymousRead')) { return { name: t('Anonymous'), + fname: t('Anonymous'), status: 'online', visualStatus: t('online'), username: 'anonymous' @@ -24,12 +25,12 @@ Template.accountBox.helpers({ break; } return { - name: Session.get(`user_${ username }_name`), + name: Session.get(`user_${ username }_name`) || username, status: Session.get(`user_${ username }_status`), visualStatus, _id: Meteor.userId(), username, - fname: name + fname: name || username }; }, From 5c0c1f9a798fa8229771b73074dd952234bdcde7 Mon Sep 17 00:00:00 2001 From: Rodrigo Nascimento Date: Wed, 26 Apr 2017 14:22:23 -0300 Subject: [PATCH 16/19] Anonymous Write: Fix permissions --- .../server/startup.js | 4 ++-- server/startup/migrations/v093.js | 20 +++++++++++++++++++ 2 files changed, 22 insertions(+), 2 deletions(-) diff --git a/packages/rocketchat-authorization/server/startup.js b/packages/rocketchat-authorization/server/startup.js index 8715666f4eeb..d1aad55d4851 100644 --- a/packages/rocketchat-authorization/server/startup.js +++ b/packages/rocketchat-authorization/server/startup.js @@ -47,10 +47,10 @@ Meteor.startup(function() { { _id: 'set-owner', roles : ['admin', 'owner'] }, { _id: 'unarchive-room', roles : ['admin'] }, { _id: 'view-c-room', roles : ['admin', 'user', 'bot', 'anonymous'] }, - { _id: 'view-d-room', roles : ['admin', 'user', 'bot', 'anonymous'] }, + { _id: 'view-d-room', roles : ['admin', 'user', 'bot'] }, { _id: 'view-full-other-user-info', roles : ['admin'] }, { _id: 'view-history', roles : ['admin', 'user', 'anonymous'] }, - { _id: 'view-joined-room', roles : ['guest', 'bot'] }, + { _id: 'view-joined-room', roles : ['guest', 'bot', 'anonymous'] }, { _id: 'view-join-code', roles : ['admin'] }, { _id: 'view-logs', roles : ['admin'] }, { _id: 'view-other-user-channels', roles : ['admin'] }, diff --git a/server/startup/migrations/v093.js b/server/startup/migrations/v093.js index 4ee2ed8f34b3..ee2b645e1130 100644 --- a/server/startup/migrations/v093.js +++ b/server/startup/migrations/v093.js @@ -8,5 +8,25 @@ RocketChat.Migrations.add({ RocketChat.models.Settings.update({ _id: 'Accounts_AllowAnonymousRead' }, { $set: { value: setting.value } }); } } + + const query = { + _id: { + $in: [ + 'view-c-room', + 'view-history', + 'view-joined-room', + 'view-p-room', + 'preview-c-room' + ] + } + }; + + const update = { + $addToSet: { + roles: 'anonymous' + } + }; + + RocketChat.models.Permissions.update(query, update, { multi: true }); } }); From 99adf308534517c13af6aec16e5f7eea388cb06d Mon Sep 17 00:00:00 2001 From: Guilherme Gazzo Date: Wed, 26 Apr 2017 14:51:30 -0300 Subject: [PATCH 17/19] createToken just receive userId --- packages/rocketchat-api/server/v1/users.js | 2 +- packages/rocketchat-lib/server/methods/createToken.js | 8 ++++---- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/packages/rocketchat-api/server/v1/users.js b/packages/rocketchat-api/server/v1/users.js index 3dc3c38773ba..746358988519 100644 --- a/packages/rocketchat-api/server/v1/users.js +++ b/packages/rocketchat-api/server/v1/users.js @@ -269,7 +269,7 @@ RocketChat.API.v1.addRoute('users.createToken', { authRequired: true }, { const user = this.getUserFromParams(); let data; Meteor.runAsUser(this.userId, () => { - data = Meteor.call('createToken', {user}); + data = Meteor.call('createToken', user._id); }); return data ? RocketChat.API.v1.success({data}) : RocketChat.API.v1.unauthorized(); } diff --git a/packages/rocketchat-lib/server/methods/createToken.js b/packages/rocketchat-lib/server/methods/createToken.js index 6ea2e4ec649d..29879093c1c5 100644 --- a/packages/rocketchat-lib/server/methods/createToken.js +++ b/packages/rocketchat-lib/server/methods/createToken.js @@ -1,12 +1,12 @@ Meteor.methods({ - createToken({user}) { - if (Meteor.userId() !== user._id && !RocketChat.authz.hasPermission(Meteor.userId(), 'user-generate-access-token')) { + createToken(userId) { + if (Meteor.userId() !== userId && !RocketChat.authz.hasPermission(Meteor.userId(), 'user-generate-access-token')) { throw new Meteor.Error('error-not-authorized', 'Not authorized', { method: 'createToken' }); } const token = Accounts._generateStampedLoginToken(); - Accounts._insertLoginToken(user._id, token); + Accounts._insertLoginToken(userId, token); return { - userId: user._id, + userId, authToken: token.token }; } From e0b584c9acad4b3321d5291a538877df1164d08f Mon Sep 17 00:00:00 2001 From: Guilherme Gazzo Date: Wed, 26 Apr 2017 18:12:34 -0300 Subject: [PATCH 18/19] createToken - tested if the generated token is valid --- tests/end-to-end/api/01-users.js | 258 +++++++++++++++++-------------- 1 file changed, 138 insertions(+), 120 deletions(-) diff --git a/tests/end-to-end/api/01-users.js b/tests/end-to-end/api/01-users.js index 17621b246095..6d8e42bc3755 100644 --- a/tests/end-to-end/api/01-users.js +++ b/tests/end-to-end/api/01-users.js @@ -13,134 +13,134 @@ describe('Users', function() { it('/users.create', (done) => { request.post(api('users.create')) - .set(credentials) - .send({ - email: apiEmail, - name: apiUsername, - username: apiUsername, - password, - active: true, - roles: ['user'], - joinDefaultChannels: true, - verified:true - }) - .expect('Content-Type', 'application/json') - .expect(200) - .expect((res) => { - expect(res.body).to.have.property('success', true); - expect(res.body).to.have.deep.property('user.username', apiUsername); - expect(res.body).to.have.deep.property('user.emails[0].address', apiEmail); - expect(res.body).to.have.deep.property('user.active', true); - expect(res.body).to.have.deep.property('user.name', apiUsername); - targetUser._id = res.body.user._id; - }) - .end(done); + .set(credentials) + .send({ + email: apiEmail, + name: apiUsername, + username: apiUsername, + password, + active: true, + roles: ['user'], + joinDefaultChannels: true, + verified:true + }) + .expect('Content-Type', 'application/json') + .expect(200) + .expect((res) => { + expect(res.body).to.have.property('success', true); + expect(res.body).to.have.deep.property('user.username', apiUsername); + expect(res.body).to.have.deep.property('user.emails[0].address', apiEmail); + expect(res.body).to.have.deep.property('user.active', true); + expect(res.body).to.have.deep.property('user.name', apiUsername); + targetUser._id = res.body.user._id; + }) + .end(done); }); it('/users.info', (done) => { request.get(api('users.info')) - .set(credentials) - .query({ - userId: targetUser._id - }) - .expect('Content-Type', 'application/json') - .expect(200) - .expect((res) => { - expect(res.body).to.have.property('success', true); - expect(res.body).to.have.deep.property('user.username', apiUsername); - expect(res.body).to.have.deep.property('user.emails[0].address', apiEmail); - expect(res.body).to.have.deep.property('user.active', true); - expect(res.body).to.have.deep.property('user.name', apiUsername); - }) - .end(done); + .set(credentials) + .query({ + userId: targetUser._id + }) + .expect('Content-Type', 'application/json') + .expect(200) + .expect((res) => { + expect(res.body).to.have.property('success', true); + expect(res.body).to.have.deep.property('user.username', apiUsername); + expect(res.body).to.have.deep.property('user.emails[0].address', apiEmail); + expect(res.body).to.have.deep.property('user.active', true); + expect(res.body).to.have.deep.property('user.name', apiUsername); + }) + .end(done); }); it('/users.getPresence', (done) => { request.get(api('users.getPresence')) - .set(credentials) - .query({ - userId: targetUser._id - }) - .expect('Content-Type', 'application/json') - .expect(200) - .expect((res) => { - expect(res.body).to.have.property('success', true); - expect(res.body).to.have.deep.property('presence', 'offline'); - }) - .end(done); + .set(credentials) + .query({ + userId: targetUser._id + }) + .expect('Content-Type', 'application/json') + .expect(200) + .expect((res) => { + expect(res.body).to.have.property('success', true); + expect(res.body).to.have.deep.property('presence', 'offline'); + }) + .end(done); }); it('/users.list', (done) => { request.get(api('users.list')) - .set(credentials) - .expect('Content-Type', 'application/json') - .expect(200) - .expect((res) => { - expect(res.body).to.have.property('success', true); - expect(res.body).to.have.property('count'); - expect(res.body).to.have.property('total'); - }) - .end(done); + .set(credentials) + .expect('Content-Type', 'application/json') + .expect(200) + .expect((res) => { + expect(res.body).to.have.property('success', true); + expect(res.body).to.have.property('count'); + expect(res.body).to.have.property('total'); + }) + .end(done); }); it.skip('/users.list', (done) => { - //filtering user list + //filtering user list request.get(api('users.list')) - .set(credentials) - .query({ - name: { '$regex': 'g' } - }) - .field('username', 1) - .sort('createdAt', -1) - .expect(log) - .expect('Content-Type', 'application/json') - .expect(200) - .expect((res) => { - expect(res.body).to.have.property('success', true); - expect(res.body).to.have.property('count'); - expect(res.body).to.have.property('total'); - }) - .end(done); + .set(credentials) + .query({ + name: { '$regex': 'g' } + }) + .field('username', 1) + .sort('createdAt', -1) + .expect(log) + .expect('Content-Type', 'application/json') + .expect(200) + .expect((res) => { + expect(res.body).to.have.property('success', true); + expect(res.body).to.have.property('count'); + expect(res.body).to.have.property('total'); + }) + .end(done); }); it.skip('/users.setAvatar', (done) => { request.post(api('users.setAvatar')) - .set(credentials) - .attach('avatarUrl', imgURL) - .expect('Content-Type', 'application/json') - .expect(200) - .expect((res) => { - expect(res.body).to.have.property('success', true); - }) - .end(done); + .set(credentials) + .attach('avatarUrl', imgURL) + .expect('Content-Type', 'application/json') + .expect(200) + .expect((res) => { + expect(res.body).to.have.property('success', true); + }) + .end(done); }); it('/users.update', (done) => { request.post(api('users.update')) - .set(credentials) - .send({ - userId: targetUser._id, - data :{ - email: apiEmail, - name: `edited${ apiUsername }`, - username: `edited${ apiUsername }`, - password, - active: true, - roles: ['user'] - } - }) - .expect('Content-Type', 'application/json') - .expect(200) - .expect((res) => { - expect(res.body).to.have.property('success', true); - expect(res.body).to.have.deep.property('user.username', `edited${ apiUsername }`); - expect(res.body).to.have.deep.property('user.emails[0].address', apiEmail); - expect(res.body).to.have.deep.property('user.active', true); - expect(res.body).to.have.deep.property('user.name', `edited${ apiUsername }`); - }) - .end(done); + .set(credentials) + .send({ + userId: targetUser._id, + data :{ + email: apiEmail, + name: `edited${ apiUsername }`, + username: `edited${ apiUsername }`, + password, + active: true, + roles: ['user'] + } + }) + .expect('Content-Type', 'application/json') + .expect(200) + .expect((res) => { + expect(res.body).to.have.property('success', true); + expect(res.body).to.have.deep.property('user.username', `edited${ apiUsername }`); + expect(res.body).to.have.deep.property('user.emails[0].address', apiEmail); + expect(res.body).to.have.deep.property('user.active', true); + expect(res.body).to.have.deep.property('user.name', `edited${ apiUsername }`); + }) + .end(done); }); describe('/users.createToken', () => { @@ -149,29 +149,29 @@ describe('Users', function() { const username = `user.test.${ Date.now() }`; const email = `${ username }@rocket.chat`; request.post(api('users.create')) - .set(credentials) - .send({ email, name: username, username, password }) - .end((err, res) => { - user = res.body.user; - done(); - }); + .set(credentials) + .send({ email, name: username, username, password }) + .end((err, res) => { + user = res.body.user; + done(); + }); }); let userCredentials; beforeEach((done) => { request.post(api('login')) - .send({ - user: user.username, - password - }) - .expect('Content-Type', 'application/json') - .expect(200) - .expect((res) => { - userCredentials = {}; - userCredentials['X-Auth-Token'] = res.body.data.authToken; - userCredentials['X-User-Id'] = res.body.data.userId; - }) - .end(done); + .send({ + user: user.username, + password + }) + .expect('Content-Type', 'application/json') + .expect(200) + .expect((res) => { + userCredentials = {}; + userCredentials['X-Auth-Token'] = res.body.data.authToken; + userCredentials['X-User-Id'] = res.body.data.userId; + }) + .end(done); }); afterEach(done => { request.post(api('users.delete')).set(credentials).send({ @@ -247,5 +247,23 @@ describe('Users', function() { .end(done); }); }); + + describe('Testing if the returned token is valid', (done) => { + it('should return 200', (done) => { + return request.post(api('users.createToken')) + .set(credentials) + .send({ username: user.username }) + .expect('Content-Type', 'application/json') + .end((err, res) => { + return err ? done () : request.get(api('me')) + .set({ 'X-Auth-Token': `${ res.body.data.authToken }`, 'X-User-Id': res.body.data.userId }) + .expect(200) + .expect((res) => { + expect(res.body).to.have.property('success', true); + }) + .end(done); + }); + }); + }); }); }); From 7355cf3c121c0d5462215900639a103b79c2bd82 Mon Sep 17 00:00:00 2001 From: Gabriel Engel Date: Wed, 26 Apr 2017 23:19:34 +0000 Subject: [PATCH 19/19] LingoHub Update :rocket: Manual push by LingoHub User: Gabriel Engel. Project: Rocket.Chat Made with :heart: by https://lingohub.com --- packages/rocketchat-i18n/i18n/bg.i18n.json | 10 ++ packages/rocketchat-i18n/i18n/ca.i18n.json | 7 +- packages/rocketchat-i18n/i18n/cs.i18n.json | 15 ++- packages/rocketchat-i18n/i18n/de-AT.i18n.json | 1 - packages/rocketchat-i18n/i18n/de.i18n.json | 3 +- packages/rocketchat-i18n/i18n/en.i18n.json | 2 +- packages/rocketchat-i18n/i18n/es.i18n.json | 1 - packages/rocketchat-i18n/i18n/fr.i18n.json | 92 +++++++++---------- packages/rocketchat-i18n/i18n/he.i18n.json | 1 - packages/rocketchat-i18n/i18n/hr.i18n.json | 1 - packages/rocketchat-i18n/i18n/it.i18n.json | 1 - packages/rocketchat-i18n/i18n/ja.i18n.json | 1 - packages/rocketchat-i18n/i18n/ko.i18n.json | 12 ++- packages/rocketchat-i18n/i18n/pl.i18n.json | 1 - packages/rocketchat-i18n/i18n/sv.i18n.json | 4 + packages/rocketchat-i18n/i18n/zh.i18n.json | 1 - .../rocketchat-livechat/app/i18n/bg.i18n.json | 1 + 17 files changed, 94 insertions(+), 60 deletions(-) diff --git a/packages/rocketchat-i18n/i18n/bg.i18n.json b/packages/rocketchat-i18n/i18n/bg.i18n.json index fbedfc1e680b..893252288ea9 100644 --- a/packages/rocketchat-i18n/i18n/bg.i18n.json +++ b/packages/rocketchat-i18n/i18n/bg.i18n.json @@ -1,6 +1,8 @@ { "#channel": "#канал", "0_Errors_Only": "0 - Само Грешки", + "1_Errors_and_Information": "1 - Грешки и Информация", + "2_Erros_Information_and_Debug": "2 - Грешки, Информация и Дебъг", "403": "Забранен", "@username": "@потребителско име", "@username_message": "@потребителско име", @@ -23,6 +25,7 @@ "Accounts_OAuth_Facebook": "Влизана с Facebook профил", "Accounts_OAuth_Google": "Влизане с Google профил", "Accounts_RegistrationForm_Public": "Обществен", + "All_channels": "Всички канали", "All_messages": "Всички съобщения", "and": "и", "Application_Name": "Име на Приложение", @@ -38,6 +41,8 @@ "Busy_male": "Зает", "channel": "канал", "Channel": "Канал", + "Channels": "Канали", + "Channels_list": "Списък на публични канали", "Click_here": "Натисни тук", "close": "затвори", "Close": "Затвори", @@ -84,6 +89,7 @@ "LDAP_Port": "Порт", "Leave_room": "Излез от стаята", "line": "линия", + "List_of_Channels": "Списък с Канали", "Loading...": "Зареждане...", "Log_Package": "Покажи пакет", "Login": "Влез", @@ -96,6 +102,7 @@ "Message_too_long": "Съобщението е твърде дълго", "Messages": "Съобщения", "minutes": "Минути", + "More_channels": "Още канали", "My_Account": "Моя Профил", "n_messages": "%s съобщения", "N_new_messages": "%s нови съобщения", @@ -112,6 +119,7 @@ "Online": "На линия", "Oops!": "Упс", "Open": "Отвори", + "Password": "Парола", "People": "Хора", "Please_add_a_comment": "Добави коментар моля", "Please_wait": "Моля изчакайте", @@ -145,6 +153,8 @@ "Site_Name": "Име на Сайта", "Skip": "Прескочи", "Smarsh_MissingEmail_Email": "Липсваща Електрона поща", + "Stats_Total_Channels": "Общо Канали", + "Stats_Total_Messages_Channel": "Общо Съобщения в Канали", "Test_Desktop_Notifications": "Изпробвай Известия на работния плот", "Thank_you_exclamation_mark": "Благодаря!", "The_server_will_restart_in_s_seconds": "Сървъра ще бъде рестартиран след %s секунди", diff --git a/packages/rocketchat-i18n/i18n/ca.i18n.json b/packages/rocketchat-i18n/i18n/ca.i18n.json index c80a1e4b61fb..436bcca1e9de 100644 --- a/packages/rocketchat-i18n/i18n/ca.i18n.json +++ b/packages/rocketchat-i18n/i18n/ca.i18n.json @@ -17,6 +17,7 @@ "Accessing_permissions": "L'accés als permisos", "Account_SID": "Compte SID", "Accounts": "Comptes", + "Accounts_AllowAnonymousAccess": "Permet accés anònim", "Accounts_AllowDeleteOwnAccount": "Permetre als usuaris eliminar el seu propi compte", "Accounts_AllowedDomainsList": "Llista de dominis permesos", "Accounts_AllowedDomainsList_Description": "Llista dels dominis permesos separada per comes ", @@ -416,6 +417,7 @@ "Desktop_Notifications_Enabled": "Les notificacions d'escriptori estan activades", "Direct_message_someone": "Envia un missatge directe a algú", "Direct_Messages": "Missatges directes", + "Disable_Notifications": "Desactiva notificacions", "Disable_two-factor_authentication": "Desactiva l'autenticació de dos factors", "Display_offline_form": "Mostra el formulari de fora de línia", "Displays_action_text": "Mostra text de l'acció", @@ -644,6 +646,7 @@ "Hide_room": "Oculta sala", "Hide_Room_Warning": "Segur que voleu ocultar la sala \"%s\"?", "Hide_roles": "Amaga rols", + "Hide_Unread_Room_Status": "Amaga l'estat de sales no llegides", "Hide_usernames": "Oculta els noms d'usuari", "Highlights": "Ressalta", "Highlights_How_To": "Per ser notificat quan algú esmenta una paraula o frase, afegeix-la aquí. Es poden separar les paraules o frases amb comes. No es distingeix entre majúscules i minúscules.", @@ -1082,6 +1085,7 @@ "Nothing_found": "No s'ha trobat res", "Notification_Duration": "Duració de la notificació", "Notifications": "Notificacions", + "Notifications_Muted_Description": "Si esculls silenciar-ho tot, no veuràs la sala destacada a la llista quan hi hagi nous missatges, excepte si són mencions. Silenciar les notificacions sobreescriurà les opcions de notificació.", "Notify_all_in_this_room": "Notifica a tothom d'aquest canal", "Notify_active_in_this_room": "Notifica als usuaris actius d'aquesta sala", "Num_Agents": "# d'agents", @@ -1224,6 +1228,7 @@ "Register": "Crea un compte nou", "Registration": "Registre", "Registration_Succeeded": "Registre reeixit", + "Register_or_login_to_send_messages": "Registra't o identifica't per enviar missatges", "Registration_via_Admin": "Registre via Admin", "Regular_Expressions": "Expressions regulars", "Release": "Llançament", @@ -1547,7 +1552,7 @@ "Unmute_user": "Dóna veu a l'usuari", "Unnamed": "Sense nom", "Unpin_Message": "Desfixa el missatge", - "Unread_Alert": "Alerta de no llegit", + "Unread_Tray_Icon_Alert": "Icona d'alerta de no llegits a la safata", "Unread_Messages": "Missatges no llegits", "Unread_Rooms": "Sales no llegides", "Unread_Rooms_Mode": "Mode de sales no llegides", diff --git a/packages/rocketchat-i18n/i18n/cs.i18n.json b/packages/rocketchat-i18n/i18n/cs.i18n.json index 29faa0d6d50c..ba2dab094d9a 100644 --- a/packages/rocketchat-i18n/i18n/cs.i18n.json +++ b/packages/rocketchat-i18n/i18n/cs.i18n.json @@ -17,6 +17,7 @@ "Accessing_permissions": "Přístup k oprávnění", "Account_SID": "SID účtu", "Accounts": "Účty", + "Accounts_AllowAnonymousAccess": "Povolit anonymní přístup", "Accounts_AllowDeleteOwnAccount": "Povolit uživatelům odstranit vlastní účet", "Accounts_AllowedDomainsList": "Seznam povolených domén", "Accounts_AllowedDomainsList_Description": "Čárkami oddělený seznam povolených domén", @@ -62,6 +63,10 @@ "Accounts_OAuth_Custom_Token_Path": "Cesta k tokenu", "Accounts_OAuth_Custom_Token_Sent_Via": "Token odesílány přes", "Accounts_OAuth_Custom_Username_Field": "Pole uživatelské jméno", + "Accounts_OAuth_Drupal": "Povolit Drupal přihlášení", + "Accounts_OAuth_Drupal_callback_url": "Drupal oAuth2 URI Přesměrování", + "Accounts_OAuth_Drupal_id": "Drupal oAuth2 ID klienta", + "Accounts_OAuth_Drupal_secret": "Drupal oAuth2 Secret klienta", "Accounts_OAuth_Facebook": "Facebook Přihlášení", "Accounts_OAuth_Facebook_callback_url": "Facebook Callback URL", "Accounts_OAuth_Facebook_id": "Facebook App Id", @@ -170,6 +175,8 @@ "API_CORS_Origin": "CORS Origin", "API_Default_Count": "Výchozí počet", "API_Default_Count_Description": "Výchozí počet výsledků v REST API pokud není zažádáno konkrétní číslo", + "API_Drupal_URL": "Drupal URL Serveru", + "API_Drupal_URL_Description": "Například: https://domain.com (bez lomítka na konci)", "API_Embed": "Náhled vložených odkazů", "API_Embed_Description": "Zda zobrazit náhled stránky když uživatel pošle odkaz", "API_EmbedCacheExpirationDays": "Počet dní expirace cache embed", @@ -410,6 +417,7 @@ "Desktop_Notifications_Enabled": "Oznámení na ploše jsou povolena", "Direct_message_someone": "Přímá zpráva někomu", "Direct_Messages": "Přímé zprávy", + "Disable_Notifications": "Zakázat notifikace", "Disable_two-factor_authentication": "Zakázat dvoufázové ověření", "Display_offline_form": "Zobrazit offline formulář", "Displays_action_text": "Zobrazuje text akce", @@ -638,6 +646,7 @@ "Hide_room": "Skrýt místnost", "Hide_Room_Warning": "Jste si jisti, že chcete skrýt místnost \"%s\"?", "Hide_roles": "Schovat role", + "Hide_Unread_Room_Status": "Schovat stav nepřečtených místností", "Hide_usernames": "Skrýt uživatelská jména", "Highlights": "Klíčová slova", "Highlights_How_To": "Chcete-li být upozorněni, když někdo zmíní slovo nebo frázi, přidejte jej sem. Můžete oddělit slova nebo fráze čárkami. Velikost písmen nehraje roli", @@ -730,6 +739,8 @@ "Integration_Retry_Count_Description": "Kolikrát by se integrace měla znova pokusit volat URL pokud byl první pokus neúspěšný?", "Integration_Retry_Delay": "Čas prodlení opakování", "Integration_Retry_Delay_Description": "Jaký algoritmus prodlení by se měl použít?10^x, 2^x nebo x*2", + "Integration_Run_When_Message_Is_Edited": "Spustit při editaci", + "Integration_Run_When_Message_Is_Edited_Description": "Měla by být integrace spuštěna po editaci zprávy? Pokud volbu vypnete, integrace se bude spouštět pouze pro nové zprávy.", "Integration_Word_Trigger_Placement": "Přepisování slov kdekoliv", "Integration_Word_Trigger_Placement_Description": "Mělo by se vyvolat pokud je slovo umístěno jinde než na začátku?", "Integration_updated": "Integrace byla aktualizována", @@ -1074,6 +1085,7 @@ "Nothing_found": "Nic nalezeno", "Notification_Duration": "Délka zobrazení oznámení", "Notifications": "Oznámení", + "Notifications_Muted_Description": "Pokud ztišíte všechno, neuvidíte zvýrazněné místnosti s novými zprávami, krom zmínek. Ztišení notifikací přetěží nastavení notifikací v jednotlivých místnostech.", "Notify_all_in_this_room": "Oznámit všem v této místnosti", "Notify_active_in_this_room": "Notifikovat aktivní uživatele v místnosti", "Num_Agents": "# Operátorů", @@ -1216,6 +1228,7 @@ "Register": "Zaregistrovat nový účet", "Registration": "Registrace", "Registration_Succeeded": "Registrace úspěšná", + "Register_or_login_to_send_messages": "Pro odeslání zpráv je třeba se zaregistrovat nebo přihlásit", "Registration_via_Admin": "Registrace přes Admin", "Regular_Expressions": "Regulární výrazy", "Release": "Verze", @@ -1539,7 +1552,7 @@ "Unmute_user": "Zrušit ztlumení uživatele", "Unnamed": "Nepojmenovaný", "Unpin_Message": "Odepnout Zprávu", - "Unread_Alert": "Nepřečtené upozornění", + "Unread_Tray_Icon_Alert": "Ikona v oznamovací oblasti upozorňuje na nepřečtené zprávy", "Unread_Messages": "Nepřečtěné zprávy", "Unread_Rooms": "Nepřečtené místnosti", "Unread_Rooms_Mode": "Mód Nepřečtených místností", diff --git a/packages/rocketchat-i18n/i18n/de-AT.i18n.json b/packages/rocketchat-i18n/i18n/de-AT.i18n.json index d342f6c1d806..95bf6f011673 100644 --- a/packages/rocketchat-i18n/i18n/de-AT.i18n.json +++ b/packages/rocketchat-i18n/i18n/de-AT.i18n.json @@ -1127,7 +1127,6 @@ "Unmute_user": "Benutzern das Chatten erlauben ", "Unnamed": "Unbenannt", "Unpin_Message": "Nachicht nicht mehr fixieren", - "Unread_Alert": "Über Ungelesenes benachrichtigen", "Unread_Rooms": "Ungelesene Räume", "Unread_Rooms_Mode": "Ungelesene Räume aufgelistet anzeigen ", "Unstar_Message": "Markierung entfernen", diff --git a/packages/rocketchat-i18n/i18n/de.i18n.json b/packages/rocketchat-i18n/i18n/de.i18n.json index 3e319b51c4cb..24e7b29e401d 100644 --- a/packages/rocketchat-i18n/i18n/de.i18n.json +++ b/packages/rocketchat-i18n/i18n/de.i18n.json @@ -1233,7 +1233,6 @@ "Unmute_user": "Benutzern das Chatten erlauben ", "Unnamed": "Unbenannt", "Unpin_Message": "Nachicht nicht mehr anheften", - "Unread_Alert": "Über Ungelesenes benachrichtigen", "Unread_Rooms": "Ungelesene Räume", "Unread_Rooms_Mode": "Ungelesene Räume aufgelistet anzeigen ", "Unstar_Message": "Markierung entfernen", @@ -1376,4 +1375,4 @@ "your_message_optional": "ihre optionale Nachricht", "Your_password_is_wrong": "Falsches Passwort", "Your_push_was_sent_to_s_devices": "Die Push-Nachricht wurde an %s Geräte gesendet." -} +} \ No newline at end of file diff --git a/packages/rocketchat-i18n/i18n/en.i18n.json b/packages/rocketchat-i18n/i18n/en.i18n.json index 9bdb5ece9c2b..92e0f59ce01c 100644 --- a/packages/rocketchat-i18n/i18n/en.i18n.json +++ b/packages/rocketchat-i18n/i18n/en.i18n.json @@ -1716,4 +1716,4 @@ "your_message_optional": "your message (optional)", "Your_password_is_wrong": "Your password is wrong!", "Your_push_was_sent_to_s_devices": "Your push was sent to %s devices" -} +} \ No newline at end of file diff --git a/packages/rocketchat-i18n/i18n/es.i18n.json b/packages/rocketchat-i18n/i18n/es.i18n.json index d1af87871a10..e5dceb0f4260 100644 --- a/packages/rocketchat-i18n/i18n/es.i18n.json +++ b/packages/rocketchat-i18n/i18n/es.i18n.json @@ -1227,7 +1227,6 @@ "Unmute_user": "Des-silenciar usuario", "Unnamed": "Sin nombre", "Unpin_Message": "Desfijar Mensaje", - "Unread_Alert": "Alerta de no leídos", "Unread_Rooms": "Salas sin leer", "Unread_Rooms_Mode": "Modo Salas sin leer", "Unstar_Message": "Eliminar Destacado", diff --git a/packages/rocketchat-i18n/i18n/fr.i18n.json b/packages/rocketchat-i18n/i18n/fr.i18n.json index 8edb98662179..7d9b43e0c9fc 100644 --- a/packages/rocketchat-i18n/i18n/fr.i18n.json +++ b/packages/rocketchat-i18n/i18n/fr.i18n.json @@ -337,13 +337,13 @@ "Custom": "Personnalisé", "Custom_Emoji": "Emoticône personnalisée", "Custom_Emoji_Add": "Ajouter une nouvelle émoticône", - "Custom_Emoji_Added_Successfully": "Emoji personnalisé ajouté avec succès", - "Custom_Emoji_Delete_Warning": "Effacer un emoji ne peut pas être annulé.", - "Custom_Emoji_Error_Invalid_Emoji": "émoticône non valide", - "Custom_Emoji_Error_Name_Or_Alias_Already_In_Use": "L'émoji personnalisé ou un de ses alias est déjà en cours d'utilisation.", - "Custom_Emoji_Has_Been_Deleted": "L'émoji personnalisé a été effacé.", - "Custom_Emoji_Info": "Information sur l'émoji personnalisé", - "Custom_Emoji_Updated_Successfully": "Emoji personnalisé mis à jour avec succès", + "Custom_Emoji_Added_Successfully": "Emoticône personnalisée ajouté avec succès", + "Custom_Emoji_Delete_Warning": "Effacer une émoticône est irréversible.", + "Custom_Emoji_Error_Invalid_Emoji": "Emoticône non valide", + "Custom_Emoji_Error_Name_Or_Alias_Already_In_Use": "L'émoticône personnalisée ou un de ses alias est déjà en cours d'utilisation.", + "Custom_Emoji_Has_Been_Deleted": "L'émoticône personnalisée a été effacé.", + "Custom_Emoji_Info": "Information sur l'émoticône personnalisée", + "Custom_Emoji_Updated_Successfully": "Emoticône personnalisée mise à jour avec succès", "Custom_Fields": "Champs personnalisés", "Custom_oauth_helper": "Lorsque vous configurez votre service OAuth, vous devez indiquer une URL pour le Callback. Utilisez
%s
", "Custom_oauth_unique_name": "Nom unique de l'OAuth personnalisé", @@ -366,16 +366,16 @@ "Date_From": "De", "Date_to": "à", "days": "jours", - "DB_Migration": "Base de données de migration", - "DB_Migration_Date": "Base de données de migration date", + "DB_Migration": "Mise à jour de la base de données", + "DB_Migration_Date": "Date de mise à jour de la base de données", "Deactivate": "Désactiver", "Decline": "Refuser", "Default": "Défaut", "Delete": "Supprimer", - "Delete_message": "Suppression de messages", + "Delete_message": "Supprimer le message", "Delete_my_account": "Supprimer mon compte", "Delete_Room_Warning": "Supprimer un salon supprimera également tous les messages postés dans le salon. Cette action est irréversible.", - "Delete_User_Warning": "Supprimer un utilisateur va également supprimer tous les messages de celui-ci. Cette action ne peut être annulée.", + "Delete_User_Warning": "Supprimer un utilisateur va également supprimer tous les messages de celui-ci. Cette action est irréversible.", "Deleted": "Supprimé !", "Department": "Département", "Department_removed": "Département supprimé", @@ -393,7 +393,7 @@ "Direct_Messages": "Messages Privés", "Display_offline_form": "Affichage formulaire hors ligne", "Displays_action_text": "Texte d'affichage", - "Do_you_want_to_change_to_s_question": "Voulez-vous changer pour %s ?", + "Do_you_want_to_change_to_s_question": "Voulez-vous changer pour %s ?", "Domain": "Domaine", "Domain_added": "Domaine ajouté", "Domain_removed": "Domaine supprimé", @@ -404,7 +404,7 @@ "Dry_run_description": "Envoi un unique e-mail, à l'adresse de l'expéditeur. L'adresse e-mail doit appartenir à un utilisateur valide.", "Duplicate_archived_channel_name": "Un canal archivé avec le nom '#%s' existe", "Duplicate_archived_private_group_name": "Un groupe privé archivé avec le nom '%s' existe", - "Duplicate_channel_name": "Un canal avec le nom '% s' existe", + "Duplicate_channel_name": "Un canal avec le nom '%s' existe", "Duplicate_private_group_name": "Un groupe privé avec le nom '%s' existe déjà", "Duration": "Durée", "Edit": "Modifier", @@ -419,9 +419,9 @@ "Email_already_exists": "L'adresse e-mail existe déjà", "Email_body": "Corps du message", "Email_Change_Disabled": "Votre administrateur de Rocket.Chat a désactivé le changement d'adresse e-mail", - "Email_Footer_Description": "Vous pouvez utiliser les variables suivantes:
  • [Site_Name] et [Site_URL] pour le nom de l'application et URL respectivement.
", + "Email_Footer_Description": "Vous pouvez utiliser les variables suivantes:
  • [Site_Name] et [Site_URL] pour le nom de l'application et URL respectivement.
", "Email_from": "De", - "Email_Header_Description": "Vous pouvez utiliser les variables suivantes:
  • [Site_Name] et [Site_URL] pour le nom de l'application et URL respectivement.
", + "Email_Header_Description": "Vous pouvez utiliser les variables suivantes:
  • [Site_Name] et [Site_URL] pour le nom de l'application et URL respectivement.
", "Email_Notification_Mode": "Notifications hors-ligne par e-mail", "Email_Notification_Mode_All": "Toutes les Mentions/MP", "Email_Notification_Mode_Disabled": "Désactivé", @@ -429,7 +429,7 @@ "Email_subject": "Sujet", "Email_verified": "Adresse e-mail vérifiée", "Emoji": "Emoticône ", - "EmojiCustomFilesystem": "Système de fichier d'émoticones personnalisés", + "EmojiCustomFilesystem": "Système de fichier d'émoticônes personnalisés", "Empty_title": "Titre vide", "Enable": "Activer", "Enable_Desktop_Notifications": "Activer les notifications sur le bureau", @@ -467,7 +467,7 @@ "error-file-too-large": "Le fichier est trop lourd", "error-importer-not-defined": "L'importateur n'a pas été défini correctement, il manque la classe Import.", "error-input-is-not-a-valid-field": "__input__ n'est pas un __field__ valide", - "error-invalid-actionlink": "lien d'action non valide", + "error-invalid-actionlink": "Lien d'action non valide", "error-invalid-arguments": "Arguments non valides", "error-invalid-asset": "Ressource invalide", "error-invalid-channel": "Canal non valide.", @@ -625,7 +625,7 @@ "If_you_are_sure_type_in_your_username": "Si vous êtes certain(e), saisissez votre nom d'utilisateur :", "Iframe_Integration": "Intégration Iframe", "Iframe_Integration_receive_enable": "Activer la réception", - "Iframe_Integration_receive_enable_Description": "Autoriser la fenêtre parente à envoyer des commandes à Rocket.Chat", + "Iframe_Integration_receive_enable_Description": "Autoriser la fenêtre parente à envoyer des commandes à Rocket.Chat.", "Iframe_Integration_receive_origin": "Recevoir les origines", "Iframe_Integration_receive_origin_Description": "Seules les pages ayant une origine donnée seront autorisée à envoyer des commandes ou `*` pour toutes les origines. Vous pouvez utiliser de multiples valeurs séparées par des` ,`. Exemple : `http://localhost,https://localhost`", "Iframe_Integration_send_enable": "Activer l'envoi", @@ -646,11 +646,11 @@ "Importer_Prepare_Restart_Import": "Recommencer l’Importation", "Importer_Prepare_Start_Import": "Commencer l'Importation", "Importer_Prepare_Uncheck_Archived_Channels": "Désélectionner les canaux archivés", - "Importer_Prepare_Uncheck_Deleted_Users": "Désélectionner les Utilisateurs Supprimés", + "Importer_Prepare_Uncheck_Deleted_Users": "Désélectionner les utilisateurs supprimés", "Importer_progress_error": "Impossible d'obtenir l'état de l'importation.", "Importer_setup_error": "Une erreur est survenue lors du paramétrage de l'importateur.", "Importer_Source_File": "Sélection du fichier source", - "Incoming_Livechats": "Arrivée de nouveaux Livechats", + "Incoming_Livechats": "Arrivée de nouveaux chats en direct", "inline_code": "Ligne de code", "Install_Extension": "Installer l'extension", "Install_FxOs": "Installez Rocket.Chat dans votre Firefox", @@ -696,6 +696,7 @@ "Invalid_pass": "Le mot de passe doit être renseigné", "Invalid_room_name": "%s n'est pas un nom de salon valide.
Utilisez uniquement des lettres, des chiffres et des tirets (milieu et bas)", "Invalid_secret_URL_message": "L'URL fournie est invalide.", + "Invalid_setting_s": "Paramètre invalide : %s", "invisible": "invisible", "Invisible": "Invisible", "Invitation": "Invitation", @@ -739,11 +740,11 @@ "Jump_to_message": "Aller au message", "Jump_to_recent_messages": "Aller aux messages récents", "Katex_Dollar_Syntax": "Autoriser Dollar Syntaxe", - "Katex_Dollar_Syntax_Description": "Autoriser avec $$ bloc Katex $$ et $ Katex inline $ syntaxes", + "Katex_Dollar_Syntax_Description": "Autoriser les syntaxes : $$bloc katex$$ et $katex inline$", "Katex_Enabled": "Katex activé", "Katex_Enabled_Description": "Autoriser l' utilisation Katex pour les mathématiques photocomposition dans les messages", "Katex_Parenthesis_Syntax": "Autoriser Parenthesis Syntaxe", - "Katex_Parenthesis_Syntax_Description": "Autoriser l'utilisation \\ [bloc Katex \\] et \\ (inline Katex \\) syntaxes", + "Katex_Parenthesis_Syntax_Description": "Autoriser les syntaxes : \\[bloc katex\\] et \\(inline katex\\)", "Knowledge_Base": "Base de connaissances", "Label": "Label", "Language": "Langue", @@ -825,7 +826,6 @@ "Domains_allowed_to_embed_the_livechat_widget": "Liste des domaines autorisés à intégrer le widget de chat en direct, séparés par des virgules. Laissez vide pour autoriser tous les domaines. ", "Livechat_Dashboard": "Tableau de bord du chat en direct", "Livechat_enabled": "Chat en direct activé", - "Livechat_forward_open_chats": "chats Forward ouverts", "Livechat_forward_open_chats_timeout": "Timeout (en secondes) de transmettre les chats", "Livechat_guest_count": "Compteur d'invités", "Livechat_Inquiry_Already_Taken": "Demande de chat en direct déjà prise en compte", @@ -906,7 +906,7 @@ "Message_GroupingPeriodDescription": "Les messages seront regroupés avec les messages précédents si ils sont du même utilisateur et si le temps écoulé est inférieur au temps indiqué en secondes.", "Message_HideType_au": "Masquer les messages \"Utilisateur ajouté\"", "Message_HideType_mute_unmute": "Masquer les messages \"Utilisateur rendu muet / a retrouvé la parole\"", - "Message_HideType_ru": "Masquer les messages \"Utilisateur ejecté\"", + "Message_HideType_ru": "Masquer les messages \"Utilisateur éjecté\"", "Message_HideType_uj": "Masquer les messages \"L'utilisateur a rejoint\"", "Message_HideType_ul": "Masquer les messages \"L'utilisateur a quitté\"", "Message_KeepHistory": "Conserver l'historique des messages", @@ -928,7 +928,7 @@ "Message_VideoRecorderEnabled": "Enregistreur vidéo activé", "Message_VideoRecorderEnabledDescription": "Nécessite que le type de média \"video/webm\" soit accepté dans les paramètres d'envoi des fichiers.", "Messages": "Messages", - "Messages_that_are_sent_to_the_Incoming_WebHook_will_be_posted_here": "Les messages envoyés au WebHook Entrant seront postés ici", + "Messages_that_are_sent_to_the_Incoming_WebHook_will_be_posted_here": "Les messages envoyés au WebHook Entrant seront postés ici.", "Meta": "Meta", "Meta_fb_app_id": "App ID Facebook", "Meta_google-site-verification": "Google Site Verification", @@ -1008,13 +1008,13 @@ "Office_hours_updated": "Heures de bureau modifiées", "Offline": "Hors ligne", "Offline_DM_Email": "Vous avez reçu des messages privés de __user__", - "Offline_form": "forme Hors ligne", - "Offline_form_unavailable_message": "forme Offline Message indisponible", - "Offline_Link_Message": "Aller au message", + "Offline_form": "Formulaire hors ligne", + "Offline_form_unavailable_message": "Message indisponible du formulaire hors ligne", + "Offline_Link_Message": "ALLER AU MESSAGE", "Offline_Mention_Email": "Vous avez été mentionné par __user__ dans le salon #__room__", - "Offline_message": "un message Hors ligne", - "Offline_success_message": "message de succès hors ligne", - "Offline_unavailable": "Offline indisponible", + "Offline_message": "Message hors ligne", + "Offline_success_message": "Message de succès hors ligne", + "Offline_unavailable": "Hors ligne indisponible", "On": "Allumé", "Online": "Connecté", "Only_On_Desktop": "Mode Bureau (envoyé seulement quand Entrée sur le bureau)", @@ -1022,7 +1022,7 @@ "Oops!": "Oups", "Open": "Ouvrerture", "Open_days_of_the_week": "Jours d'ouverture", - "Open_Livechats": "Ouvrir les Livechats", + "Open_Livechats": "Ouvrir les chats en direct", "Opened": "Ouvert", "Opened_in_a_new_window": "Ouvert dans une nouvelle fenêtre.", "Opens_a_channel_group_or_direct_message": "Ouvre un canal, un groupe ou un message direct", @@ -1060,27 +1060,27 @@ "PiwikAnalytics_url_Description": "L'URL où le Piwik réside, assurez-vous d'inclure la barre trialing. Exemple: //piwik.rocket.chat/", "Placeholder_for_email_or_username_login_field": "Texte de remplacement pour l'adresse e-mail ou le nom d'utilisateur à la connexion", "Placeholder_for_password_login_field": "Texte de remplacement pour le mot de passe", - "Please_add_a_comment": "S'il vous plaît ajouter un commentaire", + "Please_add_a_comment": "Merci d'ajouter un commentaire", "Please_add_a_comment_to_close_the_room": "Merci d'ajouter un commentaire pour fermer le salon", - "Please_answer_survey": "S'il vous plait , prenez un moment pour répondre à un court sondage à propos de ce chat ", + "Please_answer_survey": "Merci de prendre un moment pour répondre à un court sondage à propos de cette conversation", "Please_enter_value_for_url": "Veuillez entrer l'url de votre avatar.", "Please_enter_your_new_password_below": "Veuillez écrire votre nouveau mot de passe ci-dessous :", - "Please_enter_your_password": "Veuillez ré-entrer votre mot de passe", + "Please_enter_your_password": "Veuillez entrer votre mot de passe", "please_enter_valid_domain": "Merci d'entrer un domaine valide", "Please_fill_a_label": "Veuillez entrer une étiquette", "Please_fill_a_name": "Veuillez saisir un nom", "Please_fill_a_username": "Veuillez enter un nom d'utilisateur", "Please_fill_name_and_email": "Veuillez remplir le nom et l'adresse e-mail", "Please_select_an_user": "Merci de sélectionner un utilisateur", - "Please_select_enabled_yes_or_no": "Veuillez choisir une option pour Activé", + "Please_select_enabled_yes_or_no": "Veuillez choisir une option pour \"Activé\"", "Please_wait": "Veuillez patienter", "Please_wait_activation": "Veuillez patienter, cela peut prendre un peu de temps.", "Please_wait_while_OTR_is_being_established": "Veuillez patienter pendant l'établissement de l'OTR", - "Please_wait_while_your_account_is_being_deleted": "Veuillez patienter pendant que votre compte est supprimé...", - "Please_wait_while_your_profile_is_being_saved": "Veuillez patienter pendant que votre profil est enregistré ...", + "Please_wait_while_your_account_is_being_deleted": "Veuillez patienter pendant la suppression de votre compte...", + "Please_wait_while_your_profile_is_being_saved": "Veuillez patienter pendant l'enregistrement de votre profil...", "Port": "Port", "Post_as": "Publié en tant que", - "Post_to_Channel": "Publié sur le Canal", + "Post_to_Channel": "Publié sur le canal", "Post_to_s_as_s": "Publié sur %s en tant que %s", "Preferences": "Préférences", "Preferences_saved": "Préférences enregistrées", @@ -1323,6 +1323,7 @@ "Stats_Total_Messages": "Nombre total de messages", "Stats_Total_Messages_Channel": "Nombre total de messages dans les canaux", "Stats_Total_Messages_Direct": "Nombre total de messages dans les discussions privées", + "Stats_Total_Messages_Livechat": "Nombre total de messages de chat en direct", "Stats_Total_Private_Groups": "Nombre total de groupes privés", "Stats_Total_Rooms": "Nombre total de salons", "Stats_Total_Users": "Nombre total d'utilisateurs", @@ -1379,10 +1380,10 @@ "theme-color-unread-notification-color": "Couleur des notifications non-lues", "theme-custom-css": "CSS personnalisé", "theme-font-body-font-family": "Famille de police du body", - "There_are_no_agents_added_to_this_department_yet": "Il n'y a pas d'assistant ajouté à ce département pour le moment", + "There_are_no_agents_added_to_this_department_yet": "Il n'y a pas d'assistant ajouté à ce département pour le moment.", "There_are_no_integrations": "Il n'y a aucune intégration", "There_are_no_users_in_this_role": "Il n'y a aucun utilisateur avec ce rôle.", - "This_conversation_is_already_closed": "Ces conversation a déjà été fermée.", + "This_conversation_is_already_closed": "Cette conversation a déjà été fermée.", "This_email_has_already_been_used_and_has_not_been_verified__Please_change_your_password": "Cette adresse e-mail a déjà été utilisée et n'a pas été vérifiée. Veuillez changer votre mot de passe.", "This_is_a_desktop_notification": "Ceci est une notification sur le bureau.", "This_is_a_push_test_messsage": "Ceci est une notification de test", @@ -1422,7 +1423,6 @@ "Unmute_user": "Rendre la parole", "Unnamed": "Sans nom", "Unpin_Message": "Désépingler ce message", - "Unread_Alert": "Alerte non lue", "Unread_Messages": "Messages non lus", "Unread_Rooms": "Salons contenant des messages non-lus", "Unread_Rooms_Mode": "Mode des salons non-lus", @@ -1431,10 +1431,10 @@ "Upload_file_name": "Nom du fichier", "Upload_file_question": "Envoyer le fichier ?", "Uploading_file": "Envoi du fichier en cours...", - "Uptime": "uptime", + "Uptime": "Durée de fonctionnement", "URL": "URL", "Use_account_preference": "Préférence du compte utilisateur", - "Use_Emojis": "Utiliser les Emojis", + "Use_Emojis": "Utiliser les émoticônes", "Use_Global_Settings": "Utiliser les paramètres globaux", "Use_initials_avatar": "Utiliser les initiales de votre nom d'utilisateur", "Use_service_avatar": "Utiliser l'avatar %s", @@ -1446,10 +1446,10 @@ "User__username__is_now_a_owner_of__room_name_": "L'utilisateur __username__ est désormais un propriétaire du salon __room_name__", "User__username__removed_from__room_name__moderators": "L'utilisateur __username__ n'est plus modérateur du salon __room_name__.", "User__username__removed_from__room_name__owners": "L'utilisateur __username__ n'est plus propriétaire du salon __room_name__.", - "User_added": "L'utilisateur __user_added__ a été ajouté", + "User_added": "Utilisateur ajouté", "User_added_by": "L'utilisateur __user_added__ a été ajouté par __user_by__.", "User_added_successfully": "Utilisateur ajouté avec succès", - "User_doesnt_exist": "Aucun utilisateur nommé `@%s` existe.", + "User_doesnt_exist": "Aucun utilisateur nommé `@%s` existant.", "User_has_been_activated": "L'utilisateur a été activé", "User_has_been_deactivated": "L'utilisateur a été désactivé", "User_has_been_deleted": "L'utilisateur a été supprimé", diff --git a/packages/rocketchat-i18n/i18n/he.i18n.json b/packages/rocketchat-i18n/i18n/he.i18n.json index 459b1008f5f8..b912f90ea58d 100644 --- a/packages/rocketchat-i18n/i18n/he.i18n.json +++ b/packages/rocketchat-i18n/i18n/he.i18n.json @@ -1097,7 +1097,6 @@ "Unmute_user": "בטל השתקת משתמש", "Unnamed": "ללא שם", "Unpin_Message": "שחרור הודעה", - "Unread_Alert": "התרעה על לא נקרא", "Unread_Rooms": "חדרים שלא נקראו", "Unread_Rooms_Mode": "מצב חדרים שלא נקראו", "Unstar_Message": "הסר ממועדפים", diff --git a/packages/rocketchat-i18n/i18n/hr.i18n.json b/packages/rocketchat-i18n/i18n/hr.i18n.json index 59f172d3704d..83e9f1a937d0 100644 --- a/packages/rocketchat-i18n/i18n/hr.i18n.json +++ b/packages/rocketchat-i18n/i18n/hr.i18n.json @@ -1292,7 +1292,6 @@ "Unmute_user": "Uključi korisnika", "Unnamed": "Neimenovano", "Unpin_Message": "Otkvači Poruku", - "Unread_Alert": "Nepročitane obavijesti", "Unread_Rooms": "Nepročitane Sobe", "Unread_Rooms_Mode": "Mod Nepročitanih Soba", "Unstar_Message": "Ukloni zvjezdicu", diff --git a/packages/rocketchat-i18n/i18n/it.i18n.json b/packages/rocketchat-i18n/i18n/it.i18n.json index af5735a40eb1..06d62a2f4d7f 100644 --- a/packages/rocketchat-i18n/i18n/it.i18n.json +++ b/packages/rocketchat-i18n/i18n/it.i18n.json @@ -1482,7 +1482,6 @@ "Unmute_user": "Togli il muto all'utente", "Unnamed": "Senza nome", "Unpin_Message": "Rimuovi il pin dal messaggio", - "Unread_Alert": "Avviso Non Letto", "Unread_Rooms": "Stanze non letti", "Unread_Rooms_Mode": "Modalità Stanze Non Letta", "Unstar_Message": "Rimuovi segnalibro", diff --git a/packages/rocketchat-i18n/i18n/ja.i18n.json b/packages/rocketchat-i18n/i18n/ja.i18n.json index 8cc4b4e22f4e..d207cdff4f02 100644 --- a/packages/rocketchat-i18n/i18n/ja.i18n.json +++ b/packages/rocketchat-i18n/i18n/ja.i18n.json @@ -1103,7 +1103,6 @@ "Unmute_user": "ミュートを解除", "Unnamed": "無名", "Unpin_Message": "ピン留めを外す", - "Unread_Alert": "未読アラート", "Unread_Rooms": "未読のあるルーム", "Unread_Rooms_Mode": "未読ルーム表示モード", "Unstar_Message": "スターを外す", diff --git a/packages/rocketchat-i18n/i18n/ko.i18n.json b/packages/rocketchat-i18n/i18n/ko.i18n.json index ca1ae1f28e18..02492e8aa80c 100644 --- a/packages/rocketchat-i18n/i18n/ko.i18n.json +++ b/packages/rocketchat-i18n/i18n/ko.i18n.json @@ -16,7 +16,7 @@ "Accessing_permissions": "권한 액세스", "Account_SID": "계정 SID", "Accounts": "계정", - "Accounts_AllowDeleteOwnAccount": "사용자가 자신의 계정을 삭제할 수있습니다.", + "Accounts_AllowDeleteOwnAccount": "사용자가 자신의 계정을 삭제할 수 있습니다.", "Accounts_AllowedDomainsList": "허용된 도메인 목록", "Accounts_AllowedDomainsList_Description": "허용된 도메인을 쉼표(,)로 구분하기", "Accounts_AllowEmailChange": "이메일 변경을 허용합니다", @@ -203,6 +203,8 @@ "AutoLinker_Urls_www": "AutoLinker 'WWW'의 URL", "AutoLinker_UrlsRegExp": "AutoLinker URL 정규 표현식", "Automatic_Translation": "자동 번역", + "Auto_Translate": "자동 번역", + "AutoTranslate_Enabled": "자동 번역 활성화", "AutoTranslate_GoogleAPIKey": "구글 API 키", "Available": "유효한", "Available_agents": "사용 가능한 에이전트", @@ -221,9 +223,12 @@ "Back_to_integrations": "위로 통합에", "Back_to_login": "로그인으로 돌아가기", "Back_to_permissions": "돌아 가기 권한", + "Block_User": "사용자 차단", "Body": "신체", "bold": "굵게", + "BotHelpers_userFields": "사용자 필드", "Branch": "분기", + "Bugsnag_api_key": "Bugsnag API 키", "busy": "바쁨", "Busy": "바쁨", "busy_female": "바쁨", @@ -231,9 +236,14 @@ "busy_male": "바쁨", "Busy_male": "바쁨", "by": "으로", + "cache_cleared": "캐시가 삭제됨", "Cancel": "취소", "Cancel_message_input": "취소", "Cannot_invite_users_to_direct_rooms": "객실을 지시하는 사용자를 초대 할 수 없습니다", + "CAS_autoclose": "로그인 팝업을 자동으로 닫음", + "CAS_button_color": "로그인 버튼 배경 색상", + "CAS_button_label_color": "로그인 버튼 텍스트 색상", + "CAS_button_label_text": "로그인 버튼 레이블", "CDN_PREFIX": "CDN Prefix", "Certificates_and_Keys": "인증서와 키", "Changing_email": "변경 이메일", diff --git a/packages/rocketchat-i18n/i18n/pl.i18n.json b/packages/rocketchat-i18n/i18n/pl.i18n.json index 85a9d5cfc414..28492fd71c39 100644 --- a/packages/rocketchat-i18n/i18n/pl.i18n.json +++ b/packages/rocketchat-i18n/i18n/pl.i18n.json @@ -1202,7 +1202,6 @@ "Unmute_user": "Anuluj wyciszenie użytkownika", "Unnamed": "Anonimowy", "Unpin_Message": "Odepnij wiadomość", - "Unread_Alert": "Alarm nieprzeczytany", "Unread_Rooms": "Nieprzeczytane pokoje", "Unread_Rooms_Mode": "Tryb nieprzeczytanych pokoi", "Unstar_Message": "Usuń oznaczenie", diff --git a/packages/rocketchat-i18n/i18n/sv.i18n.json b/packages/rocketchat-i18n/i18n/sv.i18n.json index 92c5f703e5d6..b677c0687450 100644 --- a/packages/rocketchat-i18n/i18n/sv.i18n.json +++ b/packages/rocketchat-i18n/i18n/sv.i18n.json @@ -421,6 +421,7 @@ "Field": "Fält", "Field_removed": "fältet avlägsnas", "File_exceeds_allowed_size_of_bytes": "Filen överskrider tillåten storlek __size__ bytes", + "File_uploaded": "Uppladdad fil", "FileUpload": "Uppladdad fil", "FileUpload_Enabled": "Filuppladdningar aktiverade", "FileUpload_File_Empty": "Tom fil", @@ -506,6 +507,7 @@ "Integration_added": "Integrationen har lagts", "Integration_Incoming_WebHook": "Inkommande WebHook Integration", "Integration_New": "Ny integrering", + "Integrations_Outgoing_Type_FileUploaded": "Uppladdad fil", "Integration_Outgoing_WebHook": "Utgående WebHook Integration", "Integration_updated": "Integrationen har uppdaterats", "Integrations": "Integreringar", @@ -1103,6 +1105,8 @@ "Unread_Rooms": "Olästa rum", "Unread_Rooms_Mode": "Olästa Rum Läge", "Unstar_Message": "Ta bort stjärnmarkering", + "Upload_file_description": "Filbeskrivning", + "Upload_file_name": "Filnamn", "Upload_file_question": "Ladda upp fil?", "Uploading_file": "Laddar upp fil...", "Uptime": "drifttid", diff --git a/packages/rocketchat-i18n/i18n/zh.i18n.json b/packages/rocketchat-i18n/i18n/zh.i18n.json index 10364945aa10..00b01cda799a 100644 --- a/packages/rocketchat-i18n/i18n/zh.i18n.json +++ b/packages/rocketchat-i18n/i18n/zh.i18n.json @@ -1341,7 +1341,6 @@ "Unmute_user": "取消禁言", "Unnamed": "未命名", "Unpin_Message": "取消固定", - "Unread_Alert": "未读警报", "Unread_Messages": "未读消息", "Unread_Rooms": "未读房间", "Unread_Rooms_Mode": "未读房间模式", diff --git a/packages/rocketchat-livechat/app/i18n/bg.i18n.json b/packages/rocketchat-livechat/app/i18n/bg.i18n.json index 060a3ee27880..2a6ec769e46c 100644 --- a/packages/rocketchat-livechat/app/i18n/bg.i18n.json +++ b/packages/rocketchat-livechat/app/i18n/bg.i18n.json @@ -1,6 +1,7 @@ { "Are_you_sure_do_you_want_end_this_chat": "Сигурен ли си че искаш да прекратиш този чат?", "Cancel": "Отказ", + "Change": "Промени", "Chat_ended": "Край на чата", "Close_menu": "Затваряне на менюто", "Conversation_finished": "Разговорът завърши",