@budibase/worker 2.5.6-alpha.3 → 2.5.6-alpha.31
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
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@budibase/worker",
|
|
3
3
|
"email": "hi@budibase.com",
|
|
4
|
-
"version": "2.5.6-alpha.
|
|
4
|
+
"version": "2.5.6-alpha.31",
|
|
5
5
|
"description": "Budibase background service",
|
|
6
6
|
"main": "src/index.ts",
|
|
7
7
|
"repository": {
|
|
@@ -37,10 +37,10 @@
|
|
|
37
37
|
"author": "Budibase",
|
|
38
38
|
"license": "GPL-3.0",
|
|
39
39
|
"dependencies": {
|
|
40
|
-
"@budibase/backend-core": "2.5.6-alpha.
|
|
41
|
-
"@budibase/pro": "2.5.6-alpha.
|
|
42
|
-
"@budibase/string-templates": "2.5.6-alpha.
|
|
43
|
-
"@budibase/types": "2.5.6-alpha.
|
|
40
|
+
"@budibase/backend-core": "2.5.6-alpha.31",
|
|
41
|
+
"@budibase/pro": "2.5.6-alpha.30",
|
|
42
|
+
"@budibase/string-templates": "2.5.6-alpha.31",
|
|
43
|
+
"@budibase/types": "2.5.6-alpha.31",
|
|
44
44
|
"@koa/router": "8.0.8",
|
|
45
45
|
"@sentry/node": "6.17.7",
|
|
46
46
|
"@techpass/passport-openidconnect": "0.3.2",
|
|
@@ -102,5 +102,5 @@
|
|
|
102
102
|
"typescript": "4.7.3",
|
|
103
103
|
"update-dotenv": "1.1.1"
|
|
104
104
|
},
|
|
105
|
-
"gitHead": "
|
|
105
|
+
"gitHead": "aa0b9fe116c5fbf2dc7ecaae529541aa6c1f2235"
|
|
106
106
|
}
|
|
@@ -329,6 +329,7 @@ export const checkInvite = async (ctx: any) => {
|
|
|
329
329
|
try {
|
|
330
330
|
invite = await checkInviteCode(code, false)
|
|
331
331
|
} catch (e) {
|
|
332
|
+
console.warn("Error getting invite from code", e)
|
|
332
333
|
ctx.throw(400, "There was a problem with the invite")
|
|
333
334
|
}
|
|
334
335
|
ctx.body = {
|
|
@@ -415,8 +416,8 @@ export const inviteAccept = async (
|
|
|
415
416
|
})
|
|
416
417
|
|
|
417
418
|
ctx.body = {
|
|
418
|
-
_id: user._id
|
|
419
|
-
_rev: user._rev
|
|
419
|
+
_id: user._id!,
|
|
420
|
+
_rev: user._rev!,
|
|
420
421
|
email: user.email,
|
|
421
422
|
}
|
|
422
423
|
} catch (err: any) {
|
|
@@ -1,7 +1,7 @@
|
|
|
1
|
-
import { Account, AccountMetadata } from "@budibase/types"
|
|
1
|
+
import { Account, AccountMetadata, Ctx } from "@budibase/types"
|
|
2
2
|
import * as accounts from "../../../sdk/accounts"
|
|
3
3
|
|
|
4
|
-
export const save = async (ctx:
|
|
4
|
+
export const save = async (ctx: Ctx<Account, AccountMetadata>) => {
|
|
5
5
|
const account = ctx.request.body as Account
|
|
6
6
|
let metadata: AccountMetadata = {
|
|
7
7
|
_id: accounts.metadata.formatAccountMetadataId(account.accountId),
|
package/src/sdk/users/users.ts
CHANGED
|
@@ -20,7 +20,6 @@ import {
|
|
|
20
20
|
import {
|
|
21
21
|
AccountMetadata,
|
|
22
22
|
AllDocsResponse,
|
|
23
|
-
BulkUserResponse,
|
|
24
23
|
CloudAccount,
|
|
25
24
|
InviteUsersRequest,
|
|
26
25
|
InviteUsersResponse,
|
|
@@ -31,6 +30,8 @@ import {
|
|
|
31
30
|
RowResponse,
|
|
32
31
|
User,
|
|
33
32
|
SaveUserOpts,
|
|
33
|
+
BulkUserCreated,
|
|
34
|
+
BulkUserDeleted,
|
|
34
35
|
Account,
|
|
35
36
|
} from "@budibase/types"
|
|
36
37
|
import { sendEmail } from "../../utilities/email"
|
|
@@ -196,6 +197,8 @@ export async function isPreventPasswordActions(user: User, account?: Account) {
|
|
|
196
197
|
return !!(account && account.email === user.email && isSSOAccount(account))
|
|
197
198
|
}
|
|
198
199
|
|
|
200
|
+
// TODO: The single save should re-use the bulk insert with a single
|
|
201
|
+
// user so that we don't need to duplicate logic
|
|
199
202
|
export const save = async (
|
|
200
203
|
user: User,
|
|
201
204
|
opts: SaveUserOpts = {}
|
|
@@ -242,53 +245,56 @@ export const save = async (
|
|
|
242
245
|
}
|
|
243
246
|
}
|
|
244
247
|
|
|
245
|
-
|
|
248
|
+
const change = dbUser ? 0 : 1 // no change if there is existing user
|
|
249
|
+
return pro.quotas.addUsers(change, async () => {
|
|
250
|
+
await validateUniqueUser(email, tenantId)
|
|
246
251
|
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
252
|
+
let builtUser = await buildUser(user, opts, tenantId, dbUser)
|
|
253
|
+
// don't allow a user to update its own roles/perms
|
|
254
|
+
if (opts.currentUserId && opts.currentUserId === dbUser?._id) {
|
|
255
|
+
builtUser.builder = dbUser.builder
|
|
256
|
+
builtUser.admin = dbUser.admin
|
|
257
|
+
builtUser.roles = dbUser.roles
|
|
258
|
+
}
|
|
254
259
|
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
260
|
+
if (!dbUser && roles?.length) {
|
|
261
|
+
builtUser.roles = { ...roles }
|
|
262
|
+
}
|
|
258
263
|
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
+
// make sure we set the _id field for a new user
|
|
265
|
+
// Also if this is a new user, associate groups with them
|
|
266
|
+
let groupPromises = []
|
|
267
|
+
if (!_id) {
|
|
268
|
+
_id = builtUser._id!
|
|
264
269
|
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
270
|
+
if (userGroups.length > 0) {
|
|
271
|
+
for (let groupId of userGroups) {
|
|
272
|
+
groupPromises.push(pro.groups.addUsers(groupId, [_id]))
|
|
273
|
+
}
|
|
268
274
|
}
|
|
269
275
|
}
|
|
270
|
-
}
|
|
271
276
|
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
|
|
277
|
+
try {
|
|
278
|
+
// save the user to db
|
|
279
|
+
let response = await db.put(builtUser)
|
|
280
|
+
builtUser._rev = response.rev
|
|
276
281
|
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
282
|
+
await eventHelpers.handleSaveEvents(builtUser, dbUser)
|
|
283
|
+
await platform.users.addUser(tenantId, builtUser._id!, builtUser.email)
|
|
284
|
+
await cache.user.invalidateUser(response.id)
|
|
280
285
|
|
|
281
|
-
|
|
286
|
+
await Promise.all(groupPromises)
|
|
282
287
|
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
|
|
288
|
+
// finally returned the saved user from the db
|
|
289
|
+
return db.get(builtUser._id!)
|
|
290
|
+
} catch (err: any) {
|
|
291
|
+
if (err.status === 409) {
|
|
292
|
+
throw "User exists already"
|
|
293
|
+
} else {
|
|
294
|
+
throw err
|
|
295
|
+
}
|
|
290
296
|
}
|
|
291
|
-
}
|
|
297
|
+
})
|
|
292
298
|
}
|
|
293
299
|
|
|
294
300
|
const getExistingTenantUsers = async (emails: string[]): Promise<User[]> => {
|
|
@@ -374,7 +380,7 @@ const searchExistingEmails = async (emails: string[]) => {
|
|
|
374
380
|
export const bulkCreate = async (
|
|
375
381
|
newUsersRequested: User[],
|
|
376
382
|
groups: string[]
|
|
377
|
-
): Promise<
|
|
383
|
+
): Promise<BulkUserCreated> => {
|
|
378
384
|
const tenantId = tenancy.getTenantId()
|
|
379
385
|
|
|
380
386
|
let usersToSave: any[] = []
|
|
@@ -402,54 +408,56 @@ export const bulkCreate = async (
|
|
|
402
408
|
}
|
|
403
409
|
|
|
404
410
|
const account = await accountSdk.api.getAccountByTenantId(tenantId)
|
|
405
|
-
|
|
406
|
-
|
|
407
|
-
|
|
408
|
-
|
|
409
|
-
|
|
410
|
-
|
|
411
|
-
|
|
412
|
-
|
|
413
|
-
|
|
414
|
-
|
|
415
|
-
|
|
416
|
-
|
|
411
|
+
return pro.quotas.addUsers(newUsers.length, async () => {
|
|
412
|
+
// create the promises array that will be called by bulkDocs
|
|
413
|
+
newUsers.forEach((user: any) => {
|
|
414
|
+
usersToSave.push(
|
|
415
|
+
buildUser(
|
|
416
|
+
user,
|
|
417
|
+
{
|
|
418
|
+
hashPassword: true,
|
|
419
|
+
requirePassword: user.requirePassword,
|
|
420
|
+
},
|
|
421
|
+
tenantId,
|
|
422
|
+
undefined, // no dbUser
|
|
423
|
+
account
|
|
424
|
+
)
|
|
417
425
|
)
|
|
418
|
-
)
|
|
419
|
-
})
|
|
420
|
-
|
|
421
|
-
const usersToBulkSave = await Promise.all(usersToSave)
|
|
422
|
-
await usersCore.bulkUpdateGlobalUsers(usersToBulkSave)
|
|
426
|
+
})
|
|
423
427
|
|
|
424
|
-
|
|
425
|
-
|
|
426
|
-
// TODO: Refactor to bulk insert users into the info db
|
|
427
|
-
// instead of relying on looping tenant creation
|
|
428
|
-
await platform.users.addUser(tenantId, user._id, user.email)
|
|
429
|
-
await eventHelpers.handleSaveEvents(user, undefined)
|
|
430
|
-
}
|
|
428
|
+
const usersToBulkSave = await Promise.all(usersToSave)
|
|
429
|
+
await usersCore.bulkUpdateGlobalUsers(usersToBulkSave)
|
|
431
430
|
|
|
432
|
-
|
|
433
|
-
|
|
434
|
-
|
|
435
|
-
|
|
431
|
+
// Post-processing of bulk added users, e.g. events and cache operations
|
|
432
|
+
for (const user of usersToBulkSave) {
|
|
433
|
+
// TODO: Refactor to bulk insert users into the info db
|
|
434
|
+
// instead of relying on looping tenant creation
|
|
435
|
+
await platform.users.addUser(tenantId, user._id, user.email)
|
|
436
|
+
await eventHelpers.handleSaveEvents(user, undefined)
|
|
436
437
|
}
|
|
437
|
-
})
|
|
438
438
|
|
|
439
|
-
|
|
440
|
-
|
|
441
|
-
|
|
442
|
-
|
|
443
|
-
|
|
444
|
-
|
|
439
|
+
const saved = usersToBulkSave.map(user => {
|
|
440
|
+
return {
|
|
441
|
+
_id: user._id,
|
|
442
|
+
email: user.email,
|
|
443
|
+
}
|
|
444
|
+
})
|
|
445
|
+
|
|
446
|
+
// now update the groups
|
|
447
|
+
if (Array.isArray(saved) && groups) {
|
|
448
|
+
const groupPromises = []
|
|
449
|
+
const createdUserIds = saved.map(user => user._id)
|
|
450
|
+
for (let groupId of groups) {
|
|
451
|
+
groupPromises.push(pro.groups.addUsers(groupId, createdUserIds))
|
|
452
|
+
}
|
|
453
|
+
await Promise.all(groupPromises)
|
|
445
454
|
}
|
|
446
|
-
await Promise.all(groupPromises)
|
|
447
|
-
}
|
|
448
455
|
|
|
449
|
-
|
|
450
|
-
|
|
451
|
-
|
|
452
|
-
|
|
456
|
+
return {
|
|
457
|
+
successful: saved,
|
|
458
|
+
unsuccessful,
|
|
459
|
+
}
|
|
460
|
+
})
|
|
453
461
|
}
|
|
454
462
|
|
|
455
463
|
/**
|
|
@@ -474,10 +482,10 @@ const getAccountHolderFromUserIds = async (
|
|
|
474
482
|
|
|
475
483
|
export const bulkDelete = async (
|
|
476
484
|
userIds: string[]
|
|
477
|
-
): Promise<
|
|
485
|
+
): Promise<BulkUserDeleted> => {
|
|
478
486
|
const db = tenancy.getGlobalDB()
|
|
479
487
|
|
|
480
|
-
const response:
|
|
488
|
+
const response: BulkUserDeleted = {
|
|
481
489
|
successful: [],
|
|
482
490
|
unsuccessful: [],
|
|
483
491
|
}
|
|
@@ -511,6 +519,8 @@ export const bulkDelete = async (
|
|
|
511
519
|
_deleted: true,
|
|
512
520
|
}))
|
|
513
521
|
const dbResponse = await usersCore.bulkUpdateGlobalUsers(toDelete)
|
|
522
|
+
|
|
523
|
+
await pro.quotas.removeUsers(toDelete.length)
|
|
514
524
|
for (let user of usersToDelete) {
|
|
515
525
|
await bulkDeleteProcessing(user)
|
|
516
526
|
}
|
|
@@ -540,6 +550,8 @@ export const bulkDelete = async (
|
|
|
540
550
|
return response
|
|
541
551
|
}
|
|
542
552
|
|
|
553
|
+
// TODO: The single delete should re-use the bulk delete with a single
|
|
554
|
+
// user so that we don't need to duplicate logic
|
|
543
555
|
export const destroy = async (id: string) => {
|
|
544
556
|
const db = tenancy.getGlobalDB()
|
|
545
557
|
const dbUser = (await db.get(id)) as User
|
|
@@ -562,6 +574,7 @@ export const destroy = async (id: string) => {
|
|
|
562
574
|
|
|
563
575
|
await db.remove(userId, dbUser._rev)
|
|
564
576
|
|
|
577
|
+
await pro.quotas.removeUsers(1)
|
|
565
578
|
await eventHelpers.handleDeleteEvents(dbUser)
|
|
566
579
|
await cache.user.invalidateUser(userId)
|
|
567
580
|
await sessions.invalidateSessions(userId, { reason: "deletion" })
|
package/src/utilities/email.ts
CHANGED
|
@@ -62,8 +62,8 @@ function createSMTPTransport(config?: SMTPInnerConfig) {
|
|
|
62
62
|
host: "smtp.ethereal.email",
|
|
63
63
|
secure: false,
|
|
64
64
|
auth: {
|
|
65
|
-
user: "
|
|
66
|
-
pass: "
|
|
65
|
+
user: "seamus99@ethereal.email",
|
|
66
|
+
pass: "5ghVteZAqj6jkKJF9R",
|
|
67
67
|
},
|
|
68
68
|
}
|
|
69
69
|
}
|
package/tsconfig.json
CHANGED