@budibase/worker 1.2.58-alpha.4 → 1.2.58
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 +6 -7
- package/scripts/jestSetup.js +0 -6
- package/scripts/load/users.js +97 -0
- package/src/api/controllers/global/auth.ts +1 -14
- package/src/api/controllers/global/users.ts +8 -6
- package/src/api/{index.ts → index.js} +16 -12
- package/src/api/routes/global/configs.js +0 -1
- package/src/api/routes/index.js +0 -2
- package/src/api/routes/{global/tests/auth.spec.ts → tests/auth.spec.js} +56 -32
- package/src/api/routes/{global/tests/configs.spec.ts → tests/configs.spec.js} +47 -76
- package/src/api/routes/{global/tests/email.spec.ts → tests/email.spec.js} +15 -7
- package/src/api/routes/{global/tests/realEmail.spec.ts → tests/realEmail.spec.js} +21 -20
- package/src/api/routes/{global/tests/self.spec.ts → tests/self.spec.js} +18 -10
- package/src/api/routes/tests/users.spec.js +390 -0
- package/src/{environment.ts → environment.js} +9 -10
- package/src/index.ts +4 -6
- package/src/sdk/index.ts +0 -1
- package/src/sdk/users/users.ts +77 -217
- package/src/tests/TestConfiguration.js +231 -0
- package/src/tests/index.js +12 -0
- package/src/tests/mocks/index.js +5 -0
- package/src/tests/structures/index.js +14 -0
- package/src/tests/structures/users.ts +4 -12
- package/src/utilities/redis.js +0 -1
- package/src/api/controllers/system/accounts.ts +0 -21
- package/src/api/routes/global/tests/users.spec.ts +0 -464
- package/src/api/routes/system/accounts.ts +0 -19
- package/src/api/routes/system/tests/accounts.spec.ts +0 -57
- package/src/sdk/accounts/accounts.ts +0 -53
- package/src/sdk/accounts/index.ts +0 -1
- package/src/tests/TestConfiguration.ts +0 -273
- package/src/tests/api/accounts.ts +0 -28
- package/src/tests/api/auth.ts +0 -48
- package/src/tests/api/configs.ts +0 -40
- package/src/tests/api/email.ts +0 -24
- package/src/tests/api/index.ts +0 -25
- package/src/tests/api/self.ts +0 -21
- package/src/tests/api/users.ts +0 -95
- package/src/tests/index.ts +0 -14
- package/src/tests/mocks/index.ts +0 -7
- package/src/tests/structures/accounts.ts +0 -24
- package/src/tests/structures/index.ts +0 -20
package/src/sdk/users/users.ts
CHANGED
|
@@ -14,23 +14,8 @@ import {
|
|
|
14
14
|
HTTPError,
|
|
15
15
|
accounts,
|
|
16
16
|
migrations,
|
|
17
|
-
StaticDatabases,
|
|
18
|
-
ViewName,
|
|
19
17
|
} from "@budibase/backend-core"
|
|
20
|
-
import {
|
|
21
|
-
MigrationType,
|
|
22
|
-
PlatformUserByEmail,
|
|
23
|
-
User,
|
|
24
|
-
Account,
|
|
25
|
-
BulkCreateUsersResponse,
|
|
26
|
-
CreateUserResponse,
|
|
27
|
-
BulkDeleteUsersResponse,
|
|
28
|
-
CloudAccount,
|
|
29
|
-
AllDocsResponse,
|
|
30
|
-
RowResponse,
|
|
31
|
-
BulkDocsResponse,
|
|
32
|
-
AccountMetadata,
|
|
33
|
-
} from "@budibase/types"
|
|
18
|
+
import { MigrationType, User } from "@budibase/types"
|
|
34
19
|
import { groups as groupUtils } from "@budibase/pro"
|
|
35
20
|
|
|
36
21
|
const PAGE_LIMIT = 8
|
|
@@ -113,6 +98,7 @@ export const getUser = async (userId: string) => {
|
|
|
113
98
|
interface SaveUserOpts {
|
|
114
99
|
hashPassword?: boolean
|
|
115
100
|
requirePassword?: boolean
|
|
101
|
+
bulkCreate?: boolean
|
|
116
102
|
}
|
|
117
103
|
|
|
118
104
|
const buildUser = async (
|
|
@@ -123,7 +109,7 @@ const buildUser = async (
|
|
|
123
109
|
},
|
|
124
110
|
tenantId: string,
|
|
125
111
|
dbUser?: any
|
|
126
|
-
)
|
|
112
|
+
) => {
|
|
127
113
|
let { password, _id } = user
|
|
128
114
|
|
|
129
115
|
let hashedPassword
|
|
@@ -157,63 +143,62 @@ const buildUser = async (
|
|
|
157
143
|
return user
|
|
158
144
|
}
|
|
159
145
|
|
|
160
|
-
const validateUniqueUser = async (email: string, tenantId: string) => {
|
|
161
|
-
// check budibase users in other tenants
|
|
162
|
-
if (env.MULTI_TENANCY) {
|
|
163
|
-
const tenantUser = await tenancy.getTenantUser(email)
|
|
164
|
-
if (tenantUser != null && tenantUser.tenantId !== tenantId) {
|
|
165
|
-
throw `Unavailable`
|
|
166
|
-
}
|
|
167
|
-
}
|
|
168
|
-
|
|
169
|
-
// check root account users in account portal
|
|
170
|
-
if (!env.SELF_HOSTED && !env.DISABLE_ACCOUNT_PORTAL) {
|
|
171
|
-
const account = await accounts.getAccount(email)
|
|
172
|
-
if (account && account.verified && account.tenantId !== tenantId) {
|
|
173
|
-
throw `Unavailable`
|
|
174
|
-
}
|
|
175
|
-
}
|
|
176
|
-
}
|
|
177
|
-
|
|
178
146
|
export const save = async (
|
|
179
|
-
user:
|
|
147
|
+
user: any,
|
|
180
148
|
opts: SaveUserOpts = {
|
|
181
149
|
hashPassword: true,
|
|
182
150
|
requirePassword: true,
|
|
151
|
+
bulkCreate: false,
|
|
183
152
|
}
|
|
184
|
-
)
|
|
153
|
+
) => {
|
|
185
154
|
const tenantId = tenancy.getTenantId()
|
|
186
155
|
const db = tenancy.getGlobalDB()
|
|
187
156
|
let { email, _id } = user
|
|
188
|
-
|
|
189
|
-
let dbUser:
|
|
190
|
-
if (
|
|
191
|
-
|
|
192
|
-
dbUser = (await db.get(_id)) as User
|
|
193
|
-
if (email && dbUser.email !== email) {
|
|
194
|
-
throw "Email address cannot be changed"
|
|
195
|
-
}
|
|
196
|
-
email = dbUser.email
|
|
157
|
+
// make sure another user isn't using the same email
|
|
158
|
+
let dbUser: any
|
|
159
|
+
if (opts.bulkCreate) {
|
|
160
|
+
dbUser = null
|
|
197
161
|
} else if (email) {
|
|
198
|
-
//
|
|
162
|
+
// check budibase users inside the tenant
|
|
199
163
|
dbUser = await usersCore.getGlobalUserByEmail(email)
|
|
200
|
-
if (dbUser && dbUser._id !== _id) {
|
|
201
|
-
throw `
|
|
164
|
+
if (dbUser != null && (dbUser._id !== _id || Array.isArray(dbUser))) {
|
|
165
|
+
throw `Email address ${email} already in use.`
|
|
202
166
|
}
|
|
203
|
-
} else {
|
|
204
|
-
throw new Error("_id or email is required")
|
|
205
|
-
}
|
|
206
167
|
|
|
207
|
-
|
|
168
|
+
// check budibase users in other tenants
|
|
169
|
+
if (env.MULTI_TENANCY) {
|
|
170
|
+
const tenantUser = await tenancy.getTenantUser(email)
|
|
171
|
+
if (tenantUser != null && tenantUser.tenantId !== tenantId) {
|
|
172
|
+
throw `Email address ${email} already in use.`
|
|
173
|
+
}
|
|
174
|
+
}
|
|
175
|
+
|
|
176
|
+
// check root account users in account portal
|
|
177
|
+
if (!env.SELF_HOSTED && !env.DISABLE_ACCOUNT_PORTAL) {
|
|
178
|
+
const account = await accounts.getAccount(email)
|
|
179
|
+
if (account && account.verified && account.tenantId !== tenantId) {
|
|
180
|
+
throw `Email address ${email} already in use.`
|
|
181
|
+
}
|
|
182
|
+
}
|
|
183
|
+
} else if (_id) {
|
|
184
|
+
dbUser = await db.get(_id)
|
|
185
|
+
}
|
|
208
186
|
|
|
209
187
|
let builtUser = await buildUser(user, opts, tenantId, dbUser)
|
|
210
188
|
|
|
211
189
|
// make sure we set the _id field for a new user
|
|
212
190
|
if (!_id) {
|
|
213
|
-
_id = builtUser._id
|
|
191
|
+
_id = builtUser._id
|
|
214
192
|
}
|
|
215
193
|
|
|
216
194
|
try {
|
|
195
|
+
const putOpts = {
|
|
196
|
+
password: builtUser.password,
|
|
197
|
+
...user,
|
|
198
|
+
}
|
|
199
|
+
if (opts.bulkCreate) {
|
|
200
|
+
return putOpts
|
|
201
|
+
}
|
|
217
202
|
// save the user to db
|
|
218
203
|
let response
|
|
219
204
|
const putUserFn = () => {
|
|
@@ -262,87 +247,29 @@ export const addTenant = async (
|
|
|
262
247
|
}
|
|
263
248
|
}
|
|
264
249
|
|
|
265
|
-
const getExistingTenantUsers = async (emails: string[]): Promise<User[]> => {
|
|
266
|
-
return dbUtils.queryGlobalView(ViewName.USER_BY_EMAIL, {
|
|
267
|
-
keys: emails,
|
|
268
|
-
include_docs: true,
|
|
269
|
-
arrayResponse: true,
|
|
270
|
-
})
|
|
271
|
-
}
|
|
272
|
-
|
|
273
|
-
const getExistingPlatformUsers = async (
|
|
274
|
-
emails: string[]
|
|
275
|
-
): Promise<PlatformUserByEmail[]> => {
|
|
276
|
-
return dbUtils.doWithDB(
|
|
277
|
-
StaticDatabases.PLATFORM_INFO.name,
|
|
278
|
-
async (infoDb: any) => {
|
|
279
|
-
const response: AllDocsResponse<PlatformUserByEmail> =
|
|
280
|
-
await infoDb.allDocs({
|
|
281
|
-
keys: emails,
|
|
282
|
-
include_docs: true,
|
|
283
|
-
})
|
|
284
|
-
return response.rows
|
|
285
|
-
.filter(row => row.doc && (row.error !== "not_found") !== null)
|
|
286
|
-
.map((row: any) => row.doc)
|
|
287
|
-
}
|
|
288
|
-
)
|
|
289
|
-
}
|
|
290
|
-
|
|
291
|
-
const getExistingAccounts = async (
|
|
292
|
-
emails: string[]
|
|
293
|
-
): Promise<AccountMetadata[]> => {
|
|
294
|
-
return dbUtils.queryPlatformView(ViewName.ACCOUNT_BY_EMAIL, {
|
|
295
|
-
keys: emails,
|
|
296
|
-
include_docs: true,
|
|
297
|
-
arrayResponse: true,
|
|
298
|
-
})
|
|
299
|
-
}
|
|
300
|
-
|
|
301
|
-
/**
|
|
302
|
-
* Apply a system-wide search on emails:
|
|
303
|
-
* - in tenant
|
|
304
|
-
* - cross tenant
|
|
305
|
-
* - accounts
|
|
306
|
-
* return an array of emails that match the supplied emails.
|
|
307
|
-
*/
|
|
308
|
-
const searchExistingEmails = async (emails: string[]) => {
|
|
309
|
-
let matchedEmails: string[] = []
|
|
310
|
-
|
|
311
|
-
const existingTenantUsers = await getExistingTenantUsers(emails)
|
|
312
|
-
matchedEmails.push(...existingTenantUsers.map(user => user.email))
|
|
313
|
-
|
|
314
|
-
const existingPlatformUsers = await getExistingPlatformUsers(emails)
|
|
315
|
-
matchedEmails.push(...existingPlatformUsers.map(user => user._id!))
|
|
316
|
-
|
|
317
|
-
const existingAccounts = await getExistingAccounts(emails)
|
|
318
|
-
matchedEmails.push(...existingAccounts.map(account => account.email))
|
|
319
|
-
|
|
320
|
-
return [...new Set(matchedEmails)]
|
|
321
|
-
}
|
|
322
|
-
|
|
323
250
|
export const bulkCreate = async (
|
|
324
251
|
newUsersRequested: User[],
|
|
325
252
|
groups: string[]
|
|
326
|
-
)
|
|
253
|
+
) => {
|
|
327
254
|
const db = tenancy.getGlobalDB()
|
|
328
255
|
const tenantId = tenancy.getTenantId()
|
|
329
256
|
|
|
330
257
|
let usersToSave: any[] = []
|
|
331
258
|
let newUsers: any[] = []
|
|
332
259
|
|
|
333
|
-
const
|
|
334
|
-
|
|
335
|
-
|
|
260
|
+
const allUsers = await db.allDocs(
|
|
261
|
+
dbUtils.getGlobalUserParams(null, {
|
|
262
|
+
include_docs: true,
|
|
263
|
+
})
|
|
264
|
+
)
|
|
265
|
+
let mapped = allUsers.rows.map((row: any) => row.id)
|
|
336
266
|
|
|
267
|
+
const currentUserEmails = mapped.map((x: any) => x.email) || []
|
|
337
268
|
for (const newUser of newUsersRequested) {
|
|
338
269
|
if (
|
|
339
270
|
newUsers.find((x: any) => x.email === newUser.email) ||
|
|
340
|
-
|
|
271
|
+
currentUserEmails.includes(newUser.email)
|
|
341
272
|
) {
|
|
342
|
-
unsuccessful.push({
|
|
343
|
-
email: newUser.email,
|
|
344
|
-
reason: `Unavailable`,
|
|
345
|
-
})
|
|
346
273
|
continue
|
|
347
274
|
}
|
|
348
275
|
newUser.userGroups = groups
|
|
@@ -380,129 +307,62 @@ export const bulkCreate = async (
|
|
|
380
307
|
await apps.syncUserInApps(user._id)
|
|
381
308
|
}
|
|
382
309
|
|
|
383
|
-
|
|
310
|
+
return usersToBulkSave.map(user => {
|
|
384
311
|
return {
|
|
385
312
|
_id: user._id,
|
|
386
313
|
email: user.email,
|
|
387
314
|
}
|
|
388
315
|
})
|
|
389
|
-
|
|
390
|
-
return {
|
|
391
|
-
successful: saved,
|
|
392
|
-
unsuccessful,
|
|
393
|
-
}
|
|
394
316
|
}
|
|
395
317
|
|
|
396
|
-
|
|
397
|
-
* For the given user id's, return the account holder if it is in the ids.
|
|
398
|
-
*/
|
|
399
|
-
const getAccountHolderFromUserIds = async (
|
|
400
|
-
userIds: string[]
|
|
401
|
-
): Promise<CloudAccount | undefined> => {
|
|
402
|
-
if (!env.SELF_HOSTED && !env.DISABLE_ACCOUNT_PORTAL) {
|
|
403
|
-
const tenantId = tenancy.getTenantId()
|
|
404
|
-
const account = await accounts.getAccountByTenantId(tenantId)
|
|
405
|
-
if (!account) {
|
|
406
|
-
throw new Error(`Account not found for tenantId=${tenantId}`)
|
|
407
|
-
}
|
|
408
|
-
|
|
409
|
-
const budibaseUserId = account.budibaseUserId
|
|
410
|
-
if (userIds.includes(budibaseUserId)) {
|
|
411
|
-
return account
|
|
412
|
-
}
|
|
413
|
-
}
|
|
414
|
-
}
|
|
415
|
-
|
|
416
|
-
export const bulkDelete = async (
|
|
417
|
-
userIds: string[]
|
|
418
|
-
): Promise<BulkDeleteUsersResponse> => {
|
|
318
|
+
export const bulkDelete = async (userIds: any) => {
|
|
419
319
|
const db = tenancy.getGlobalDB()
|
|
420
320
|
|
|
421
|
-
const response: BulkDeleteUsersResponse = {
|
|
422
|
-
successful: [],
|
|
423
|
-
unsuccessful: [],
|
|
424
|
-
}
|
|
425
|
-
|
|
426
|
-
// remove the account holder from the delete request if present
|
|
427
|
-
const account = await getAccountHolderFromUserIds(userIds)
|
|
428
|
-
if (account) {
|
|
429
|
-
userIds = userIds.filter(u => u !== account.budibaseUserId)
|
|
430
|
-
// mark user as unsuccessful
|
|
431
|
-
response.unsuccessful.push({
|
|
432
|
-
_id: account.budibaseUserId,
|
|
433
|
-
email: account.email,
|
|
434
|
-
reason: "Account holder cannot be deleted",
|
|
435
|
-
})
|
|
436
|
-
}
|
|
437
|
-
|
|
438
321
|
let groupsToModify: any = {}
|
|
439
322
|
let builderCount = 0
|
|
440
|
-
|
|
441
323
|
// Get users and delete
|
|
442
|
-
|
|
443
|
-
|
|
444
|
-
|
|
445
|
-
|
|
446
|
-
|
|
447
|
-
|
|
448
|
-
|
|
449
|
-
|
|
450
|
-
|
|
451
|
-
|
|
452
|
-
|
|
453
|
-
|
|
454
|
-
|
|
455
|
-
|
|
456
|
-
|
|
457
|
-
}
|
|
324
|
+
let usersToDelete = (
|
|
325
|
+
await db.allDocs({
|
|
326
|
+
include_docs: true,
|
|
327
|
+
keys: userIds,
|
|
328
|
+
})
|
|
329
|
+
).rows.map((user: any) => {
|
|
330
|
+
// if we find a user that has an associated group, add it to
|
|
331
|
+
// an array so we can easily use allDocs on them later.
|
|
332
|
+
// This prevents us having to re-loop over all the users
|
|
333
|
+
if (user.doc.userGroups) {
|
|
334
|
+
for (let groupId of user.doc.userGroups) {
|
|
335
|
+
if (!Object.keys(groupsToModify).includes(groupId)) {
|
|
336
|
+
groupsToModify[groupId] = [user.id]
|
|
337
|
+
} else {
|
|
338
|
+
groupsToModify[groupId] = [...groupsToModify[groupId], user.id]
|
|
458
339
|
}
|
|
459
340
|
}
|
|
341
|
+
}
|
|
460
342
|
|
|
461
|
-
|
|
462
|
-
|
|
463
|
-
|
|
464
|
-
}
|
|
465
|
-
|
|
466
|
-
return user.doc
|
|
343
|
+
// Also figure out how many builders are being deleted
|
|
344
|
+
if (eventHelpers.isAddingBuilder(user.doc, null)) {
|
|
345
|
+
builderCount++
|
|
467
346
|
}
|
|
468
|
-
)
|
|
469
347
|
|
|
470
|
-
|
|
471
|
-
|
|
472
|
-
|
|
348
|
+
return user.doc
|
|
349
|
+
})
|
|
350
|
+
|
|
351
|
+
const response = await db.bulkDocs(
|
|
352
|
+
usersToDelete.map((user: any) => ({
|
|
473
353
|
...user,
|
|
474
354
|
_deleted: true,
|
|
475
355
|
}))
|
|
476
356
|
)
|
|
477
357
|
|
|
478
|
-
// Deletion post processing
|
|
479
358
|
await groupUtils.bulkDeleteGroupUsers(groupsToModify)
|
|
359
|
+
|
|
360
|
+
//Deletion post processing
|
|
480
361
|
for (let user of usersToDelete) {
|
|
481
362
|
await bulkDeleteProcessing(user)
|
|
482
363
|
}
|
|
483
|
-
await quotas.removeDevelopers(builderCount)
|
|
484
364
|
|
|
485
|
-
|
|
486
|
-
// index users by id
|
|
487
|
-
const userIndex: { [key: string]: User } = {}
|
|
488
|
-
usersToDelete.reduce((prev, current) => {
|
|
489
|
-
prev[current._id!] = current
|
|
490
|
-
return prev
|
|
491
|
-
}, userIndex)
|
|
492
|
-
|
|
493
|
-
// add the successful and unsuccessful users to response
|
|
494
|
-
dbResponse.forEach(item => {
|
|
495
|
-
const email = userIndex[item.id].email
|
|
496
|
-
if (item.ok) {
|
|
497
|
-
response.successful.push({ _id: item.id, email })
|
|
498
|
-
} else {
|
|
499
|
-
response.unsuccessful.push({
|
|
500
|
-
_id: item.id,
|
|
501
|
-
email,
|
|
502
|
-
reason: "Database error",
|
|
503
|
-
})
|
|
504
|
-
}
|
|
505
|
-
})
|
|
365
|
+
await quotas.removeDevelopers(builderCount)
|
|
506
366
|
|
|
507
367
|
return response
|
|
508
368
|
}
|
|
@@ -0,0 +1,231 @@
|
|
|
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
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
const TestConfiguration = require("./TestConfiguration")
|
|
2
|
+
const structures = require("./structures")
|
|
3
|
+
const mocks = require("./mocks")
|
|
4
|
+
const config = new TestConfiguration()
|
|
5
|
+
const request = config.getRequest()
|
|
6
|
+
|
|
7
|
+
module.exports = {
|
|
8
|
+
structures,
|
|
9
|
+
mocks,
|
|
10
|
+
config,
|
|
11
|
+
request,
|
|
12
|
+
}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
const configs = require("./configs")
|
|
2
|
+
const users = require("./users")
|
|
3
|
+
const groups = require("./groups")
|
|
4
|
+
|
|
5
|
+
const TENANT_ID = "default"
|
|
6
|
+
const CSRF_TOKEN = "e3727778-7af0-4226-b5eb-f43cbe60a306"
|
|
7
|
+
|
|
8
|
+
module.exports = {
|
|
9
|
+
configs,
|
|
10
|
+
users,
|
|
11
|
+
TENANT_ID,
|
|
12
|
+
CSRF_TOKEN,
|
|
13
|
+
groups,
|
|
14
|
+
}
|
|
@@ -1,32 +1,24 @@
|
|
|
1
1
|
export const email = "test@test.com"
|
|
2
|
-
import { AdminUser, BuilderUser, User } from "@budibase/types"
|
|
3
|
-
import { v4 as uuid } from "uuid"
|
|
4
2
|
|
|
5
|
-
export const
|
|
6
|
-
return `${uuid()}@test.com`
|
|
7
|
-
}
|
|
8
|
-
export const user = (userProps?: any): User => {
|
|
3
|
+
export const user = (userProps: any) => {
|
|
9
4
|
return {
|
|
10
|
-
email:
|
|
5
|
+
email: "test@test.com",
|
|
11
6
|
password: "test",
|
|
12
7
|
roles: {},
|
|
13
8
|
...userProps,
|
|
14
9
|
}
|
|
15
10
|
}
|
|
16
11
|
|
|
17
|
-
export const adminUser = (userProps
|
|
12
|
+
export const adminUser = (userProps: any) => {
|
|
18
13
|
return {
|
|
19
14
|
...user(userProps),
|
|
20
15
|
admin: {
|
|
21
16
|
global: true,
|
|
22
17
|
},
|
|
23
|
-
builder: {
|
|
24
|
-
global: true,
|
|
25
|
-
},
|
|
26
18
|
}
|
|
27
19
|
}
|
|
28
20
|
|
|
29
|
-
export const builderUser = (userProps
|
|
21
|
+
export const builderUser = (userProps: any) => {
|
|
30
22
|
return {
|
|
31
23
|
...user(userProps),
|
|
32
24
|
builder: {
|