forked from canada-ca/tracker
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathremove-user-from-org.js
More file actions
219 lines (202 loc) · 6.9 KB
/
remove-user-from-org.js
File metadata and controls
219 lines (202 loc) · 6.9 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
import { GraphQLNonNull, GraphQLID } from 'graphql'
import { mutationWithClientMutationId, fromGlobalId } from 'graphql-relay'
import { t } from '@lingui/macro'
import { removeUserFromOrgUnion } from '../unions'
export const removeUserFromOrg = new mutationWithClientMutationId({
name: 'RemoveUserFromOrg',
description:
'This mutation allows admins or higher to remove users from any organizations they belong to.',
inputFields: () => ({
userId: {
type: GraphQLNonNull(GraphQLID),
description: 'The user id of the user to be removed.',
},
orgId: {
type: GraphQLNonNull(GraphQLID),
description: 'The organization that the user is to be removed from.',
},
}),
outputFields: () => ({
result: {
type: removeUserFromOrgUnion,
description:
'`RemoveUserFromOrgUnion` returning either a `RemoveUserFromOrgResult`, or `RemoveUserFromOrgError` object.',
resolve: (payload) => payload,
},
}),
mutateAndGetPayload: async (
args,
{
i18n,
query,
collections,
transaction,
userKey,
auth: { checkPermission, userRequired, verifiedRequired },
loaders: { loadOrgByKey, loadUserByKey },
validators: { cleanseInput },
},
) => {
// Cleanse Input
const { id: requestedUserKey } = fromGlobalId(cleanseInput(args.userId))
const { id: requestedOrgKey } = fromGlobalId(cleanseInput(args.orgId))
// Get requesting user
const user = await userRequired()
verifiedRequired({ user })
// Get requested org
const requestedOrg = await loadOrgByKey.load(requestedOrgKey)
if (typeof requestedOrg === 'undefined') {
console.warn(
`User: ${userKey} attempted to remove user: ${requestedUserKey} from org: ${requestedOrgKey}, however no org with that id could be found.`,
)
return {
_type: 'error',
code: 400,
description: i18n._(
t`Unable to remove user from unknown organization.`,
),
}
}
// Check requesting users permission
const permission = await checkPermission({ orgId: requestedOrg._id })
if (permission === 'user' || typeof permission === 'undefined') {
console.warn(
`User: ${userKey} attempted to remove user: ${requestedUserKey} from org: ${requestedOrg._key}, however they do not have the permission to remove users.`,
)
return {
_type: 'error',
code: 400,
description: i18n._(t`Unable to remove user from organization.`),
}
}
// Get requested user
const requestedUser = await loadUserByKey.load(requestedUserKey)
if (typeof requestedUser === 'undefined') {
console.warn(
`User: ${userKey} attempted to remove user: ${requestedUserKey} from org: ${requestedOrg._key}, however no user with that id could be found.`,
)
return {
_type: 'error',
code: 400,
description: i18n._(
t`Unable to remove unknown user from organization.`,
),
}
}
// Get requested users current permission level
let affiliationCursor
try {
affiliationCursor = await query`
WITH affiliations, organizations, users
FOR v, e IN 1..1 ANY ${requestedUser._id} affiliations
FILTER e._from == ${requestedOrg._id}
RETURN { _key: e._key, permission: e.permission }
`
} catch (err) {
console.error(
`Database error occurred when user: ${userKey} attempted to check the current permission of user: ${requestedUser._key} to see if they could be removed: ${err}`,
)
throw new Error(
i18n._(
t`Unable to remove user from this organization. Please try again.`,
),
)
}
if (affiliationCursor.count < 1) {
console.warn(
`User: ${userKey} attempted to remove user: ${requestedUser._key}, but they do not have any affiliations to org: ${requestedOrg._key}.`,
)
return {
_type: 'error',
code: 400,
description: i18n._(
t`Unable to remove a user that already does not belong to this organization.`,
),
}
}
let affiliation
try {
affiliation = await affiliationCursor.next()
} catch (err) {
console.error(
`Cursor error occurred when user: ${userKey} attempted to check the current permission of user: ${requestedUser._key} to see if they could be removed: ${err}`,
)
throw new Error(
i18n._(
t`Unable to remove user from this organization. Please try again.`,
),
)
}
let canRemove
if (
permission === 'super_admin' &&
(affiliation.permission === 'admin' || affiliation.permission === 'user')
) {
canRemove = true
} else if (permission === 'admin' && affiliation.permission === 'user') {
canRemove = true
} else {
canRemove = false
}
if (canRemove) {
// Generate list of collections names
const collectionStrings = []
for (const property in collections) {
collectionStrings.push(property.toString())
}
// Setup Transaction
const trx = await transaction(collectionStrings)
try {
await trx.step(async () => {
query`
WITH affiliations, organizations, users
FOR aff IN affiliations
FILTER aff._from == ${requestedOrg._id}
FILTER aff._to == ${requestedUser._id}
REMOVE aff IN affiliations
RETURN true
`
})
} catch (err) {
console.error(
`Trx step error occurred when user: ${userKey} attempted to remove user: ${requestedUser._key} from org: ${requestedOrg._key}, error: ${err}`,
)
throw new Error(
i18n._(t`Unable to remove user from this organization. Please try again.`),
)
}
try {
await trx.commit()
} catch (err) {
console.error(
`Trx commit error occurred when user: ${userKey} attempted to remove user: ${requestedUser._key} from org: ${requestedOrg._key}, error: ${err}`,
)
throw new Error(
i18n._(t`Unable to remove user from this organization. Please try again.`),
)
}
console.info(
`User: ${userKey} successfully removed user: ${requestedUser._key} from org: ${requestedOrg._key}.`,
)
return {
_type: 'regular',
status: i18n._(t`Successfully removed user from organization.`),
user: {
id: requestedUser.id,
userName: requestedUser.userName,
},
}
} else {
console.warn(
`User: ${userKey} attempted to remove user: ${requestedUser._key} from org: ${requestedOrg._key}, but they do not have the right permission.`,
)
return {
_type: 'error',
code: 400,
description: i18n._(
t`Permission Denied: Please contact organization admin for help with removing users.`,
),
}
}
},
})