@budibase/worker 1.2.57 → 1.2.58-alpha.2
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 +7 -6
- package/scripts/jestSetup.js +6 -0
- package/src/api/controllers/global/auth.ts +14 -1
- package/src/api/controllers/global/users.ts +6 -8
- package/src/api/controllers/system/accounts.ts +21 -0
- package/src/api/{index.js → index.ts} +12 -16
- package/src/api/routes/global/configs.js +1 -0
- package/src/api/routes/{tests/auth.spec.js → global/tests/auth.spec.ts} +32 -56
- package/src/api/routes/{tests/configs.spec.js → global/tests/configs.spec.ts} +76 -47
- package/src/api/routes/{tests/email.spec.js → global/tests/email.spec.ts} +7 -15
- package/src/api/routes/{tests/realEmail.spec.js → global/tests/realEmail.spec.ts} +20 -21
- package/src/api/routes/{tests/self.spec.js → global/tests/self.spec.ts} +10 -18
- package/src/api/routes/global/tests/users.spec.ts +464 -0
- package/src/api/routes/index.js +2 -0
- package/src/api/routes/system/accounts.ts +19 -0
- package/src/api/routes/system/tests/accounts.spec.ts +57 -0
- package/src/{environment.js → environment.ts} +10 -9
- package/src/index.ts +6 -4
- package/src/sdk/accounts/accounts.ts +53 -0
- package/src/sdk/accounts/index.ts +1 -0
- package/src/sdk/index.ts +1 -0
- package/src/sdk/users/users.ts +217 -77
- package/src/tests/TestConfiguration.ts +273 -0
- package/src/tests/api/accounts.ts +28 -0
- package/src/tests/api/auth.ts +48 -0
- package/src/tests/api/configs.ts +40 -0
- package/src/tests/api/email.ts +24 -0
- package/src/tests/api/index.ts +25 -0
- package/src/tests/api/self.ts +21 -0
- package/src/tests/api/users.ts +95 -0
- package/src/tests/index.ts +14 -0
- package/src/tests/mocks/index.ts +7 -0
- package/src/tests/structures/accounts.ts +24 -0
- package/src/tests/structures/index.ts +20 -0
- package/src/tests/structures/users.ts +12 -4
- package/src/utilities/redis.js +1 -0
- package/scripts/load/users.js +0 -97
- package/src/api/routes/tests/users.spec.js +0 -390
- package/src/tests/TestConfiguration.js +0 -231
- package/src/tests/index.js +0 -12
- package/src/tests/mocks/index.js +0 -5
- package/src/tests/structures/index.js +0 -14
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@budibase/worker",
|
|
3
3
|
"email": "hi@budibase.com",
|
|
4
|
-
"version": "1.2.
|
|
4
|
+
"version": "1.2.58-alpha.2",
|
|
5
5
|
"description": "Budibase background service",
|
|
6
6
|
"main": "src/index.ts",
|
|
7
7
|
"repository": {
|
|
@@ -35,10 +35,10 @@
|
|
|
35
35
|
"author": "Budibase",
|
|
36
36
|
"license": "GPL-3.0",
|
|
37
37
|
"dependencies": {
|
|
38
|
-
"@budibase/backend-core": "
|
|
39
|
-
"@budibase/pro": "1.2.
|
|
40
|
-
"@budibase/string-templates": "
|
|
41
|
-
"@budibase/types": "
|
|
38
|
+
"@budibase/backend-core": "1.2.58-alpha.2",
|
|
39
|
+
"@budibase/pro": "1.2.58-alpha.1",
|
|
40
|
+
"@budibase/string-templates": "1.2.58-alpha.2",
|
|
41
|
+
"@budibase/types": "1.2.58-alpha.2",
|
|
42
42
|
"@koa/router": "8.0.8",
|
|
43
43
|
"@sentry/node": "6.17.7",
|
|
44
44
|
"@techpass/passport-openidconnect": "0.3.2",
|
|
@@ -74,6 +74,7 @@
|
|
|
74
74
|
"@types/koa-router": "7.4.4",
|
|
75
75
|
"@types/koa__router": "8.0.11",
|
|
76
76
|
"@types/node": "14.18.20",
|
|
77
|
+
"@types/uuid": "8.3.4",
|
|
77
78
|
"@typescript-eslint/parser": "5.12.0",
|
|
78
79
|
"copyfiles": "2.4.1",
|
|
79
80
|
"eslint": "6.8.0",
|
|
@@ -102,5 +103,5 @@
|
|
|
102
103
|
"./scripts/jestSetup.js"
|
|
103
104
|
]
|
|
104
105
|
},
|
|
105
|
-
"gitHead": "
|
|
106
|
+
"gitHead": "675fdd4b88456e4a663f8e2efb148556e0a35aab"
|
|
106
107
|
}
|
package/scripts/jestSetup.js
CHANGED
|
@@ -14,3 +14,9 @@ const tk = require("timekeeper")
|
|
|
14
14
|
tk.freeze(mocks.date.MOCK_DATE)
|
|
15
15
|
|
|
16
16
|
global.console.log = jest.fn() // console.log are ignored in tests
|
|
17
|
+
|
|
18
|
+
if (!process.env.CI) {
|
|
19
|
+
// set a longer timeout in dev for debugging
|
|
20
|
+
// 100 seconds
|
|
21
|
+
jest.setTimeout(100000)
|
|
22
|
+
}
|
|
@@ -227,9 +227,22 @@ export const oidcPreAuth = async (ctx: any, next: any) => {
|
|
|
227
227
|
|
|
228
228
|
setCookie(ctx, configId, Cookies.OIDC_CONFIG)
|
|
229
229
|
|
|
230
|
+
const db = getGlobalDB()
|
|
231
|
+
const config = await core.db.getScopedConfig(db, {
|
|
232
|
+
type: Configs.OIDC,
|
|
233
|
+
group: ctx.query.group,
|
|
234
|
+
})
|
|
235
|
+
|
|
236
|
+
const chosenConfig = config.configs.filter((c: any) => c.uuid === configId)[0]
|
|
237
|
+
|
|
238
|
+
let authScopes =
|
|
239
|
+
chosenConfig.scopes?.length > 0
|
|
240
|
+
? chosenConfig.scopes
|
|
241
|
+
: ["profile", "email", "offline_access"]
|
|
242
|
+
|
|
230
243
|
return passport.authenticate(strategy, {
|
|
231
244
|
// required 'openid' scope is added by oidc strategy factory
|
|
232
|
-
scope:
|
|
245
|
+
scope: authScopes,
|
|
233
246
|
})(ctx, next)
|
|
234
247
|
}
|
|
235
248
|
|
|
@@ -3,7 +3,7 @@ import { checkInviteCode } from "../../../utilities/redis"
|
|
|
3
3
|
import { sendEmail } from "../../../utilities/email"
|
|
4
4
|
import { users } from "../../../sdk"
|
|
5
5
|
import env from "../../../environment"
|
|
6
|
-
import { CloudAccount, User } from "@budibase/types"
|
|
6
|
+
import { BulkDeleteUsersRequest, CloudAccount, User } from "@budibase/types"
|
|
7
7
|
import {
|
|
8
8
|
accounts,
|
|
9
9
|
cache,
|
|
@@ -46,8 +46,8 @@ export const bulkCreate = async (ctx: any) => {
|
|
|
46
46
|
}
|
|
47
47
|
|
|
48
48
|
try {
|
|
49
|
-
|
|
50
|
-
await groupUtils.bulkSaveGroupUsers(groupsToSave, response)
|
|
49
|
+
const response = await users.bulkCreate(newUsersRequested, groups)
|
|
50
|
+
await groupUtils.bulkSaveGroupUsers(groupsToSave, response.successful)
|
|
51
51
|
|
|
52
52
|
ctx.body = response
|
|
53
53
|
} catch (err: any) {
|
|
@@ -138,17 +138,15 @@ export const destroy = async (ctx: any) => {
|
|
|
138
138
|
}
|
|
139
139
|
|
|
140
140
|
export const bulkDelete = async (ctx: any) => {
|
|
141
|
-
const { userIds } = ctx.request.body
|
|
141
|
+
const { userIds } = ctx.request.body as BulkDeleteUsersRequest
|
|
142
142
|
if (userIds?.indexOf(ctx.user._id) !== -1) {
|
|
143
143
|
ctx.throw(400, "Unable to delete self.")
|
|
144
144
|
}
|
|
145
145
|
|
|
146
146
|
try {
|
|
147
|
-
let
|
|
147
|
+
let response = await users.bulkDelete(userIds)
|
|
148
148
|
|
|
149
|
-
ctx.body =
|
|
150
|
-
message: `${usersResponse.length} user(s) deleted`,
|
|
151
|
-
}
|
|
149
|
+
ctx.body = response
|
|
152
150
|
} catch (err) {
|
|
153
151
|
ctx.throw(err)
|
|
154
152
|
}
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import { Account, AccountMetadata } from "@budibase/types"
|
|
2
|
+
import { accounts } from "../../../sdk"
|
|
3
|
+
|
|
4
|
+
export const save = async (ctx: any) => {
|
|
5
|
+
const account = ctx.request.body as Account
|
|
6
|
+
let metadata: AccountMetadata = {
|
|
7
|
+
_id: accounts.formatAccountMetadataId(account.accountId),
|
|
8
|
+
email: account.email,
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
metadata = await accounts.saveMetadata(metadata)
|
|
12
|
+
|
|
13
|
+
ctx.body = metadata
|
|
14
|
+
ctx.status = 200
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
export const destroy = async (ctx: any) => {
|
|
18
|
+
const accountId = accounts.formatAccountMetadataId(ctx.params.accountId)
|
|
19
|
+
await accounts.destroyMetadata(accountId)
|
|
20
|
+
ctx.status = 204
|
|
21
|
+
}
|
|
@@ -1,15 +1,10 @@
|
|
|
1
|
-
|
|
1
|
+
import Router from "@koa/router"
|
|
2
2
|
const compress = require("koa-compress")
|
|
3
3
|
const zlib = require("zlib")
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
buildTenancyMiddleware,
|
|
9
|
-
buildCsrfMiddleware,
|
|
10
|
-
} = require("@budibase/backend-core/auth")
|
|
11
|
-
const { middleware: pro } = require("@budibase/pro")
|
|
12
|
-
const { errors } = require("@budibase/backend-core")
|
|
4
|
+
import { routes } from "./routes"
|
|
5
|
+
import { middleware as pro } from "@budibase/pro"
|
|
6
|
+
import { errors, auth, middleware } from "@budibase/backend-core"
|
|
7
|
+
import { APIError } from "@budibase/types"
|
|
13
8
|
|
|
14
9
|
const PUBLIC_ENDPOINTS = [
|
|
15
10
|
// old deprecated endpoints kept for backwards compat
|
|
@@ -97,9 +92,9 @@ router
|
|
|
97
92
|
})
|
|
98
93
|
)
|
|
99
94
|
.use("/health", ctx => (ctx.status = 200))
|
|
100
|
-
.use(buildAuthMiddleware(PUBLIC_ENDPOINTS))
|
|
101
|
-
.use(buildTenancyMiddleware(PUBLIC_ENDPOINTS, NO_TENANCY_ENDPOINTS))
|
|
102
|
-
.use(buildCsrfMiddleware({ noCsrfPatterns: NO_CSRF_ENDPOINTS }))
|
|
95
|
+
.use(auth.buildAuthMiddleware(PUBLIC_ENDPOINTS))
|
|
96
|
+
.use(auth.buildTenancyMiddleware(PUBLIC_ENDPOINTS, NO_TENANCY_ENDPOINTS))
|
|
97
|
+
.use(auth.buildCsrfMiddleware({ noCsrfPatterns: NO_CSRF_ENDPOINTS }))
|
|
103
98
|
.use(pro.licensing())
|
|
104
99
|
// for now no public access is allowed to worker (bar health check)
|
|
105
100
|
.use((ctx, next) => {
|
|
@@ -114,21 +109,22 @@ router
|
|
|
114
109
|
}
|
|
115
110
|
return next()
|
|
116
111
|
})
|
|
117
|
-
.use(auditLog)
|
|
112
|
+
.use(middleware.auditLog)
|
|
118
113
|
|
|
119
114
|
// error handling middleware - TODO: This could be moved to backend-core
|
|
120
115
|
router.use(async (ctx, next) => {
|
|
121
116
|
try {
|
|
122
117
|
await next()
|
|
123
|
-
} catch (err) {
|
|
118
|
+
} catch (err: any) {
|
|
124
119
|
ctx.log.error(err)
|
|
125
120
|
ctx.status = err.status || err.statusCode || 500
|
|
126
121
|
const error = errors.getPublicError(err)
|
|
127
|
-
|
|
122
|
+
const body: APIError = {
|
|
128
123
|
message: err.message,
|
|
129
124
|
status: ctx.status,
|
|
130
125
|
error,
|
|
131
126
|
}
|
|
127
|
+
ctx.body = body
|
|
132
128
|
}
|
|
133
129
|
})
|
|
134
130
|
|
|
@@ -1,11 +1,11 @@
|
|
|
1
1
|
jest.mock("nodemailer")
|
|
2
|
-
|
|
2
|
+
import { TestConfiguration, mocks, API } from "../../../../tests"
|
|
3
3
|
const sendMailMock = mocks.email.mock()
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
const TENANT_ID = structures.TENANT_ID
|
|
4
|
+
import { events } from "@budibase/backend-core"
|
|
7
5
|
|
|
8
6
|
describe("/api/global/auth", () => {
|
|
7
|
+
const config = new TestConfiguration()
|
|
8
|
+
const api = new API(config)
|
|
9
9
|
|
|
10
10
|
beforeAll(async () => {
|
|
11
11
|
await config.beforeAll()
|
|
@@ -19,56 +19,32 @@ describe("/api/global/auth", () => {
|
|
|
19
19
|
jest.clearAllMocks()
|
|
20
20
|
})
|
|
21
21
|
|
|
22
|
-
const requestPasswordReset = async () => {
|
|
23
|
-
await config.saveSmtpConfig()
|
|
24
|
-
await config.saveSettingsConfig()
|
|
25
|
-
await config.createUser()
|
|
26
|
-
const res = await request
|
|
27
|
-
.post(`/api/global/auth/${TENANT_ID}/reset`)
|
|
28
|
-
.send({
|
|
29
|
-
email: "test@test.com",
|
|
30
|
-
})
|
|
31
|
-
.expect("Content-Type", /json/)
|
|
32
|
-
.expect(200)
|
|
33
|
-
const emailCall = sendMailMock.mock.calls[0][0]
|
|
34
|
-
const parts = emailCall.html.split(`http://localhost:10000/builder/auth/reset?code=`)
|
|
35
|
-
const code = parts[1].split("\"")[0].split("&")[0]
|
|
36
|
-
return { code, res }
|
|
37
|
-
}
|
|
38
|
-
|
|
39
22
|
it("should logout", async () => {
|
|
40
|
-
await
|
|
41
|
-
.post("/api/global/auth/logout")
|
|
42
|
-
.set(config.defaultHeaders())
|
|
43
|
-
.expect(200)
|
|
23
|
+
await api.auth.logout()
|
|
44
24
|
expect(events.auth.logout).toBeCalledTimes(1)
|
|
45
25
|
})
|
|
46
26
|
|
|
47
27
|
it("should be able to generate password reset email", async () => {
|
|
48
|
-
const { res, code } = await requestPasswordReset()
|
|
28
|
+
const { res, code } = await api.auth.requestPasswordReset(sendMailMock)
|
|
49
29
|
const user = await config.getUser("test@test.com")
|
|
50
30
|
|
|
51
|
-
expect(res.body).toEqual({
|
|
31
|
+
expect(res.body).toEqual({
|
|
32
|
+
message: "Please check your email for a reset link.",
|
|
33
|
+
})
|
|
52
34
|
expect(sendMailMock).toHaveBeenCalled()
|
|
53
|
-
|
|
35
|
+
|
|
54
36
|
expect(code).toBeDefined()
|
|
55
37
|
expect(events.user.passwordResetRequested).toBeCalledTimes(1)
|
|
56
38
|
expect(events.user.passwordResetRequested).toBeCalledWith(user)
|
|
57
39
|
})
|
|
58
40
|
|
|
59
41
|
it("should allow resetting user password with code", async () => {
|
|
60
|
-
const { code } = await requestPasswordReset()
|
|
42
|
+
const { code } = await api.auth.requestPasswordReset(sendMailMock)
|
|
61
43
|
const user = await config.getUser("test@test.com")
|
|
62
|
-
delete user.password
|
|
44
|
+
delete user.password
|
|
45
|
+
|
|
46
|
+
const res = await api.auth.updatePassword(code)
|
|
63
47
|
|
|
64
|
-
const res = await request
|
|
65
|
-
.post(`/api/global/auth/${TENANT_ID}/reset/update`)
|
|
66
|
-
.send({
|
|
67
|
-
password: "newpassword",
|
|
68
|
-
resetCode: code,
|
|
69
|
-
})
|
|
70
|
-
.expect("Content-Type", /json/)
|
|
71
|
-
.expect(200)
|
|
72
48
|
expect(res.body).toEqual({ message: "password reset successfully." })
|
|
73
49
|
expect(events.user.passwordReset).toBeCalledTimes(1)
|
|
74
50
|
expect(events.user.passwordReset).toBeCalledWith(user)
|
|
@@ -79,15 +55,15 @@ describe("/api/global/auth", () => {
|
|
|
79
55
|
|
|
80
56
|
const passportSpy = jest.spyOn(auth.passport, "authenticate")
|
|
81
57
|
let oidcConf
|
|
82
|
-
let chosenConfig
|
|
83
|
-
let configId
|
|
58
|
+
let chosenConfig: any
|
|
59
|
+
let configId: string
|
|
84
60
|
|
|
85
61
|
// mock the oidc strategy implementation and return value
|
|
86
62
|
let strategyFactory = jest.fn()
|
|
87
63
|
let mockStrategyReturn = jest.fn()
|
|
88
64
|
let mockStrategyConfig = jest.fn()
|
|
89
65
|
auth.oidc.fetchStrategyConfig = mockStrategyConfig
|
|
90
|
-
|
|
66
|
+
|
|
91
67
|
strategyFactory.mockReturnValue(mockStrategyReturn)
|
|
92
68
|
auth.oidc.strategyFactory = strategyFactory
|
|
93
69
|
|
|
@@ -99,34 +75,34 @@ describe("/api/global/auth", () => {
|
|
|
99
75
|
})
|
|
100
76
|
|
|
101
77
|
afterEach(() => {
|
|
102
|
-
expect(strategyFactory).toBeCalledWith(
|
|
103
|
-
chosenConfig,
|
|
104
|
-
expect.any(Function)
|
|
105
|
-
)
|
|
78
|
+
expect(strategyFactory).toBeCalledWith(chosenConfig, expect.any(Function))
|
|
106
79
|
})
|
|
107
80
|
|
|
108
81
|
describe("oidc configs", () => {
|
|
109
82
|
it("should load strategy and delegate to passport", async () => {
|
|
110
|
-
await
|
|
83
|
+
await api.configs.getOIDCConfig(configId)
|
|
111
84
|
|
|
112
85
|
expect(passportSpy).toBeCalledWith(mockStrategyReturn, {
|
|
113
|
-
scope: ["profile", "email", "offline_access"]
|
|
86
|
+
scope: ["profile", "email", "offline_access"],
|
|
114
87
|
})
|
|
115
|
-
expect(passportSpy.mock.calls.length).toBe(1)
|
|
88
|
+
expect(passportSpy.mock.calls.length).toBe(1)
|
|
116
89
|
})
|
|
117
90
|
})
|
|
118
91
|
|
|
119
92
|
describe("oidc callback", () => {
|
|
120
93
|
it("should load strategy and delegate to passport", async () => {
|
|
121
|
-
await
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
94
|
+
await api.configs.OIDCCallback(configId)
|
|
95
|
+
|
|
96
|
+
expect(passportSpy).toBeCalledWith(
|
|
97
|
+
mockStrategyReturn,
|
|
98
|
+
{
|
|
99
|
+
successRedirect: "/",
|
|
100
|
+
failureRedirect: "/error",
|
|
101
|
+
},
|
|
102
|
+
expect.anything()
|
|
103
|
+
)
|
|
104
|
+
expect(passportSpy.mock.calls.length).toBe(1)
|
|
128
105
|
})
|
|
129
106
|
})
|
|
130
|
-
|
|
131
107
|
})
|
|
132
108
|
})
|
|
@@ -1,11 +1,12 @@
|
|
|
1
1
|
// mock the email system
|
|
2
2
|
jest.mock("nodemailer")
|
|
3
|
-
|
|
3
|
+
import { TestConfiguration, structures, mocks, API } from "../../../../tests"
|
|
4
4
|
mocks.email.mock()
|
|
5
|
-
|
|
6
|
-
const { events } = require("@budibase/backend-core")
|
|
5
|
+
import { Configs, events } from "@budibase/backend-core"
|
|
7
6
|
|
|
8
7
|
describe("configs", () => {
|
|
8
|
+
const config = new TestConfiguration()
|
|
9
|
+
const api = new API(config)
|
|
9
10
|
|
|
10
11
|
beforeAll(async () => {
|
|
11
12
|
await config.beforeAll()
|
|
@@ -20,35 +21,33 @@ describe("configs", () => {
|
|
|
20
21
|
})
|
|
21
22
|
|
|
22
23
|
describe("post /api/global/configs", () => {
|
|
23
|
-
|
|
24
|
-
const saveConfig = async (conf, _id, _rev) => {
|
|
24
|
+
const saveConfig = async (conf: any, _id?: string, _rev?: string) => {
|
|
25
25
|
const data = {
|
|
26
26
|
...conf,
|
|
27
27
|
_id,
|
|
28
|
-
_rev
|
|
28
|
+
_rev,
|
|
29
29
|
}
|
|
30
30
|
|
|
31
|
-
const res = await
|
|
32
|
-
.post(`/api/global/configs`)
|
|
33
|
-
.send(data)
|
|
34
|
-
.set(config.defaultHeaders())
|
|
35
|
-
.expect("Content-Type", /json/)
|
|
36
|
-
.expect(200)
|
|
31
|
+
const res = await api.configs.saveConfig(data)
|
|
37
32
|
|
|
38
33
|
return {
|
|
39
34
|
...data,
|
|
40
|
-
...res.body
|
|
35
|
+
...res.body,
|
|
41
36
|
}
|
|
42
37
|
}
|
|
43
38
|
|
|
44
39
|
describe("google", () => {
|
|
45
|
-
const saveGoogleConfig = async (
|
|
40
|
+
const saveGoogleConfig = async (
|
|
41
|
+
conf?: any,
|
|
42
|
+
_id?: string,
|
|
43
|
+
_rev?: string
|
|
44
|
+
) => {
|
|
46
45
|
const googleConfig = structures.configs.google(conf)
|
|
47
46
|
return saveConfig(googleConfig, _id, _rev)
|
|
48
47
|
}
|
|
49
|
-
|
|
48
|
+
|
|
50
49
|
describe("create", () => {
|
|
51
|
-
it
|
|
50
|
+
it("should create activated google config", async () => {
|
|
52
51
|
await saveGoogleConfig()
|
|
53
52
|
expect(events.auth.SSOCreated).toBeCalledTimes(1)
|
|
54
53
|
expect(events.auth.SSOCreated).toBeCalledWith(Configs.GOOGLE)
|
|
@@ -58,7 +57,7 @@ describe("configs", () => {
|
|
|
58
57
|
await config.deleteConfig(Configs.GOOGLE)
|
|
59
58
|
})
|
|
60
59
|
|
|
61
|
-
it
|
|
60
|
+
it("should create deactivated google config", async () => {
|
|
62
61
|
await saveGoogleConfig({ activated: false })
|
|
63
62
|
expect(events.auth.SSOCreated).toBeCalledTimes(1)
|
|
64
63
|
expect(events.auth.SSOCreated).toBeCalledWith(Configs.GOOGLE)
|
|
@@ -69,10 +68,14 @@ describe("configs", () => {
|
|
|
69
68
|
})
|
|
70
69
|
|
|
71
70
|
describe("update", () => {
|
|
72
|
-
it
|
|
71
|
+
it("should update google config to deactivated", async () => {
|
|
73
72
|
const googleConf = await saveGoogleConfig()
|
|
74
73
|
jest.clearAllMocks()
|
|
75
|
-
await saveGoogleConfig(
|
|
74
|
+
await saveGoogleConfig(
|
|
75
|
+
{ ...googleConf.config, activated: false },
|
|
76
|
+
googleConf._id,
|
|
77
|
+
googleConf._rev
|
|
78
|
+
)
|
|
76
79
|
expect(events.auth.SSOUpdated).toBeCalledTimes(1)
|
|
77
80
|
expect(events.auth.SSOUpdated).toBeCalledWith(Configs.GOOGLE)
|
|
78
81
|
expect(events.auth.SSOActivated).not.toBeCalled()
|
|
@@ -81,10 +84,14 @@ describe("configs", () => {
|
|
|
81
84
|
await config.deleteConfig(Configs.GOOGLE)
|
|
82
85
|
})
|
|
83
86
|
|
|
84
|
-
it
|
|
87
|
+
it("should update google config to activated", async () => {
|
|
85
88
|
const googleConf = await saveGoogleConfig({ activated: false })
|
|
86
89
|
jest.clearAllMocks()
|
|
87
|
-
await saveGoogleConfig(
|
|
90
|
+
await saveGoogleConfig(
|
|
91
|
+
{ ...googleConf.config, activated: true },
|
|
92
|
+
googleConf._id,
|
|
93
|
+
googleConf._rev
|
|
94
|
+
)
|
|
88
95
|
expect(events.auth.SSOUpdated).toBeCalledTimes(1)
|
|
89
96
|
expect(events.auth.SSOUpdated).toBeCalledWith(Configs.GOOGLE)
|
|
90
97
|
expect(events.auth.SSODeactivated).not.toBeCalled()
|
|
@@ -92,17 +99,21 @@ describe("configs", () => {
|
|
|
92
99
|
expect(events.auth.SSOActivated).toBeCalledWith(Configs.GOOGLE)
|
|
93
100
|
await config.deleteConfig(Configs.GOOGLE)
|
|
94
101
|
})
|
|
95
|
-
})
|
|
102
|
+
})
|
|
96
103
|
})
|
|
97
104
|
|
|
98
105
|
describe("oidc", () => {
|
|
99
|
-
const saveOIDCConfig = async (
|
|
106
|
+
const saveOIDCConfig = async (
|
|
107
|
+
conf?: any,
|
|
108
|
+
_id?: string,
|
|
109
|
+
_rev?: string
|
|
110
|
+
) => {
|
|
100
111
|
const oidcConfig = structures.configs.oidc(conf)
|
|
101
112
|
return saveConfig(oidcConfig, _id, _rev)
|
|
102
113
|
}
|
|
103
114
|
|
|
104
115
|
describe("create", () => {
|
|
105
|
-
it
|
|
116
|
+
it("should create activated OIDC config", async () => {
|
|
106
117
|
await saveOIDCConfig()
|
|
107
118
|
expect(events.auth.SSOCreated).toBeCalledTimes(1)
|
|
108
119
|
expect(events.auth.SSOCreated).toBeCalledWith(Configs.OIDC)
|
|
@@ -112,7 +123,7 @@ describe("configs", () => {
|
|
|
112
123
|
await config.deleteConfig(Configs.OIDC)
|
|
113
124
|
})
|
|
114
125
|
|
|
115
|
-
it
|
|
126
|
+
it("should create deactivated OIDC config", async () => {
|
|
116
127
|
await saveOIDCConfig({ activated: false })
|
|
117
128
|
expect(events.auth.SSOCreated).toBeCalledTimes(1)
|
|
118
129
|
expect(events.auth.SSOCreated).toBeCalledWith(Configs.OIDC)
|
|
@@ -123,10 +134,14 @@ describe("configs", () => {
|
|
|
123
134
|
})
|
|
124
135
|
|
|
125
136
|
describe("update", () => {
|
|
126
|
-
it
|
|
137
|
+
it("should update OIDC config to deactivated", async () => {
|
|
127
138
|
const oidcConf = await saveOIDCConfig()
|
|
128
139
|
jest.clearAllMocks()
|
|
129
|
-
await saveOIDCConfig(
|
|
140
|
+
await saveOIDCConfig(
|
|
141
|
+
{ ...oidcConf.config.configs[0], activated: false },
|
|
142
|
+
oidcConf._id,
|
|
143
|
+
oidcConf._rev
|
|
144
|
+
)
|
|
130
145
|
expect(events.auth.SSOUpdated).toBeCalledTimes(1)
|
|
131
146
|
expect(events.auth.SSOUpdated).toBeCalledWith(Configs.OIDC)
|
|
132
147
|
expect(events.auth.SSOActivated).not.toBeCalled()
|
|
@@ -135,10 +150,14 @@ describe("configs", () => {
|
|
|
135
150
|
await config.deleteConfig(Configs.OIDC)
|
|
136
151
|
})
|
|
137
152
|
|
|
138
|
-
it
|
|
153
|
+
it("should update OIDC config to activated", async () => {
|
|
139
154
|
const oidcConf = await saveOIDCConfig({ activated: false })
|
|
140
155
|
jest.clearAllMocks()
|
|
141
|
-
await saveOIDCConfig(
|
|
156
|
+
await saveOIDCConfig(
|
|
157
|
+
{ ...oidcConf.config.configs[0], activated: true },
|
|
158
|
+
oidcConf._id,
|
|
159
|
+
oidcConf._rev
|
|
160
|
+
)
|
|
142
161
|
expect(events.auth.SSOUpdated).toBeCalledTimes(1)
|
|
143
162
|
expect(events.auth.SSOUpdated).toBeCalledWith(Configs.OIDC)
|
|
144
163
|
expect(events.auth.SSODeactivated).not.toBeCalled()
|
|
@@ -147,17 +166,20 @@ describe("configs", () => {
|
|
|
147
166
|
await config.deleteConfig(Configs.OIDC)
|
|
148
167
|
})
|
|
149
168
|
})
|
|
150
|
-
|
|
151
169
|
})
|
|
152
170
|
|
|
153
171
|
describe("smtp", () => {
|
|
154
|
-
const saveSMTPConfig = async (
|
|
172
|
+
const saveSMTPConfig = async (
|
|
173
|
+
conf?: any,
|
|
174
|
+
_id?: string,
|
|
175
|
+
_rev?: string
|
|
176
|
+
) => {
|
|
155
177
|
const smtpConfig = structures.configs.smtp(conf)
|
|
156
178
|
return saveConfig(smtpConfig, _id, _rev)
|
|
157
179
|
}
|
|
158
180
|
|
|
159
181
|
describe("create", () => {
|
|
160
|
-
it
|
|
182
|
+
it("should create SMTP config", async () => {
|
|
161
183
|
await config.deleteConfig(Configs.SMTP)
|
|
162
184
|
await saveSMTPConfig()
|
|
163
185
|
expect(events.email.SMTPUpdated).not.toBeCalled()
|
|
@@ -167,7 +189,7 @@ describe("configs", () => {
|
|
|
167
189
|
})
|
|
168
190
|
|
|
169
191
|
describe("update", () => {
|
|
170
|
-
it
|
|
192
|
+
it("should update SMTP config", async () => {
|
|
171
193
|
const smtpConf = await saveSMTPConfig()
|
|
172
194
|
jest.clearAllMocks()
|
|
173
195
|
await saveSMTPConfig(smtpConf.config, smtpConf._id, smtpConf._rev)
|
|
@@ -179,15 +201,19 @@ describe("configs", () => {
|
|
|
179
201
|
})
|
|
180
202
|
|
|
181
203
|
describe("settings", () => {
|
|
182
|
-
const saveSettingsConfig = async (
|
|
204
|
+
const saveSettingsConfig = async (
|
|
205
|
+
conf?: any,
|
|
206
|
+
_id?: string,
|
|
207
|
+
_rev?: string
|
|
208
|
+
) => {
|
|
183
209
|
const settingsConfig = structures.configs.settings(conf)
|
|
184
210
|
return saveConfig(settingsConfig, _id, _rev)
|
|
185
211
|
}
|
|
186
212
|
|
|
187
213
|
describe("create", () => {
|
|
188
|
-
it
|
|
214
|
+
it("should create settings config with default settings", async () => {
|
|
189
215
|
await config.deleteConfig(Configs.SETTINGS)
|
|
190
|
-
|
|
216
|
+
|
|
191
217
|
await saveSettingsConfig()
|
|
192
218
|
|
|
193
219
|
expect(events.org.nameUpdated).not.toBeCalled()
|
|
@@ -195,35 +221,43 @@ describe("configs", () => {
|
|
|
195
221
|
expect(events.org.platformURLUpdated).not.toBeCalled()
|
|
196
222
|
})
|
|
197
223
|
|
|
198
|
-
it
|
|
224
|
+
it("should create settings config with non-default settings", async () => {
|
|
225
|
+
config.modeSelf()
|
|
199
226
|
await config.deleteConfig(Configs.SETTINGS)
|
|
200
227
|
const conf = {
|
|
201
228
|
company: "acme",
|
|
202
229
|
logoUrl: "http://example.com",
|
|
203
|
-
platformUrl: "http://example.com"
|
|
230
|
+
platformUrl: "http://example.com",
|
|
204
231
|
}
|
|
205
232
|
|
|
206
233
|
await saveSettingsConfig(conf)
|
|
207
|
-
|
|
234
|
+
|
|
208
235
|
expect(events.org.nameUpdated).toBeCalledTimes(1)
|
|
209
236
|
expect(events.org.logoUpdated).toBeCalledTimes(1)
|
|
210
237
|
expect(events.org.platformURLUpdated).toBeCalledTimes(1)
|
|
238
|
+
config.modeAccount()
|
|
211
239
|
})
|
|
212
240
|
})
|
|
213
241
|
|
|
214
242
|
describe("update", () => {
|
|
215
|
-
it
|
|
243
|
+
it("should update settings config", async () => {
|
|
244
|
+
config.modeSelf()
|
|
216
245
|
await config.deleteConfig(Configs.SETTINGS)
|
|
217
246
|
const settingsConfig = await saveSettingsConfig()
|
|
218
247
|
settingsConfig.config.company = "acme"
|
|
219
248
|
settingsConfig.config.logoUrl = "http://example.com"
|
|
220
249
|
settingsConfig.config.platformUrl = "http://example.com"
|
|
221
250
|
|
|
222
|
-
await saveSettingsConfig(
|
|
251
|
+
await saveSettingsConfig(
|
|
252
|
+
settingsConfig.config,
|
|
253
|
+
settingsConfig._id,
|
|
254
|
+
settingsConfig._rev
|
|
255
|
+
)
|
|
223
256
|
|
|
224
257
|
expect(events.org.nameUpdated).toBeCalledTimes(1)
|
|
225
258
|
expect(events.org.logoUpdated).toBeCalledTimes(1)
|
|
226
259
|
expect(events.org.platformURLUpdated).toBeCalledTimes(1)
|
|
260
|
+
config.modeAccount()
|
|
227
261
|
})
|
|
228
262
|
})
|
|
229
263
|
})
|
|
@@ -232,12 +266,7 @@ describe("configs", () => {
|
|
|
232
266
|
it("should return the correct checklist status based on the state of the budibase installation", async () => {
|
|
233
267
|
await config.saveSmtpConfig()
|
|
234
268
|
|
|
235
|
-
const res = await
|
|
236
|
-
.get(`/api/global/configs/checklist`)
|
|
237
|
-
.set(config.defaultHeaders())
|
|
238
|
-
.expect("Content-Type", /json/)
|
|
239
|
-
.expect(200)
|
|
240
|
-
|
|
269
|
+
const res = await api.configs.getConfigChecklist()
|
|
241
270
|
const checklist = res.body
|
|
242
271
|
|
|
243
272
|
expect(checklist.apps.checked).toBeFalsy()
|