@budibase/worker 2.31.2 → 2.31.7
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 -6
- package/scripts/dev/manage.js +0 -1
- package/src/api/controllers/global/users.ts +11 -0
- package/src/api/controllers/system/environment.ts +2 -2
- package/src/api/index.ts +2 -6
- package/src/api/routes/global/tenant.ts +1 -26
- package/src/api/routes/global/tests/auditLogs.spec.ts +7 -4
- package/src/api/routes/global/tests/realEmail.spec.ts +4 -29
- package/src/api/routes/global/tests/users.spec.ts +22 -0
- package/src/tests/api/environment.ts +1 -0
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@budibase/worker",
|
|
3
3
|
"email": "hi@budibase.com",
|
|
4
|
-
"version": "2.31.
|
|
4
|
+
"version": "2.31.7",
|
|
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.31.
|
|
41
|
-
"@budibase/pro": "2.31.
|
|
42
|
-
"@budibase/string-templates": "2.31.
|
|
43
|
-
"@budibase/types": "2.31.
|
|
40
|
+
"@budibase/backend-core": "2.31.7",
|
|
41
|
+
"@budibase/pro": "2.31.7",
|
|
42
|
+
"@budibase/string-templates": "2.31.7",
|
|
43
|
+
"@budibase/types": "2.31.7",
|
|
44
44
|
"@koa/router": "8.0.8",
|
|
45
45
|
"@techpass/passport-openidconnect": "0.3.3",
|
|
46
46
|
"@types/global-agent": "2.1.1",
|
|
@@ -107,5 +107,5 @@
|
|
|
107
107
|
}
|
|
108
108
|
}
|
|
109
109
|
},
|
|
110
|
-
"gitHead": "
|
|
110
|
+
"gitHead": "a98ce68410543e6721e2670081aaaa43b1f7d80a"
|
|
111
111
|
}
|
package/scripts/dev/manage.js
CHANGED
|
@@ -54,6 +54,17 @@ export const save = async (ctx: UserCtx<User, SaveUserResponse>) => {
|
|
|
54
54
|
const currentUserId = ctx.user?._id
|
|
55
55
|
const requestUser = ctx.request.body
|
|
56
56
|
|
|
57
|
+
// Do not allow the account holder role to be changed
|
|
58
|
+
const tenantInfo = await tenancy.getTenantInfo(requestUser.tenantId)
|
|
59
|
+
if (tenantInfo?.owner.email === requestUser.email) {
|
|
60
|
+
if (
|
|
61
|
+
requestUser.admin?.global !== true ||
|
|
62
|
+
requestUser.builder?.global !== true
|
|
63
|
+
) {
|
|
64
|
+
throw Error("Cannot set role of account holder")
|
|
65
|
+
}
|
|
66
|
+
}
|
|
67
|
+
|
|
57
68
|
const user = await userSdk.db.save(requestUser, { currentUserId })
|
|
58
69
|
|
|
59
70
|
ctx.body = {
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { Ctx, MaintenanceType } from "@budibase/types"
|
|
2
2
|
import env from "../../../environment"
|
|
3
|
-
import { env as coreEnv, db as dbCore } from "@budibase/backend-core"
|
|
3
|
+
import { env as coreEnv, db as dbCore, features } from "@budibase/backend-core"
|
|
4
4
|
import nodeFetch from "node-fetch"
|
|
5
5
|
|
|
6
6
|
let sqsAvailable: boolean
|
|
@@ -29,7 +29,7 @@ async function isSqsAvailable() {
|
|
|
29
29
|
}
|
|
30
30
|
|
|
31
31
|
async function isSqsMissing() {
|
|
32
|
-
return
|
|
32
|
+
return (await features.flags.isEnabled("SQS")) && !(await isSqsAvailable())
|
|
33
33
|
}
|
|
34
34
|
|
|
35
35
|
export const fetch = async (ctx: Ctx) => {
|
package/src/api/index.ts
CHANGED
|
@@ -4,12 +4,8 @@ const compress = require("koa-compress")
|
|
|
4
4
|
|
|
5
5
|
import zlib from "zlib"
|
|
6
6
|
import { routes } from "./routes"
|
|
7
|
-
import { middleware as pro
|
|
8
|
-
import { auth, middleware
|
|
9
|
-
|
|
10
|
-
if (env.SQS_SEARCH_ENABLE) {
|
|
11
|
-
sdk.auditLogs.useSQLSearch()
|
|
12
|
-
}
|
|
7
|
+
import { middleware as pro } from "@budibase/pro"
|
|
8
|
+
import { auth, middleware } from "@budibase/backend-core"
|
|
13
9
|
|
|
14
10
|
const PUBLIC_ENDPOINTS = [
|
|
15
11
|
// deprecated single tenant sso callback
|
|
@@ -1,36 +1,11 @@
|
|
|
1
1
|
import Router from "@koa/router"
|
|
2
|
-
import Joi from "joi"
|
|
3
|
-
import { auth } from "@budibase/backend-core"
|
|
4
2
|
import * as controller from "../../controllers/global/tenant"
|
|
5
3
|
import cloudRestricted from "../../../middleware/cloudRestricted"
|
|
6
4
|
|
|
7
5
|
const router: Router = new Router()
|
|
8
|
-
const OPTIONAL_STRING = Joi.string().optional().allow(null).allow("")
|
|
9
|
-
|
|
10
|
-
function buildTenantInfoValidation() {
|
|
11
|
-
return auth.joiValidator.body(
|
|
12
|
-
Joi.object({
|
|
13
|
-
owner: Joi.object({
|
|
14
|
-
email: Joi.string().required(),
|
|
15
|
-
password: OPTIONAL_STRING,
|
|
16
|
-
ssoId: OPTIONAL_STRING,
|
|
17
|
-
givenName: OPTIONAL_STRING,
|
|
18
|
-
familyName: OPTIONAL_STRING,
|
|
19
|
-
budibaseUserId: OPTIONAL_STRING,
|
|
20
|
-
}).required(),
|
|
21
|
-
hosting: Joi.string().required(),
|
|
22
|
-
tenantId: Joi.string().required(),
|
|
23
|
-
}).required()
|
|
24
|
-
)
|
|
25
|
-
}
|
|
26
6
|
|
|
27
7
|
router
|
|
28
|
-
.post(
|
|
29
|
-
"/api/global/tenant",
|
|
30
|
-
cloudRestricted,
|
|
31
|
-
buildTenantInfoValidation(),
|
|
32
|
-
controller.save
|
|
33
|
-
)
|
|
8
|
+
.post("/api/global/tenant", cloudRestricted, controller.save)
|
|
34
9
|
.get("/api/global/tenant/:id", controller.get)
|
|
35
10
|
|
|
36
11
|
export default router
|
|
@@ -1,7 +1,6 @@
|
|
|
1
1
|
import { mocks, structures } from "@budibase/backend-core/tests"
|
|
2
|
-
import { context, events } from "@budibase/backend-core"
|
|
2
|
+
import { context, events, setEnv as setCoreEnv } from "@budibase/backend-core"
|
|
3
3
|
import { Event, IdentityType } from "@budibase/types"
|
|
4
|
-
import { auditLogs } from "@budibase/pro"
|
|
5
4
|
import { TestConfiguration } from "../../../../tests"
|
|
6
5
|
|
|
7
6
|
mocks.licenses.useAuditLogs()
|
|
@@ -15,15 +14,19 @@ const APP_ID = "app_1"
|
|
|
15
14
|
|
|
16
15
|
describe.each(["lucene", "sql"])("/api/global/auditlogs (%s)", method => {
|
|
17
16
|
const config = new TestConfiguration()
|
|
17
|
+
let envCleanup: (() => void) | undefined
|
|
18
18
|
|
|
19
19
|
beforeAll(async () => {
|
|
20
|
-
if (method === "
|
|
21
|
-
|
|
20
|
+
if (method === "lucene") {
|
|
21
|
+
envCleanup = setCoreEnv({ TENANT_FEATURE_FLAGS: "*:!SQS" })
|
|
22
|
+
} else if (method === "sql") {
|
|
23
|
+
envCleanup = setCoreEnv({ TENANT_FEATURE_FLAGS: "*:SQS" })
|
|
22
24
|
}
|
|
23
25
|
await config.beforeAll()
|
|
24
26
|
})
|
|
25
27
|
|
|
26
28
|
afterAll(async () => {
|
|
29
|
+
envCleanup?.()
|
|
27
30
|
await config.afterAll()
|
|
28
31
|
})
|
|
29
32
|
|
|
@@ -2,6 +2,8 @@ jest.unmock("node-fetch")
|
|
|
2
2
|
import { TestConfiguration } from "../../../../tests"
|
|
3
3
|
import { EmailTemplatePurpose } from "../../../../constants"
|
|
4
4
|
import { objectStore } from "@budibase/backend-core"
|
|
5
|
+
import { helpers } from "@budibase/shared-core"
|
|
6
|
+
|
|
5
7
|
import tk from "timekeeper"
|
|
6
8
|
import { EmailAttachment } from "@budibase/types"
|
|
7
9
|
|
|
@@ -12,33 +14,6 @@ const nodemailer = require("nodemailer")
|
|
|
12
14
|
// for the real email tests give them a long time to try complete/fail
|
|
13
15
|
jest.setTimeout(30000)
|
|
14
16
|
|
|
15
|
-
function cancelableTimeout(timeout: number): [Promise<unknown>, () => void] {
|
|
16
|
-
let timeoutId: NodeJS.Timeout
|
|
17
|
-
return [
|
|
18
|
-
new Promise((resolve, reject) => {
|
|
19
|
-
timeoutId = setTimeout(() => {
|
|
20
|
-
reject({
|
|
21
|
-
status: 301,
|
|
22
|
-
errno: "ETIME",
|
|
23
|
-
})
|
|
24
|
-
}, timeout)
|
|
25
|
-
}),
|
|
26
|
-
() => {
|
|
27
|
-
clearTimeout(timeoutId)
|
|
28
|
-
},
|
|
29
|
-
]
|
|
30
|
-
}
|
|
31
|
-
|
|
32
|
-
async function withTimeout<T>(
|
|
33
|
-
timeout: number,
|
|
34
|
-
promise: Promise<T>
|
|
35
|
-
): Promise<T> {
|
|
36
|
-
const [timeoutPromise, cancel] = cancelableTimeout(timeout)
|
|
37
|
-
const result = (await Promise.race([promise, timeoutPromise])) as T
|
|
38
|
-
cancel()
|
|
39
|
-
return result
|
|
40
|
-
}
|
|
41
|
-
|
|
42
17
|
describe("/api/global/email", () => {
|
|
43
18
|
const config = new TestConfiguration()
|
|
44
19
|
|
|
@@ -57,8 +32,8 @@ describe("/api/global/email", () => {
|
|
|
57
32
|
) {
|
|
58
33
|
let response, text
|
|
59
34
|
try {
|
|
60
|
-
await withTimeout(20000, config.saveEtherealSmtpConfig())
|
|
61
|
-
await withTimeout(20000, config.saveSettingsConfig())
|
|
35
|
+
await helpers.withTimeout(20000, config.saveEtherealSmtpConfig())
|
|
36
|
+
await helpers.withTimeout(20000, config.saveSettingsConfig())
|
|
62
37
|
let res
|
|
63
38
|
if (attachments) {
|
|
64
39
|
res = await config.api.emails
|
|
@@ -412,6 +412,28 @@ describe("/api/global/users", () => {
|
|
|
412
412
|
expect(events.user.permissionBuilderRemoved).toHaveBeenCalledTimes(1)
|
|
413
413
|
})
|
|
414
414
|
|
|
415
|
+
it("should not be able to update an account holder user to a basic user", async () => {
|
|
416
|
+
const accountHolderUser = await config.createUser(
|
|
417
|
+
structures.users.adminUser()
|
|
418
|
+
)
|
|
419
|
+
jest.clearAllMocks()
|
|
420
|
+
tenancy.getTenantInfo = jest.fn().mockImplementation(() => ({
|
|
421
|
+
owner: {
|
|
422
|
+
email: accountHolderUser.email,
|
|
423
|
+
},
|
|
424
|
+
}))
|
|
425
|
+
|
|
426
|
+
accountHolderUser.admin!.global = false
|
|
427
|
+
accountHolderUser.builder!.global = false
|
|
428
|
+
|
|
429
|
+
await config.api.users.saveUser(accountHolderUser, 400)
|
|
430
|
+
|
|
431
|
+
expect(events.user.created).not.toHaveBeenCalled()
|
|
432
|
+
expect(events.user.updated).not.toHaveBeenCalled()
|
|
433
|
+
expect(events.user.permissionAdminRemoved).not.toHaveBeenCalled()
|
|
434
|
+
expect(events.user.permissionBuilderRemoved).not.toHaveBeenCalled()
|
|
435
|
+
})
|
|
436
|
+
|
|
415
437
|
it("should be able to update an builder user to a basic user", async () => {
|
|
416
438
|
const user = await config.createUser(structures.users.builderUser())
|
|
417
439
|
jest.clearAllMocks()
|