diff --git a/apps/meteor/app/api/server/v1/teams.ts b/apps/meteor/app/api/server/v1/teams.ts index 0403418db6a5b..6d570ae49b0f2 100644 --- a/apps/meteor/app/api/server/v1/teams.ts +++ b/apps/meteor/app/api/server/v1/teams.ts @@ -15,8 +15,8 @@ import type { ITeam } from '@rocket.chat/core-typings'; import { TEAM_TYPE } from '@rocket.chat/core-typings'; import { removeUserFromRoom } from '../../../lib/server/functions/removeUserFromRoom'; -import { Users } from '../../../models/server'; -import { hasAtLeastOnePermission, hasPermission } from '../../../authorization/server'; +import { Rooms, Users } from '../../../models/server'; +import { canAccessRoom, hasAtLeastOnePermission, hasPermission } from '../../../authorization/server'; import { Team } from '../../../../server/sdk'; import { API } from '../api'; @@ -576,6 +576,18 @@ API.v1.addRoute( return API.v1.failure('Team not found'); } + const room = Rooms.findOneById(teamInfo.roomId); + + if (!room) { + return API.v1.failure('Room not found'); + } + + const canViewInfo = canAccessRoom(room, { _id: this.userId }) || hasPermission(this.userId, 'view-all-teams'); + + if (!canViewInfo) { + return API.v1.unauthorized(); + } + return API.v1.success({ teamInfo }); }, }, diff --git a/apps/meteor/tests/end-to-end/api/25-teams.js b/apps/meteor/tests/end-to-end/api/25-teams.js index dd4419432ddb3..49bdc86af6bc0 100644 --- a/apps/meteor/tests/end-to-end/api/25-teams.js +++ b/apps/meteor/tests/end-to-end/api/25-teams.js @@ -819,6 +819,77 @@ describe('[Teams]', () => { }); }); + describe('/teams.info', () => { + it('should successfully get a team info by name', (done) => { + request + .get(api('teams.info')) + .set(credentials) + .query({ + teamName: publicTeam.name, + }) + .expect('Content-Type', 'application/json') + .expect(200) + .expect((response) => { + expect(response.body).to.have.property('success', true); + expect(response.body).to.have.property('teamInfo'); + expect(response.body.teamInfo).to.have.property('_id', publicTeam._id); + expect(response.body.teamInfo).to.have.property('name', publicTeam.name); + }) + .then(() => done()) + .catch(done); + }); + it('should successfully get a team info by id', (done) => { + request + .get(api('teams.info')) + .set(credentials) + .query({ + teamId: publicTeam._id, + }) + .expect('Content-Type', 'application/json') + .expect(200) + .expect((response) => { + expect(response.body).to.have.property('success', true); + expect(response.body).to.have.property('teamInfo'); + expect(response.body.teamInfo).to.have.property('_id', publicTeam._id); + expect(response.body.teamInfo).to.have.property('name', publicTeam.name); + }) + .then(() => done()) + .catch(done); + }); + it('should fail if a team is not found', (done) => { + request + .get(api('teams.info')) + .set(credentials) + .query({ + teamName: '', + }) + .expect('Content-Type', 'application/json') + .expect(400) + .expect((response) => { + expect(response.body).to.have.property('success', false); + expect(response.body).to.have.property('error', 'Team not found'); + }) + .then(() => done()) + .catch(done); + }); + it('should fail if a user doesnt belong to a team', (done) => { + request + .get(api('teams.info')) + .set(testUserCredentials) + .query({ + teamName: privateTeam.name, + }) + .expect('Content-Type', 'application/json') + .expect(403) + .expect((response) => { + expect(response.body).to.have.property('success', false); + expect(response.body).to.have.property('error', 'unauthorized'); + }) + .then(() => done()) + .catch(done); + }); + }); + describe('/teams.delete', () => { describe('deleting an empty team', () => { let roomId;