Skip to content

Commit

Permalink
fix: org admin can change team lead (#9742)
Browse files Browse the repository at this point in the history
  • Loading branch information
nickoferrall committed May 8, 2024
1 parent 162de5e commit d5520ae
Show file tree
Hide file tree
Showing 3 changed files with 29 additions and 18 deletions.
12 changes: 7 additions & 5 deletions packages/server/graphql/mutations/archiveTeam.ts
Expand Up @@ -6,7 +6,7 @@ import NotificationTeamArchived from '../../database/types/NotificationTeamArchi
import removeMeetingTemplatesForTeam from '../../postgres/queries/removeMeetingTemplatesForTeam'
import safeArchiveTeam from '../../safeMutations/safeArchiveTeam'
import {analytics} from '../../utils/analytics/analytics'
import {getUserId, isSuperUser, isTeamLead} from '../../utils/authorization'
import {getUserId, isSuperUser, isTeamLead, isUserOrgAdmin} from '../../utils/authorization'
import publish from '../../utils/publish'
import standardError from '../../utils/standardError'
import {GQLContext} from '../graphql'
Expand Down Expand Up @@ -35,12 +35,14 @@ export default {

// AUTH
const viewerId = getUserId(authToken)
const [teamLead, viewer] = await Promise.all([
const [teamLead, viewer, teamToArchive] = await Promise.all([
isTeamLead(viewerId, teamId, dataLoader),
dataLoader.get('users').loadNonNull(viewerId)
dataLoader.get('users').loadNonNull(viewerId),
dataLoader.get('teams').loadNonNull(teamId)
])
if (!teamLead && !isSuperUser(authToken)) {
return standardError(new Error('Not team lead'), {userId: viewerId})
const isOrgAdmin = await isUserOrgAdmin(viewerId, teamToArchive.orgId, dataLoader)
if (!teamLead && !isSuperUser(authToken) && !isOrgAdmin) {
return standardError(new Error('Not team lead or org admin'), {userId: viewerId})
}

// RESOLUTION
Expand Down
24 changes: 14 additions & 10 deletions packages/server/graphql/mutations/promoteToTeamLead.ts
Expand Up @@ -2,7 +2,7 @@ import {GraphQLID, GraphQLNonNull} from 'graphql'
import {SubscriptionChannel} from 'parabol-client/types/constEnums'
import TeamMemberId from '../../../client/shared/gqlIds/TeamMemberId'
import getRethink from '../../database/rethinkDriver'
import {getUserId, isSuperUser} from '../../utils/authorization'
import {getUserId, isSuperUser, isUserOrgAdmin} from '../../utils/authorization'
import publish from '../../utils/publish'
import standardError from '../../utils/standardError'
import {GQLContext} from '../graphql'
Expand Down Expand Up @@ -32,18 +32,22 @@ export default {
const viewerId = getUserId(authToken)

// AUTH
const oldLeadTeamMemberId = await r
.table('TeamMember')
.getAll(teamId, {index: 'teamId'})
.filter({isNotRemoved: true, isLead: true})
.nth(0)('id')
.default(null)
.run()
const [oldLeadTeamMemberId, team] = await Promise.all([
r
.table('TeamMember')
.getAll(teamId, {index: 'teamId'})
.filter({isNotRemoved: true, isLead: true})
.nth(0)('id')
.default(null)
.run(),
dataLoader.get('teams').loadNonNull(teamId)
])

if (!isSuperUser(authToken)) {
const isOrgAdmin = await isUserOrgAdmin(viewerId, team.orgId, dataLoader)
const viewerTeamMemberId = TeamMemberId.join(teamId, viewerId)
if (viewerTeamMemberId !== oldLeadTeamMemberId) {
return standardError(new Error('Not team lead'), {userId: viewerId})
if (viewerTeamMemberId !== oldLeadTeamMemberId && !isOrgAdmin) {
return standardError(new Error('Not team lead or org admin'), {userId: viewerId})
}
}

Expand Down
11 changes: 8 additions & 3 deletions packages/server/graphql/mutations/removeTeamMember.ts
@@ -1,7 +1,7 @@
import {GraphQLID, GraphQLNonNull, GraphQLObjectType} from 'graphql'
import {SubscriptionChannel} from 'parabol-client/types/constEnums'
import fromTeamMemberId from 'parabol-client/utils/relay/fromTeamMemberId'
import {getUserId, isTeamLead} from '../../utils/authorization'
import {getUserId, isTeamLead, isUserOrgAdmin} from '../../utils/authorization'
import publish from '../../utils/publish'
import standardError from '../../utils/standardError'
import {GQLContext} from '../graphql'
Expand Down Expand Up @@ -30,10 +30,15 @@ export default {
// AUTH
const viewerId = getUserId(authToken)
const {userId, teamId} = fromTeamMemberId(teamMemberId)
const team = await dataLoader.get('teams').loadNonNull(teamId)
const [isOrgAdmin, isViewerTeamLead] = await Promise.all([
isUserOrgAdmin(viewerId, team.orgId, dataLoader),
isTeamLead(viewerId, teamId, dataLoader)
])
const isSelf = viewerId === userId
if (!isSelf) {
if (!(await isTeamLead(viewerId, teamId, dataLoader))) {
return standardError(new Error('Not team lead'), {userId: viewerId})
if (!isOrgAdmin && !isViewerTeamLead) {
return standardError(new Error('Not team lead or org admin'), {userId: viewerId})
}
}

Expand Down

0 comments on commit d5520ae

Please sign in to comment.