@budibase/backend-core 2.11.41 → 2.11.43
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/dist/index.js +45 -56
- package/dist/index.js.map +3 -3
- package/dist/index.js.meta.json +1 -1
- package/dist/package.json +4 -4
- package/dist/plugins.js.meta.json +1 -1
- package/dist/src/cache/writethrough.d.ts +1 -1
- package/dist/src/cache/writethrough.js +2 -2
- package/dist/src/cache/writethrough.js.map +1 -1
- package/dist/src/environment.js +2 -2
- package/dist/src/environment.js.map +1 -1
- package/dist/src/users/db.d.ts +1 -1
- package/dist/src/users/db.js +4 -11
- package/dist/src/users/db.js.map +1 -1
- package/dist/src/users/users.d.ts +1 -1
- package/dist/tests/core/utilities/structures/licenses.js +0 -8
- package/dist/tests/core/utilities/structures/licenses.js.map +1 -1
- package/package.json +4 -4
- package/src/cache/writethrough.ts +2 -2
- package/src/environment.ts +2 -2
- package/src/users/db.ts +46 -62
- package/src/users/users.ts +1 -1
- package/tests/core/utilities/structures/licenses.ts +0 -8
- package/tests/core/users/users.spec.js +0 -54
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@budibase/backend-core",
|
|
3
|
-
"version": "2.11.
|
|
3
|
+
"version": "2.11.43",
|
|
4
4
|
"description": "Budibase backend core libraries used in server and worker",
|
|
5
5
|
"main": "dist/index.js",
|
|
6
6
|
"types": "dist/src/index.d.ts",
|
|
@@ -23,8 +23,8 @@
|
|
|
23
23
|
"dependencies": {
|
|
24
24
|
"@budibase/nano": "10.1.2",
|
|
25
25
|
"@budibase/pouchdb-replication-stream": "1.2.10",
|
|
26
|
-
"@budibase/shared-core": "2.11.
|
|
27
|
-
"@budibase/types": "2.11.
|
|
26
|
+
"@budibase/shared-core": "2.11.43",
|
|
27
|
+
"@budibase/types": "2.11.43",
|
|
28
28
|
"@techpass/passport-openidconnect": "0.3.2",
|
|
29
29
|
"aws-cloudfront-sign": "3.0.2",
|
|
30
30
|
"aws-sdk": "2.1030.0",
|
|
@@ -96,5 +96,5 @@
|
|
|
96
96
|
}
|
|
97
97
|
}
|
|
98
98
|
},
|
|
99
|
-
"gitHead": "
|
|
99
|
+
"gitHead": "7f83c1b897398f29dbc5571ac039cff430a5db47"
|
|
100
100
|
}
|
|
@@ -119,8 +119,8 @@ export class Writethrough {
|
|
|
119
119
|
this.writeRateMs = writeRateMs
|
|
120
120
|
}
|
|
121
121
|
|
|
122
|
-
async put(doc: any
|
|
123
|
-
return put(this.db, doc, writeRateMs)
|
|
122
|
+
async put(doc: any) {
|
|
123
|
+
return put(this.db, doc, this.writeRateMs)
|
|
124
124
|
}
|
|
125
125
|
|
|
126
126
|
async get(id: string) {
|
package/src/environment.ts
CHANGED
|
@@ -75,12 +75,12 @@ function getPackageJsonFields(): {
|
|
|
75
75
|
const content = readFileSync(packageJsonFile!, "utf-8")
|
|
76
76
|
const parsedContent = JSON.parse(content)
|
|
77
77
|
return {
|
|
78
|
-
VERSION: parsedContent.version,
|
|
78
|
+
VERSION: process.env.BUDIBASE_VERSION || parsedContent.version,
|
|
79
79
|
SERVICE_NAME: parsedContent.name,
|
|
80
80
|
}
|
|
81
81
|
} catch {
|
|
82
82
|
// throwing an error here is confusing/causes backend-core to be hard to import
|
|
83
|
-
return { VERSION: "", SERVICE_NAME: "" }
|
|
83
|
+
return { VERSION: process.env.BUDIBASE_VERSION || "", SERVICE_NAME: "" }
|
|
84
84
|
}
|
|
85
85
|
}
|
|
86
86
|
|
package/src/users/db.ts
CHANGED
|
@@ -25,17 +25,12 @@ import {
|
|
|
25
25
|
import {
|
|
26
26
|
getAccountHolderFromUserIds,
|
|
27
27
|
isAdmin,
|
|
28
|
-
isCreator,
|
|
29
28
|
validateUniqueUser,
|
|
30
29
|
} from "./utils"
|
|
31
30
|
import { searchExistingEmails } from "./lookup"
|
|
32
31
|
import { hash } from "../utils"
|
|
33
32
|
|
|
34
|
-
type QuotaUpdateFn = (
|
|
35
|
-
change: number,
|
|
36
|
-
creatorsChange: number,
|
|
37
|
-
cb?: () => Promise<any>
|
|
38
|
-
) => Promise<any>
|
|
33
|
+
type QuotaUpdateFn = (change: number, cb?: () => Promise<any>) => Promise<any>
|
|
39
34
|
type GroupUpdateFn = (groupId: string, userIds: string[]) => Promise<any>
|
|
40
35
|
type FeatureFn = () => Promise<Boolean>
|
|
41
36
|
type GroupGetFn = (ids: string[]) => Promise<UserGroup[]>
|
|
@@ -250,8 +245,7 @@ export class UserDB {
|
|
|
250
245
|
}
|
|
251
246
|
|
|
252
247
|
const change = dbUser ? 0 : 1 // no change if there is existing user
|
|
253
|
-
|
|
254
|
-
return UserDB.quotas.addUsers(change, creatorsChange, async () => {
|
|
248
|
+
return UserDB.quotas.addUsers(change, async () => {
|
|
255
249
|
await validateUniqueUser(email, tenantId)
|
|
256
250
|
|
|
257
251
|
let builtUser = await UserDB.buildUser(user, opts, tenantId, dbUser)
|
|
@@ -313,7 +307,6 @@ export class UserDB {
|
|
|
313
307
|
|
|
314
308
|
let usersToSave: any[] = []
|
|
315
309
|
let newUsers: any[] = []
|
|
316
|
-
let newCreators: any[] = []
|
|
317
310
|
|
|
318
311
|
const emails = newUsersRequested.map((user: User) => user.email)
|
|
319
312
|
const existingEmails = await searchExistingEmails(emails)
|
|
@@ -334,66 +327,59 @@ export class UserDB {
|
|
|
334
327
|
}
|
|
335
328
|
newUser.userGroups = groups
|
|
336
329
|
newUsers.push(newUser)
|
|
337
|
-
if (isCreator(newUser)) {
|
|
338
|
-
newCreators.push(newUser)
|
|
339
|
-
}
|
|
340
330
|
}
|
|
341
331
|
|
|
342
332
|
const account = await accountSdk.getAccountByTenantId(tenantId)
|
|
343
|
-
return UserDB.quotas.addUsers(
|
|
344
|
-
|
|
345
|
-
|
|
346
|
-
|
|
347
|
-
|
|
348
|
-
|
|
349
|
-
|
|
350
|
-
|
|
351
|
-
user,
|
|
352
|
-
|
|
353
|
-
|
|
354
|
-
|
|
355
|
-
|
|
356
|
-
tenantId,
|
|
357
|
-
undefined, // no dbUser
|
|
358
|
-
account
|
|
359
|
-
)
|
|
333
|
+
return UserDB.quotas.addUsers(newUsers.length, async () => {
|
|
334
|
+
// create the promises array that will be called by bulkDocs
|
|
335
|
+
newUsers.forEach((user: any) => {
|
|
336
|
+
usersToSave.push(
|
|
337
|
+
UserDB.buildUser(
|
|
338
|
+
user,
|
|
339
|
+
{
|
|
340
|
+
hashPassword: true,
|
|
341
|
+
requirePassword: user.requirePassword,
|
|
342
|
+
},
|
|
343
|
+
tenantId,
|
|
344
|
+
undefined, // no dbUser
|
|
345
|
+
account
|
|
360
346
|
)
|
|
361
|
-
|
|
347
|
+
)
|
|
348
|
+
})
|
|
362
349
|
|
|
363
|
-
|
|
364
|
-
|
|
350
|
+
const usersToBulkSave = await Promise.all(usersToSave)
|
|
351
|
+
await usersCore.bulkUpdateGlobalUsers(usersToBulkSave)
|
|
365
352
|
|
|
366
|
-
|
|
367
|
-
|
|
368
|
-
|
|
369
|
-
|
|
370
|
-
|
|
371
|
-
|
|
372
|
-
|
|
373
|
-
|
|
374
|
-
const saved = usersToBulkSave.map(user => {
|
|
375
|
-
return {
|
|
376
|
-
_id: user._id,
|
|
377
|
-
email: user.email,
|
|
378
|
-
}
|
|
379
|
-
})
|
|
353
|
+
// Post-processing of bulk added users, e.g. events and cache operations
|
|
354
|
+
for (const user of usersToBulkSave) {
|
|
355
|
+
// TODO: Refactor to bulk insert users into the info db
|
|
356
|
+
// instead of relying on looping tenant creation
|
|
357
|
+
await platform.users.addUser(tenantId, user._id, user.email)
|
|
358
|
+
await eventHelpers.handleSaveEvents(user, undefined)
|
|
359
|
+
}
|
|
380
360
|
|
|
381
|
-
|
|
382
|
-
|
|
383
|
-
|
|
384
|
-
|
|
385
|
-
for (let groupId of groups) {
|
|
386
|
-
groupPromises.push(UserDB.groups.addUsers(groupId, createdUserIds))
|
|
387
|
-
}
|
|
388
|
-
await Promise.all(groupPromises)
|
|
361
|
+
const saved = usersToBulkSave.map(user => {
|
|
362
|
+
return {
|
|
363
|
+
_id: user._id,
|
|
364
|
+
email: user.email,
|
|
389
365
|
}
|
|
366
|
+
})
|
|
390
367
|
|
|
391
|
-
|
|
392
|
-
|
|
393
|
-
|
|
368
|
+
// now update the groups
|
|
369
|
+
if (Array.isArray(saved) && groups) {
|
|
370
|
+
const groupPromises = []
|
|
371
|
+
const createdUserIds = saved.map(user => user._id)
|
|
372
|
+
for (let groupId of groups) {
|
|
373
|
+
groupPromises.push(UserDB.groups.addUsers(groupId, createdUserIds))
|
|
394
374
|
}
|
|
375
|
+
await Promise.all(groupPromises)
|
|
395
376
|
}
|
|
396
|
-
|
|
377
|
+
|
|
378
|
+
return {
|
|
379
|
+
successful: saved,
|
|
380
|
+
unsuccessful,
|
|
381
|
+
}
|
|
382
|
+
})
|
|
397
383
|
}
|
|
398
384
|
|
|
399
385
|
static async bulkDelete(userIds: string[]): Promise<BulkUserDeleted> {
|
|
@@ -433,12 +419,11 @@ export class UserDB {
|
|
|
433
419
|
_deleted: true,
|
|
434
420
|
}))
|
|
435
421
|
const dbResponse = await usersCore.bulkUpdateGlobalUsers(toDelete)
|
|
436
|
-
const creatorsToDelete = usersToDelete.filter(isCreator)
|
|
437
422
|
|
|
423
|
+
await UserDB.quotas.removeUsers(toDelete.length)
|
|
438
424
|
for (let user of usersToDelete) {
|
|
439
425
|
await bulkDeleteProcessing(user)
|
|
440
426
|
}
|
|
441
|
-
await UserDB.quotas.removeUsers(toDelete.length, creatorsToDelete.length)
|
|
442
427
|
|
|
443
428
|
// Build Response
|
|
444
429
|
// index users by id
|
|
@@ -487,8 +472,7 @@ export class UserDB {
|
|
|
487
472
|
|
|
488
473
|
await db.remove(userId, dbUser._rev)
|
|
489
474
|
|
|
490
|
-
|
|
491
|
-
await UserDB.quotas.removeUsers(1, creatorsToDelete)
|
|
475
|
+
await UserDB.quotas.removeUsers(1)
|
|
492
476
|
await eventHelpers.handleDeleteEvents(dbUser)
|
|
493
477
|
await cache.user.invalidateUser(userId)
|
|
494
478
|
await sessions.invalidateSessions(userId, { reason: "deletion" })
|
package/src/users/users.ts
CHANGED
|
@@ -14,11 +14,11 @@ import {
|
|
|
14
14
|
} from "../db"
|
|
15
15
|
import {
|
|
16
16
|
BulkDocsResponse,
|
|
17
|
+
ContextUser,
|
|
17
18
|
SearchQuery,
|
|
18
19
|
SearchQueryOperators,
|
|
19
20
|
SearchUsersRequest,
|
|
20
21
|
User,
|
|
21
|
-
ContextUser,
|
|
22
22
|
DatabaseQueryOpts,
|
|
23
23
|
} from "@budibase/types"
|
|
24
24
|
import { getGlobalDB } from "../context"
|
|
@@ -123,10 +123,6 @@ export function customer(): Customer {
|
|
|
123
123
|
export function subscription(): Subscription {
|
|
124
124
|
return {
|
|
125
125
|
amount: 10000,
|
|
126
|
-
amounts: {
|
|
127
|
-
user: 10000,
|
|
128
|
-
creator: 0,
|
|
129
|
-
},
|
|
130
126
|
cancelAt: undefined,
|
|
131
127
|
currency: "usd",
|
|
132
128
|
currentPeriodEnd: 0,
|
|
@@ -135,10 +131,6 @@ export function subscription(): Subscription {
|
|
|
135
131
|
duration: PriceDuration.MONTHLY,
|
|
136
132
|
pastDueAt: undefined,
|
|
137
133
|
quantity: 0,
|
|
138
|
-
quantities: {
|
|
139
|
-
user: 0,
|
|
140
|
-
creator: 0,
|
|
141
|
-
},
|
|
142
134
|
status: "active",
|
|
143
135
|
}
|
|
144
136
|
}
|
|
@@ -1,54 +0,0 @@
|
|
|
1
|
-
const _ = require('lodash/fp')
|
|
2
|
-
const {structures} = require("../../../tests")
|
|
3
|
-
|
|
4
|
-
jest.mock("../../../src/context")
|
|
5
|
-
jest.mock("../../../src/db")
|
|
6
|
-
|
|
7
|
-
const context = require("../../../src/context")
|
|
8
|
-
const db = require("../../../src/db")
|
|
9
|
-
|
|
10
|
-
const {getCreatorCount} = require('../../../src/users/users')
|
|
11
|
-
|
|
12
|
-
describe("Users", () => {
|
|
13
|
-
|
|
14
|
-
let getGlobalDBMock
|
|
15
|
-
let getGlobalUserParamsMock
|
|
16
|
-
let paginationMock
|
|
17
|
-
|
|
18
|
-
beforeEach(() => {
|
|
19
|
-
jest.resetAllMocks()
|
|
20
|
-
|
|
21
|
-
getGlobalDBMock = jest.spyOn(context, "getGlobalDB")
|
|
22
|
-
getGlobalUserParamsMock = jest.spyOn(db, "getGlobalUserParams")
|
|
23
|
-
paginationMock = jest.spyOn(db, "pagination")
|
|
24
|
-
})
|
|
25
|
-
|
|
26
|
-
it("Retrieves the number of creators", async () => {
|
|
27
|
-
const getUsers = (offset, limit, creators = false) => {
|
|
28
|
-
const range = _.range(offset, limit)
|
|
29
|
-
const opts = creators ? {builder: {global: true}} : undefined
|
|
30
|
-
return range.map(() => structures.users.user(opts))
|
|
31
|
-
}
|
|
32
|
-
const page1Data = getUsers(0, 8)
|
|
33
|
-
const page2Data = getUsers(8, 12, true)
|
|
34
|
-
getGlobalDBMock.mockImplementation(() => ({
|
|
35
|
-
name : "fake-db",
|
|
36
|
-
allDocs: () => ({
|
|
37
|
-
rows: [...page1Data, ...page2Data]
|
|
38
|
-
})
|
|
39
|
-
}))
|
|
40
|
-
paginationMock.mockImplementationOnce(() => ({
|
|
41
|
-
data: page1Data,
|
|
42
|
-
hasNextPage: true,
|
|
43
|
-
nextPage: "1"
|
|
44
|
-
}))
|
|
45
|
-
paginationMock.mockImplementation(() => ({
|
|
46
|
-
data: page2Data,
|
|
47
|
-
hasNextPage: false,
|
|
48
|
-
nextPage: undefined
|
|
49
|
-
}))
|
|
50
|
-
const creatorsCount = await getCreatorCount()
|
|
51
|
-
expect(creatorsCount).toBe(4)
|
|
52
|
-
expect(paginationMock).toHaveBeenCalledTimes(2)
|
|
53
|
-
})
|
|
54
|
-
})
|