Skip to content
2 changes: 1 addition & 1 deletion app/api/server/v1/channels.js
Original file line number Diff line number Diff line change
Expand Up @@ -248,7 +248,7 @@ API.v1.addRoute('channels.create', { authRequired: true }, {
const teamMembers = [];

for (const team of teams) {
const { records: members } = Promise.await(Team.members(this.userId, team._id, undefined, canSeeAllTeams, { offset: 0, count: Number.MAX_SAFE_INTEGER }));
const { records: members } = Promise.await(Team.members(this.userId, team._id, canSeeAllTeams, { offset: 0, count: Number.MAX_SAFE_INTEGER }));
const uids = members.map((member) => member.user.username);
teamMembers.push(...uids);
}
Expand Down
127 changes: 88 additions & 39 deletions app/api/server/v1/teams.ts
Original file line number Diff line number Diff line change
Expand Up @@ -68,43 +68,58 @@ API.v1.addRoute('teams.create', { authRequired: true }, {

API.v1.addRoute('teams.addRoom', { authRequired: true }, {
post() {
const { roomId, teamId, isDefault } = this.bodyParams;
const { roomId, teamId, teamName, isDefault } = this.bodyParams;

if (!hasPermission(this.userId, 'add-team-channel')) {
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, teamId, isDefault));
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 } = this.bodyParams;
const { rooms, teamId, teamName } = 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')) {
if (!hasPermission(this.userId, 'add-team-channel', team.roomId)) {
return API.v1.unauthorized();
}

const validRooms = Promise.await(Team.addRooms(this.userId, rooms, teamId));
const validRooms = Promise.await(Team.addRooms(this.userId, rooms, team._id));

return API.v1.success({ rooms: validRooms });
},
});

API.v1.addRoute('teams.removeRoom', { authRequired: true }, {
post() {
const { roomId, teamId } = this.bodyParams;
const { roomId, teamId, teamName } = this.bodyParams;

if (!hasPermission(this.userId, 'remove-team-channel')) {
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, 'remove-team-channel', team.roomId)) {
return API.v1.unauthorized();
}

const canRemoveAny = !!hasPermission(this.userId, 'view-all-team-channels');
const canRemoveAny = !!hasPermission(this.userId, 'view-all-team-channels', team.roomId);

const room = Promise.await(Team.removeRoom(this.userId, roomId, teamId, canRemoveAny));
const room = Promise.await(Team.removeRoom(this.userId, roomId, team._id, canRemoveAny));

return API.v1.success({ room });
},
Expand All @@ -114,10 +129,12 @@ API.v1.addRoute('teams.updateRoom', { authRequired: true }, {
post() {
const { roomId, isDefault } = this.bodyParams;

if (!hasPermission(this.userId, 'edit-team-channel')) {
const team = Promise.await(Team.getOneByRoomId(roomId));

if (!hasPermission(this.userId, 'edit-team-channel', team.roomId)) {
return API.v1.unauthorized();
}
const canUpdateAny = !!hasPermission(this.userId, 'view-all-team-channels');
const canUpdateAny = !!hasPermission(this.userId, 'view-all-team-channels', team.roomId);

const room = Promise.await(Team.updateRoom(this.userId, roomId, isDefault, canUpdateAny));

Expand All @@ -127,18 +144,23 @@ API.v1.addRoute('teams.updateRoom', { authRequired: true }, {

API.v1.addRoute('teams.listRooms', { authRequired: true }, {
get() {
const { teamId } = this.queryParams;
const { teamId, teamName } = this.queryParams;
const { offset, count } = this.getPaginationItems();
const { query } = this.parseJsonQuery();

const allowPrivateTeam = hasPermission(this.userId, 'view-all-teams');
const team = teamId ? Promise.await(Team.getOneById(teamId)) : Promise.await(Team.getOneByName(teamName));
if (!team) {
return API.v1.failure('team-does-not-exist');
}

const allowPrivateTeam = hasPermission(this.userId, 'view-all-teams', team.roomId);

let getAllRooms = false;
if (hasPermission(this.userId, 'view-all-team-channels')) {
if (hasPermission(this.userId, 'view-all-team-channels', team.roomId)) {
getAllRooms = true;
}

const { records, total } = Promise.await(Team.listRooms(this.userId, teamId, getAllRooms, allowPrivateTeam, { offset, count }, { query }));
const { records, total } = Promise.await(Team.listRooms(this.userId, team._id, getAllRooms, allowPrivateTeam, { offset, count }, { query }));

return API.v1.success({
rooms: records,
Expand All @@ -152,15 +174,20 @@ API.v1.addRoute('teams.listRooms', { authRequired: true }, {
API.v1.addRoute('teams.listRoomsOfUser', { authRequired: true }, {
get() {
const { offset, count } = this.getPaginationItems();
const { teamId, userId } = this.queryParams;
const { teamId, teamName, userId } = this.queryParams;

const team = teamId ? Promise.await(Team.getOneById(teamId)) : Promise.await(Team.getOneByName(teamName));
if (!team) {
return API.v1.failure('team-does-not-exist');
}

const allowPrivateTeam = hasPermission(this.userId, 'view-all-teams');
const allowPrivateTeam = hasPermission(this.userId, 'view-all-teams', team.roomId);

if (!hasPermission(this.userId, 'view-all-team-channels')) {
if (!hasPermission(this.userId, 'view-all-team-channels', team.roomId)) {
return API.v1.unauthorized();
}

const { records, total } = Promise.await(Team.listRoomsOfUser(this.userId, teamId, userId, allowPrivateTeam, { offset, count }));
const { records, total } = Promise.await(Team.listRoomsOfUser(this.userId, team._id, userId, allowPrivateTeam, { offset, count }));

return API.v1.success({
rooms: records,
Expand All @@ -176,9 +203,14 @@ API.v1.addRoute('teams.members', { authRequired: true }, {
const { offset, count } = this.getPaginationItems();
const { teamId, teamName } = this.queryParams;
const { query } = this.parseJsonQuery();
const canSeeAllMembers = hasPermission(this.userId, 'view-all-teams');

const { records, total } = Promise.await(Team.members(this.userId, teamId, teamName, canSeeAllMembers, { offset, count }, { query }));
const team = teamId ? Promise.await(Team.getOneById(teamId)) : Promise.await(Team.getOneByName(teamName));
if (!team) {
return API.v1.failure('team-does-not-exist');
}
const canSeeAllMembers = hasPermission(this.userId, 'view-all-teams', team.roomId);

const { records, total } = Promise.await(Team.members(this.userId, team._id, canSeeAllMembers, { offset, count }, { query }));

return API.v1.success({
members: records,
Expand All @@ -191,41 +223,56 @@ API.v1.addRoute('teams.members', { authRequired: true }, {

API.v1.addRoute('teams.addMembers', { authRequired: true }, {
post() {
if (!hasAtLeastOnePermission(this.userId, ['add-team-member', 'edit-team-member'])) {
return API.v1.unauthorized();
const { teamId, teamName, members } = 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');
}

const { teamId, teamName, members } = this.bodyParams;
if (!hasAtLeastOnePermission(this.userId, ['add-team-member', 'edit-team-member'], team.roomId)) {
return API.v1.unauthorized();
}

Promise.await(Team.addMembers(this.userId, teamId, teamName, members));
Promise.await(Team.addMembers(this.userId, team._id, members));

return API.v1.success();
},
});

API.v1.addRoute('teams.updateMember', { authRequired: true }, {
post() {
if (!hasAtLeastOnePermission(this.userId, ['edit-team-member'])) {
return API.v1.unauthorized();
const { teamId, teamName, member } = 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');
}

const { teamId, teamName, member } = this.bodyParams;
if (!hasAtLeastOnePermission(this.userId, ['edit-team-member'], team.roomId)) {
return API.v1.unauthorized();
}

Promise.await(Team.updateMember(teamId, teamName, member));
Promise.await(Team.updateMember(team._id, member));

return API.v1.success();
},
});

API.v1.addRoute('teams.removeMembers', { authRequired: true }, {
post() {
if (!hasAtLeastOnePermission(this.userId, ['edit-team-member'])) {
return API.v1.unauthorized();
const { teamId, teamName, members, rooms } = 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');
}

const { teamId, teamName, members, rooms } = this.bodyParams;
if (!hasAtLeastOnePermission(this.userId, ['edit-team-member'], team.roomId)) {
return API.v1.unauthorized();
}

Promise.await(Team.removeMembers(teamId, teamName, members));
Promise.await(Team.removeMembers(team._id, members));

if (rooms?.length) {
Subscriptions.removeByRoomIdsAndUserId(rooms, this.userId);
Expand All @@ -239,7 +286,9 @@ API.v1.addRoute('teams.leave', { authRequired: true }, {
post() {
const { teamId, teamName, rooms } = this.bodyParams;

Promise.await(Team.removeMembers(teamId, teamName, [{
const team = teamId ? Promise.await(Team.getOneById(teamId)) : Promise.await(Team.getOneByName(teamName));

Promise.await(Team.removeMembers(team._id, [{
userId: this.userId,
}]));

Expand Down Expand Up @@ -273,10 +322,6 @@ API.v1.addRoute('teams.info', { authRequired: true }, {

API.v1.addRoute('teams.delete', { authRequired: true }, {
post() {
if (!hasPermission(this.userId, 'delete-team')) {
return API.v1.unauthorized();
}

const { teamId, teamName, roomsToRemove } = this.bodyParams;

if (!teamId && !teamName) {
Expand All @@ -292,6 +337,10 @@ API.v1.addRoute('teams.delete', { authRequired: true }, {
return API.v1.failure('Team not found.');
}

if (!hasPermission(this.userId, 'delete-team', team.roomId)) {
return API.v1.unauthorized();
}

const rooms: string[] = Promise.await(Team.getMatchingTeamRooms(team._id, roomsToRemove));

// Remove the team's main room
Expand Down
2 changes: 1 addition & 1 deletion server/methods/addRoomLeader.js
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,7 @@ Meteor.methods({
role: 'leader',
});

const team = Promise.await(Team.getOneByRoomId(rid));
const team = Promise.await(Team.getOneByMainRoomId(rid));
if (team) {
Promise.await(Team.addRolesToMember(team._id, userId, ['leader']));
}
Expand Down
2 changes: 1 addition & 1 deletion server/methods/addRoomModerator.js
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,7 @@ Meteor.methods({
role: 'moderator',
});

const team = Promise.await(Team.getOneByRoomId(rid));
const team = Promise.await(Team.getOneByMainRoomId(rid));
if (team) {
Promise.await(Team.addRolesToMember(team._id, userId, ['moderator']));
}
Expand Down
2 changes: 1 addition & 1 deletion server/methods/addRoomOwner.js
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,7 @@ Meteor.methods({
role: 'owner',
});

const team = Promise.await(Team.getOneByRoomId(rid));
const team = Promise.await(Team.getOneByMainRoomId(rid));
if (team) {
Promise.await(Team.addRolesToMember(team._id, userId, ['owner']));
}
Expand Down
2 changes: 1 addition & 1 deletion server/methods/removeRoomLeader.js
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,7 @@ Meteor.methods({
role: 'leader',
});

const team = Promise.await(Team.getOneByRoomId(rid));
const team = Promise.await(Team.getOneByMainRoomId(rid));
if (team) {
Promise.await(Team.removeRolesFromMember(team._id, userId, ['leader']));
}
Expand Down
2 changes: 1 addition & 1 deletion server/methods/removeRoomModerator.js
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,7 @@ Meteor.methods({
role: 'moderator',
});

const team = Promise.await(Team.getOneByRoomId(rid));
const team = Promise.await(Team.getOneByMainRoomId(rid));
if (team) {
Promise.await(Team.removeRolesFromMember(team._id, userId, ['moderator']));
}
Expand Down
2 changes: 1 addition & 1 deletion server/methods/removeRoomOwner.js
Original file line number Diff line number Diff line change
Expand Up @@ -65,7 +65,7 @@ Meteor.methods({
role: 'owner',
});

const team = Promise.await(Team.getOneByRoomId(rid));
const team = Promise.await(Team.getOneByMainRoomId(rid));
if (team) {
Promise.await(Team.removeRolesFromMember(team._id, userId, ['owner']));
}
Expand Down
12 changes: 7 additions & 5 deletions server/sdk/types/ITeamService.ts
Original file line number Diff line number Diff line change
Expand Up @@ -53,17 +53,19 @@ export interface ITeamService {
listByNames(names: Array<string>, options?: FindOneOptions<ITeam>): Promise<Array<ITeam>>;
listByIds(ids: Array<string>, options?: FindOneOptions<ITeam>): Promise<ITeam[]>;
search(userId: string, term: string | RegExp, options?: FindOneOptions<ITeam>): Promise<ITeam[]>;
members(uid: string, teamId: string, teamName: string, canSeeAll: boolean, options?: IPaginationOptions, queryOptions?: IQueryOptions<ITeamMember>): Promise<IRecordsWithTotal<ITeamMemberInfo>>;
addMembers(uid: string, teamId: string, teamName: string, members: Array<ITeamMemberParams>): Promise<void>;
updateMember(teamId: string, teamName: string, members: ITeamMemberParams): Promise<void>;
removeMembers(teamId: string, teamName: string, members: Array<ITeamMemberParams>): Promise<void>;
members(uid: string, teamId: string, canSeeAll: boolean, options?: IPaginationOptions, queryOptions?: IQueryOptions<ITeamMember>): Promise<IRecordsWithTotal<ITeamMemberInfo>>;
addMembers(uid: string, teamId: string, members: Array<ITeamMemberParams>): Promise<void>;
updateMember(teamId: string, members: ITeamMemberParams): Promise<void>;
removeMembers(teamId: string, members: Array<ITeamMemberParams>): Promise<void>;
getInfoByName(teamName: string): Promise<Partial<ITeam> | undefined>;
getInfoById(teamId: string): Promise<Partial<ITeam> | undefined>;
deleteById(teamId: string): Promise<boolean>;
deleteByName(teamName: string): Promise<boolean>;
unsetTeamIdOfRooms(teamId: string): void;
getOneById(teamId: string, options?: FindOneOptions<ITeam>): Promise<ITeam | undefined>;
getOneByName(teamName: string): Promise<ITeam | null>;
getOneByName(teamName: string, options?: FindOneOptions<ITeam>): Promise<ITeam | null>;
getOneByMainRoomId(teamId: string): Promise<ITeam | null>;
getOneByRoomId(teamId: string): Promise<ITeam | undefined>;
getMatchingTeamRooms(teamId: string, rids: Array<string>): Promise<Array<string>>;
autocomplete(uid: string, name: string): Promise<Array<IRoom>>;
}
Loading