diff --git a/client/startup/unread.js b/client/startup/unread.js index 258bfa418a2d..f124cf6d75d7 100644 --- a/client/startup/unread.js +++ b/client/startup/unread.js @@ -39,7 +39,7 @@ Meteor.startup(function() { } } - if (RoomManager.openedRooms[subscription.t + subscription.name]) { + if (RoomManager.openedRooms[subscription.t + subscription.team + '/' + subscription.name]) { readMessage.refreshUnreadMark(subscription.rid); } } diff --git a/packages/rocketchat-api/server/v1/channels.js b/packages/rocketchat-api/server/v1/channels.js index 5cf1321164ad..efc559da4c53 100644 --- a/packages/rocketchat-api/server/v1/channels.js +++ b/packages/rocketchat-api/server/v1/channels.js @@ -15,7 +15,7 @@ function findChannelByIdOrName({ params, checkedArchived = true, returnUsernames if (params.roomId) { room = RocketChat.models.Rooms.findOneById(params.roomId, { fields }); } else if (params.roomName) { - room = RocketChat.models.Rooms.findOneByName(params.roomName, { fields }); + room = RocketChat.models.Rooms.findOneByName(params.roomName, params.team, { fields }); } if (!room || room.t !== 'c') { diff --git a/packages/rocketchat-api/server/v1/groups.js b/packages/rocketchat-api/server/v1/groups.js index 6e12f4b4d225..627749fd9e66 100644 --- a/packages/rocketchat-api/server/v1/groups.js +++ b/packages/rocketchat-api/server/v1/groups.js @@ -9,8 +9,9 @@ function findPrivateGroupByIdOrName({ params, userId, checkedArchived = true }) let roomSub; if (params.roomId) { roomSub = RocketChat.models.Subscriptions.findOneByRoomIdAndUserId(params.roomId, userId); - } else if (params.roomName) { - roomSub = RocketChat.models.Subscriptions.findOneByRoomNameAndUserId(params.roomName, userId); + } else if (params.roomName && params.team) { + // Add team + roomSub = RocketChat.models.Subscriptions.findOneByRoomNameAndUserId(params.team, params.roomName, userId); } if (!roomSub || roomSub.t !== 'p') { @@ -118,6 +119,10 @@ RocketChat.API.v1.addRoute('groups.create', { authRequired: true }, { return RocketChat.API.v1.failure('Body param "name" is required'); } + if (!this.bodyParams.team) { + return RocketChat.API.v1.failure('Body param "team" is required'); + } + if (this.bodyParams.members && !_.isArray(this.bodyParams.members)) { return RocketChat.API.v1.failure('Body param "members" must be an array if provided'); } @@ -132,8 +137,9 @@ RocketChat.API.v1.addRoute('groups.create', { authRequired: true }, { } let id; + const { name, team, members, customFields } = this.bodyParams; Meteor.runAsUser(this.userId, () => { - id = Meteor.call('createPrivateGroup', this.bodyParams.name, this.bodyParams.members ? this.bodyParams.members : [], readOnly, this.bodyParams.customFields); + id = Meteor.call('createPrivateGroup', name, members || [], readOnly, customFields, { team }); }); return RocketChat.API.v1.success({ diff --git a/packages/rocketchat-api/server/v1/im.js b/packages/rocketchat-api/server/v1/im.js index 4a554f6f585a..7b6a95a770b2 100644 --- a/packages/rocketchat-api/server/v1/im.js +++ b/packages/rocketchat-api/server/v1/im.js @@ -8,7 +8,8 @@ function findDirectMessageRoom(params, user) { const room = RocketChat.getRoomByNameOrIdWithOptionToJoin({ currentUserId: user._id, nameOrId: params.username || params.roomId, - type: 'd' + type: 'd', + team: params.team }); if (!room || room.t !== 'd') { diff --git a/packages/rocketchat-apps/server/bridges/rooms.js b/packages/rocketchat-apps/server/bridges/rooms.js index 85c4b946081e..ddd1366528e7 100644 --- a/packages/rocketchat-apps/server/bridges/rooms.js +++ b/packages/rocketchat-apps/server/bridges/rooms.js @@ -9,6 +9,7 @@ export class AppRoomBridge { console.log(`The App ${ appId } is creating a new room.`, room); const rcRoom = this.orch.getConverters().get('rooms').convertAppRoom(room); + const params = [rcRoom.usernames]; let method; switch (room.type) { @@ -17,6 +18,8 @@ export class AppRoomBridge { break; case RoomType.PRIVATE_GROUP: method = 'createPrivateGroup'; + // params.push(team) + throw new Error('Team not set'); break; default: throw new Error('Only channels and private groups can be created.'); @@ -24,7 +27,7 @@ export class AppRoomBridge { let rid; Meteor.runAsUser(room.creator.id, () => { - const info = Meteor.call(method, rcRoom.usernames); + const info = Meteor.call(method, ...params); rid = info.rid; }); diff --git a/packages/rocketchat-channel-settings/client/startup/trackSettingsChange.js b/packages/rocketchat-channel-settings/client/startup/trackSettingsChange.js index 8df8addd789f..5283d2d78319 100644 --- a/packages/rocketchat-channel-settings/client/startup/trackSettingsChange.js +++ b/packages/rocketchat-channel-settings/client/startup/trackSettingsChange.js @@ -4,11 +4,11 @@ Meteor.startup(function() { if (msg.t === 'room_changed_privacy') { if (Session.get('openedRoom') === msg.rid) { const type = FlowRouter.current().route.name === 'channel' ? 'c' : 'p'; - RoomManager.close(type + FlowRouter.getParam('name')); + RoomManager.close(type + FlowRouter.getParam('team') + '/' + FlowRouter.getParam('name')); const subscription = ChatSubscription.findOne({ rid: msg.rid }); const route = subscription.t === 'c' ? 'channel' : 'group'; - FlowRouter.go(route, { name: subscription.name }, FlowRouter.current().queryParams); + FlowRouter.go(route, { name: subscription.name, team: subscription.team }, FlowRouter.current().queryParams); } } }); @@ -24,7 +24,7 @@ Meteor.startup(function() { if (Session.get('openedRoom') === msg.rid) { const room = ChatRoom.findOne(msg.rid); if (room.name !== FlowRouter.getParam('name')) { - RoomManager.close(room.t + FlowRouter.getParam('name')); + RoomManager.close(room.t + FlowRouter.getParam('team') + '/' + FlowRouter.getParam('name')); RocketChat.roomTypes.openRouteLink(room.t, room, FlowRouter.current().queryParams); } } diff --git a/packages/rocketchat-channel-settings/server/functions/saveRoomName.js b/packages/rocketchat-channel-settings/server/functions/saveRoomName.js index 72d86581f3cb..5654e2fc4417 100644 --- a/packages/rocketchat-channel-settings/server/functions/saveRoomName.js +++ b/packages/rocketchat-channel-settings/server/functions/saveRoomName.js @@ -10,7 +10,7 @@ RocketChat.saveRoomName = function(rid, displayName, user, sendMessage = true) { return; } - const slugifiedRoomName = RocketChat.getValidRoomName(displayName, rid); + const slugifiedRoomName = RocketChat.getValidRoomName(displayName, team, rid); const update = RocketChat.models.Rooms.setNameById(rid, slugifiedRoomName, displayName) && RocketChat.models.Subscriptions.updateNameAndAlertByRoomId(rid, slugifiedRoomName, displayName); diff --git a/packages/rocketchat-error-handler/server/lib/RocketChat.ErrorHandler.js b/packages/rocketchat-error-handler/server/lib/RocketChat.ErrorHandler.js index 276e3c6ddd44..dff10a624c1e 100644 --- a/packages/rocketchat-error-handler/server/lib/RocketChat.ErrorHandler.js +++ b/packages/rocketchat-error-handler/server/lib/RocketChat.ErrorHandler.js @@ -36,9 +36,9 @@ class ErrorHandler { }; } - getRoomId(roomName) { + getRoomId(roomName, team) { roomName = roomName.replace('#'); - const room = RocketChat.models.Rooms.findOneByName(roomName, { fields: { _id: 1, t: 1 } }); + const room = RocketChat.models.Rooms.findOneByName(roomName, team, { fields: { _id: 1, t: 1 } }); if (room && (room.t === 'c' || room.t === 'p')) { return room._id; } else { diff --git a/packages/rocketchat-integrations/server/processWebhookMessage.js b/packages/rocketchat-integrations/server/processWebhookMessage.js index 91b3a85f55ab..d13516d92bfd 100644 --- a/packages/rocketchat-integrations/server/processWebhookMessage.js +++ b/packages/rocketchat-integrations/server/processWebhookMessage.js @@ -4,6 +4,7 @@ import s from 'underscore.string'; this.processWebhookMessage = function(messageObj, user, defaultValues = { channel: '', alias: '', avatar: '', emoji: '' }, mustBeJoined = false) { const sentData = []; const channels = [].concat(messageObj.channel || messageObj.roomId || defaultValues.channel); + const team = messageObj.team; for (const channel of channels) { const channelType = channel[0]; @@ -13,22 +14,22 @@ this.processWebhookMessage = function(messageObj, user, defaultValues = { channe switch (channelType) { case '#': - room = RocketChat.getRoomByNameOrIdWithOptionToJoin({ currentUserId: user._id, nameOrId: channelValue, joinChannel: true }); + room = RocketChat.getRoomByNameOrIdWithOptionToJoin({ currentUserId: user._id, team, nameOrId: channelValue, joinChannel: true }); break; case '@': - room = RocketChat.getRoomByNameOrIdWithOptionToJoin({ currentUserId: user._id, nameOrId: channelValue, type: 'd' }); + room = RocketChat.getRoomByNameOrIdWithOptionToJoin({ currentUserId: user._id, team, nameOrId: channelValue, type: 'd' }); break; default: channelValue = channelType + channelValue; //Try to find the room by id or name if they didn't include the prefix. - room = RocketChat.getRoomByNameOrIdWithOptionToJoin({ currentUserId: user._id, nameOrId: channelValue, joinChannel: true, errorOnEmpty: false }); + room = RocketChat.getRoomByNameOrIdWithOptionToJoin({ currentUserId: user._id, team, nameOrId: channelValue, joinChannel: true, errorOnEmpty: false }); if (room) { break; } //We didn't get a room, let's try finding direct messages - room = RocketChat.getRoomByNameOrIdWithOptionToJoin({ currentUserId: user._id, nameOrId: channelValue, type: 'd', tryDirectByUserIdOnly: true }); + room = RocketChat.getRoomByNameOrIdWithOptionToJoin({ currentUserId: user._id, team, nameOrId: channelValue, type: 'd', tryDirectByUserIdOnly: true }); if (room) { break; } diff --git a/packages/rocketchat-lib/client/lib/cachedCollection.js b/packages/rocketchat-lib/client/lib/cachedCollection.js index ddeaa2888081..b6c045082169 100644 --- a/packages/rocketchat-lib/client/lib/cachedCollection.js +++ b/packages/rocketchat-lib/client/lib/cachedCollection.js @@ -331,7 +331,7 @@ class CachedCollection { this.log('record received', t, record); if (t === 'removed') { this.collection.remove(record._id); - RoomManager.close(record.t+record.name); + RoomManager.close(record.t + record.team + '/' + record.name); } else { delete record.$loki; this.collection.upsert({ _id: record._id }, _.omit(record, '_id')); diff --git a/packages/rocketchat-lib/client/lib/openRoom.js b/packages/rocketchat-lib/client/lib/openRoom.js index 3ca566a57cc4..6c2254643006 100644 --- a/packages/rocketchat-lib/client/lib/openRoom.js +++ b/packages/rocketchat-lib/client/lib/openRoom.js @@ -3,7 +3,7 @@ import _ from 'underscore'; currentTracker = undefined; -function openRoom(type, name) { +function openRoom(type, name, team) { Session.set('openedRoom', null); return Meteor.defer(() => @@ -14,7 +14,7 @@ function openRoom(type, name) { return; } - if (RoomManager.open(type + name).ready() !== true) { + if (RoomManager.open(type + team + '/' + name).ready() !== true) { BlazeLayout.render('main', { modal: RocketChat.Layout.isEmbedded(), center: 'loading' }); return; } @@ -23,13 +23,13 @@ function openRoom(type, name) { } c.stop(); - const room = RocketChat.roomTypes.findRoom(type, name, user); + const room = RocketChat.roomTypes.findRoom(type, team, name, user); if (room == null) { if (type === 'd') { - Meteor.call('createDirectMessage', name, function(err) { + Meteor.call('createDirectMessage', name, team, function(err) { if (!err) { - RoomManager.close(type + name); - return openRoom('d', name); + RoomManager.close(type + team + '/' + name); + return openRoom('d', name, team); } else { Session.set('roomNotFound', {type, name}); BlazeLayout.render('main', {center: 'roomNotFound'}); @@ -44,8 +44,8 @@ function openRoom(type, name) { } else { delete record.$loki; RocketChat.models.Rooms.upsert({ _id: record._id }, _.omit(record, '_id')); - RoomManager.close(type + name); - return openRoom(type, name); + RoomManager.close(type + team + '/' + name); + return openRoom(type, name, team); } }); } @@ -57,7 +57,7 @@ function openRoom(type, name) { for (const child of Array.from(mainNode.children)) { if (child) { mainNode.removeChild(child); } } - const roomDom = RoomManager.getDomOfRoom(type + name, room._id); + const roomDom = RoomManager.getDomOfRoom(type + team + '/' + name, room._id); mainNode.appendChild(roomDom); if (roomDom.classList.contains('room-container')) { roomDom.querySelector('.messages-box > .wrapper').scrollTop = roomDom.oldScrollTop; @@ -70,7 +70,7 @@ function openRoom(type, name) { fireGlobalEvent('room-opened', _.omit(room, 'usernames')); Session.set('editRoomTitle', false); - RoomManager.updateMentionsMarksOfRoom(type + name); + RoomManager.updateMentionsMarksOfRoom(type + team + '/' + name); Meteor.setTimeout(() => readMessage.readNow(), 2000); // KonchatNotification.removeRoomNotification(params._id) // update user's room subscription diff --git a/packages/rocketchat-lib/client/lib/roomTypes.js b/packages/rocketchat-lib/client/lib/roomTypes.js index 101bb0b3f429..ec62341ce0fd 100644 --- a/packages/rocketchat-lib/client/lib/roomTypes.js +++ b/packages/rocketchat-lib/client/lib/roomTypes.js @@ -26,8 +26,8 @@ RocketChat.roomTypes = new class RocketChatRoomTypes extends RoomTypesCommon { getUserStatus(roomType, roomId) { return this.roomTypes[roomType] && typeof this.roomTypes[roomType].getUserStatus === 'function' && this.roomTypes[roomType].getUserStatus(roomId); } - findRoom(roomType, identifier, user) { - return this.roomTypes[roomType] && this.roomTypes[roomType].findRoom(identifier, user); + findRoom(roomType, team, identifier, user) { + return this.roomTypes[roomType] && this.roomTypes[roomType].findRoom(identifier, team, user); } canSendMessage(roomId) { return ChatSubscription.find({ diff --git a/packages/rocketchat-lib/lib/RoomTypesCommon.js b/packages/rocketchat-lib/lib/RoomTypesCommon.js index e7cead3d9dde..8795476887a1 100644 --- a/packages/rocketchat-lib/lib/RoomTypesCommon.js +++ b/packages/rocketchat-lib/lib/RoomTypesCommon.js @@ -66,11 +66,11 @@ export class RoomTypesCommon { if (this.roomTypes[roomType] && this.roomTypes[roomType].route && this.roomTypes[roomType].route.link) { routeData = this.roomTypes[roomType].route.link(subData); } else if (subData && subData.name) { - routeData = { - name: subData.name - }; + routeData = { name: subData.name }; } + routeData.team = subData.team; + return FlowRouter.path(this.roomTypes[roomType].route.name, routeData); } diff --git a/packages/rocketchat-lib/lib/getValidRoomName.js b/packages/rocketchat-lib/lib/getValidRoomName.js index eb85ab9bc663..cfb37e8054e7 100644 --- a/packages/rocketchat-lib/lib/getValidRoomName.js +++ b/packages/rocketchat-lib/lib/getValidRoomName.js @@ -1,10 +1,10 @@ import s from 'underscore.string'; -RocketChat.getValidRoomName = function getValidRoomName(displayName, rid = '') { +RocketChat.getValidRoomName = function getValidRoomName(displayName, team, rid = '') { let slugifiedName = displayName; if (RocketChat.settings.get('UI_Allow_room_names_with_special_chars')) { - const room = RocketChat.models.Rooms.findOneByDisplayName(displayName); + const room = RocketChat.models.Rooms.findOneByDisplayName(displayName, team); if (room && room._id !== rid) { if (room.archived) { throw new Meteor.Error('error-archived-duplicate-name', `There's an archived channel with name ${ displayName }`, { function: 'RocketChat.getValidRoomName', channel_name: displayName }); @@ -28,7 +28,7 @@ RocketChat.getValidRoomName = function getValidRoomName(displayName, rid = '') { }); } - const room = RocketChat.models.Rooms.findOneByName(slugifiedName); + const room = RocketChat.models.Rooms.findOneByName(slugifiedName, team); if (room && room._id !== rid) { if (RocketChat.settings.get('UI_Allow_room_names_with_special_chars')) { let tmpName = slugifiedName; diff --git a/packages/rocketchat-lib/lib/roomTypes/direct.js b/packages/rocketchat-lib/lib/roomTypes/direct.js index 44078e0e9190..62a748d7afc9 100644 --- a/packages/rocketchat-lib/lib/roomTypes/direct.js +++ b/packages/rocketchat-lib/lib/roomTypes/direct.js @@ -5,12 +5,12 @@ export class DirectMessageRoomRoute extends RoomTypeRouteConfig { constructor() { super({ name: 'direct', - path: '/direct/:username' + path: '/:team/direct/:username' }); } action(params) { - return openRoom('d', params.username); + return openRoom('d', params.username, params.team); } link(sub) { @@ -28,10 +28,11 @@ export class DirectMessageRoomType extends RoomTypeConfig { }); } - findRoom(identifier) { + findRoom(identifier, team) { const query = { t: 'd', - name: identifier + name: identifier, + team }; const subscription = ChatSubscription.findOne(query); diff --git a/packages/rocketchat-lib/lib/roomTypes/private.js b/packages/rocketchat-lib/lib/roomTypes/private.js index 5522d95a8110..1834ea881cca 100644 --- a/packages/rocketchat-lib/lib/roomTypes/private.js +++ b/packages/rocketchat-lib/lib/roomTypes/private.js @@ -5,12 +5,12 @@ export class PrivateRoomRoute extends RoomTypeRouteConfig { constructor() { super({ name: 'group', - path: '/group/:name' + path: '/:team/group/:name' }); } action(params) { - return openRoom('p', params.name); + return openRoom('p', params.name, params.team); } } @@ -25,10 +25,11 @@ export class PrivateRoomType extends RoomTypeConfig { }); } - findRoom(identifier) { + findRoom(identifier, team) { const query = { t: 'p', - name: identifier + name: identifier, + team }; return ChatRoom.findOne(query); diff --git a/packages/rocketchat-lib/lib/roomTypes/public.js b/packages/rocketchat-lib/lib/roomTypes/public.js index fb9c9e277ad3..c5ab3a48bbb2 100644 --- a/packages/rocketchat-lib/lib/roomTypes/public.js +++ b/packages/rocketchat-lib/lib/roomTypes/public.js @@ -5,12 +5,12 @@ export class PublicRoomRoute extends RoomTypeRouteConfig { constructor() { super({ name: 'channel', - path: '/channel/:name' + path: '/:team/channel/:name' }); } action(params) { - return openRoom('c', params.name); + return openRoom('c', params.name, params.team); } } @@ -25,10 +25,11 @@ export class PublicRoomType extends RoomTypeConfig { }); } - findRoom(identifier) { + findRoom(identifier, team) { const query = { t: 'c', - name: identifier + name: identifier, + team }; return ChatRoom.findOne(query); } diff --git a/packages/rocketchat-lib/server/functions/createRoom.js b/packages/rocketchat-lib/server/functions/createRoom.js index 386680e6b797..8eefe2144a0a 100644 --- a/packages/rocketchat-lib/server/functions/createRoom.js +++ b/packages/rocketchat-lib/server/functions/createRoom.js @@ -16,7 +16,7 @@ RocketChat.createRoom = function(type, name, owner, members, readOnly, extraData throw new Meteor.Error('error-invalid-user', 'Invalid user', { function: 'RocketChat.createRoom' }); } - const slugifiedRoomName = RocketChat.getValidRoomName(name); + const slugifiedRoomName = RocketChat.getValidRoomName(name, extraData.team); const now = new Date(); if (!_.contains(members, owner.username)) { diff --git a/packages/rocketchat-lib/server/functions/getRoomByNameOrIdWithOptionToJoin.js b/packages/rocketchat-lib/server/functions/getRoomByNameOrIdWithOptionToJoin.js index 17aa5c6d7dad..86492b4dd4f4 100644 --- a/packages/rocketchat-lib/server/functions/getRoomByNameOrIdWithOptionToJoin.js +++ b/packages/rocketchat-lib/server/functions/getRoomByNameOrIdWithOptionToJoin.js @@ -1,7 +1,7 @@ /* globals RocketChat */ import _ from 'underscore'; -RocketChat.getRoomByNameOrIdWithOptionToJoin = function _getRoomByNameOrIdWithOptionToJoin({ currentUserId, nameOrId, type='', tryDirectByUserIdOnly=false, joinChannel=true, errorOnEmpty=true }) { +RocketChat.getRoomByNameOrIdWithOptionToJoin = function _getRoomByNameOrIdWithOptionToJoin({ currentUserId, nameOrId, team, type='', tryDirectByUserIdOnly=false, joinChannel=true, errorOnEmpty=true }) { let room; //If the nameOrId starts with #, then let's try to find a channel or group @@ -37,7 +37,7 @@ RocketChat.getRoomByNameOrIdWithOptionToJoin = function _getRoomByNameOrIdWithOp } room = Meteor.runAsUser(currentUserId, function() { - const {rid} = Meteor.call('createDirectMessage', roomUser.username); + const {rid} = Meteor.call('createDirectMessage', roomUser.username, team); return RocketChat.models.Rooms.findOneById(rid); }); } diff --git a/packages/rocketchat-lib/server/models/Messages.js b/packages/rocketchat-lib/server/models/Messages.js index 2bb631520ddb..cfca02114aa1 100644 --- a/packages/rocketchat-lib/server/models/Messages.js +++ b/packages/rocketchat-lib/server/models/Messages.js @@ -6,7 +6,7 @@ RocketChat.models.Messages = new class extends RocketChat.models._Base { this.tryEnsureIndex({ 'rid': 1, 'ts': 1 }); this.tryEnsureIndex({ 'ts': 1 }); - this.tryEnsureIndex({ 'u._id': 1 }); + this.tryEnsureIndex({ 'u._id': 1, 'team': 1 }); this.tryEnsureIndex({ 'editedAt': 1 }, { sparse: 1 }); this.tryEnsureIndex({ 'editedBy._id': 1 }, { sparse: 1 }); this.tryEnsureIndex({ 'rid': 1, 't': 1, 'u._id': 1 }); diff --git a/packages/rocketchat-lib/server/models/Rooms.js b/packages/rocketchat-lib/server/models/Rooms.js index cc7806c8e152..52d51f6beb50 100644 --- a/packages/rocketchat-lib/server/models/Rooms.js +++ b/packages/rocketchat-lib/server/models/Rooms.js @@ -5,7 +5,7 @@ class ModelRooms extends RocketChat.models._Base { constructor() { super(...arguments); - this.tryEnsureIndex({ 'name': 1 }, { unique: 1, sparse: 1 }); + this.tryEnsureIndex({ 'name': 1, team: 1 }, { unique: 1, sparse: 1 }); this.tryEnsureIndex({ 'default': 1 }); this.tryEnsureIndex({ 'usernames': 1 }); this.tryEnsureIndex({ 't': 1 }); @@ -34,8 +34,8 @@ class ModelRooms extends RocketChat.models._Base { return this.findOne(query, options); } - findOneByName(name, options) { - const query = {name}; + findOneByName(name, team, options) { + const query = {name, team}; return this.findOne(query, options); } @@ -49,8 +49,8 @@ class ModelRooms extends RocketChat.models._Base { return this.findOne(query); } - findOneByDisplayName(fname, options) { - const query = {fname}; + findOneByDisplayName(fname, team, options) { + const query = {fname, team}; return this.findOne(query, options); } diff --git a/packages/rocketchat-lib/server/models/Subscriptions.js b/packages/rocketchat-lib/server/models/Subscriptions.js index 9e585150bf01..bf25d7c0532f 100644 --- a/packages/rocketchat-lib/server/models/Subscriptions.js +++ b/packages/rocketchat-lib/server/models/Subscriptions.js @@ -8,7 +8,7 @@ class ModelSubscriptions extends RocketChat.models._Base { this.tryEnsureIndex({ 'rid': 1, 'alert': 1, 'u._id': 1 }); this.tryEnsureIndex({ 'rid': 1, 'roles': 1 }); this.tryEnsureIndex({ 'u._id': 1, 'name': 1, 't': 1 }); - this.tryEnsureIndex({ 'u._id': 1, 'name': 1, 't': 1, 'code': 1 }, { unique: 1 }); + this.tryEnsureIndex({ 'u._id': 1, 'name': 1, 't': 1, 'code': 1, 'team': 1 }, { unique: 1 }); this.tryEnsureIndex({ 'open': 1 }); this.tryEnsureIndex({ 'alert': 1 }); this.tryEnsureIndex({ 'unread': 1 }); @@ -25,7 +25,7 @@ class ModelSubscriptions extends RocketChat.models._Base { this.cache.ensureIndex('u._id', 'array'); this.cache.ensureIndex('name', 'array'); this.cache.ensureIndex(['rid', 'u._id'], 'unique'); - this.cache.ensureIndex(['name', 'u._id'], 'unique'); + this.cache.ensureIndex(['name', 'team', 'u._id'], 'unique'); } @@ -42,12 +42,13 @@ class ModelSubscriptions extends RocketChat.models._Base { return this.findOne(query, options); } - findOneByRoomNameAndUserId(roomName, userId) { + findOneByRoomNameAndUserId(team, roomName, userId) { if (this.useCache) { - return this.cache.findByIndex('name,u._id', [roomName, userId]).fetch(); + return this.cache.findByIndex('name,team,u._id', [team, roomName, userId]).fetch(); } const query = { name: roomName, + team, 'u._id': userId }; @@ -599,7 +600,8 @@ class ModelSubscriptions extends RocketChat.models._Base { _id: user._id, username: user.username, name: user.name - } + }, + team: room.team }; _.extend(subscription, extraData); diff --git a/packages/rocketchat-livechat/.app/client/lib/fromApp/RoomHistoryManager.js b/packages/rocketchat-livechat/.app/client/lib/fromApp/RoomHistoryManager.js index 2d6ab8f92441..4f07bbabca77 100644 --- a/packages/rocketchat-livechat/.app/client/lib/fromApp/RoomHistoryManager.js +++ b/packages/rocketchat-livechat/.app/client/lib/fromApp/RoomHistoryManager.js @@ -150,10 +150,12 @@ export const RoomHistoryManager = new class { const subscription = ChatSubscription.findOne({rid: message.rid}); if (subscription) { // const { ls } = subscription; - typeName = subscription.t + subscription.name; + typeName = subscription.t + subscription.team + '/' + subscription.name; } else { const curRoomDoc = ChatRoom.findOne({_id: message.rid}); - typeName = (curRoomDoc != null ? curRoomDoc.t : undefined) + (curRoomDoc != null ? curRoomDoc.name : undefined); + if(curRoomDoc != null) { + typeName = curRoomDoc.t + curRoomDoc.team + '/' + curRoomDoc.name; + } } return Meteor.call('loadSurroundingMessages', message, limit, function(err, result) { diff --git a/packages/rocketchat-message-mark-as-unread/client/actionButton.js b/packages/rocketchat-message-mark-as-unread/client/actionButton.js index 41c63ef328dd..2e9a8af9dd47 100644 --- a/packages/rocketchat-message-mark-as-unread/client/actionButton.js +++ b/packages/rocketchat-message-mark-as-unread/client/actionButton.js @@ -16,7 +16,7 @@ Meteor.startup(() => { if (subscription == null) { return; } - RoomManager.close(subscription.t + subscription.name); + RoomManager.close(subscription.t + subscription.team + '/' + subscription.name); return FlowRouter.go('home'); }); }, diff --git a/packages/rocketchat-ui-flextab/client/tabs/userActions.js b/packages/rocketchat-ui-flextab/client/tabs/userActions.js index 6f79c1c68d10..cad540201a5a 100644 --- a/packages/rocketchat-ui-flextab/client/tabs/userActions.js +++ b/packages/rocketchat-ui-flextab/client/tabs/userActions.js @@ -93,7 +93,7 @@ export const getActions = function({ user, directActions, hideAdminControls }) { icon: 'message', name: t('Conversation'), action: prevent(getUser, ({username}) => - Meteor.call('createDirectMessage', username, success(result => result.rid && FlowRouter.go('direct', { username }, FlowRouter.current().queryParams))) + Meteor.call('createDirectMessage', username, FlowRouter.getParam('team'), success(result => result.rid && FlowRouter.go('direct', { username, team: FlowRouter.getParam('team') }, FlowRouter.current().queryParams))) ), condition() { return (directActions && canDirectMessage(this.username)); diff --git a/packages/rocketchat-ui-sidenav/client/listPrivateGroupsFlex.js b/packages/rocketchat-ui-sidenav/client/listPrivateGroupsFlex.js index 6c81377dd7a8..f11e7e798e46 100644 --- a/packages/rocketchat-ui-sidenav/client/listPrivateGroupsFlex.js +++ b/packages/rocketchat-ui-sidenav/client/listPrivateGroupsFlex.js @@ -66,12 +66,18 @@ Template.listPrivateGroupsFlex.onCreated(function() { } } - this.groups.set(RocketChat.models.Subscriptions.find({ + const query = { name: new RegExp(s.trim(s.escapeRegExp(this.nameFilter.get())), 'i'), t: 'p', archived: { $ne: true } - }, options).fetch() - ); + }; + const team = FlowRouter.getParam('team'); + + if(team) { + query.team = team; + } + + this.groups.set(RocketChat.models.Subscriptions.find(query, options).fetch()); if (this.groups.get().length < this.limit.get()) { return this.hasMore.set(false); } diff --git a/packages/rocketchat-ui-sidenav/client/roomList.js b/packages/rocketchat-ui-sidenav/client/roomList.js index c3786e929be6..b543d683e5f4 100644 --- a/packages/rocketchat-ui-sidenav/client/roomList.js +++ b/packages/rocketchat-ui-sidenav/client/roomList.js @@ -82,6 +82,12 @@ Template.roomList.helpers({ }; }), 'lm').reverse(); } + + const team = FlowRouter.getParam('team'); + if(team) { + query.team = team; + } + return ChatSubscription.find(query, {sort}); }, diff --git a/packages/rocketchat-ui/client/lib/RoomHistoryManager.js b/packages/rocketchat-ui/client/lib/RoomHistoryManager.js index 6be9d25efcf5..b81ec5bf7ee9 100644 --- a/packages/rocketchat-ui/client/lib/RoomHistoryManager.js +++ b/packages/rocketchat-ui/client/lib/RoomHistoryManager.js @@ -183,10 +183,12 @@ export const RoomHistoryManager = new class { const subscription = ChatSubscription.findOne({rid: message.rid}); if (subscription) { // const { ls } = subscription; - typeName = subscription.t + subscription.name; + typeName = subscription.t + subscription.team + '/' + subscription.name; } else { const curRoomDoc = ChatRoom.findOne({_id: message.rid}); - typeName = (curRoomDoc != null ? curRoomDoc.t : undefined) + (curRoomDoc != null ? curRoomDoc.name : undefined); + if (curRoomDoc) { + typeName = curRoomDoc.t + curRoomDoc.team + '/' + curRoomDoc.name; + } } return Meteor.call('loadSurroundingMessages', message, limit, function(err, result) { diff --git a/packages/rocketchat-ui/client/lib/RoomManager.js b/packages/rocketchat-ui/client/lib/RoomManager.js index c50521198617..b38f3e4479d7 100644 --- a/packages/rocketchat-ui/client/lib/RoomManager.js +++ b/packages/rocketchat-ui/client/lib/RoomManager.js @@ -19,10 +19,11 @@ const RoomManager = new function() { const user = Meteor.user(); const type = typeName.substr(0, 1); - const name = typeName.substr(1); + const team = typeName.substr(1).split('/')[0]; + const name = typeName.substr(1).split('/')[1]; const room = Tracker.nonreactive(() => { - return RocketChat.roomTypes.findRoom(type, name, user); + return RocketChat.roomTypes.findRoom(type, team, name, user); }); if (room != null) { diff --git a/packages/rocketchat-ui/client/lib/readMessages.js b/packages/rocketchat-ui/client/lib/readMessages.js index e03ee4afbc63..9cbbe6999143 100644 --- a/packages/rocketchat-ui/client/lib/readMessages.js +++ b/packages/rocketchat-ui/client/lib/readMessages.js @@ -120,7 +120,7 @@ const readMessage = new class { return; } - const room = RoomManager.openedRooms[subscription.t + subscription.name]; + const room = RoomManager.openedRooms[subscription.t + subscription.team + '/' + subscription.name]; if (room == null) { return; } diff --git a/packages/rocketchat-ui/client/views/app/popover.js b/packages/rocketchat-ui/client/views/app/popover.js index 1a04ec3171cb..ebeec7b4f800 100644 --- a/packages/rocketchat-ui/client/views/app/popover.js +++ b/packages/rocketchat-ui/client/views/app/popover.js @@ -199,7 +199,7 @@ Template.popover.events({ if (subscription == null) { return; } - RoomManager.close(subscription.t + subscription.name); + RoomManager.close(subscription.t + subscription.team + '/' + subscription.name); FlowRouter.go('home'); }); diff --git a/server/methods/createDirectMessage.js b/server/methods/createDirectMessage.js index 95b8d634c965..3ee01f703071 100644 --- a/server/methods/createDirectMessage.js +++ b/server/methods/createDirectMessage.js @@ -1,6 +1,9 @@ Meteor.methods({ - createDirectMessage(username) { + createDirectMessage(username, team) { check(username, String); + check(team, String); + + // TODO add security to only send team based private messages when both users are on the provided team if (!Meteor.userId()) { throw new Meteor.Error('error-invalid-user', 'Invalid user', { @@ -36,7 +39,7 @@ Meteor.methods({ }); } - const rid = [me._id, to._id].sort().join(''); + const rid = [me._id, to._id].sort().join('') + '_' + team; const now = new Date(); @@ -50,7 +53,8 @@ Meteor.methods({ $setOnInsert: { t: 'd', msgs: 0, - ts: now + ts: now, + team } }); @@ -72,7 +76,8 @@ Meteor.methods({ u: { _id: me._id, username: me.username - } + }, + team } }; @@ -101,7 +106,8 @@ Meteor.methods({ u: { _id: to._id, username: to.username - } + }, + team } }); diff --git a/server/publications/room.js b/server/publications/room.js index 9dfe5637f707..6e0b7cdd224e 100644 --- a/server/publications/room.js +++ b/server/publications/room.js @@ -18,6 +18,7 @@ const fields = { default: 1, customFields: 1, lastMessage: 1, + team: 1, // @TODO create an API to register this fields based on room type livechatData: 1, diff --git a/server/publications/subscription.js b/server/publications/subscription.js index 2b00302f00fa..4a0971d2a7ff 100644 --- a/server/publications/subscription.js +++ b/server/publications/subscription.js @@ -28,7 +28,8 @@ const fields = { autoTranslate: 1, autoTranslateLanguage: 1, disableNotifications: 1, - hideUnreadStatus: 1 + hideUnreadStatus: 1, + team: 1 }; Meteor.methods({ diff --git a/server/startup/initialData.js b/server/startup/initialData.js index f3f4badf77f0..3a17e7037714 100644 --- a/server/startup/initialData.js +++ b/server/startup/initialData.js @@ -2,13 +2,13 @@ import _ from 'underscore'; Meteor.startup(function() { Meteor.defer(function() { - if (!RocketChat.models.Rooms.findOneById('GENERAL')) { + if (process.env.GENERAL_CHANNEL && !RocketChat.models.Rooms.findOneById('GENERAL')) { RocketChat.models.Rooms.createWithIdTypeAndName('GENERAL', 'c', 'general', { 'default': true }); } - if (!RocketChat.models.Users.db.findOneById('rocket.cat')) { + if (process.env.ROCKET_CAT && !RocketChat.models.Users.db.findOneById('rocket.cat')) { RocketChat.models.Users.create({ _id: 'rocket.cat', name: 'Rocket.Cat',