diff --git a/app/api/server/v1/teams.ts b/app/api/server/v1/teams.ts index 4245ca218f2c9..31fcd1f106ff7 100644 --- a/app/api/server/v1/teams.ts +++ b/app/api/server/v1/teams.ts @@ -66,25 +66,6 @@ API.v1.addRoute('teams.create', { authRequired: true }, { }, }); -API.v1.addRoute('teams.addRoom', { authRequired: true }, { - post() { - const { roomId, teamId, teamName, isDefault } = this.bodyParams; - - const team = teamId ? Promise.await(Team.getOneById(teamId)) : Promise.await(Team.getOneByName(teamName)); - if (!team) { - return API.v1.failure('team-does-not-exist'); - } - - if (!hasPermission(this.userId, 'add-team-channel', team.roomId)) { - return API.v1.unauthorized(); - } - - const room = Promise.await(Team.addRoom(this.userId, roomId, team._id, isDefault)); - - return API.v1.success({ room }); - }, -}); - API.v1.addRoute('teams.addRooms', { authRequired: true }, { post() { const { rooms, teamId, teamName } = this.bodyParams; diff --git a/client/views/room/contextualBar/Info/RoomInfo/RoomInfo.js b/client/views/room/contextualBar/Info/RoomInfo/RoomInfo.js index 116ec42ae34be..e2e610261772f 100644 --- a/client/views/room/contextualBar/Info/RoomInfo/RoomInfo.js +++ b/client/views/room/contextualBar/Info/RoomInfo/RoomInfo.js @@ -224,7 +224,7 @@ const RoomInfoWithData = ({ const leaveRoom = useMethod('leaveRoom'); const router = useRoute('home'); - const moveChannelToTeam = useEndpointActionExperimental('POST', 'teams.addRoom', t('Success')); + const moveChannelToTeam = useEndpointActionExperimental('POST', 'teams.addRooms', t('Success')); const convertRoomToTeam = useEndpointActionExperimental( 'POST', type === 'c' ? 'channels.convertToTeam' : 'groups.convertToTeam', @@ -303,7 +303,7 @@ const RoomInfoWithData = ({ const onMoveToTeam = useMutableCallback(async () => { const onConfirm = async (teamId) => { try { - await moveChannelToTeam({ roomId: rid, teamId }); + await moveChannelToTeam({ rooms: [rid], teamId }); } catch (error) { dispatchToastMessage({ type: 'error', message: error }); } finally { diff --git a/server/sdk/types/ITeamService.ts b/server/sdk/types/ITeamService.ts index 8d9711c7e5200..007e6e2dca3cb 100644 --- a/server/sdk/types/ITeamService.ts +++ b/server/sdk/types/ITeamService.ts @@ -42,7 +42,6 @@ export interface ITeamInfo extends ITeam { export interface ITeamService { create(uid: string, params: ITeamCreateParams): Promise; - addRoom(uid: string, rid: string, teamId: string, isDefault: boolean): Promise; addRooms(uid: string, rooms: Array, teamId: string): Promise>; removeRoom(uid: string, rid: string, teamId: string, canRemoveAnyRoom: boolean): Promise; listRooms(uid: string, teamId: string, getAllRooms: boolean, allowPrivateTeam: boolean, pagination: IPaginationOptions, queryOptions: IQueryOptions): Promise>; diff --git a/server/services/team/service.ts b/server/services/team/service.ts index b6db3fc3aa8ac..fe771d67f30c5 100644 --- a/server/services/team/service.ts +++ b/server/services/team/service.ts @@ -242,41 +242,6 @@ export class TeamService extends ServiceClass implements ITeamService { return this.TeamModel.findByIds(ids, options).toArray(); } - async addRoom(uid: string, rid: string, teamId: string, isDefault = false): Promise { - if (!teamId) { - throw new Error('missing-teamId'); - } - if (!rid) { - throw new Error('missing-roomId'); - } - if (!uid) { - throw new Error('missing-userId'); - } - // at this point, we already checked for the permission - // so we just need to check if the user can see the room - const room = await this.RoomsModel.findOneById(rid); - const user = await this.Users.findOneById(uid); - const canSeeRoom = await canAccessRoom(room, user); - if (!canSeeRoom) { - throw new Error('invalid-room'); - } - - const team = await this.TeamModel.findOneById(teamId, { projection: { _id: 1 } }); - if (!team) { - throw new Error('invalid-team'); - } - if (room.teamId) { - throw new Error('room-already-on-team'); - } - - room.teamId = teamId; - room.teamDefault = !!isDefault; - this.RoomsModel.setTeamById(room._id, teamId, isDefault); - return { - ...room, - }; - } - async addRooms(uid: string, rooms: Array, teamId: string): Promise> { if (!teamId) { throw new Error('missing-teamId'); diff --git a/tests/end-to-end/api/25-teams.js b/tests/end-to-end/api/25-teams.js index 75c792ef59d46..5e3b6e7d87c9d 100644 --- a/tests/end-to-end/api/25-teams.js +++ b/tests/end-to-end/api/25-teams.js @@ -12,6 +12,7 @@ describe('[Teams]', () => { let publicRoom = null; let publicRoom2 = null; let privateRoom = null; + let privateRoom2 = null; let testUser; let testUser2; @@ -117,335 +118,6 @@ describe('[Teams]', () => { }); }); - describe('/teams.addRoom', () => { - before('create private channel', (done) => { - const channelName = `community-channel-private${ Date.now() }`; - request.post(api('groups.create')) - .set(credentials) - .send({ - name: channelName, - }) - .expect('Content-Type', 'application/json') - .expect(200) - .expect((res) => { - expect(res.body).to.have.property('success', true); - expect(res.body).to.have.nested.property('group._id'); - expect(res.body).to.have.nested.property('group.name', channelName); - expect(res.body).to.have.nested.property('group.t', 'p'); - expect(res.body).to.have.nested.property('group.msgs', 0); - privateRoom = res.body.group; - }) - .end(done); - }); - before('create public channel', (done) => { - const channelName = `community-channel-public${ Date.now() }`; - request.post(api('channels.create')) - .set(credentials) - .send({ - name: channelName, - }) - .expect('Content-Type', 'application/json') - .expect(200) - .expect((res) => { - expect(res.body).to.have.property('success', true); - expect(res.body).to.have.nested.property('channel._id'); - expect(res.body).to.have.nested.property('channel.name', channelName); - expect(res.body).to.have.nested.property('channel.t', 'c'); - expect(res.body).to.have.nested.property('channel.msgs', 0); - publicRoom = res.body.channel; - }) - .end(done); - }); - before('create another public channel', (done) => { - const channelName = `community-channel-public${ Date.now() }`; - request.post(api('channels.create')) - .set(credentials) - .send({ - name: `${ channelName }2`, - }) - .expect('Content-Type', 'application/json') - .expect(200) - .expect((res) => { - expect(res.body).to.have.property('success', true); - expect(res.body).to.have.nested.property('channel._id'); - expect(res.body).to.have.nested.property('channel.name', `${ channelName }2`); - expect(res.body).to.have.nested.property('channel.t', 'c'); - expect(res.body).to.have.nested.property('channel.msgs', 0); - publicRoom2 = res.body.channel; - }) - .end(done); - }); - - it('should throw an error if no permission', (done) => { - updatePermission('add-team-channel', []).then(() => { - request.post(api('teams.addRoom')) - .set(credentials) - .send({ - roomId: publicRoom._id, - teamId: publicTeam._id, - }) - .expect('Content-Type', 'application/json') - .expect(403) - .expect((res) => { - expect(res.body).to.have.property('success', false); - expect(res.body).to.have.property('error'); - expect(res.body.error).to.be.equal('unauthorized'); - }) - .end(done); - }); - }); - - it('should add public room to team', (done) => { - updatePermission('add-team-channel', ['admin']).then(() => { - request.post(api('teams.addRoom')) - .set(credentials) - .send({ - roomId: publicRoom._id, - teamId: publicTeam._id, - }) - .expect('Content-Type', 'application/json') - .expect(200) - .expect((res) => { - expect(res.body).to.have.property('success', true); - expect(res.body).to.have.property('room'); - expect(res.body.room).to.have.property('teamId', publicTeam._id); - expect(res.body.room).to.have.property('teamDefault', false); - }) - .end(done); - }); - }); - - it('should add another public room to private team', (done) => { - updatePermission('add-team-channel', ['admin']).then(() => { - request.post(api('teams.addRoom')) - .set(credentials) - .send({ - roomId: publicRoom2._id, - teamId: privateTeam._id, - }) - .expect('Content-Type', 'application/json') - .expect(200) - .expect((res) => { - expect(res.body).to.have.property('success', true); - expect(res.body).to.have.property('room'); - expect(res.body.room).to.have.property('teamId', privateTeam._id); - expect(res.body.room).to.have.property('teamDefault', false); - }) - .end(done); - }); - }); - - it('should add private room to team', (done) => { - updatePermission('add-team-channel', ['admin']).then(() => { - request.post(api('teams.addRoom')) - .set(credentials) - .send({ - roomId: privateRoom._id, - teamId: publicTeam._id, - }) - .expect('Content-Type', 'application/json') - .expect(200) - .expect((res) => { - expect(res.body).to.have.property('success', true); - expect(res.body).to.have.property('room'); - expect(res.body.room).to.have.property('teamId', publicTeam._id); - expect(res.body.room).to.have.property('teamDefault', false); - }) - .end(done); - }); - }); - }); - - describe('/teams.updateRoom', () => { - it('should throw an error if no permission', (done) => { - updatePermission('edit-team-channel', []).then(() => { - request.post(api('teams.updateRoom')) - .set(credentials) - .send({ - roomId: publicRoom._id, - isDefault: true, - }) - .expect('Content-Type', 'application/json') - .expect(403) - .expect((res) => { - expect(res.body).to.have.property('success', false); - expect(res.body).to.have.property('error'); - expect(res.body.error).to.be.equal('unauthorized'); - }) - .end(done); - }); - }); - - it('should set room to team default', (done) => { - updatePermission('edit-team-channel', ['admin']).then(() => { - request.post(api('teams.updateRoom')) - .set(credentials) - .send({ - roomId: publicRoom._id, - isDefault: true, - }) - .expect('Content-Type', 'application/json') - .expect(200) - .expect((res) => { - expect(res.body).to.have.property('success', true); - expect(res.body).to.have.property('room'); - expect(res.body.room).to.have.property('teamId', publicTeam._id); - expect(res.body.room).to.have.property('teamDefault', true); - }) - .end(done); - }); - }); - }); - - describe('/teams.listRooms', () => { - let testUser; - let testUserCredentials; - before('Create test user', (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: username }) - .end((err, res) => { - testUser = res.body.user; - done(); - }); - }); - before('Login as test user', (done) => { - request.post(api('login')) - .send({ - user: testUser.username, - password: testUser.username, - }) - .expect('Content-Type', 'application/json') - .expect(200) - .expect((res) => { - testUserCredentials = {}; - testUserCredentials['X-Auth-Token'] = res.body.data.authToken; - testUserCredentials['X-User-Id'] = res.body.data.userId; - }) - .end(done); - }); - it('should throw an error if team is private and no permission', (done) => { - updatePermission('view-all-teams', []).then(() => { - request.get(api('teams.listRooms')) - .set(testUserCredentials) - .query({ - teamId: privateTeam._id, - }) - .expect('Content-Type', 'application/json') - .expect(400) - .expect((res) => { - expect(res.body).to.have.property('success', false); - expect(res.body).to.have.property('error'); - expect(res.body.error).to.be.equal('user-not-on-private-team'); - }) - .end(done); - }); - }); - - it('should return only public rooms for public team', (done) => { - updatePermission('view-all-team-channels', []).then(() => { - request.get(api('teams.listRooms')) - .set(testUserCredentials) - .query({ - teamId: publicTeam._id, - }) - .expect('Content-Type', 'application/json') - .expect(200) - .expect((res) => { - expect(res.body).to.have.property('success', true); - expect(res.body).to.have.property('rooms'); - expect(res.body.rooms).to.be.an('array'); - // main room should not be returned here - expect(res.body.rooms.length).to.equal(1); - }) - .end(done); - }); - }); - - it('should return all rooms for public team', (done) => { - updatePermission('view-all-team-channels', ['user']).then(() => { - request.get(api('teams.listRooms')) - .set(testUserCredentials) - .query({ - teamId: publicTeam._id, - }) - .expect('Content-Type', 'application/json') - .expect(200) - .expect((res) => { - expect(res.body).to.have.property('success', true); - expect(res.body).to.have.property('rooms'); - expect(res.body.rooms).to.be.an('array'); - expect(res.body.rooms.length).to.equal(2); - }) - .end(done); - }); - }); - - it('should return public rooms for private team', (done) => { - updatePermission('view-all-team-channels', []).then(() => { - updatePermission('view-all-teams', ['admin']).then(() => { - request.get(api('teams.listRooms')) - .set(credentials) - .query({ - teamId: privateTeam._id, - }) - .expect('Content-Type', 'application/json') - .expect(200) - .expect((res) => { - expect(res.body).to.have.property('success', true); - expect(res.body).to.have.property('rooms'); - expect(res.body.rooms).to.be.an('array'); - expect(res.body.rooms.length).to.equal(1); - }) - .end(done); - }); - }); - }); - }); - - describe('/teams.removeRoom', () => { - it('should throw an error if no permission', (done) => { - updatePermission('remove-team-channel', []).then(() => { - request.post(api('teams.removeRoom')) - .set(credentials) - .send({ - roomId: publicRoom._id, - teamId: publicTeam._id, - }) - .expect('Content-Type', 'application/json') - .expect(403) - .expect((res) => { - expect(res.body).to.have.property('success', false); - expect(res.body).to.have.property('error'); - expect(res.body.error).to.be.equal('unauthorized'); - }) - .end(done); - }); - }); - - it('should remove room from team', (done) => { - updatePermission('remove-team-channel', ['admin']).then(() => { - request.post(api('teams.removeRoom')) - .set(credentials) - .send({ - roomId: publicRoom._id, - teamId: publicTeam._id, - }) - .expect('Content-Type', 'application/json') - .expect(200) - .expect((res) => { - expect(res.body).to.have.property('success', true); - expect(res.body).to.have.property('room'); - expect(res.body.room).to.not.have.property('teamId'); - expect(res.body.room).to.not.have.property('teamDefault'); - }) - .end(done); - }); - }); - }); - describe('/teams.addMembers', () => { let testTeam; before('Create test team', (done) => { @@ -976,19 +648,19 @@ describe('[Teams]', () => { }); before('add channel 1 to team', (done) => { - request.post(api('teams.addRoom')) + request.post(api('teams.addRooms')) .set(credentials) .send({ - roomId: channel1Id, + rooms: [channel1Id], teamId, }) .expect('Content-Type', 'application/json') .expect(200) .expect((res) => { expect(res.body).to.have.property('success', true); - expect(res.body).to.have.property('room'); - expect(res.body.room).to.have.property('teamId', teamId); - expect(res.body.room).to.have.property('teamDefault', false); + expect(res.body).to.have.property('rooms'); + expect(res.body.rooms[0]).to.have.property('teamId', teamId); + expect(res.body.rooms[0]).to.not.have.property('teamDefault'); }) .then(() => done()); }); @@ -1013,19 +685,19 @@ describe('[Teams]', () => { }); before('add channel 2 to team', (done) => { - request.post(api('teams.addRoom')) + request.post(api('teams.addRooms')) .set(credentials) .send({ - roomId: channel2Id, + rooms: [channel2Id], teamId, }) .expect('Content-Type', 'application/json') .expect(200) .expect((res) => { expect(res.body).to.have.property('success', true); - expect(res.body).to.have.property('room'); - expect(res.body.room).to.have.property('teamId', teamId); - expect(res.body.room).to.have.property('teamDefault', false); + expect(res.body).to.have.property('rooms'); + expect(res.body.rooms[0]).to.have.property('teamId', teamId); + expect(res.body.rooms[0]).to.not.have.property('teamDefault'); }) .then(() => done()); }); @@ -1097,6 +769,25 @@ describe('[Teams]', () => { }) .end(done); }); + before('create another private channel', (done) => { + const channelName = `community-channel-private${ Date.now() }`; + request.post(api('groups.create')) + .set(credentials) + .send({ + name: channelName, + }) + .expect('Content-Type', 'application/json') + .expect(200) + .expect((res) => { + expect(res.body).to.have.property('success', true); + expect(res.body).to.have.nested.property('group._id'); + expect(res.body).to.have.nested.property('group.name', channelName); + expect(res.body).to.have.nested.property('group.t', 'p'); + expect(res.body).to.have.nested.property('group.msgs', 0); + privateRoom2 = res.body.group; + }) + .end(done); + }); before('create public channel', (done) => { const channelName = `community-channel-public${ Date.now() }`; request.post(api('channels.create')) @@ -1160,7 +851,7 @@ describe('[Teams]', () => { request.post(api('teams.addRooms')) .set(credentials) .send({ - rooms: [publicRoom._id, publicRoom2._id, privateRoom._id], + rooms: [publicRoom._id, privateRoom._id], teamId: publicTeam._id, }) .expect('Content-Type', 'application/json') @@ -1168,21 +859,249 @@ describe('[Teams]', () => { .expect((res) => { expect(res.body).to.have.property('success', true); expect(res.body).to.have.property('rooms'); - expect(res.body.rooms).to.have.length(3); + expect(res.body.rooms).to.have.length(2); expect(res.body.rooms[0]).to.have.property('_id'); expect(res.body.rooms[0]).to.have.property('teamId', publicTeam._id); expect(res.body.rooms[1]).to.have.property('_id'); expect(res.body.rooms[1]).to.have.property('teamId', publicTeam._id); - expect(res.body.rooms[2]).to.have.property('_id'); - expect(res.body.rooms[2]).to.have.property('teamId', publicTeam._id); + const rids = res.body.rooms.map(({ _id }) => _id); expect(rids).to.include(publicRoom._id); - expect(rids).to.include(publicRoom2._id); expect(rids).to.include(privateRoom._id); }) .end(done); }); }); + + it('should add public room to private team', (done) => { + updatePermission('add-team-channel', ['admin']).then(() => { + request.post(api('teams.addRooms')) + .set(credentials) + .send({ + rooms: [publicRoom2._id], + teamId: privateTeam._id, + }) + .expect('Content-Type', 'application/json') + .expect(200) + .expect((res) => { + expect(res.body).to.have.property('success', true); + expect(res.body).to.have.property('rooms'); + expect(res.body.rooms[0]).to.have.property('teamId', privateTeam._id); + expect(res.body.rooms[0]).to.not.have.property('teamDefault'); + }) + .end(done); + }); + }); + + it('should add private room to team', (done) => { + updatePermission('add-team-channel', ['admin']).then(() => { + request.post(api('teams.addRooms')) + .set(credentials) + .send({ + rooms: [privateRoom2._id], + teamId: privateTeam._id, + }) + .expect('Content-Type', 'application/json') + .expect(200) + .expect((res) => { + expect(res.body).to.have.property('success', true); + expect(res.body).to.have.property('rooms'); + expect(res.body.rooms[0]).to.have.property('teamId', privateTeam._id); + expect(res.body.rooms[0]).to.not.have.property('teamDefault'); + }) + .end(done); + }); + }); + }); + + describe('/teams.listRooms', () => { + let testUser; + let testUserCredentials; + before('Create test user', (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: username }) + .end((err, res) => { + testUser = res.body.user; + done(); + }); + }); + before('Login as test user', (done) => { + request.post(api('login')) + .send({ + user: testUser.username, + password: testUser.username, + }) + .expect('Content-Type', 'application/json') + .expect(200) + .expect((res) => { + testUserCredentials = {}; + testUserCredentials['X-Auth-Token'] = res.body.data.authToken; + testUserCredentials['X-User-Id'] = res.body.data.userId; + }) + .end(done); + }); + it('should throw an error if team is private and no permission', (done) => { + updatePermission('view-all-teams', []).then(() => { + request.get(api('teams.listRooms')) + .set(testUserCredentials) + .query({ + teamId: privateTeam._id, + }) + .expect('Content-Type', 'application/json') + .expect(400) + .expect((res) => { + expect(res.body).to.have.property('success', false); + expect(res.body).to.have.property('error'); + expect(res.body.error).to.be.equal('user-not-on-private-team'); + }) + .end(done); + }); + }); + + it('should return only public rooms for public team', (done) => { + updatePermission('view-all-team-channels', []).then(() => { + request.get(api('teams.listRooms')) + .set(testUserCredentials) + .query({ + teamId: publicTeam._id, + }) + .expect('Content-Type', 'application/json') + .expect(200) + .expect((res) => { + expect(res.body).to.have.property('success', true); + expect(res.body).to.have.property('rooms'); + expect(res.body.rooms).to.be.an('array'); + // main room should not be returned here + expect(res.body.rooms.length).to.equal(1); + }) + .end(done); + }); + }); + + it('should return all rooms for public team', (done) => { + updatePermission('view-all-team-channels', ['user']).then(() => { + request.get(api('teams.listRooms')) + .set(testUserCredentials) + .query({ + teamId: publicTeam._id, + }) + .expect('Content-Type', 'application/json') + .expect(200) + .expect((res) => { + expect(res.body).to.have.property('success', true); + expect(res.body).to.have.property('rooms'); + expect(res.body.rooms).to.be.an('array'); + expect(res.body.rooms.length).to.equal(2); + }) + .end(done); + }); + }); + + it('should return public rooms for private team', (done) => { + updatePermission('view-all-team-channels', []).then(() => { + updatePermission('view-all-teams', ['admin']).then(() => { + request.get(api('teams.listRooms')) + .set(credentials) + .query({ + teamId: privateTeam._id, + }) + .expect('Content-Type', 'application/json') + .expect(200) + .expect((res) => { + expect(res.body).to.have.property('success', true); + expect(res.body).to.have.property('rooms'); + expect(res.body.rooms).to.be.an('array'); + expect(res.body.rooms.length).to.equal(2); + }) + .end(done); + }); + }); + }); + }); + + describe('/teams.updateRoom', () => { + it('should throw an error if no permission', (done) => { + updatePermission('edit-team-channel', []).then(() => { + request.post(api('teams.updateRoom')) + .set(credentials) + .send({ + roomId: publicRoom._id, + isDefault: true, + }) + .expect('Content-Type', 'application/json') + .expect(403) + .expect((res) => { + expect(res.body).to.have.property('success', false); + expect(res.body).to.have.property('error'); + expect(res.body.error).to.be.equal('unauthorized'); + }) + .end(done); + }); + }); + + it('should set room to team default', (done) => { + updatePermission('edit-team-channel', ['admin']).then(() => { + request.post(api('teams.updateRoom')) + .set(credentials) + .send({ + roomId: publicRoom._id, + isDefault: true, + }) + .expect('Content-Type', 'application/json') + .expect(200) + .expect((res) => { + expect(res.body).to.have.property('success', true); + expect(res.body).to.have.property('room'); + expect(res.body.room).to.have.property('teamId', publicTeam._id); + expect(res.body.room).to.have.property('teamDefault', true); + }) + .end(done); + }); + }); + }); + + describe('/teams.removeRoom', () => { + it('should throw an error if no permission', (done) => { + updatePermission('remove-team-channel', []).then(() => { + request.post(api('teams.removeRoom')) + .set(credentials) + .send({ + roomId: publicRoom._id, + teamId: publicTeam._id, + }) + .expect('Content-Type', 'application/json') + .expect(403) + .expect((res) => { + expect(res.body).to.have.property('success', false); + expect(res.body).to.have.property('error'); + expect(res.body.error).to.be.equal('unauthorized'); + }) + .end(done); + }); + }); + + it('should remove room from team', (done) => { + updatePermission('remove-team-channel', ['admin']).then(() => { + request.post(api('teams.removeRoom')) + .set(credentials) + .send({ + roomId: publicRoom._id, + teamId: publicTeam._id, + }) + .expect('Content-Type', 'application/json') + .expect(200) + .expect((res) => { + expect(res.body).to.have.property('success', true); + expect(res.body).to.have.property('room'); + expect(res.body.room).to.not.have.property('teamId'); + expect(res.body.room).to.not.have.property('teamDefault'); + }) + .end(done); + }); + }); }); });