diff --git a/packages/rocketchat-lib/lib/Message.coffee b/packages/rocketchat-lib/lib/Message.coffee
deleted file mode 100644
index cbf6e92a89ff..000000000000
--- a/packages/rocketchat-lib/lib/Message.coffee
+++ /dev/null
@@ -1,26 +0,0 @@
-RocketChat.Message =
- parse: (msg, language) ->
- messageType = RocketChat.MessageTypes.getType(msg)
- if messageType?.render?
- return messageType.render(msg)
- else if messageType?.template?
- # render template
- else if messageType?.message?
- if not language and localStorage?.getItem('userLanguage')
- language = localStorage.getItem('userLanguage')
- if messageType.data?(msg)?
- return TAPi18n.__(messageType.message, messageType.data(msg), language)
- else
- return TAPi18n.__(messageType.message, {}, language)
- else
- if msg.u?.username is RocketChat.settings.get('Chatops_Username')
- msg.html = msg.msg
- return msg.html
-
- msg.html = msg.msg
- if _.trim(msg.html) isnt ''
- msg.html = _.escapeHTML msg.html
-
- # message = RocketChat.callbacks.run 'renderMessage', msg
- msg.html = msg.html.replace /\n/gm, '
'
- return msg.html
diff --git a/packages/rocketchat-lib/lib/Message.js b/packages/rocketchat-lib/lib/Message.js
new file mode 100644
index 000000000000..1eefff6ccbac
--- /dev/null
+++ b/packages/rocketchat-lib/lib/Message.js
@@ -0,0 +1,29 @@
+RocketChat.Message = {
+ parse(msg, language) {
+ const messageType = RocketChat.MessageTypes.getType(msg);
+ if (messageType) {
+ if (messageType.render) {
+ return messageType.render(msg);
+ } else if (messageType.template) {
+ // Render message
+ return;
+ } else if (messageType.message) {
+ if (!language && typeof localStorage !== 'undefined') {
+ language = localStorage.getItem('userLanguage');
+ }
+ const data = (typeof messageType.data === 'function' && messageType.data(msg)) || {};
+ return TAPi18n.__(messageType.message, data, language);
+ }
+ }
+ if (msg.u && msg.u.username === RocketChat.settings.get('Chatops_Username')) {
+ msg.html = msg.msg;
+ return msg.html;
+ }
+ msg.html = msg.msg;
+ if (_.trim(msg.html) !== '') {
+ msg.html = _.escapeHTML(msg.html);
+ }
+ msg.html = msg.html.replace(/\n/gm, '
');
+ return msg.html;
+ }
+};
diff --git a/packages/rocketchat-lib/lib/MessageTypes.coffee b/packages/rocketchat-lib/lib/MessageTypes.coffee
deleted file mode 100644
index 7912e7fb943d..000000000000
--- a/packages/rocketchat-lib/lib/MessageTypes.coffee
+++ /dev/null
@@ -1,112 +0,0 @@
-RocketChat.MessageTypes = new class
- types = {}
-
- registerType = (options) ->
- types[options.id] = options
-
- getType = (message) ->
- return types[message?.t]
-
- isSystemMessage = (message) ->
- return types[message?.t]?.system
-
- registerType: registerType
- getType: getType
- isSystemMessage: isSystemMessage
-
-Meteor.startup ->
- RocketChat.MessageTypes.registerType
- id: 'r'
- system: true
- message: 'Room_name_changed'
- data: (message) ->
- return { room_name: message.msg, user_by: message.u.username }
-
- RocketChat.MessageTypes.registerType
- id: 'au'
- system: true
- message: 'User_added_by'
- data: (message) ->
- return { user_added: message.msg, user_by: message.u.username }
-
- RocketChat.MessageTypes.registerType
- id: 'ru'
- system: true
- message: 'User_removed_by'
- data: (message) ->
- return { user_removed: message.msg, user_by: message.u.username }
-
- RocketChat.MessageTypes.registerType
- id: 'ul'
- system: true
- message: 'User_left'
- data: (message) ->
- return { user_left: message.u.username }
-
- RocketChat.MessageTypes.registerType
- id: 'uj'
- system: true
- message: 'User_joined_channel'
- data: (message) ->
- return { user: message.u.username }
-
- RocketChat.MessageTypes.registerType
- id: 'wm'
- system: true
- message: 'Welcome'
- data: (message) ->
- return { user: message.u.username }
-
- RocketChat.MessageTypes.registerType
- id: 'rm'
- system: true
- message: 'Message_removed'
- data: (message) ->
- return { user: message.u.username }
-
- RocketChat.MessageTypes.registerType
- id: 'rtc'
- render: (message) ->
- RocketChat.callbacks.run 'renderRtcMessage', message
-
- RocketChat.MessageTypes.registerType
- id: 'user-muted'
- system: true
- message: 'User_muted_by'
- data: (message) ->
- return { user_muted: message.msg, user_by: message.u.username }
-
- RocketChat.MessageTypes.registerType
- id: 'user-unmuted'
- system: true
- message: 'User_unmuted_by'
- data: (message) ->
- return { user_unmuted: message.msg, user_by: message.u.username }
-
- RocketChat.MessageTypes.registerType
- id: 'subscription-role-added'
- system: true
- message: '__username__was_set__role__by__user_by_'
- data: (message) ->
- return { username: message.msg, role: message.role, user_by: message.u.username }
-
- RocketChat.MessageTypes.registerType
- id: 'subscription-role-removed'
- system: true
- message: '__username__is_no_longer__role__defined_by__user_by_'
- data: (message) ->
- return { username: message.msg, role: message.role, user_by: message.u.username }
-
- RocketChat.MessageTypes.registerType
- id: 'room-archived'
- system: true
- message: 'This_room_has_been_archived_by__username_'
- data: (message) ->
- return { username: message.u.username }
-
- RocketChat.MessageTypes.registerType
- id: 'room-unarchived'
- system: true
- message: 'This_room_has_been_unarchived_by__username_'
- data: (message) ->
- return { username: message.u.username }
diff --git a/packages/rocketchat-lib/lib/MessageTypes.js b/packages/rocketchat-lib/lib/MessageTypes.js
new file mode 100644
index 000000000000..db57c899ad68
--- /dev/null
+++ b/packages/rocketchat-lib/lib/MessageTypes.js
@@ -0,0 +1,167 @@
+RocketChat.MessageTypes = new class {
+ constructor() {
+ this.types = {};
+ }
+
+ registerType(options) {
+ return this.types[options.id] = options;
+ }
+
+ getType(message) {
+ return this.types[message && message.t];
+ }
+
+ isSystemMessage(message) {
+ const type = this.types[message && message.t];
+ return type && type.system;
+ }
+
+};
+
+Meteor.startup(function() {
+ RocketChat.MessageTypes.registerType({
+ id: 'r',
+ system: true,
+ message: 'Room_name_changed',
+ data(message) {
+ return {
+ room_name: message.msg,
+ user_by: message.u.username
+ };
+ }
+ });
+ RocketChat.MessageTypes.registerType({
+ id: 'au',
+ system: true,
+ message: 'User_added_by',
+ data(message) {
+ return {
+ user_added: message.msg,
+ user_by: message.u.username
+ };
+ }
+ });
+ RocketChat.MessageTypes.registerType({
+ id: 'ru',
+ system: true,
+ message: 'User_removed_by',
+ data(message) {
+ return {
+ user_removed: message.msg,
+ user_by: message.u.username
+ };
+ }
+ });
+ RocketChat.MessageTypes.registerType({
+ id: 'ul',
+ system: true,
+ message: 'User_left',
+ data(message) {
+ return {
+ user_left: message.u.username
+ };
+ }
+ });
+ RocketChat.MessageTypes.registerType({
+ id: 'uj',
+ system: true,
+ message: 'User_joined_channel',
+ data(message) {
+ return {
+ user: message.u.username
+ };
+ }
+ });
+ RocketChat.MessageTypes.registerType({
+ id: 'wm',
+ system: true,
+ message: 'Welcome',
+ data(message) {
+ return {
+ user: message.u.username
+ };
+ }
+ });
+ RocketChat.MessageTypes.registerType({
+ id: 'rm',
+ system: true,
+ message: 'Message_removed',
+ data(message) {
+ return {
+ user: message.u.username
+ };
+ }
+ });
+ RocketChat.MessageTypes.registerType({
+ id: 'rtc',
+ render(message) {
+ return RocketChat.callbacks.run('renderRtcMessage', message);
+ }
+ });
+ RocketChat.MessageTypes.registerType({
+ id: 'user-muted',
+ system: true,
+ message: 'User_muted_by',
+ data(message) {
+ return {
+ user_muted: message.msg,
+ user_by: message.u.username
+ };
+ }
+ });
+ RocketChat.MessageTypes.registerType({
+ id: 'user-unmuted',
+ system: true,
+ message: 'User_unmuted_by',
+ data(message) {
+ return {
+ user_unmuted: message.msg,
+ user_by: message.u.username
+ };
+ }
+ });
+ RocketChat.MessageTypes.registerType({
+ id: 'subscription-role-added',
+ system: true,
+ message: '__username__was_set__role__by__user_by_',
+ data(message) {
+ return {
+ username: message.msg,
+ role: message.role,
+ user_by: message.u.username
+ };
+ }
+ });
+ RocketChat.MessageTypes.registerType({
+ id: 'subscription-role-removed',
+ system: true,
+ message: '__username__is_no_longer__role__defined_by__user_by_',
+ data(message) {
+ return {
+ username: message.msg,
+ role: message.role,
+ user_by: message.u.username
+ };
+ }
+ });
+ RocketChat.MessageTypes.registerType({
+ id: 'room-archived',
+ system: true,
+ message: 'This_room_has_been_archived_by__username_',
+ data(message) {
+ return {
+ username: message.u.username
+ };
+ }
+ });
+ RocketChat.MessageTypes.registerType({
+ id: 'room-unarchived',
+ system: true,
+ message: 'This_room_has_been_unarchived_by__username_',
+ data(message) {
+ return {
+ username: message.u.username
+ };
+ }
+ });
+});
diff --git a/packages/rocketchat-lib/lib/slashCommand.coffee b/packages/rocketchat-lib/lib/slashCommand.coffee
deleted file mode 100644
index 8e8b7b4ee701..000000000000
--- a/packages/rocketchat-lib/lib/slashCommand.coffee
+++ /dev/null
@@ -1,26 +0,0 @@
-RocketChat.slashCommands =
- commands: {}
-
-RocketChat.slashCommands.add = (command, callback, options, result) ->
- RocketChat.slashCommands.commands[command] =
- command: command
- callback: callback
- params: options?.params
- description: options?.description
- clientOnly: options?.clientOnly or false
- result: result
- return
-
-RocketChat.slashCommands.run = (command, params, item) ->
- if RocketChat.slashCommands.commands[command]?.callback?
- callback = RocketChat.slashCommands.commands[command].callback
- callback command, params, item
-
-
-Meteor.methods
- slashCommand: (command) ->
- if not Meteor.userId()
- throw new Meteor.Error 'error-invalid-user', 'Invalid user', { method: 'slashCommand' }
-
- RocketChat.slashCommands.run command.cmd, command.params, command.msg
-
diff --git a/packages/rocketchat-lib/lib/slashCommand.js b/packages/rocketchat-lib/lib/slashCommand.js
new file mode 100644
index 000000000000..0a07065a15dc
--- /dev/null
+++ b/packages/rocketchat-lib/lib/slashCommand.js
@@ -0,0 +1,31 @@
+RocketChat.slashCommands = {
+ commands: {}
+};
+
+RocketChat.slashCommands.add = function(command, callback, options = {}, result) {
+ RocketChat.slashCommands.commands[command] = {
+ command,
+ callback,
+ params: options.params,
+ description: options.description,
+ clientOnly: options.clientOnly || false,
+ result
+ };
+};
+
+RocketChat.slashCommands.run = function(command, params, item) {
+ if (RocketChat.slashCommands.commands[command] && RocketChat.slashCommands.commands[command].callback) {
+ return RocketChat.slashCommands.commands[command].callback(command, params, item);
+ }
+};
+
+Meteor.methods({
+ slashCommand(command) {
+ if (!Meteor.userId()) {
+ throw new Meteor.Error('error-invalid-user', 'Invalid user', {
+ method: 'slashCommand'
+ });
+ }
+ return RocketChat.slashCommands.run(command.cmd, command.params, command.msg);
+ }
+});
diff --git a/packages/rocketchat-lib/lib/startup/settingsOnLoadSiteUrl.coffee b/packages/rocketchat-lib/lib/startup/settingsOnLoadSiteUrl.coffee
deleted file mode 100644
index 96504f5d73e1..000000000000
--- a/packages/rocketchat-lib/lib/startup/settingsOnLoadSiteUrl.coffee
+++ /dev/null
@@ -1,22 +0,0 @@
-RocketChat.settings.get 'Site_Url', (key, value) ->
- if value?.trim() isnt ''
- host = value.replace(/\/$/, '')
- prefix = ""
- match = value.match(/([^/]+\/{2}[^/]+)(\/.+)/)
- if match?
- host = match[1]
- prefix = match[2].replace(/\/$/, '')
-
- __meteor_runtime_config__.ROOT_URL = host
- # __meteor_runtime_config__.ROOT_URL_PATH_PREFIX = prefix
-
- if Meteor.absoluteUrl.defaultOptions?.rootUrl?
- Meteor.absoluteUrl.defaultOptions.rootUrl = host
-
- if Meteor.isServer
- RocketChat.hostname = host.replace(/^https?:\/\//, '')
-
- process.env.MOBILE_ROOT_URL = host
- process.env.MOBILE_DDP_URL = host
- if WebAppInternals?.generateBoilerplate
- WebAppInternals.generateBoilerplate()
diff --git a/packages/rocketchat-lib/lib/startup/settingsOnLoadSiteUrl.js b/packages/rocketchat-lib/lib/startup/settingsOnLoadSiteUrl.js
new file mode 100644
index 000000000000..17014a7dbe9b
--- /dev/null
+++ b/packages/rocketchat-lib/lib/startup/settingsOnLoadSiteUrl.js
@@ -0,0 +1,26 @@
+/* globals WebAppInternals */
+RocketChat.settings.get('Site_Url', function(key, value) {
+ if (value == null || value.trim() === '') {
+ return;
+ }
+ let host = value.replace(/\/$/, '');
+ // let prefix = '';
+ const match = value.match(/([^\/]+\/{2}[^\/]+)(\/.+)/);
+ if (match != null) {
+ host = match[1];
+ // prefix = match[2].replace(/\/$/, '');
+ }
+ __meteor_runtime_config__.ROOT_URL = host;
+
+ if (Meteor.absoluteUrl.defaultOptions && Meteor.absoluteUrl.defaultOptions.rootUrl) {
+ Meteor.absoluteUrl.defaultOptions.rootUrl = host;
+ }
+ if (Meteor.isServer) {
+ RocketChat.hostname = host.replace(/^https?:\/\//, '');
+ process.env.MOBILE_ROOT_URL = host;
+ process.env.MOBILE_DDP_URL = host;
+ if (typeof WebAppInternals !== 'undefined' && WebAppInternals.generateBoilerplate) {
+ return WebAppInternals.generateBoilerplate();
+ }
+ }
+});
diff --git a/packages/rocketchat-lib/package.js b/packages/rocketchat-lib/package.js
index 750a8bf4ca7e..6e7e7c4022e4 100644
--- a/packages/rocketchat-lib/package.js
+++ b/packages/rocketchat-lib/package.js
@@ -59,14 +59,14 @@ Package.onUse(function(api) {
api.addFiles('lib/placeholders.js');
api.addFiles('lib/promises.coffee');
api.addFiles('lib/roomTypesCommon.coffee');
- api.addFiles('lib/slashCommand.coffee');
- api.addFiles('lib/Message.coffee');
- api.addFiles('lib/MessageTypes.coffee');
+ api.addFiles('lib/slashCommand.js');
+ api.addFiles('lib/Message.js');
+ api.addFiles('lib/MessageTypes.js');
api.addFiles('server/lib/bugsnag.js', 'server');
api.addFiles('server/lib/metrics.js', 'server');
- api.addFiles('server/lib/RateLimiter.coffee', 'server');
+ api.addFiles('server/lib/RateLimiter.js', 'server');
// SERVER FUNCTIONS
api.addFiles('server/functions/isDocker.js', 'server');
@@ -97,7 +97,7 @@ Package.onUse(function(api) {
api.addFiles('server/lib/PushNotification.js', 'server');
api.addFiles('server/lib/defaultBlockedDomainsList.js', 'server');
api.addFiles('server/lib/notifyUsersOnMessage.js', 'server');
- api.addFiles('server/lib/roomTypes.coffee', 'server');
+ api.addFiles('server/lib/roomTypes.js', 'server');
api.addFiles('server/lib/sendEmailOnMessage.js', 'server');
api.addFiles('server/lib/sendNotificationsOnMessage.js', 'server');
api.addFiles('server/lib/validateEmailDomain.js', 'server');
@@ -135,7 +135,7 @@ Package.onUse(function(api) {
api.addFiles('server/methods/cleanChannelHistory.js', 'server');
api.addFiles('server/methods/createChannel.js', 'server');
api.addFiles('server/methods/createPrivateGroup.js', 'server');
- api.addFiles('server/methods/deleteMessage.coffee', 'server');
+ api.addFiles('server/methods/deleteMessage.js', 'server');
api.addFiles('server/methods/deleteUserOwnAccount.js', 'server');
api.addFiles('server/methods/filterBadWords.js', ['server']);
api.addFiles('server/methods/filterATAllTag.js', 'server');
@@ -150,11 +150,11 @@ Package.onUse(function(api) {
api.addFiles('server/methods/leaveRoom.js', 'server');
api.addFiles('server/methods/removeOAuthService.js', 'server');
api.addFiles('server/methods/restartServer.js', 'server');
- api.addFiles('server/methods/robotMethods.coffee', 'server');
+ api.addFiles('server/methods/robotMethods.js', 'server');
api.addFiles('server/methods/saveSetting.js', 'server');
- api.addFiles('server/methods/sendInvitationEmail.coffee', 'server');
+ api.addFiles('server/methods/sendInvitationEmail.js', 'server');
api.addFiles('server/methods/sendMessage.coffee', 'server');
- api.addFiles('server/methods/sendSMTPTestEmail.coffee', 'server');
+ api.addFiles('server/methods/sendSMTPTestEmail.js', 'server');
api.addFiles('server/methods/setAdminStatus.js', 'server');
api.addFiles('server/methods/setRealName.js', 'server');
api.addFiles('server/methods/setUsername.js', 'server');
@@ -170,7 +170,7 @@ Package.onUse(function(api) {
api.addFiles('server/startup/settings.js', 'server');
// COMMON STARTUP
- api.addFiles('lib/startup/settingsOnLoadSiteUrl.coffee');
+ api.addFiles('lib/startup/settingsOnLoadSiteUrl.js');
// CLIENT LIB
api.addFiles('client/Notifications.coffee', 'client');
diff --git a/packages/rocketchat-lib/server/lib/RateLimiter.coffee b/packages/rocketchat-lib/server/lib/RateLimiter.coffee
deleted file mode 100644
index edeb8572f05c..000000000000
--- a/packages/rocketchat-lib/server/lib/RateLimiter.coffee
+++ /dev/null
@@ -1,30 +0,0 @@
-RocketChat.RateLimiter = new class
- limitFunction: (fn, numRequests, timeInterval, matchers) ->
- if process.env.TEST_MODE is 'true'
- return fn
- rateLimiter = new RateLimiter()
- rateLimiter.addRule matchers, numRequests, timeInterval
- return ->
- match = {}
- args = arguments
- _.each matchers, (matcher, key) ->
- match[key] = args[key]
-
- rateLimiter.increment match
- rateLimitResult = rateLimiter.check match
- if rateLimitResult.allowed
- return fn.apply null, arguments
- else
- throw new Meteor.Error 'error-too-many-requests', "Error, too many requests. Please slow down. You must wait #{Math.ceil(rateLimitResult.timeToReset / 1000)} seconds before trying again.", { timeToReset: rateLimitResult.timeToReset, seconds: Math.ceil(rateLimitResult.timeToReset / 1000) }
-
- limitMethod: (methodName, numRequests, timeInterval, matchers) ->
- if process.env.TEST_MODE is 'true'
- return
- match =
- type: 'method'
- name: methodName
-
- _.each matchers, (matcher, key) ->
- match[key] = matchers[key]
-
- DDPRateLimiter.addRule match, numRequests, timeInterval
diff --git a/packages/rocketchat-lib/server/lib/RateLimiter.js b/packages/rocketchat-lib/server/lib/RateLimiter.js
new file mode 100644
index 000000000000..aa0554c8d566
--- /dev/null
+++ b/packages/rocketchat-lib/server/lib/RateLimiter.js
@@ -0,0 +1,41 @@
+/* globals RateLimiter */
+RocketChat.RateLimiter = new class {
+ limitFunction(fn, numRequests, timeInterval, matchers) {
+ if (process.env.TEST_MODE === 'true') {
+ return fn;
+ }
+ const rateLimiter = new RateLimiter();
+ rateLimiter.addRule(matchers, numRequests, timeInterval);
+ return function(...args) {
+ const match = {};
+ _.each(matchers, function(matcher, key) {
+ return match[key] = args[key];
+ });
+ rateLimiter.increment(match);
+ const rateLimitResult = rateLimiter.check(match);
+ if (rateLimitResult.allowed) {
+ return fn.apply(null, arguments);
+ } else {
+ throw new Meteor.Error('error-too-many-requests', `Error, too many requests. Please slow down. You must wait ${ Math.ceil(rateLimitResult.timeToReset / 1000) } seconds before trying again.`, {
+ timeToReset: rateLimitResult.timeToReset,
+ seconds: Math.ceil(rateLimitResult.timeToReset / 1000)
+ });
+ }
+ };
+ }
+
+ limitMethod(methodName, numRequests, timeInterval, matchers) {
+ if (process.env.TEST_MODE === 'true') {
+ return;
+ }
+ const match = {
+ type: 'method',
+ name: methodName
+ };
+ _.each(matchers, function(matcher, key) {
+ return match[key] = matchers[key];
+ });
+ return DDPRateLimiter.addRule(match, numRequests, timeInterval);
+ }
+
+};
diff --git a/packages/rocketchat-lib/server/lib/roomTypes.coffee b/packages/rocketchat-lib/server/lib/roomTypes.coffee
deleted file mode 100644
index db0a3d2f17a3..000000000000
--- a/packages/rocketchat-lib/server/lib/roomTypes.coffee
+++ /dev/null
@@ -1,35 +0,0 @@
-RocketChat.roomTypes = new class roomTypesServer extends roomTypesCommon
- ### add a publish for a room type
- @param roomType: room type (e.g.: c (for channels), d (for direct channels))
- @param callback: function that will return the publish's data
- ###
- setPublish: (roomType, callback) ->
- if @roomTypes[roomType]?.publish?
- throw new Meteor.Error 'route-publish-exists', 'Publish for the given type already exists'
-
- unless @roomTypes[roomType]?
- @roomTypes[roomType] = {}
-
- @roomTypes[roomType].publish = callback
-
- setRoomFind: (roomType, callback) ->
- if @roomTypes[roomType]?.roomFind?
- throw new Meteor.Error 'room-find-exists', 'Room find for the given type already exists'
-
- unless @roomTypes[roomType]?
- @roomTypes[roomType] = {}
-
- @roomTypes[roomType].roomFind = callback
-
- getRoomFind: (roomType) ->
- return unless @roomTypes[roomType]?.roomFind?
- return @roomTypes[roomType].roomFind
-
- ### run the publish for a room type
- @param scope: Meteor publish scope
- @param roomType: room type (e.g.: c (for channels), d (for direct channels))
- @param identifier: identifier of the room
- ###
- runPublish: (scope, roomType, identifier) ->
- return unless @roomTypes[roomType]?.publish?
- return @roomTypes[roomType].publish.call scope, identifier
diff --git a/packages/rocketchat-lib/server/lib/roomTypes.js b/packages/rocketchat-lib/server/lib/roomTypes.js
new file mode 100644
index 000000000000..9f238a89205d
--- /dev/null
+++ b/packages/rocketchat-lib/server/lib/roomTypes.js
@@ -0,0 +1,42 @@
+/* globals roomTypesCommon*/
+RocketChat.roomTypes = new class roomTypesServer extends roomTypesCommon {
+ /* add a publish for a room type
+ @param roomType: room type (e.g.: c (for channels), d (for direct channels))
+ @param callback: function that will return the publish's data
+ */
+
+ setPublish(roomType, callback) {
+ if (this.roomTypes[roomType] && this.roomTypes[roomType].publish != null) {
+ throw new Meteor.Error('route-publish-exists', 'Publish for the given type already exists');
+ }
+ if (this.roomTypes[roomType] == null) {
+ this.roomTypes[roomType] = {};
+ }
+ return this.roomTypes[roomType].publish = callback;
+ }
+
+ setRoomFind(roomType, callback) {
+ if (this.roomTypes[roomType] && this.roomTypes[roomType].roomFind != null) {
+ throw new Meteor.Error('room-find-exists', 'Room find for the given type already exists');
+ }
+ if (this.roomTypes[roomType] == null) {
+ this.roomTypes[roomType] = {};
+ }
+ return this.roomTypes[roomType].roomFind = callback;
+ }
+ getRoomFind(roomType) {
+ return this.roomTypes[roomType] && this.roomTypes[roomType].roomFind;
+ }
+
+
+ /* run the publish for a room type
+ @param scope: Meteor publish scope
+ @param roomType: room type (e.g.: c (for channels), d (for direct channels))
+ @param identifier: identifier of the room
+ */
+
+ runPublish(scope, roomType, identifier) {
+ return this.roomTypes[roomType] && this.roomTypes[roomType].publish && this.roomTypes[roomType].publish.call(scope, identifier);
+ }
+
+};
diff --git a/packages/rocketchat-lib/server/methods/deleteMessage.coffee b/packages/rocketchat-lib/server/methods/deleteMessage.coffee
deleted file mode 100644
index 04ab2e6f5f9b..000000000000
--- a/packages/rocketchat-lib/server/methods/deleteMessage.coffee
+++ /dev/null
@@ -1,30 +0,0 @@
-import moment from 'moment'
-
-Meteor.methods
- deleteMessage: (message) ->
-
- check message, Match.ObjectIncluding({_id:String})
-
- if not Meteor.userId()
- throw new Meteor.Error 'error-invalid-user', 'Invalid user', { method: 'deleteMessage' }
-
- originalMessage = RocketChat.models.Messages.findOneById message._id, {fields: {u: 1, rid: 1, file: 1}}
- if not originalMessage?
- throw new Meteor.Error 'error-action-not-allowed', 'Not allowed', { method: 'deleteMessage', action: 'Delete_message' }
-
- hasPermission = RocketChat.authz.hasPermission(Meteor.userId(), 'delete-message', originalMessage.rid)
- deleteAllowed = RocketChat.settings.get 'Message_AllowDeleting'
-
- deleteOwn = originalMessage?.u?._id is Meteor.userId()
-
- unless hasPermission or (deleteAllowed and deleteOwn)
- throw new Meteor.Error 'error-action-not-allowed', 'Not allowed', { method: 'deleteMessage', action: 'Delete_message' }
-
- blockDeleteInMinutes = RocketChat.settings.get 'Message_AllowDeleting_BlockDeleteInMinutes'
- if blockDeleteInMinutes? and blockDeleteInMinutes isnt 0
- msgTs = moment(originalMessage.ts) if originalMessage.ts?
- currentTsDiff = moment().diff(msgTs, 'minutes') if msgTs?
- if currentTsDiff > blockDeleteInMinutes
- throw new Meteor.Error 'error-message-deleting-blocked', 'Message deleting is blocked', { method: 'deleteMessage' }
-
- RocketChat.deleteMessage(originalMessage, Meteor.user());
diff --git a/packages/rocketchat-lib/server/methods/deleteMessage.js b/packages/rocketchat-lib/server/methods/deleteMessage.js
new file mode 100644
index 000000000000..73dd607fafcf
--- /dev/null
+++ b/packages/rocketchat-lib/server/methods/deleteMessage.js
@@ -0,0 +1,53 @@
+import moment from 'moment';
+
+Meteor.methods({
+ deleteMessage(message) {
+ check(message, Match.ObjectIncluding({
+ _id: String
+ }));
+ if (!Meteor.userId()) {
+ throw new Meteor.Error('error-invalid-user', 'Invalid user', {
+ method: 'deleteMessage'
+ });
+ }
+ const originalMessage = RocketChat.models.Messages.findOneById(message._id, {
+ fields: {
+ u: 1,
+ rid: 1,
+ file: 1
+ }
+ });
+ if (originalMessage == null) {
+ throw new Meteor.Error('error-action-not-allowed', 'Not allowed', {
+ method: 'deleteMessage',
+ action: 'Delete_message'
+ });
+ }
+ const hasPermission = RocketChat.authz.hasPermission(Meteor.userId(), 'delete-message', originalMessage.rid);
+ const deleteAllowed = RocketChat.settings.get('Message_AllowDeleting');
+ const deleteOwn = originalMessage && originalMessage.u && originalMessage.u._id === Meteor.userId();
+ if (!(hasPermission || (deleteAllowed && deleteOwn))) {
+ throw new Meteor.Error('error-action-not-allowed', 'Not allowed', {
+ method: 'deleteMessage',
+ action: 'Delete_message'
+ });
+ }
+ const blockDeleteInMinutes = RocketChat.settings.get('Message_AllowDeleting_BlockDeleteInMinutes');
+ if (blockDeleteInMinutes != null && blockDeleteInMinutes !== 0) {
+ if (originalMessage.ts == null) {
+ return;
+ }
+ const msgTs = moment(originalMessage.ts);
+ if (msgTs == null) {
+ return;
+ }
+ const currentTsDiff = moment().diff(msgTs, 'minutes');
+ if (currentTsDiff > blockDeleteInMinutes) {
+ throw new Meteor.Error('error-message-deleting-blocked', 'Message deleting is blocked', {
+ method: 'deleteMessage'
+ });
+ }
+ }
+ return RocketChat.deleteMessage(originalMessage, Meteor.user());
+ }
+});
diff --git a/packages/rocketchat-lib/server/methods/robotMethods.coffee b/packages/rocketchat-lib/server/methods/robotMethods.coffee
deleted file mode 100644
index 593a915416ab..000000000000
--- a/packages/rocketchat-lib/server/methods/robotMethods.coffee
+++ /dev/null
@@ -1,21 +0,0 @@
-Meteor.methods
- 'robot.modelCall': (model, method, args) ->
-
- check model, String
- check method, String
-
- unless Meteor.userId()
- throw new Meteor.Error 'error-invalid-user', 'Invalid user', { method: 'robot.modelCall' }
-
- unless RocketChat.authz.hasRole Meteor.userId(), 'robot'
- throw new Meteor.Error 'error-not-allowed', 'Not allowed', { method: 'robot.modelCall' }
-
- unless _.isFunction RocketChat.models[model]?[method]
- throw new Meteor.Error 'error-invalid-method', 'Invalid method', { method: 'robot.modelCall' }
-
- call = RocketChat.models[model][method].apply(RocketChat.models[model], args)
-
- if call?.fetch?()?
- return call.fetch()
- else
- return call
diff --git a/packages/rocketchat-lib/server/methods/robotMethods.js b/packages/rocketchat-lib/server/methods/robotMethods.js
new file mode 100644
index 000000000000..e14fbd287b01
--- /dev/null
+++ b/packages/rocketchat-lib/server/methods/robotMethods.js
@@ -0,0 +1,25 @@
+Meteor.methods({
+ 'robot.modelCall'(model, method, args) {
+ check(model, String);
+ check(method, String);
+ if (!Meteor.userId()) {
+ throw new Meteor.Error('error-invalid-user', 'Invalid user', {
+ method: 'robot.modelCall'
+ });
+ }
+ if (!RocketChat.authz.hasRole(Meteor.userId(), 'robot')) {
+ throw new Meteor.Error('error-not-allowed', 'Not allowed', {
+ method: 'robot.modelCall'
+ });
+ }
+ const m = RocketChat.models[model];
+
+ if (!m || !_.isFunction(m[method])) {
+ throw new Meteor.Error('error-invalid-method', 'Invalid method', {
+ method: 'robot.modelCall'
+ });
+ }
+ const cursor = RocketChat.models[model][method].apply(RocketChat.models[model], args);
+ return cursor && cursor.fetch ? cursor.fetch() : cursor;
+ }
+});
diff --git a/packages/rocketchat-lib/server/methods/sendInvitationEmail.coffee b/packages/rocketchat-lib/server/methods/sendInvitationEmail.coffee
deleted file mode 100644
index 16a7f0396ec2..000000000000
--- a/packages/rocketchat-lib/server/methods/sendInvitationEmail.coffee
+++ /dev/null
@@ -1,42 +0,0 @@
-Meteor.methods
- sendInvitationEmail: (emails) ->
-
- check emails, [String]
-
- if not Meteor.userId()
- throw new Meteor.Error 'error-invalid-user', "Invalid user", { method: 'sendInvitationEmail' }
-
- unless RocketChat.authz.hasRole(Meteor.userId(), 'admin')
- throw new Meteor.Error 'error-not-allowed', "Not allowed", { method: 'sendInvitationEmail' }
-
- 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])?)*$/
- validEmails = _.compact _.map emails, (email) -> return email if rfcMailPattern.test email
-
- header = RocketChat.placeholders.replace(RocketChat.settings.get('Email_Header') || "")
- footer = RocketChat.placeholders.replace(RocketChat.settings.get('Email_Footer') || "")
-
- if RocketChat.settings.get('Invitation_Customized')
- subject = RocketChat.settings.get('Invitation_Subject')
- html = RocketChat.settings.get('Invitation_HTML')
- else
- subject = TAPi18n.__('Invitation_Subject_Default', { lng: Meteor.user()?.language || RocketChat.settings.get('language') || 'en' })
- html = TAPi18n.__('Invitation_HTML_Default', { lng: Meteor.user()?.language || RocketChat.settings.get('language') || 'en' })
-
- subject = RocketChat.placeholders.replace(subject);
-
- for email in validEmails
- @unblock()
-
- html = RocketChat.placeholders.replace(html, { email: email });
-
- try
- Email.send
- to: email
- from: RocketChat.settings.get 'From_Email'
- subject: subject
- html: header + html + footer
- catch error
- throw new Meteor.Error 'error-email-send-failed', 'Error trying to send email: ' + error.message, { method: 'sendInvitationEmail', message: error.message }
-
-
- return validEmails
diff --git a/packages/rocketchat-lib/server/methods/sendInvitationEmail.js b/packages/rocketchat-lib/server/methods/sendInvitationEmail.js
new file mode 100644
index 000000000000..bbde68a48f8c
--- /dev/null
+++ b/packages/rocketchat-lib/server/methods/sendInvitationEmail.js
@@ -0,0 +1,60 @@
+
+Meteor.methods({
+ sendInvitationEmail(emails) {
+ check(emails, [String]);
+ if (!Meteor.userId()) {
+ throw new Meteor.Error('error-invalid-user', 'Invalid user', {
+ method: 'sendInvitationEmail'
+ });
+ }
+ if (!RocketChat.authz.hasRole(Meteor.userId(), 'admin')) {
+ throw new Meteor.Error('error-not-allowed', 'Not allowed', {
+ method: 'sendInvitationEmail'
+ });
+ }
+ const 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])?)*$/;
+ const validEmails = _.compact(_.map(emails, function(email) {
+ if (rfcMailPattern.test(email)) {
+ return email;
+ }
+ }));
+ const header = RocketChat.placeholders.replace(RocketChat.settings.get('Email_Header') || '');
+ const footer = RocketChat.placeholders.replace(RocketChat.settings.get('Email_Footer') || '');
+ let html;
+ let subject;
+ const user = Meteor.user();
+ const lng = user.language || RocketChat.settings.get('language') || 'en';
+ if (RocketChat.settings.get('Invitation_Customized')) {
+ subject = RocketChat.settings.get('Invitation_Subject');
+ html = RocketChat.settings.get('Invitation_HTML');
+ } else {
+ subject = TAPi18n.__('Invitation_Subject_Default', {
+ lng
+ });
+ html = TAPi18n.__('Invitation_HTML_Default', {
+ lng
+ });
+ }
+ subject = RocketChat.placeholders.replace(subject);
+ validEmails.forEach(email => {
+ this.unblock();
+ html = RocketChat.placeholders.replace(html, {
+ email
+ });
+ try {
+ Email.send({
+ to: email,
+ from: RocketChat.settings.get('From_Email'),
+ subject,
+ html: header + html + footer
+ });
+ } catch ({message}) {
+ throw new Meteor.Error('error-email-send-failed', `Error trying to send email: ${ message }`, {
+ method: 'sendInvitationEmail',
+ message
+ });
+ }
+ });
+ return validEmails;
+ }
+});
diff --git a/packages/rocketchat-lib/server/methods/sendSMTPTestEmail.coffee b/packages/rocketchat-lib/server/methods/sendSMTPTestEmail.coffee
deleted file mode 100644
index 10759ecdea5f..000000000000
--- a/packages/rocketchat-lib/server/methods/sendSMTPTestEmail.coffee
+++ /dev/null
@@ -1,37 +0,0 @@
-Meteor.methods
- sendSMTPTestEmail: ->
- if not Meteor.userId()
- throw new Meteor.Error 'error-invalid-user', "Invalid user", { method: 'sendSMTPTestEmail' }
-
- user = Meteor.user()
- unless user.emails?[0]?.address
- throw new Meteor.Error 'error-invalid-email', "Invalid email", { method: 'sendSMTPTestEmail' }
-
- this.unblock()
-
- header = RocketChat.placeholders.replace(RocketChat.settings.get('Email_Header') || '');
- footer = RocketChat.placeholders.replace(RocketChat.settings.get('Email_Footer') || '');
-
- console.log 'Sending test email to ' + user.emails[0].address
-
- try
- Email.send
- to: user.emails[0].address
- from: RocketChat.settings.get('From_Email')
- subject: "SMTP Test Email"
- html: header + "
You have successfully sent an email
" + footer - catch error - throw new Meteor.Error 'error-email-send-failed', 'Error trying to send email: ' + error.message, { method: 'sendSMTPTestEmail', message: error.message } - - return { - message: "Your_mail_was_sent_to_s" - params: [user.emails[0].address] - } - -# Limit a user to sending 1 test mail/second -DDPRateLimiter.addRule - type: 'method' - name: 'sendSMTPTestEmail' - userId: (userId) -> - return true -, 1, 1000 diff --git a/packages/rocketchat-lib/server/methods/sendSMTPTestEmail.js b/packages/rocketchat-lib/server/methods/sendSMTPTestEmail.js new file mode 100644 index 000000000000..df861fd6a340 --- /dev/null +++ b/packages/rocketchat-lib/server/methods/sendSMTPTestEmail.js @@ -0,0 +1,44 @@ +Meteor.methods({ + sendSMTPTestEmail() { + if (!Meteor.userId()) { + throw new Meteor.Error('error-invalid-user', 'Invalid user', { + method: 'sendSMTPTestEmail' + }); + } + const user = Meteor.user(); + if (!user.emails && !user.emails[0] && user.emails[0].address) { + throw new Meteor.Error('error-invalid-email', 'Invalid email', { + method: 'sendSMTPTestEmail' + }); + } + this.unblock(); + const header = RocketChat.placeholders.replace(RocketChat.settings.get('Email_Header') || ''); + const footer = RocketChat.placeholders.replace(RocketChat.settings.get('Email_Footer') || ''); + console.log(`Sending test email to ${ user.emails[0].address }`); + try { + Email.send({ + to: user.emails[0].address, + from: RocketChat.settings.get('From_Email'), + subject: 'SMTP Test Email', + html: `${ header }You have successfully sent an email
${ footer }` + }); + } catch ({message}) { + throw new Meteor.Error('error-email-send-failed', `Error trying to send email: ${ message }`, { + method: 'sendSMTPTestEmail', + message + }); + } + return { + message: 'Your_mail_was_sent_to_s', + params: [user.emails[0].address] + }; + } +}); + +DDPRateLimiter.addRule({ + type: 'method', + name: 'sendSMTPTestEmail', + userId() { + return true; + } +}, 1, 1000);