@budibase/worker 1.2.58 → 1.3.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/package.json +7 -6
- package/scripts/jestSetup.js +6 -0
- package/src/api/controllers/global/auth.ts +14 -1
- package/src/api/controllers/global/users.ts +26 -55
- package/src/api/controllers/system/accounts.ts +21 -0
- package/src/api/{index.js → index.ts} +12 -16
- package/src/api/routes/global/configs.js +1 -0
- package/src/api/routes/{tests/auth.spec.js → global/tests/auth.spec.ts} +32 -56
- package/src/api/routes/{tests/configs.spec.js → global/tests/configs.spec.ts} +76 -47
- package/src/api/routes/{tests/email.spec.js → global/tests/email.spec.ts} +7 -15
- package/src/api/routes/{tests/realEmail.spec.js → global/tests/realEmail.spec.ts} +20 -21
- package/src/api/routes/{tests/self.spec.js → global/tests/self.spec.ts} +10 -18
- package/src/api/routes/global/tests/users.spec.ts +512 -0
- package/src/api/routes/index.js +2 -0
- package/src/api/routes/system/accounts.ts +19 -0
- package/src/api/routes/system/tests/accounts.spec.ts +57 -0
- package/src/{environment.js → environment.ts} +10 -9
- package/src/index.ts +6 -4
- package/src/sdk/accounts/accounts.ts +53 -0
- package/src/sdk/accounts/index.ts +1 -0
- package/src/sdk/index.ts +1 -0
- package/src/sdk/users/users.ts +271 -77
- package/src/tests/TestConfiguration.ts +273 -0
- package/src/tests/api/accounts.ts +28 -0
- package/src/tests/api/auth.ts +48 -0
- package/src/tests/api/configs.ts +40 -0
- package/src/tests/api/email.ts +24 -0
- package/src/tests/api/index.ts +25 -0
- package/src/tests/api/self.ts +21 -0
- package/src/tests/api/users.ts +111 -0
- package/src/tests/index.ts +14 -0
- package/src/tests/mocks/index.ts +7 -0
- package/src/tests/structures/accounts.ts +24 -0
- package/src/tests/structures/index.ts +20 -0
- package/src/tests/structures/users.ts +12 -4
- package/src/utilities/redis.js +1 -0
- package/scripts/load/users.js +0 -97
- package/src/api/routes/tests/users.spec.js +0 -390
- package/src/tests/TestConfiguration.js +0 -231
- package/src/tests/index.js +0 -12
- package/src/tests/mocks/index.js +0 -5
- package/src/tests/structures/index.js +0 -14
package/scripts/load/users.js
DELETED
|
@@ -1,97 +0,0 @@
|
|
|
1
|
-
// get the JWT secret etc
|
|
2
|
-
require("../../src/environment")
|
|
3
|
-
require("@budibase/backend-core").init()
|
|
4
|
-
const {
|
|
5
|
-
getProdAppID,
|
|
6
|
-
generateGlobalUserID,
|
|
7
|
-
} = require("@budibase/backend-core/db")
|
|
8
|
-
const { doInTenant, getGlobalDB } = require("@budibase/backend-core/tenancy")
|
|
9
|
-
const users = require("../../src/sdk/users")
|
|
10
|
-
const { publicApiUserFix } = require("../../src/utilities/users")
|
|
11
|
-
const { hash } = require("@budibase/backend-core/utils")
|
|
12
|
-
|
|
13
|
-
const USER_LOAD_NUMBER = 10000
|
|
14
|
-
const BATCH_SIZE = 200
|
|
15
|
-
const PASSWORD = "test"
|
|
16
|
-
const TENANT_ID = "default"
|
|
17
|
-
|
|
18
|
-
const APP_ID = process.argv[2]
|
|
19
|
-
|
|
20
|
-
const words = [
|
|
21
|
-
"test",
|
|
22
|
-
"testing",
|
|
23
|
-
"budi",
|
|
24
|
-
"mail",
|
|
25
|
-
"age",
|
|
26
|
-
"risk",
|
|
27
|
-
"load",
|
|
28
|
-
"uno",
|
|
29
|
-
"arm",
|
|
30
|
-
"leg",
|
|
31
|
-
"pen",
|
|
32
|
-
"glass",
|
|
33
|
-
"box",
|
|
34
|
-
"chicken",
|
|
35
|
-
"bottle",
|
|
36
|
-
]
|
|
37
|
-
|
|
38
|
-
if (!APP_ID) {
|
|
39
|
-
console.error("Must supply app ID as first CLI option!")
|
|
40
|
-
process.exit(-1)
|
|
41
|
-
}
|
|
42
|
-
|
|
43
|
-
const WORD_1 = words[Math.floor(Math.random() * words.length)]
|
|
44
|
-
const WORD_2 = words[Math.floor(Math.random() * words.length)]
|
|
45
|
-
let HASHED_PASSWORD
|
|
46
|
-
|
|
47
|
-
function generateUser(count) {
|
|
48
|
-
return {
|
|
49
|
-
_id: generateGlobalUserID(),
|
|
50
|
-
password: HASHED_PASSWORD,
|
|
51
|
-
email: `${WORD_1}${count}@${WORD_2}.com`,
|
|
52
|
-
roles: {
|
|
53
|
-
[getProdAppID(APP_ID)]: "BASIC",
|
|
54
|
-
},
|
|
55
|
-
status: "active",
|
|
56
|
-
forceResetPassword: false,
|
|
57
|
-
firstName: "John",
|
|
58
|
-
lastName: "Smith",
|
|
59
|
-
}
|
|
60
|
-
}
|
|
61
|
-
|
|
62
|
-
async function run() {
|
|
63
|
-
HASHED_PASSWORD = await hash(PASSWORD)
|
|
64
|
-
return doInTenant(TENANT_ID, async () => {
|
|
65
|
-
const db = getGlobalDB()
|
|
66
|
-
for (let i = 0; i < USER_LOAD_NUMBER; i += BATCH_SIZE) {
|
|
67
|
-
let userSavePromises = []
|
|
68
|
-
for (let j = 0; j < BATCH_SIZE; j++) {
|
|
69
|
-
// like the public API
|
|
70
|
-
const ctx = publicApiUserFix({
|
|
71
|
-
request: {
|
|
72
|
-
body: generateUser(i + j),
|
|
73
|
-
},
|
|
74
|
-
})
|
|
75
|
-
userSavePromises.push(
|
|
76
|
-
users.save(ctx.request.body, {
|
|
77
|
-
hashPassword: false,
|
|
78
|
-
requirePassword: true,
|
|
79
|
-
bulkCreate: true,
|
|
80
|
-
})
|
|
81
|
-
)
|
|
82
|
-
}
|
|
83
|
-
const allUsers = await Promise.all(userSavePromises)
|
|
84
|
-
await db.bulkDocs(allUsers)
|
|
85
|
-
console.log(`${i + BATCH_SIZE} users have been created.`)
|
|
86
|
-
}
|
|
87
|
-
})
|
|
88
|
-
}
|
|
89
|
-
|
|
90
|
-
run()
|
|
91
|
-
.then(() => {
|
|
92
|
-
console.log(`Generated ${USER_LOAD_NUMBER} users!`)
|
|
93
|
-
})
|
|
94
|
-
.catch(err => {
|
|
95
|
-
console.error("Failed for reason: ", err)
|
|
96
|
-
process.exit(-1)
|
|
97
|
-
})
|
|
@@ -1,390 +0,0 @@
|
|
|
1
|
-
jest.mock("nodemailer")
|
|
2
|
-
const { config, request, mocks, structures } = require("../../../tests")
|
|
3
|
-
const sendMailMock = mocks.email.mock()
|
|
4
|
-
const { events } = require("@budibase/backend-core")
|
|
5
|
-
describe("/api/global/users", () => {
|
|
6
|
-
|
|
7
|
-
beforeAll(async () => {
|
|
8
|
-
await config.beforeAll()
|
|
9
|
-
})
|
|
10
|
-
|
|
11
|
-
afterAll(async () => {
|
|
12
|
-
await config.afterAll()
|
|
13
|
-
})
|
|
14
|
-
|
|
15
|
-
const sendUserInvite = async () => {
|
|
16
|
-
await config.saveSmtpConfig()
|
|
17
|
-
await config.saveSettingsConfig()
|
|
18
|
-
const res = await request
|
|
19
|
-
.post(`/api/global/users/invite`)
|
|
20
|
-
.send({
|
|
21
|
-
email: "invite@test.com",
|
|
22
|
-
})
|
|
23
|
-
.set(config.defaultHeaders())
|
|
24
|
-
.expect("Content-Type", /json/)
|
|
25
|
-
.expect(200)
|
|
26
|
-
|
|
27
|
-
const emailCall = sendMailMock.mock.calls[0][0]
|
|
28
|
-
// after this URL there should be a code
|
|
29
|
-
const parts = emailCall.html.split("http://localhost:10000/builder/invite?code=")
|
|
30
|
-
const code = parts[1].split("\"")[0].split("&")[0]
|
|
31
|
-
return { code, res }
|
|
32
|
-
}
|
|
33
|
-
|
|
34
|
-
it("should be able to generate an invitation", async () => {
|
|
35
|
-
const { code, res } = await sendUserInvite()
|
|
36
|
-
|
|
37
|
-
expect(res.body).toEqual({ message: "Invitation has been sent." })
|
|
38
|
-
expect(sendMailMock).toHaveBeenCalled()
|
|
39
|
-
expect(code).toBeDefined()
|
|
40
|
-
expect(events.user.invited).toBeCalledTimes(1)
|
|
41
|
-
})
|
|
42
|
-
|
|
43
|
-
it("should be able to create new user from invite", async () => {
|
|
44
|
-
const { code } = await sendUserInvite()
|
|
45
|
-
|
|
46
|
-
const res = await request
|
|
47
|
-
.post(`/api/global/users/invite/accept`)
|
|
48
|
-
.send({
|
|
49
|
-
password: "newpassword",
|
|
50
|
-
inviteCode: code,
|
|
51
|
-
})
|
|
52
|
-
.expect("Content-Type", /json/)
|
|
53
|
-
.expect(200)
|
|
54
|
-
expect(res.body._id).toBeDefined()
|
|
55
|
-
const user = await config.getUser("invite@test.com")
|
|
56
|
-
expect(user).toBeDefined()
|
|
57
|
-
expect(user._id).toEqual(res.body._id)
|
|
58
|
-
expect(events.user.inviteAccepted).toBeCalledTimes(1)
|
|
59
|
-
expect(events.user.inviteAccepted).toBeCalledWith(user)
|
|
60
|
-
})
|
|
61
|
-
|
|
62
|
-
const createUser = async (user) => {
|
|
63
|
-
const existing = await config.getUser(user.email)
|
|
64
|
-
if (existing) {
|
|
65
|
-
await deleteUser(existing._id)
|
|
66
|
-
}
|
|
67
|
-
return saveUser(user)
|
|
68
|
-
}
|
|
69
|
-
|
|
70
|
-
const updateUser = async (user) => {
|
|
71
|
-
const existing = await config.getUser(user.email)
|
|
72
|
-
user._id = existing._id
|
|
73
|
-
return saveUser(user)
|
|
74
|
-
}
|
|
75
|
-
|
|
76
|
-
const saveUser = async (user) => {
|
|
77
|
-
const res = await request
|
|
78
|
-
.post(`/api/global/users`)
|
|
79
|
-
.send(user)
|
|
80
|
-
.set(config.defaultHeaders())
|
|
81
|
-
.expect("Content-Type", /json/)
|
|
82
|
-
.expect(200)
|
|
83
|
-
return res.body
|
|
84
|
-
}
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
const bulkCreateUsers = async (users) => {
|
|
88
|
-
const res = await request
|
|
89
|
-
.post(`/api/global/users/bulkCreate`)
|
|
90
|
-
.send(users)
|
|
91
|
-
.set(config.defaultHeaders())
|
|
92
|
-
.expect("Content-Type", /json/)
|
|
93
|
-
.expect(200)
|
|
94
|
-
return res.body
|
|
95
|
-
}
|
|
96
|
-
|
|
97
|
-
const bulkDeleteUsers = async (users) => {
|
|
98
|
-
const res = await request
|
|
99
|
-
.post(`/api/global/users/bulkDelete`)
|
|
100
|
-
.send(users)
|
|
101
|
-
.set(config.defaultHeaders())
|
|
102
|
-
.expect("Content-Type", /json/)
|
|
103
|
-
.expect(200)
|
|
104
|
-
return res.body
|
|
105
|
-
}
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
const deleteUser = async (email) => {
|
|
110
|
-
const user = await config.getUser(email)
|
|
111
|
-
if (user) {
|
|
112
|
-
await request
|
|
113
|
-
.delete(`/api/global/users/${user._id}`)
|
|
114
|
-
.set(config.defaultHeaders())
|
|
115
|
-
.expect("Content-Type", /json/)
|
|
116
|
-
.expect(200)
|
|
117
|
-
}
|
|
118
|
-
}
|
|
119
|
-
|
|
120
|
-
describe("create", () => {
|
|
121
|
-
it("should be able to create a basic user", async () => {
|
|
122
|
-
jest.clearAllMocks()
|
|
123
|
-
const user = structures.users.user({ email: "basic@test.com" })
|
|
124
|
-
await createUser(user)
|
|
125
|
-
|
|
126
|
-
expect(events.user.created).toBeCalledTimes(1)
|
|
127
|
-
expect(events.user.updated).not.toBeCalled()
|
|
128
|
-
expect(events.user.permissionBuilderAssigned).not.toBeCalled()
|
|
129
|
-
expect(events.user.permissionAdminAssigned).not.toBeCalled()
|
|
130
|
-
})
|
|
131
|
-
|
|
132
|
-
it("should be able to bulkCreate users with different permissions", async () => {
|
|
133
|
-
jest.clearAllMocks()
|
|
134
|
-
const builder = structures.users.builderUser({ email: "bulkbasic@test.com" })
|
|
135
|
-
const admin = structures.users.adminUser({ email: "bulkadmin@test.com" })
|
|
136
|
-
const user = structures.users.user({ email: "bulkuser@test.com" })
|
|
137
|
-
|
|
138
|
-
let toCreate = { users: [builder, admin, user], groups: [] }
|
|
139
|
-
await bulkCreateUsers(toCreate)
|
|
140
|
-
|
|
141
|
-
expect(events.user.created).toBeCalledTimes(3)
|
|
142
|
-
expect(events.user.permissionAdminAssigned).toBeCalledTimes(1)
|
|
143
|
-
expect(events.user.permissionBuilderAssigned).toBeCalledTimes(1)
|
|
144
|
-
})
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
it("should be able to create an admin user", async () => {
|
|
148
|
-
jest.clearAllMocks()
|
|
149
|
-
const user = structures.users.adminUser({ email: "admin@test.com" })
|
|
150
|
-
await createUser(user)
|
|
151
|
-
|
|
152
|
-
expect(events.user.created).toBeCalledTimes(1)
|
|
153
|
-
expect(events.user.updated).not.toBeCalled()
|
|
154
|
-
expect(events.user.permissionBuilderAssigned).not.toBeCalled()
|
|
155
|
-
expect(events.user.permissionAdminAssigned).toBeCalledTimes(1)
|
|
156
|
-
})
|
|
157
|
-
|
|
158
|
-
it("should be able to create a builder user", async () => {
|
|
159
|
-
jest.clearAllMocks()
|
|
160
|
-
const user = structures.users.builderUser({ email: "builder@test.com" })
|
|
161
|
-
await createUser(user)
|
|
162
|
-
|
|
163
|
-
expect(events.user.created).toBeCalledTimes(1)
|
|
164
|
-
expect(events.user.updated).not.toBeCalled()
|
|
165
|
-
expect(events.user.permissionBuilderAssigned).toBeCalledTimes(1)
|
|
166
|
-
expect(events.user.permissionAdminAssigned).not.toBeCalled()
|
|
167
|
-
})
|
|
168
|
-
|
|
169
|
-
it("should be able to assign app roles", async () => {
|
|
170
|
-
jest.clearAllMocks()
|
|
171
|
-
const user = structures.users.user({ email: "assign-roles@test.com" })
|
|
172
|
-
user.roles = {
|
|
173
|
-
"app_123": "role1",
|
|
174
|
-
"app_456": "role2",
|
|
175
|
-
}
|
|
176
|
-
|
|
177
|
-
await createUser(user)
|
|
178
|
-
const savedUser = await config.getUser(user.email)
|
|
179
|
-
|
|
180
|
-
expect(events.user.created).toBeCalledTimes(1)
|
|
181
|
-
expect(events.user.updated).not.toBeCalled()
|
|
182
|
-
expect(events.role.assigned).toBeCalledTimes(2)
|
|
183
|
-
expect(events.role.assigned).toBeCalledWith(savedUser, "role1")
|
|
184
|
-
expect(events.role.assigned).toBeCalledWith(savedUser, "role2")
|
|
185
|
-
})
|
|
186
|
-
})
|
|
187
|
-
|
|
188
|
-
describe("update", () => {
|
|
189
|
-
it("should be able to update a basic user", async () => {
|
|
190
|
-
let user = structures.users.user({ email: "basic-update@test.com" })
|
|
191
|
-
await createUser(user)
|
|
192
|
-
jest.clearAllMocks()
|
|
193
|
-
|
|
194
|
-
await updateUser(user)
|
|
195
|
-
|
|
196
|
-
expect(events.user.created).not.toBeCalled()
|
|
197
|
-
expect(events.user.updated).toBeCalledTimes(1)
|
|
198
|
-
expect(events.user.permissionBuilderAssigned).not.toBeCalled()
|
|
199
|
-
expect(events.user.permissionAdminAssigned).not.toBeCalled()
|
|
200
|
-
expect(events.user.passwordForceReset).not.toBeCalled()
|
|
201
|
-
})
|
|
202
|
-
|
|
203
|
-
it("should be able to force reset password", async () => {
|
|
204
|
-
let user = structures.users.user({ email: "basic-password-update@test.com" })
|
|
205
|
-
await createUser(user)
|
|
206
|
-
jest.clearAllMocks()
|
|
207
|
-
|
|
208
|
-
user.forceResetPassword = true
|
|
209
|
-
user.password = "tempPassword"
|
|
210
|
-
await updateUser(user)
|
|
211
|
-
|
|
212
|
-
expect(events.user.created).not.toBeCalled()
|
|
213
|
-
expect(events.user.updated).toBeCalledTimes(1)
|
|
214
|
-
expect(events.user.permissionBuilderAssigned).not.toBeCalled()
|
|
215
|
-
expect(events.user.permissionAdminAssigned).not.toBeCalled()
|
|
216
|
-
expect(events.user.passwordForceReset).toBeCalledTimes(1)
|
|
217
|
-
})
|
|
218
|
-
|
|
219
|
-
it("should be able to update a basic user to an admin user", async () => {
|
|
220
|
-
let user = structures.users.user({ email: "basic-update-admin@test.com" })
|
|
221
|
-
await createUser(user)
|
|
222
|
-
jest.clearAllMocks()
|
|
223
|
-
|
|
224
|
-
await updateUser(structures.users.adminUser(user))
|
|
225
|
-
|
|
226
|
-
expect(events.user.created).not.toBeCalled()
|
|
227
|
-
expect(events.user.updated).toBeCalledTimes(1)
|
|
228
|
-
expect(events.user.permissionBuilderAssigned).not.toBeCalled()
|
|
229
|
-
expect(events.user.permissionAdminAssigned).toBeCalledTimes(1)
|
|
230
|
-
})
|
|
231
|
-
|
|
232
|
-
it("should be able to update a basic user to a builder user", async () => {
|
|
233
|
-
let user = structures.users.user({ email: "basic-update-builder@test.com" })
|
|
234
|
-
await createUser(user)
|
|
235
|
-
jest.clearAllMocks()
|
|
236
|
-
|
|
237
|
-
await updateUser(structures.users.builderUser(user))
|
|
238
|
-
|
|
239
|
-
expect(events.user.created).not.toBeCalled()
|
|
240
|
-
expect(events.user.updated).toBeCalledTimes(1)
|
|
241
|
-
expect(events.user.permissionBuilderAssigned).toBeCalledTimes(1)
|
|
242
|
-
expect(events.user.permissionAdminAssigned).not.toBeCalled()
|
|
243
|
-
})
|
|
244
|
-
|
|
245
|
-
it("should be able to update an admin user to a basic user", async () => {
|
|
246
|
-
let user = structures.users.adminUser({ email: "admin-update-basic@test.com" })
|
|
247
|
-
await createUser(user)
|
|
248
|
-
jest.clearAllMocks()
|
|
249
|
-
|
|
250
|
-
user.admin.global = false
|
|
251
|
-
await updateUser(user)
|
|
252
|
-
|
|
253
|
-
expect(events.user.created).not.toBeCalled()
|
|
254
|
-
expect(events.user.updated).toBeCalledTimes(1)
|
|
255
|
-
expect(events.user.permissionAdminRemoved).toBeCalledTimes(1)
|
|
256
|
-
expect(events.user.permissionBuilderRemoved).not.toBeCalled()
|
|
257
|
-
})
|
|
258
|
-
|
|
259
|
-
it("should be able to update an builder user to a basic user", async () => {
|
|
260
|
-
let user = structures.users.builderUser({ email: "builder-update-basic@test.com" })
|
|
261
|
-
await createUser(user)
|
|
262
|
-
jest.clearAllMocks()
|
|
263
|
-
|
|
264
|
-
user.builder.global = false
|
|
265
|
-
await updateUser(user)
|
|
266
|
-
|
|
267
|
-
expect(events.user.created).not.toBeCalled()
|
|
268
|
-
expect(events.user.updated).toBeCalledTimes(1)
|
|
269
|
-
expect(events.user.permissionBuilderRemoved).toBeCalledTimes(1)
|
|
270
|
-
expect(events.user.permissionAdminRemoved).not.toBeCalled()
|
|
271
|
-
})
|
|
272
|
-
|
|
273
|
-
it("should be able to assign app roles", async () => {
|
|
274
|
-
const user = structures.users.user({ email: "assign-roles-update@test.com" })
|
|
275
|
-
await createUser(user)
|
|
276
|
-
jest.clearAllMocks()
|
|
277
|
-
|
|
278
|
-
user.roles = {
|
|
279
|
-
"app_123": "role1",
|
|
280
|
-
"app_456": "role2",
|
|
281
|
-
}
|
|
282
|
-
await updateUser(user)
|
|
283
|
-
const savedUser = await config.getUser(user.email)
|
|
284
|
-
|
|
285
|
-
expect(events.user.created).not.toBeCalled()
|
|
286
|
-
expect(events.user.updated).toBeCalledTimes(1)
|
|
287
|
-
expect(events.role.assigned).toBeCalledTimes(2)
|
|
288
|
-
expect(events.role.assigned).toBeCalledWith(savedUser, "role1")
|
|
289
|
-
expect(events.role.assigned).toBeCalledWith(savedUser, "role2")
|
|
290
|
-
})
|
|
291
|
-
|
|
292
|
-
it("should be able to unassign app roles", async () => {
|
|
293
|
-
const user = structures.users.user({ email: "unassign-roles@test.com" })
|
|
294
|
-
user.roles = {
|
|
295
|
-
"app_123": "role1",
|
|
296
|
-
"app_456": "role2",
|
|
297
|
-
}
|
|
298
|
-
await createUser(user)
|
|
299
|
-
jest.clearAllMocks()
|
|
300
|
-
|
|
301
|
-
user.roles = {}
|
|
302
|
-
await updateUser(user)
|
|
303
|
-
const savedUser = await config.getUser(user.email)
|
|
304
|
-
|
|
305
|
-
expect(events.user.created).not.toBeCalled()
|
|
306
|
-
expect(events.user.updated).toBeCalledTimes(1)
|
|
307
|
-
expect(events.role.unassigned).toBeCalledTimes(2)
|
|
308
|
-
expect(events.role.unassigned).toBeCalledWith(savedUser, "role1")
|
|
309
|
-
expect(events.role.unassigned).toBeCalledWith(savedUser, "role2")
|
|
310
|
-
})
|
|
311
|
-
|
|
312
|
-
it("should be able to update existing app roles", async () => {
|
|
313
|
-
const user = structures.users.user({ email: "update-roles@test.com" })
|
|
314
|
-
user.roles = {
|
|
315
|
-
"app_123": "role1",
|
|
316
|
-
"app_456": "role2",
|
|
317
|
-
}
|
|
318
|
-
await createUser(user)
|
|
319
|
-
jest.clearAllMocks()
|
|
320
|
-
|
|
321
|
-
user.roles = {
|
|
322
|
-
"app_123": "role1",
|
|
323
|
-
"app_456": "role2-edit",
|
|
324
|
-
}
|
|
325
|
-
await updateUser(user)
|
|
326
|
-
const savedUser = await config.getUser(user.email)
|
|
327
|
-
|
|
328
|
-
expect(events.user.created).not.toBeCalled()
|
|
329
|
-
expect(events.user.updated).toBeCalledTimes(1)
|
|
330
|
-
expect(events.role.unassigned).toBeCalledTimes(1)
|
|
331
|
-
expect(events.role.unassigned).toBeCalledWith(savedUser, "role2")
|
|
332
|
-
expect(events.role.assigned).toBeCalledTimes(1)
|
|
333
|
-
expect(events.role.assigned).toBeCalledWith(savedUser, "role2-edit")
|
|
334
|
-
})
|
|
335
|
-
})
|
|
336
|
-
|
|
337
|
-
describe("destroy", () => {
|
|
338
|
-
it("should be able to destroy a basic user", async () => {
|
|
339
|
-
let user = structures.users.user({ email: "destroy@test.com" })
|
|
340
|
-
await createUser(user)
|
|
341
|
-
jest.clearAllMocks()
|
|
342
|
-
|
|
343
|
-
await deleteUser(user.email)
|
|
344
|
-
|
|
345
|
-
expect(events.user.deleted).toBeCalledTimes(1)
|
|
346
|
-
expect(events.user.permissionBuilderRemoved).not.toBeCalled()
|
|
347
|
-
expect(events.user.permissionAdminRemoved).not.toBeCalled()
|
|
348
|
-
})
|
|
349
|
-
|
|
350
|
-
it("should be able to destroy an admin user", async () => {
|
|
351
|
-
let user = structures.users.adminUser({ email: "destroy-admin@test.com" })
|
|
352
|
-
await createUser(user)
|
|
353
|
-
jest.clearAllMocks()
|
|
354
|
-
|
|
355
|
-
await deleteUser(user.email)
|
|
356
|
-
|
|
357
|
-
expect(events.user.deleted).toBeCalledTimes(1)
|
|
358
|
-
expect(events.user.permissionBuilderRemoved).not.toBeCalled()
|
|
359
|
-
expect(events.user.permissionAdminRemoved).toBeCalledTimes(1)
|
|
360
|
-
})
|
|
361
|
-
|
|
362
|
-
it("should be able to destroy a builder user", async () => {
|
|
363
|
-
let user = structures.users.builderUser({ email: "destroy-admin@test.com" })
|
|
364
|
-
await createUser(user)
|
|
365
|
-
jest.clearAllMocks()
|
|
366
|
-
|
|
367
|
-
await deleteUser(user.email)
|
|
368
|
-
|
|
369
|
-
expect(events.user.deleted).toBeCalledTimes(1)
|
|
370
|
-
expect(events.user.permissionBuilderRemoved).toBeCalledTimes(1)
|
|
371
|
-
expect(events.user.permissionAdminRemoved).not.toBeCalled()
|
|
372
|
-
})
|
|
373
|
-
|
|
374
|
-
it("should be able to bulk delete users with different permissions", async () => {
|
|
375
|
-
jest.clearAllMocks()
|
|
376
|
-
const builder = structures.users.builderUser({ email: "basic@test.com" })
|
|
377
|
-
const admin = structures.users.adminUser({ email: "admin@test.com" })
|
|
378
|
-
const user = structures.users.user({ email: "user@test.com" })
|
|
379
|
-
|
|
380
|
-
let toCreate = { users: [builder, admin, user], groups: [] }
|
|
381
|
-
let createdUsers = await bulkCreateUsers(toCreate)
|
|
382
|
-
await bulkDeleteUsers({ userIds: [createdUsers[0]._id, createdUsers[1]._id, createdUsers[2]._id] })
|
|
383
|
-
expect(events.user.deleted).toBeCalledTimes(3)
|
|
384
|
-
expect(events.user.permissionAdminRemoved).toBeCalledTimes(1)
|
|
385
|
-
expect(events.user.permissionBuilderRemoved).toBeCalledTimes(1)
|
|
386
|
-
|
|
387
|
-
})
|
|
388
|
-
|
|
389
|
-
})
|
|
390
|
-
})
|
|
@@ -1,231 +0,0 @@
|
|
|
1
|
-
require("./mocks")
|
|
2
|
-
require("../db").init()
|
|
3
|
-
const env = require("../environment")
|
|
4
|
-
const controllers = require("./controllers")
|
|
5
|
-
const supertest = require("supertest")
|
|
6
|
-
const { jwt } = require("@budibase/backend-core/auth")
|
|
7
|
-
const { Cookies, Headers } = require("@budibase/backend-core/constants")
|
|
8
|
-
const { Configs } = require("../constants")
|
|
9
|
-
const { users } = require("@budibase/backend-core")
|
|
10
|
-
const { createASession } = require("@budibase/backend-core/sessions")
|
|
11
|
-
const { TENANT_ID, CSRF_TOKEN } = require("./structures")
|
|
12
|
-
const structures = require("./structures")
|
|
13
|
-
const { doInTenant } = require("@budibase/backend-core/tenancy")
|
|
14
|
-
const { groups } = require("@budibase/pro")
|
|
15
|
-
class TestConfiguration {
|
|
16
|
-
constructor(openServer = true) {
|
|
17
|
-
if (openServer) {
|
|
18
|
-
env.PORT = "0" // random port
|
|
19
|
-
this.server = require("../index")
|
|
20
|
-
// we need the request for logging in, involves cookies, hard to fake
|
|
21
|
-
this.request = supertest(this.server)
|
|
22
|
-
}
|
|
23
|
-
}
|
|
24
|
-
|
|
25
|
-
getRequest() {
|
|
26
|
-
return this.request
|
|
27
|
-
}
|
|
28
|
-
|
|
29
|
-
// UTILS
|
|
30
|
-
|
|
31
|
-
async _req(config, params, controlFunc) {
|
|
32
|
-
const request = {}
|
|
33
|
-
// fake cookies, we don't need them
|
|
34
|
-
request.cookies = { set: () => {}, get: () => {} }
|
|
35
|
-
request.config = { jwtSecret: env.JWT_SECRET }
|
|
36
|
-
request.appId = this.appId
|
|
37
|
-
request.user = { appId: this.appId, tenantId: TENANT_ID }
|
|
38
|
-
request.query = {}
|
|
39
|
-
request.request = {
|
|
40
|
-
body: config,
|
|
41
|
-
}
|
|
42
|
-
request.throw = (status, err) => {
|
|
43
|
-
throw { status, message: err }
|
|
44
|
-
}
|
|
45
|
-
if (params) {
|
|
46
|
-
request.params = params
|
|
47
|
-
}
|
|
48
|
-
await doInTenant(TENANT_ID, () => {
|
|
49
|
-
return controlFunc(request)
|
|
50
|
-
})
|
|
51
|
-
return request.body
|
|
52
|
-
}
|
|
53
|
-
|
|
54
|
-
// SETUP / TEARDOWN
|
|
55
|
-
|
|
56
|
-
async beforeAll() {
|
|
57
|
-
await this.login()
|
|
58
|
-
}
|
|
59
|
-
|
|
60
|
-
async afterAll() {
|
|
61
|
-
if (this.server) {
|
|
62
|
-
await this.server.close()
|
|
63
|
-
}
|
|
64
|
-
}
|
|
65
|
-
|
|
66
|
-
// USER / AUTH
|
|
67
|
-
|
|
68
|
-
async login() {
|
|
69
|
-
// create a test user
|
|
70
|
-
await this._req(
|
|
71
|
-
{
|
|
72
|
-
email: "test@test.com",
|
|
73
|
-
password: "test",
|
|
74
|
-
_id: "us_uuid1",
|
|
75
|
-
builder: {
|
|
76
|
-
global: true,
|
|
77
|
-
},
|
|
78
|
-
admin: {
|
|
79
|
-
global: true,
|
|
80
|
-
},
|
|
81
|
-
},
|
|
82
|
-
null,
|
|
83
|
-
controllers.users.save
|
|
84
|
-
)
|
|
85
|
-
await createASession("us_uuid1", {
|
|
86
|
-
sessionId: "sessionid",
|
|
87
|
-
tenantId: TENANT_ID,
|
|
88
|
-
csrfToken: CSRF_TOKEN,
|
|
89
|
-
})
|
|
90
|
-
}
|
|
91
|
-
|
|
92
|
-
cookieHeader(cookies) {
|
|
93
|
-
return {
|
|
94
|
-
Cookie: [cookies],
|
|
95
|
-
}
|
|
96
|
-
}
|
|
97
|
-
|
|
98
|
-
defaultHeaders() {
|
|
99
|
-
const user = {
|
|
100
|
-
_id: "us_uuid1",
|
|
101
|
-
userId: "us_uuid1",
|
|
102
|
-
sessionId: "sessionid",
|
|
103
|
-
tenantId: TENANT_ID,
|
|
104
|
-
}
|
|
105
|
-
const authToken = jwt.sign(user, env.JWT_SECRET)
|
|
106
|
-
return {
|
|
107
|
-
Accept: "application/json",
|
|
108
|
-
...this.cookieHeader([`${Cookies.Auth}=${authToken}`]),
|
|
109
|
-
[Headers.CSRF_TOKEN]: CSRF_TOKEN,
|
|
110
|
-
}
|
|
111
|
-
}
|
|
112
|
-
|
|
113
|
-
async getUser(email) {
|
|
114
|
-
return doInTenant(TENANT_ID, () => {
|
|
115
|
-
return users.getGlobalUserByEmail(email)
|
|
116
|
-
})
|
|
117
|
-
}
|
|
118
|
-
|
|
119
|
-
async getGroup(id) {
|
|
120
|
-
return doInTenant(TENANT_ID, () => {
|
|
121
|
-
return groups.get(id)
|
|
122
|
-
})
|
|
123
|
-
}
|
|
124
|
-
|
|
125
|
-
async saveGroup(group) {
|
|
126
|
-
const res = await this.getRequest()
|
|
127
|
-
.post(`/api/global/groups`)
|
|
128
|
-
.send(group)
|
|
129
|
-
.set(this.defaultHeaders())
|
|
130
|
-
.expect("Content-Type", /json/)
|
|
131
|
-
.expect(200)
|
|
132
|
-
return res.body
|
|
133
|
-
}
|
|
134
|
-
|
|
135
|
-
async createUser(email, password) {
|
|
136
|
-
const user = await this.getUser(structures.users.email)
|
|
137
|
-
if (user) {
|
|
138
|
-
return user
|
|
139
|
-
}
|
|
140
|
-
await this._req(
|
|
141
|
-
structures.users.user({ email, password }),
|
|
142
|
-
null,
|
|
143
|
-
controllers.users.save
|
|
144
|
-
)
|
|
145
|
-
}
|
|
146
|
-
|
|
147
|
-
async saveAdminUser() {
|
|
148
|
-
await this._req(
|
|
149
|
-
structures.users.user({ tenantId: TENANT_ID }),
|
|
150
|
-
null,
|
|
151
|
-
controllers.users.adminUser
|
|
152
|
-
)
|
|
153
|
-
}
|
|
154
|
-
|
|
155
|
-
// CONFIGS
|
|
156
|
-
|
|
157
|
-
async deleteConfig(type) {
|
|
158
|
-
try {
|
|
159
|
-
const cfg = await this._req(
|
|
160
|
-
null,
|
|
161
|
-
{
|
|
162
|
-
type,
|
|
163
|
-
},
|
|
164
|
-
controllers.config.find
|
|
165
|
-
)
|
|
166
|
-
if (cfg) {
|
|
167
|
-
await this._req(
|
|
168
|
-
null,
|
|
169
|
-
{
|
|
170
|
-
id: cfg._id,
|
|
171
|
-
rev: cfg._rev,
|
|
172
|
-
},
|
|
173
|
-
controllers.config.destroy
|
|
174
|
-
)
|
|
175
|
-
}
|
|
176
|
-
} catch (err) {
|
|
177
|
-
// don't need to handle error
|
|
178
|
-
}
|
|
179
|
-
}
|
|
180
|
-
|
|
181
|
-
// CONFIGS - SETTINGS
|
|
182
|
-
|
|
183
|
-
async saveSettingsConfig() {
|
|
184
|
-
await this.deleteConfig(Configs.SETTINGS)
|
|
185
|
-
await this._req(
|
|
186
|
-
structures.configs.settings(),
|
|
187
|
-
null,
|
|
188
|
-
controllers.config.save
|
|
189
|
-
)
|
|
190
|
-
}
|
|
191
|
-
|
|
192
|
-
// CONFIGS - GOOGLE
|
|
193
|
-
|
|
194
|
-
async saveGoogleConfig() {
|
|
195
|
-
await this.deleteConfig(Configs.GOOGLE)
|
|
196
|
-
await this._req(structures.configs.google(), null, controllers.config.save)
|
|
197
|
-
}
|
|
198
|
-
|
|
199
|
-
// CONFIGS - OIDC
|
|
200
|
-
|
|
201
|
-
getOIDConfigCookie(configId) {
|
|
202
|
-
const token = jwt.sign(configId, env.JWT_SECRET)
|
|
203
|
-
return this.cookieHeader([[`${Cookies.OIDC_CONFIG}=${token}`]])
|
|
204
|
-
}
|
|
205
|
-
|
|
206
|
-
async saveOIDCConfig() {
|
|
207
|
-
await this.deleteConfig(Configs.OIDC)
|
|
208
|
-
const config = structures.configs.oidc()
|
|
209
|
-
|
|
210
|
-
await this._req(config, null, controllers.config.save)
|
|
211
|
-
return config
|
|
212
|
-
}
|
|
213
|
-
|
|
214
|
-
// CONFIGS - SMTP
|
|
215
|
-
|
|
216
|
-
async saveSmtpConfig() {
|
|
217
|
-
await this.deleteConfig(Configs.SMTP)
|
|
218
|
-
await this._req(structures.configs.smtp(), null, controllers.config.save)
|
|
219
|
-
}
|
|
220
|
-
|
|
221
|
-
async saveEtherealSmtpConfig() {
|
|
222
|
-
await this.deleteConfig(Configs.SMTP)
|
|
223
|
-
await this._req(
|
|
224
|
-
structures.configs.smtpEthereal(),
|
|
225
|
-
null,
|
|
226
|
-
controllers.config.save
|
|
227
|
-
)
|
|
228
|
-
}
|
|
229
|
-
}
|
|
230
|
-
|
|
231
|
-
module.exports = TestConfiguration
|