@budibase/worker 3.37.5 → 3.38.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
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@budibase/worker",
|
|
3
3
|
"email": "hi@budibase.com",
|
|
4
|
-
"version": "3.
|
|
4
|
+
"version": "3.38.1",
|
|
5
5
|
"description": "Budibase background service",
|
|
6
6
|
"main": "src/index.ts",
|
|
7
7
|
"repository": {
|
|
@@ -56,7 +56,7 @@
|
|
|
56
56
|
"lodash": "4.18.1",
|
|
57
57
|
"marked": "^15.0.11",
|
|
58
58
|
"node-fetch": "2.6.7",
|
|
59
|
-
"nodemailer": "8.0.
|
|
59
|
+
"nodemailer": "8.0.7",
|
|
60
60
|
"pouchdb": "9.0.0",
|
|
61
61
|
"scim-patch": "^0.8.1",
|
|
62
62
|
"scim2-parse-filter": "^0.2.8",
|
|
@@ -80,5 +80,5 @@
|
|
|
80
80
|
"supertest": "6.3.3",
|
|
81
81
|
"timekeeper": "2.2.0"
|
|
82
82
|
},
|
|
83
|
-
"gitHead": "
|
|
83
|
+
"gitHead": "5c558700d0c4dbc554a935b71b9ac99ec263a654"
|
|
84
84
|
}
|
|
@@ -59,23 +59,13 @@ import {
|
|
|
59
59
|
UserCtx,
|
|
60
60
|
UserIdentifier,
|
|
61
61
|
} from "@budibase/types"
|
|
62
|
-
import crypto from "crypto"
|
|
63
62
|
import emailValidator from "email-validator"
|
|
64
63
|
import env from "../../../environment"
|
|
65
64
|
import * as userSdk from "../../../sdk/users"
|
|
66
|
-
import { isEmailConfigured } from "../../../utilities/email"
|
|
67
65
|
import { checkAnyUserExists } from "../../../utilities/users"
|
|
68
66
|
|
|
69
67
|
const MAX_USERS_UPLOAD_LIMIT = 1000
|
|
70
68
|
|
|
71
|
-
const generatePassword = (length: number) => {
|
|
72
|
-
const array = new Uint8Array(length)
|
|
73
|
-
crypto.getRandomValues(array)
|
|
74
|
-
return Array.from(array, byte => byte.toString(36).padStart(2, "0"))
|
|
75
|
-
.join("")
|
|
76
|
-
.slice(0, length)
|
|
77
|
-
}
|
|
78
|
-
|
|
79
69
|
const stripUsers = (users: (User | StrippedUser)[]): StrippedUser[] => {
|
|
80
70
|
return users.map(user => ({
|
|
81
71
|
_id: user._id,
|
|
@@ -595,40 +585,6 @@ export const accountHolderLookup = async (
|
|
|
595
585
|
}
|
|
596
586
|
}
|
|
597
587
|
|
|
598
|
-
/*
|
|
599
|
-
Encapsulate the app user onboarding flows here.
|
|
600
|
-
*/
|
|
601
|
-
export const onboardUsers = async (
|
|
602
|
-
ctx: Ctx<InviteUsersRequest, InviteUsersResponse>
|
|
603
|
-
) => {
|
|
604
|
-
if (await isEmailConfigured()) {
|
|
605
|
-
await inviteMultiple(ctx)
|
|
606
|
-
return
|
|
607
|
-
}
|
|
608
|
-
|
|
609
|
-
let createdPasswords: Record<string, string> = {}
|
|
610
|
-
const users = ctx.request.body.map<User>(invite => {
|
|
611
|
-
const password = generatePassword(12)
|
|
612
|
-
createdPasswords[invite.email] = password
|
|
613
|
-
|
|
614
|
-
return {
|
|
615
|
-
email: invite.email,
|
|
616
|
-
password,
|
|
617
|
-
forceResetPassword: true,
|
|
618
|
-
roles: invite.userInfo.apps || {},
|
|
619
|
-
admin: { global: !!invite.userInfo.admin },
|
|
620
|
-
builder: invite.userInfo.builder,
|
|
621
|
-
tenantId: tenancy.getTenantId(),
|
|
622
|
-
}
|
|
623
|
-
})
|
|
624
|
-
|
|
625
|
-
let resp = await userSdk.db.bulkCreate(users)
|
|
626
|
-
for (const user of resp.successful) {
|
|
627
|
-
user.password = createdPasswords[user.email]
|
|
628
|
-
}
|
|
629
|
-
ctx.body = { ...resp, created: true }
|
|
630
|
-
}
|
|
631
|
-
|
|
632
588
|
export const invite = async (
|
|
633
589
|
ctx: Ctx<InviteUserRequest, InviteUserResponse>
|
|
634
590
|
) => {
|
|
@@ -4,32 +4,40 @@ import { Ctx, GetEnvironmentResponse, MaintenanceType } from "@budibase/types"
|
|
|
4
4
|
import nodeFetch from "node-fetch"
|
|
5
5
|
import env from "../../../environment"
|
|
6
6
|
|
|
7
|
-
let sqsAvailable: boolean
|
|
7
|
+
let sqsAvailable: boolean | undefined
|
|
8
|
+
let sqsLastChecked: number | undefined
|
|
9
|
+
const SQS_AVAILABLE_CACHE_TTL_MS = 30_000
|
|
10
|
+
|
|
8
11
|
async function isSqsAvailable() {
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
+
const now = Date.now()
|
|
13
|
+
if (
|
|
14
|
+
sqsAvailable !== undefined &&
|
|
15
|
+
sqsLastChecked !== undefined &&
|
|
16
|
+
now - sqsLastChecked < SQS_AVAILABLE_CACHE_TTL_MS
|
|
17
|
+
) {
|
|
12
18
|
return sqsAvailable
|
|
13
19
|
}
|
|
14
20
|
|
|
15
21
|
try {
|
|
16
|
-
const {
|
|
17
|
-
if (!
|
|
22
|
+
const { sqlUrl } = dbCore.getCouchInfo()
|
|
23
|
+
if (!sqlUrl) {
|
|
18
24
|
sqsAvailable = false
|
|
25
|
+
sqsLastChecked = now
|
|
19
26
|
return false
|
|
20
27
|
}
|
|
21
28
|
await helpers.retry(
|
|
22
29
|
async () => {
|
|
23
|
-
await nodeFetch(
|
|
30
|
+
await nodeFetch(sqlUrl, { timeout: 2000 })
|
|
24
31
|
},
|
|
25
32
|
{ times: 3 }
|
|
26
33
|
)
|
|
27
|
-
console.log("connected to SQS")
|
|
28
34
|
sqsAvailable = true
|
|
35
|
+
sqsLastChecked = now
|
|
29
36
|
return true
|
|
30
37
|
} catch (e) {
|
|
31
38
|
console.warn("failed to connect to SQS", e)
|
|
32
39
|
sqsAvailable = false
|
|
40
|
+
sqsLastChecked = now
|
|
33
41
|
return false
|
|
34
42
|
}
|
|
35
43
|
}
|
|
@@ -1372,27 +1372,6 @@ describe("/api/global/users", () => {
|
|
|
1372
1372
|
})
|
|
1373
1373
|
})
|
|
1374
1374
|
|
|
1375
|
-
describe("POST /api/global/users/onboard", () => {
|
|
1376
|
-
it("should successfully onboard a user", async () => {
|
|
1377
|
-
const response = await config.api.users.onboardUser([
|
|
1378
|
-
{ email: structures.users.newEmail(), userInfo: {} },
|
|
1379
|
-
])
|
|
1380
|
-
expect(response.successful.length).toBe(1)
|
|
1381
|
-
expect(response.unsuccessful.length).toBe(0)
|
|
1382
|
-
})
|
|
1383
|
-
|
|
1384
|
-
it("should not onboard a user who has been invited", async () => {
|
|
1385
|
-
const email = structures.users.newEmail()
|
|
1386
|
-
await config.api.users.sendUserInvite(sendMailMock, email)
|
|
1387
|
-
|
|
1388
|
-
const response = await config.api.users.onboardUser([
|
|
1389
|
-
{ email, userInfo: {} },
|
|
1390
|
-
])
|
|
1391
|
-
expect(response.successful.length).toBe(0)
|
|
1392
|
-
expect(response.unsuccessful.length).toBe(1)
|
|
1393
|
-
})
|
|
1394
|
-
})
|
|
1395
|
-
|
|
1396
1375
|
describe("PUT /api/global/users/tenant/owner", () => {
|
|
1397
1376
|
it("should successfully change tenant owner email for existing user", async () => {
|
|
1398
1377
|
const originalEmail = `original-${structures.uuid()}@example.com`
|
|
@@ -103,11 +103,6 @@ builderOrAdminRoutes
|
|
|
103
103
|
"/api/global/users/invite/:code",
|
|
104
104
|
controller.removeWorkspaceIdFromInvite
|
|
105
105
|
)
|
|
106
|
-
.post(
|
|
107
|
-
"/api/global/users/onboard",
|
|
108
|
-
buildInviteMultipleValidation(),
|
|
109
|
-
controller.onboardUsers
|
|
110
|
-
)
|
|
111
106
|
.post(
|
|
112
107
|
"/api/global/users/:userId/permission/:role",
|
|
113
108
|
controller.addUserToWorkspace
|
package/src/tests/api/users.ts
CHANGED
|
@@ -4,7 +4,6 @@ import {
|
|
|
4
4
|
BulkUserResponse,
|
|
5
5
|
CreateAdminUserRequest,
|
|
6
6
|
InviteUsersRequest,
|
|
7
|
-
InviteUsersResponse,
|
|
8
7
|
SearchUsersRequest,
|
|
9
8
|
User,
|
|
10
9
|
} from "@budibase/types"
|
|
@@ -180,26 +179,6 @@ export class UserAPI extends TestAPI {
|
|
|
180
179
|
.expect(opts?.status ? opts.status : 200)
|
|
181
180
|
}
|
|
182
181
|
|
|
183
|
-
onboardUser = async (
|
|
184
|
-
req: InviteUsersRequest
|
|
185
|
-
): Promise<InviteUsersResponse> => {
|
|
186
|
-
const resp = await this.request
|
|
187
|
-
.post(`/api/global/users/onboard`)
|
|
188
|
-
.send(req)
|
|
189
|
-
.set(this.config.defaultHeaders())
|
|
190
|
-
.expect("Content-Type", /json/)
|
|
191
|
-
|
|
192
|
-
if (resp.status !== 200) {
|
|
193
|
-
throw new Error(
|
|
194
|
-
`request failed with status ${resp.status} and body ${JSON.stringify(
|
|
195
|
-
resp.body
|
|
196
|
-
)}`
|
|
197
|
-
)
|
|
198
|
-
}
|
|
199
|
-
|
|
200
|
-
return resp.body as InviteUsersResponse
|
|
201
|
-
}
|
|
202
|
-
|
|
203
182
|
changeTenantOwnerEmail = (
|
|
204
183
|
newAccountEmail: string,
|
|
205
184
|
originalEmail: string,
|