@budibase/worker 2.1.40-alpha.4 → 2.1.41
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 +24 -14
- package/{src/tests/jestSetup.ts → scripts/jestSetup.js} +3 -12
- package/scripts/localdomain.js +7 -33
- package/src/api/controllers/global/auth.ts +43 -51
- package/src/api/controllers/global/{configs.ts → configs.js} +114 -119
- package/src/api/controllers/global/{email.ts → email.js} +5 -6
- package/src/api/controllers/global/roles.js +68 -0
- package/src/api/controllers/global/self.ts +2 -2
- package/src/api/controllers/global/users.ts +2 -4
- package/src/api/controllers/global/{workspaces.ts → workspaces.js} +18 -15
- package/src/api/controllers/system/{environment.ts → environment.js} +2 -3
- package/src/api/controllers/system/restore.ts +1 -1
- package/src/api/controllers/system/{status.ts → status.js} +3 -4
- package/src/api/controllers/system/tenants.ts +51 -8
- package/src/api/index.ts +8 -31
- package/src/api/routes/global/{auth.ts → auth.js} +48 -31
- package/src/api/routes/global/{configs.ts → configs.js} +23 -22
- package/src/api/routes/global/{email.ts → email.js} +10 -9
- package/src/api/routes/global/license.ts +1 -1
- package/src/api/routes/global/roles.js +12 -0
- package/src/api/routes/global/self.ts +2 -2
- package/src/api/routes/global/templates.ts +4 -4
- package/src/api/routes/global/tests/auth.spec.ts +64 -134
- package/src/api/routes/global/tests/configs.spec.ts +35 -34
- package/src/api/routes/global/tests/email.spec.ts +3 -4
- package/src/api/routes/global/tests/realEmail.spec.ts +3 -2
- package/src/api/routes/global/tests/self.spec.ts +4 -3
- package/src/api/routes/global/tests/users.spec.ts +59 -51
- package/src/api/routes/global/{users.ts → users.js} +32 -26
- package/src/api/routes/global/{workspaces.ts → workspaces.js} +10 -9
- package/src/api/routes/index.ts +1 -2
- package/src/api/routes/system/accounts.ts +1 -1
- package/src/api/routes/system/environment.js +8 -0
- package/src/api/routes/system/migrations.ts +1 -1
- package/src/api/routes/system/restore.ts +1 -1
- package/src/api/routes/system/status.js +8 -0
- package/src/api/routes/system/tenants.js +12 -0
- package/src/api/routes/system/tests/accounts.spec.ts +6 -5
- package/src/api/routes/validation/users.ts +3 -3
- package/src/constants/{index.ts → index.js} +64 -57
- package/src/constants/templates/{index.ts → index.js} +19 -23
- package/src/db/index.js +11 -0
- package/src/environment.ts +7 -9
- package/src/index.ts +16 -15
- package/src/middleware/{cloudRestricted.ts → cloudRestricted.js} +4 -5
- package/src/tests/TestConfiguration.ts +50 -99
- package/src/tests/api/accounts.ts +8 -5
- package/src/tests/api/auth.ts +6 -3
- package/src/tests/api/configs.ts +8 -15
- package/src/tests/api/email.ts +6 -3
- package/src/tests/api/index.ts +0 -15
- package/src/tests/api/self.ts +6 -11
- package/src/tests/api/users.ts +8 -40
- package/src/tests/controllers.js +7 -0
- package/src/tests/index.ts +1 -5
- package/src/tests/structures/accounts.ts +24 -0
- package/src/tests/structures/{configs.ts → configs.js} +11 -11
- package/src/tests/structures/index.ts +3 -5
- package/src/tests/structures/users.ts +0 -1
- package/src/utilities/appService.js +33 -0
- package/src/utilities/{email.ts → email.js} +45 -78
- package/src/utilities/fileSystem.js +5 -0
- package/src/utilities/{index.ts → index.js} +1 -1
- package/src/utilities/{redis.ts → redis.js} +24 -29
- package/src/utilities/templates.js +49 -0
- package/src/utilities/users.js +17 -0
- package/tsconfig.build.json +3 -2
- package/tsconfig.json +1 -3
- package/__mocks__/aws-sdk.ts +0 -15
- package/__mocks__/oauth.ts +0 -57
- package/coverage/clover.xml +0 -2153
- package/coverage/coverage-final.json +0 -78
- package/coverage/lcov-report/base.css +0 -224
- package/coverage/lcov-report/block-navigation.js +0 -87
- package/coverage/lcov-report/favicon.png +0 -0
- package/coverage/lcov-report/index.html +0 -431
- package/coverage/lcov-report/prettify.css +0 -1
- package/coverage/lcov-report/prettify.js +0 -2
- package/coverage/lcov-report/sort-arrow-sprite.png +0 -0
- package/coverage/lcov-report/sorter.js +0 -196
- package/coverage/lcov-report/src/api/controllers/global/auth.ts.html +0 -925
- package/coverage/lcov-report/src/api/controllers/global/configs.ts.html +0 -1405
- package/coverage/lcov-report/src/api/controllers/global/email.ts.html +0 -196
- package/coverage/lcov-report/src/api/controllers/global/index.html +0 -236
- package/coverage/lcov-report/src/api/controllers/global/license.ts.html +0 -187
- package/coverage/lcov-report/src/api/controllers/global/roles.ts.html +0 -283
- package/coverage/lcov-report/src/api/controllers/global/self.ts.html +0 -577
- package/coverage/lcov-report/src/api/controllers/global/templates.ts.html +0 -316
- package/coverage/lcov-report/src/api/controllers/global/users.ts.html +0 -796
- package/coverage/lcov-report/src/api/controllers/global/workspaces.ts.html +0 -244
- package/coverage/lcov-report/src/api/controllers/system/accounts.ts.html +0 -148
- package/coverage/lcov-report/src/api/controllers/system/environment.ts.html +0 -124
- package/coverage/lcov-report/src/api/controllers/system/index.html +0 -191
- package/coverage/lcov-report/src/api/controllers/system/migrations.ts.html +0 -124
- package/coverage/lcov-report/src/api/controllers/system/restore.ts.html +0 -124
- package/coverage/lcov-report/src/api/controllers/system/status.ts.html +0 -133
- package/coverage/lcov-report/src/api/controllers/system/tenants.ts.html +0 -154
- package/coverage/lcov-report/src/api/index.html +0 -116
- package/coverage/lcov-report/src/api/index.ts.html +0 -583
- package/coverage/lcov-report/src/api/routes/global/auth.ts.html +0 -349
- package/coverage/lcov-report/src/api/routes/global/configs.ts.html +0 -457
- package/coverage/lcov-report/src/api/routes/global/email.ts.html +0 -193
- package/coverage/lcov-report/src/api/routes/global/index.html +0 -236
- package/coverage/lcov-report/src/api/routes/global/license.ts.html +0 -124
- package/coverage/lcov-report/src/api/routes/global/roles.ts.html +0 -133
- package/coverage/lcov-report/src/api/routes/global/self.ts.html +0 -139
- package/coverage/lcov-report/src/api/routes/global/templates.ts.html +0 -196
- package/coverage/lcov-report/src/api/routes/global/users.ts.html +0 -409
- package/coverage/lcov-report/src/api/routes/global/workspaces.ts.html +0 -196
- package/coverage/lcov-report/src/api/routes/index.html +0 -116
- package/coverage/lcov-report/src/api/routes/index.ts.html +0 -196
- package/coverage/lcov-report/src/api/routes/system/accounts.ts.html +0 -142
- package/coverage/lcov-report/src/api/routes/system/environment.ts.html +0 -109
- package/coverage/lcov-report/src/api/routes/system/index.html +0 -191
- package/coverage/lcov-report/src/api/routes/system/migrations.ts.html +0 -142
- package/coverage/lcov-report/src/api/routes/system/restore.ts.html +0 -109
- package/coverage/lcov-report/src/api/routes/system/status.ts.html +0 -109
- package/coverage/lcov-report/src/api/routes/system/tenants.ts.html +0 -124
- package/coverage/lcov-report/src/api/routes/validation/index.html +0 -131
- package/coverage/lcov-report/src/api/routes/validation/index.ts.html +0 -88
- package/coverage/lcov-report/src/api/routes/validation/users.ts.html +0 -235
- package/coverage/lcov-report/src/constants/index.html +0 -116
- package/coverage/lcov-report/src/constants/index.ts.html +0 -613
- package/coverage/lcov-report/src/constants/templates/index.html +0 -116
- package/coverage/lcov-report/src/constants/templates/index.ts.html +0 -316
- package/coverage/lcov-report/src/db/index.html +0 -116
- package/coverage/lcov-report/src/db/index.ts.html +0 -115
- package/coverage/lcov-report/src/environment.ts.html +0 -373
- package/coverage/lcov-report/src/index.html +0 -131
- package/coverage/lcov-report/src/index.ts.html +0 -394
- package/coverage/lcov-report/src/middleware/cloudRestricted.ts.html +0 -139
- package/coverage/lcov-report/src/middleware/index.html +0 -116
- package/coverage/lcov-report/src/migrations/functions/globalInfoSyncUsers.ts.html +0 -145
- package/coverage/lcov-report/src/migrations/functions/index.html +0 -116
- package/coverage/lcov-report/src/migrations/index.html +0 -116
- package/coverage/lcov-report/src/migrations/index.ts.html +0 -271
- package/coverage/lcov-report/src/sdk/accounts/accounts.ts.html +0 -262
- package/coverage/lcov-report/src/sdk/accounts/index.html +0 -131
- package/coverage/lcov-report/src/sdk/accounts/index.ts.html +0 -88
- package/coverage/lcov-report/src/sdk/index.html +0 -116
- package/coverage/lcov-report/src/sdk/index.ts.html +0 -106
- package/coverage/lcov-report/src/sdk/users/events.ts.html +0 -577
- package/coverage/lcov-report/src/sdk/users/index.html +0 -146
- package/coverage/lcov-report/src/sdk/users/index.ts.html +0 -88
- package/coverage/lcov-report/src/sdk/users/users.ts.html +0 -1903
- package/coverage/lcov-report/src/tests/TestConfiguration.ts.html +0 -1051
- package/coverage/lcov-report/src/tests/api/accounts.ts.html +0 -160
- package/coverage/lcov-report/src/tests/api/auth.ts.html +0 -220
- package/coverage/lcov-report/src/tests/api/base.ts.html +0 -133
- package/coverage/lcov-report/src/tests/api/configs.ts.html +0 -226
- package/coverage/lcov-report/src/tests/api/email.ts.html +0 -148
- package/coverage/lcov-report/src/tests/api/environment.ts.html +0 -130
- package/coverage/lcov-report/src/tests/api/index.html +0 -296
- package/coverage/lcov-report/src/tests/api/index.ts.html +0 -205
- package/coverage/lcov-report/src/tests/api/migrations.ts.html +0 -151
- package/coverage/lcov-report/src/tests/api/restore.ts.html +0 -127
- package/coverage/lcov-report/src/tests/api/self.ts.html +0 -163
- package/coverage/lcov-report/src/tests/api/status.ts.html +0 -121
- package/coverage/lcov-report/src/tests/api/tenants.ts.html +0 -130
- package/coverage/lcov-report/src/tests/api/users.ts.html +0 -511
- package/coverage/lcov-report/src/tests/controllers.ts.html +0 -100
- package/coverage/lcov-report/src/tests/index.html +0 -146
- package/coverage/lcov-report/src/tests/index.ts.html +0 -139
- package/coverage/lcov-report/src/tests/mocks/email.js.html +0 -115
- package/coverage/lcov-report/src/tests/mocks/index.html +0 -131
- package/coverage/lcov-report/src/tests/mocks/index.ts.html +0 -106
- package/coverage/lcov-report/src/tests/structures/configs.ts.html +0 -313
- package/coverage/lcov-report/src/tests/structures/groups.ts.html +0 -118
- package/coverage/lcov-report/src/tests/structures/index.html +0 -161
- package/coverage/lcov-report/src/tests/structures/index.ts.html +0 -151
- package/coverage/lcov-report/src/tests/structures/users.ts.html +0 -196
- package/coverage/lcov-report/src/utilities/appService.ts.html +0 -181
- package/coverage/lcov-report/src/utilities/email.ts.html +0 -850
- package/coverage/lcov-report/src/utilities/fileSystem.ts.html +0 -100
- package/coverage/lcov-report/src/utilities/index.html +0 -206
- package/coverage/lcov-report/src/utilities/index.ts.html +0 -112
- package/coverage/lcov-report/src/utilities/redis.ts.html +0 -424
- package/coverage/lcov-report/src/utilities/templates.ts.html +0 -232
- package/coverage/lcov-report/src/utilities/users.ts.html +0 -133
- package/coverage/lcov.info +0 -3958
- package/jest.config.ts +0 -29
- package/src/api/controllers/global/roles.ts +0 -66
- package/src/api/routes/global/roles.ts +0 -16
- package/src/api/routes/global/tests/license.spec.ts +0 -31
- package/src/api/routes/global/tests/roles.spec.ts +0 -27
- package/src/api/routes/global/tests/templates.spec.ts +0 -35
- package/src/api/routes/global/tests/workspaces.spec.ts +0 -29
- package/src/api/routes/system/environment.ts +0 -8
- package/src/api/routes/system/status.ts +0 -8
- package/src/api/routes/system/tenants.ts +0 -13
- package/src/api/routes/system/tests/environment.spec.ts +0 -29
- package/src/api/routes/system/tests/migrations.spec.ts +0 -63
- package/src/api/routes/system/tests/restore.spec.ts +0 -36
- package/src/api/routes/system/tests/status.spec.ts +0 -48
- package/src/api/routes/system/tests/tenants.spec.ts +0 -61
- package/src/db/index.ts +0 -10
- package/src/middleware/tests/tenancy.spec.ts +0 -73
- package/src/tests/api/base.ts +0 -16
- package/src/tests/api/environment.ts +0 -15
- package/src/tests/api/migrations.ts +0 -22
- package/src/tests/api/restore.ts +0 -14
- package/src/tests/api/status.ts +0 -12
- package/src/tests/api/tenants.ts +0 -15
- package/src/tests/controllers.ts +0 -5
- package/src/utilities/appService.ts +0 -32
- package/src/utilities/fileSystem.ts +0 -5
- package/src/utilities/templates.ts +0 -49
- package/src/utilities/users.ts +0 -16
|
@@ -1,26 +1,28 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
1
|
+
const {
|
|
2
|
+
generateConfigID,
|
|
3
|
+
getConfigParams,
|
|
4
|
+
getScopedFullConfig,
|
|
5
|
+
getAllApps,
|
|
6
|
+
} = require("@budibase/backend-core/db")
|
|
7
|
+
const { Configs } = require("../../../constants")
|
|
8
|
+
const email = require("../../../utilities/email")
|
|
9
|
+
const {
|
|
10
|
+
upload,
|
|
11
|
+
ObjectStoreBuckets,
|
|
12
|
+
} = require("@budibase/backend-core/objectStore")
|
|
13
|
+
const { getGlobalDB, getTenantId } = require("@budibase/backend-core/tenancy")
|
|
14
|
+
const env = require("../../../environment")
|
|
15
|
+
const { googleCallbackUrl, oidcCallbackUrl } = require("./auth")
|
|
16
|
+
const {
|
|
17
|
+
withCache,
|
|
18
|
+
CacheKeys,
|
|
19
|
+
bustCache,
|
|
6
20
|
cache,
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
import {
|
|
13
|
-
Database,
|
|
14
|
-
Config as ConfigDoc,
|
|
15
|
-
ConfigType,
|
|
16
|
-
SSOType,
|
|
17
|
-
GoogleConfig,
|
|
18
|
-
OIDCConfig,
|
|
19
|
-
SettingsConfig,
|
|
20
|
-
BBContext,
|
|
21
|
-
} from "@budibase/types"
|
|
22
|
-
|
|
23
|
-
const getEventFns = async (db: Database, config: ConfigDoc) => {
|
|
21
|
+
} = require("@budibase/backend-core/cache")
|
|
22
|
+
const { events } = require("@budibase/backend-core")
|
|
23
|
+
const { checkAnyUserExists } = require("../../../utilities/users")
|
|
24
|
+
|
|
25
|
+
const getEventFns = async (db, config) => {
|
|
24
26
|
const fns = []
|
|
25
27
|
const type = config.type
|
|
26
28
|
|
|
@@ -29,45 +31,41 @@ const getEventFns = async (db: Database, config: ConfigDoc) => {
|
|
|
29
31
|
existing = await db.get(config._id)
|
|
30
32
|
}
|
|
31
33
|
|
|
32
|
-
const ssoType = type as SSOType
|
|
33
34
|
if (!existing) {
|
|
34
35
|
switch (config.type) {
|
|
35
|
-
case
|
|
36
|
+
case Configs.SMTP: {
|
|
36
37
|
fns.push(events.email.SMTPCreated)
|
|
37
38
|
break
|
|
38
39
|
}
|
|
39
|
-
case
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
fns.push(() => events.auth.SSOActivated(ssoType))
|
|
40
|
+
case Configs.GOOGLE: {
|
|
41
|
+
fns.push(() => events.auth.SSOCreated(type))
|
|
42
|
+
if (config.config.activated) {
|
|
43
|
+
fns.push(() => events.auth.SSOActivated(type))
|
|
44
44
|
}
|
|
45
45
|
break
|
|
46
46
|
}
|
|
47
|
-
case
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
fns.push(() => events.auth.SSOActivated(ssoType))
|
|
47
|
+
case Configs.OIDC: {
|
|
48
|
+
fns.push(() => events.auth.SSOCreated(type))
|
|
49
|
+
if (config.config.configs[0].activated) {
|
|
50
|
+
fns.push(() => events.auth.SSOActivated(type))
|
|
52
51
|
}
|
|
53
52
|
break
|
|
54
53
|
}
|
|
55
|
-
case
|
|
54
|
+
case Configs.SETTINGS: {
|
|
56
55
|
// company
|
|
57
|
-
const
|
|
58
|
-
const company = settingsCfg.config.company
|
|
56
|
+
const company = config.config.company
|
|
59
57
|
if (company && company !== "Budibase") {
|
|
60
58
|
fns.push(events.org.nameUpdated)
|
|
61
59
|
}
|
|
62
60
|
|
|
63
61
|
// logo
|
|
64
|
-
const logoUrl =
|
|
62
|
+
const logoUrl = config.config.logoUrl
|
|
65
63
|
if (logoUrl) {
|
|
66
64
|
fns.push(events.org.logoUpdated)
|
|
67
65
|
}
|
|
68
66
|
|
|
69
67
|
// platform url
|
|
70
|
-
const platformUrl =
|
|
68
|
+
const platformUrl = config.config.platformUrl
|
|
71
69
|
if (
|
|
72
70
|
platformUrl &&
|
|
73
71
|
platformUrl !== "http://localhost:10000" &&
|
|
@@ -80,55 +78,52 @@ const getEventFns = async (db: Database, config: ConfigDoc) => {
|
|
|
80
78
|
}
|
|
81
79
|
} else {
|
|
82
80
|
switch (config.type) {
|
|
83
|
-
case
|
|
81
|
+
case Configs.SMTP: {
|
|
84
82
|
fns.push(events.email.SMTPUpdated)
|
|
85
83
|
break
|
|
86
84
|
}
|
|
87
|
-
case
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
fns.push(() => events.auth.SSODeactivated(ssoType))
|
|
85
|
+
case Configs.GOOGLE: {
|
|
86
|
+
fns.push(() => events.auth.SSOUpdated(type))
|
|
87
|
+
if (!existing.config.activated && config.config.activated) {
|
|
88
|
+
fns.push(() => events.auth.SSOActivated(type))
|
|
89
|
+
} else if (existing.config.activated && !config.config.activated) {
|
|
90
|
+
fns.push(() => events.auth.SSODeactivated(type))
|
|
94
91
|
}
|
|
95
92
|
break
|
|
96
93
|
}
|
|
97
|
-
case
|
|
98
|
-
|
|
99
|
-
fns.push(() => events.auth.SSOUpdated(ssoType))
|
|
94
|
+
case Configs.OIDC: {
|
|
95
|
+
fns.push(() => events.auth.SSOUpdated(type))
|
|
100
96
|
if (
|
|
101
97
|
!existing.config.configs[0].activated &&
|
|
102
|
-
|
|
98
|
+
config.config.configs[0].activated
|
|
103
99
|
) {
|
|
104
|
-
fns.push(() => events.auth.SSOActivated(
|
|
100
|
+
fns.push(() => events.auth.SSOActivated(type))
|
|
105
101
|
} else if (
|
|
106
102
|
existing.config.configs[0].activated &&
|
|
107
|
-
!
|
|
103
|
+
!config.config.configs[0].activated
|
|
108
104
|
) {
|
|
109
|
-
fns.push(() => events.auth.SSODeactivated(
|
|
105
|
+
fns.push(() => events.auth.SSODeactivated(type))
|
|
110
106
|
}
|
|
111
107
|
break
|
|
112
108
|
}
|
|
113
|
-
case
|
|
109
|
+
case Configs.SETTINGS: {
|
|
114
110
|
// company
|
|
115
|
-
const settingsCfg = config as SettingsConfig
|
|
116
111
|
const existingCompany = existing.config.company
|
|
117
|
-
const company =
|
|
112
|
+
const company = config.config.company
|
|
118
113
|
if (company && company !== "Budibase" && existingCompany !== company) {
|
|
119
114
|
fns.push(events.org.nameUpdated)
|
|
120
115
|
}
|
|
121
116
|
|
|
122
117
|
// logo
|
|
123
118
|
const existingLogoUrl = existing.config.logoUrl
|
|
124
|
-
const logoUrl =
|
|
119
|
+
const logoUrl = config.config.logoUrl
|
|
125
120
|
if (logoUrl && existingLogoUrl !== logoUrl) {
|
|
126
121
|
fns.push(events.org.logoUpdated)
|
|
127
122
|
}
|
|
128
123
|
|
|
129
124
|
// platform url
|
|
130
125
|
const existingPlatformUrl = existing.config.platformUrl
|
|
131
|
-
const platformUrl =
|
|
126
|
+
const platformUrl = config.config.platformUrl
|
|
132
127
|
if (
|
|
133
128
|
platformUrl &&
|
|
134
129
|
platformUrl !== "http://localhost:10000" &&
|
|
@@ -145,13 +140,13 @@ const getEventFns = async (db: Database, config: ConfigDoc) => {
|
|
|
145
140
|
return fns
|
|
146
141
|
}
|
|
147
142
|
|
|
148
|
-
|
|
149
|
-
const db =
|
|
143
|
+
exports.save = async function (ctx) {
|
|
144
|
+
const db = getGlobalDB()
|
|
150
145
|
const { type, workspace, user, config } = ctx.request.body
|
|
151
146
|
let eventFns = await getEventFns(db, ctx.request.body)
|
|
152
147
|
// Config does not exist yet
|
|
153
148
|
if (!ctx.request.body._id) {
|
|
154
|
-
ctx.request.body._id =
|
|
149
|
+
ctx.request.body._id = generateConfigID({
|
|
155
150
|
type,
|
|
156
151
|
workspace,
|
|
157
152
|
user,
|
|
@@ -160,18 +155,18 @@ export async function save(ctx: BBContext) {
|
|
|
160
155
|
try {
|
|
161
156
|
// verify the configuration
|
|
162
157
|
switch (type) {
|
|
163
|
-
case
|
|
158
|
+
case Configs.SMTP:
|
|
164
159
|
await email.verifyConfig(config)
|
|
165
160
|
break
|
|
166
161
|
}
|
|
167
|
-
} catch (err
|
|
162
|
+
} catch (err) {
|
|
168
163
|
ctx.throw(400, err)
|
|
169
164
|
}
|
|
170
165
|
|
|
171
166
|
try {
|
|
172
167
|
const response = await db.put(ctx.request.body)
|
|
173
|
-
await
|
|
174
|
-
await
|
|
168
|
+
await bustCache(CacheKeys.CHECKLIST)
|
|
169
|
+
await bustCache(CacheKeys.ANALYTICS_ENABLED)
|
|
175
170
|
|
|
176
171
|
for (const fn of eventFns) {
|
|
177
172
|
await fn()
|
|
@@ -182,15 +177,15 @@ export async function save(ctx: BBContext) {
|
|
|
182
177
|
_id: response.id,
|
|
183
178
|
_rev: response.rev,
|
|
184
179
|
}
|
|
185
|
-
} catch (err
|
|
180
|
+
} catch (err) {
|
|
186
181
|
ctx.throw(400, err)
|
|
187
182
|
}
|
|
188
183
|
}
|
|
189
184
|
|
|
190
|
-
|
|
191
|
-
const db =
|
|
185
|
+
exports.fetch = async function (ctx) {
|
|
186
|
+
const db = getGlobalDB()
|
|
192
187
|
const response = await db.allDocs(
|
|
193
|
-
|
|
188
|
+
getConfigParams(
|
|
194
189
|
{ type: ctx.params.type },
|
|
195
190
|
{
|
|
196
191
|
include_docs: true,
|
|
@@ -204,23 +199,23 @@ export async function fetch(ctx: BBContext) {
|
|
|
204
199
|
* Gets the most granular config for a particular configuration type.
|
|
205
200
|
* The hierarchy is type -> workspace -> user.
|
|
206
201
|
*/
|
|
207
|
-
|
|
208
|
-
const db =
|
|
202
|
+
exports.find = async function (ctx) {
|
|
203
|
+
const db = getGlobalDB()
|
|
209
204
|
|
|
210
205
|
const { userId, workspaceId } = ctx.query
|
|
211
206
|
if (workspaceId && userId) {
|
|
212
|
-
const workspace = await db.get(workspaceId
|
|
207
|
+
const workspace = await db.get(workspaceId)
|
|
213
208
|
const userInWorkspace = workspace.users.some(
|
|
214
|
-
|
|
209
|
+
workspaceUser => workspaceUser === userId
|
|
215
210
|
)
|
|
216
|
-
if (!ctx.user
|
|
211
|
+
if (!ctx.user.admin && !userInWorkspace) {
|
|
217
212
|
ctx.throw(400, `User is not in specified workspace: ${workspace}.`)
|
|
218
213
|
}
|
|
219
214
|
}
|
|
220
215
|
|
|
221
216
|
try {
|
|
222
217
|
// Find the config with the most granular scope based on context
|
|
223
|
-
const scopedConfig = await
|
|
218
|
+
const scopedConfig = await getScopedFullConfig(db, {
|
|
224
219
|
type: ctx.params.type,
|
|
225
220
|
user: userId,
|
|
226
221
|
workspace: workspaceId,
|
|
@@ -232,48 +227,48 @@ export async function find(ctx: BBContext) {
|
|
|
232
227
|
// don't throw an error, there simply is nothing to return
|
|
233
228
|
ctx.body = {}
|
|
234
229
|
}
|
|
235
|
-
} catch (err
|
|
236
|
-
ctx.throw(err
|
|
230
|
+
} catch (err) {
|
|
231
|
+
ctx.throw(err.status, err)
|
|
237
232
|
}
|
|
238
233
|
}
|
|
239
234
|
|
|
240
|
-
|
|
241
|
-
const db =
|
|
235
|
+
exports.publicOidc = async function (ctx) {
|
|
236
|
+
const db = getGlobalDB()
|
|
242
237
|
try {
|
|
243
238
|
// Find the config with the most granular scope based on context
|
|
244
|
-
const oidcConfig = await
|
|
245
|
-
type:
|
|
239
|
+
const oidcConfig = await getScopedFullConfig(db, {
|
|
240
|
+
type: Configs.OIDC,
|
|
246
241
|
})
|
|
247
242
|
|
|
248
243
|
if (!oidcConfig) {
|
|
249
244
|
ctx.body = {}
|
|
250
245
|
} else {
|
|
251
|
-
ctx.body = oidcConfig.config.configs.map(
|
|
246
|
+
ctx.body = oidcConfig.config.configs.map(config => ({
|
|
252
247
|
logo: config.logo,
|
|
253
248
|
name: config.name,
|
|
254
249
|
uuid: config.uuid,
|
|
255
250
|
}))
|
|
256
251
|
}
|
|
257
|
-
} catch (err
|
|
252
|
+
} catch (err) {
|
|
258
253
|
ctx.throw(err.status, err)
|
|
259
254
|
}
|
|
260
255
|
}
|
|
261
256
|
|
|
262
|
-
|
|
263
|
-
const db =
|
|
257
|
+
exports.publicSettings = async function (ctx) {
|
|
258
|
+
const db = getGlobalDB()
|
|
264
259
|
|
|
265
260
|
try {
|
|
266
261
|
// Find the config with the most granular scope based on context
|
|
267
|
-
const publicConfig = await
|
|
268
|
-
type:
|
|
262
|
+
const publicConfig = await getScopedFullConfig(db, {
|
|
263
|
+
type: Configs.SETTINGS,
|
|
269
264
|
})
|
|
270
265
|
|
|
271
|
-
const googleConfig = await
|
|
272
|
-
type:
|
|
266
|
+
const googleConfig = await getScopedFullConfig(db, {
|
|
267
|
+
type: Configs.GOOGLE,
|
|
273
268
|
})
|
|
274
269
|
|
|
275
|
-
const oidcConfig = await
|
|
276
|
-
type:
|
|
270
|
+
const oidcConfig = await getScopedFullConfig(db, {
|
|
271
|
+
type: Configs.OIDC,
|
|
277
272
|
})
|
|
278
273
|
|
|
279
274
|
let config
|
|
@@ -306,12 +301,12 @@ export async function publicSettings(ctx: BBContext) {
|
|
|
306
301
|
}
|
|
307
302
|
|
|
308
303
|
ctx.body = config
|
|
309
|
-
} catch (err
|
|
304
|
+
} catch (err) {
|
|
310
305
|
ctx.throw(err.status, err)
|
|
311
306
|
}
|
|
312
307
|
}
|
|
313
308
|
|
|
314
|
-
|
|
309
|
+
exports.upload = async function (ctx) {
|
|
315
310
|
if (ctx.request.files == null || ctx.request.files.file.length > 1) {
|
|
316
311
|
ctx.throw(400, "One file must be uploaded.")
|
|
317
312
|
}
|
|
@@ -320,19 +315,19 @@ export async function upload(ctx: BBContext) {
|
|
|
320
315
|
|
|
321
316
|
let bucket
|
|
322
317
|
if (env.SELF_HOSTED) {
|
|
323
|
-
bucket =
|
|
318
|
+
bucket = ObjectStoreBuckets.GLOBAL
|
|
324
319
|
} else {
|
|
325
|
-
bucket =
|
|
320
|
+
bucket = ObjectStoreBuckets.GLOBAL_CLOUD
|
|
326
321
|
}
|
|
327
322
|
|
|
328
323
|
let key
|
|
329
324
|
if (env.MULTI_TENANCY) {
|
|
330
|
-
key = `${
|
|
325
|
+
key = `${getTenantId()}/${type}/${name}`
|
|
331
326
|
} else {
|
|
332
327
|
key = `${type}/${name}`
|
|
333
328
|
}
|
|
334
329
|
|
|
335
|
-
await
|
|
330
|
+
await upload({
|
|
336
331
|
bucket,
|
|
337
332
|
filename: key,
|
|
338
333
|
path: file.path,
|
|
@@ -341,11 +336,11 @@ export async function upload(ctx: BBContext) {
|
|
|
341
336
|
|
|
342
337
|
// add to configuration structure
|
|
343
338
|
// TODO: right now this only does a global level
|
|
344
|
-
const db =
|
|
345
|
-
let cfgStructure = await
|
|
339
|
+
const db = getGlobalDB()
|
|
340
|
+
let cfgStructure = await getScopedFullConfig(db, { type })
|
|
346
341
|
if (!cfgStructure) {
|
|
347
342
|
cfgStructure = {
|
|
348
|
-
_id:
|
|
343
|
+
_id: generateConfigID({ type }),
|
|
349
344
|
config: {},
|
|
350
345
|
}
|
|
351
346
|
}
|
|
@@ -366,49 +361,49 @@ export async function upload(ctx: BBContext) {
|
|
|
366
361
|
}
|
|
367
362
|
}
|
|
368
363
|
|
|
369
|
-
|
|
370
|
-
const db =
|
|
364
|
+
exports.destroy = async function (ctx) {
|
|
365
|
+
const db = getGlobalDB()
|
|
371
366
|
const { id, rev } = ctx.params
|
|
372
367
|
try {
|
|
373
368
|
await db.remove(id, rev)
|
|
374
|
-
await cache.
|
|
369
|
+
await cache.delete(CacheKeys.CHECKLIST)
|
|
375
370
|
ctx.body = { message: "Config deleted successfully" }
|
|
376
|
-
} catch (err
|
|
371
|
+
} catch (err) {
|
|
377
372
|
ctx.throw(err.status, err)
|
|
378
373
|
}
|
|
379
374
|
}
|
|
380
375
|
|
|
381
|
-
|
|
382
|
-
const db =
|
|
383
|
-
const tenantId =
|
|
376
|
+
exports.configChecklist = async function (ctx) {
|
|
377
|
+
const db = getGlobalDB()
|
|
378
|
+
const tenantId = getTenantId()
|
|
384
379
|
|
|
385
380
|
try {
|
|
386
|
-
ctx.body = await
|
|
387
|
-
|
|
381
|
+
ctx.body = await withCache(
|
|
382
|
+
CacheKeys.CHECKLIST,
|
|
388
383
|
env.CHECKLIST_CACHE_TTL,
|
|
389
384
|
async () => {
|
|
390
385
|
let apps = []
|
|
391
386
|
if (!env.MULTI_TENANCY || tenantId) {
|
|
392
387
|
// Apps exist
|
|
393
|
-
apps = await
|
|
388
|
+
apps = await getAllApps({ idsOnly: true, efficient: true })
|
|
394
389
|
}
|
|
395
390
|
|
|
396
391
|
// They have set up SMTP
|
|
397
|
-
const smtpConfig = await
|
|
398
|
-
type:
|
|
392
|
+
const smtpConfig = await getScopedFullConfig(db, {
|
|
393
|
+
type: Configs.SMTP,
|
|
399
394
|
})
|
|
400
395
|
|
|
401
396
|
// They have set up Google Auth
|
|
402
|
-
const googleConfig = await
|
|
403
|
-
type:
|
|
397
|
+
const googleConfig = await getScopedFullConfig(db, {
|
|
398
|
+
type: Configs.GOOGLE,
|
|
404
399
|
})
|
|
405
400
|
|
|
406
401
|
// They have set up OIDC
|
|
407
|
-
const oidcConfig = await
|
|
408
|
-
type:
|
|
402
|
+
const oidcConfig = await getScopedFullConfig(db, {
|
|
403
|
+
type: Configs.OIDC,
|
|
409
404
|
})
|
|
410
405
|
|
|
411
|
-
// They have set up
|
|
406
|
+
// They have set up an global user
|
|
412
407
|
const userExists = await checkAnyUserExists()
|
|
413
408
|
return {
|
|
414
409
|
apps: {
|
|
@@ -434,7 +429,7 @@ export async function configChecklist(ctx: BBContext) {
|
|
|
434
429
|
}
|
|
435
430
|
}
|
|
436
431
|
)
|
|
437
|
-
} catch (err
|
|
432
|
+
} catch (err) {
|
|
438
433
|
ctx.throw(err.status, err)
|
|
439
434
|
}
|
|
440
435
|
}
|
|
@@ -1,8 +1,7 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
import { BBContext } from "@budibase/types"
|
|
1
|
+
const { sendEmail } = require("../../../utilities/email")
|
|
2
|
+
const { getGlobalDB } = require("@budibase/backend-core/tenancy")
|
|
4
3
|
|
|
5
|
-
|
|
4
|
+
exports.sendEmail = async ctx => {
|
|
6
5
|
let {
|
|
7
6
|
workspaceId,
|
|
8
7
|
email,
|
|
@@ -17,10 +16,10 @@ export async function sendEmail(ctx: BBContext) {
|
|
|
17
16
|
} = ctx.request.body
|
|
18
17
|
let user
|
|
19
18
|
if (userId) {
|
|
20
|
-
const db =
|
|
19
|
+
const db = getGlobalDB()
|
|
21
20
|
user = await db.get(userId)
|
|
22
21
|
}
|
|
23
|
-
const response = await
|
|
22
|
+
const response = await sendEmail(email, purpose, {
|
|
24
23
|
workspaceId,
|
|
25
24
|
user,
|
|
26
25
|
contents,
|
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
const { getAllRoles } = require("@budibase/backend-core/roles")
|
|
2
|
+
const {
|
|
3
|
+
getAllApps,
|
|
4
|
+
getProdAppID,
|
|
5
|
+
getDevAppID,
|
|
6
|
+
DocumentType,
|
|
7
|
+
} = require("@budibase/backend-core/db")
|
|
8
|
+
const { doInAppContext, getAppDB } = require("@budibase/backend-core/context")
|
|
9
|
+
const { user: userCache } = require("@budibase/backend-core/cache")
|
|
10
|
+
const { getGlobalDB } = require("@budibase/backend-core/tenancy")
|
|
11
|
+
const { allUsers } = require("../../../sdk/users")
|
|
12
|
+
|
|
13
|
+
exports.fetch = async ctx => {
|
|
14
|
+
const tenantId = ctx.user.tenantId
|
|
15
|
+
// always use the dev apps as they'll be most up to date (true)
|
|
16
|
+
const apps = await getAllApps({ tenantId, all: true })
|
|
17
|
+
const promises = []
|
|
18
|
+
for (let app of apps) {
|
|
19
|
+
// use dev app IDs
|
|
20
|
+
promises.push(getAllRoles(app.appId))
|
|
21
|
+
}
|
|
22
|
+
const roles = await Promise.all(promises)
|
|
23
|
+
const response = {}
|
|
24
|
+
for (let app of apps) {
|
|
25
|
+
const deployedAppId = getProdAppID(app.appId)
|
|
26
|
+
response[deployedAppId] = {
|
|
27
|
+
roles: roles.shift(),
|
|
28
|
+
name: app.name,
|
|
29
|
+
version: app.version,
|
|
30
|
+
url: app.url,
|
|
31
|
+
}
|
|
32
|
+
}
|
|
33
|
+
ctx.body = response
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
exports.find = async ctx => {
|
|
37
|
+
const appId = ctx.params.appId
|
|
38
|
+
await doInAppContext(getDevAppID(appId), async () => {
|
|
39
|
+
const db = getAppDB()
|
|
40
|
+
const app = await db.get(DocumentType.APP_METADATA)
|
|
41
|
+
ctx.body = {
|
|
42
|
+
roles: await getAllRoles(),
|
|
43
|
+
name: app.name,
|
|
44
|
+
version: app.version,
|
|
45
|
+
url: app.url,
|
|
46
|
+
}
|
|
47
|
+
})
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
exports.removeAppRole = async ctx => {
|
|
51
|
+
const { appId } = ctx.params
|
|
52
|
+
const db = getGlobalDB()
|
|
53
|
+
const users = await allUsers(ctx)
|
|
54
|
+
const bulk = []
|
|
55
|
+
const cacheInvalidations = []
|
|
56
|
+
for (let user of users) {
|
|
57
|
+
if (user.roles[appId]) {
|
|
58
|
+
cacheInvalidations.push(userCache.invalidateUser(user._id))
|
|
59
|
+
delete user.roles[appId]
|
|
60
|
+
bulk.push(user)
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
await db.bulkDocs(bulk)
|
|
64
|
+
await Promise.all(cacheInvalidations)
|
|
65
|
+
ctx.body = {
|
|
66
|
+
message: "App role removed from all users",
|
|
67
|
+
}
|
|
68
|
+
}
|
|
@@ -73,12 +73,12 @@ export async function fetchAPIKey(ctx: any) {
|
|
|
73
73
|
}
|
|
74
74
|
|
|
75
75
|
const checkCurrentApp = (ctx: any) => {
|
|
76
|
-
const appCookie = getCookie(ctx, constants.
|
|
76
|
+
const appCookie = getCookie(ctx, constants.Cookies.CurrentApp)
|
|
77
77
|
if (appCookie && !tenancy.isUserInAppTenant(appCookie.appId)) {
|
|
78
78
|
// there is a currentapp cookie from another tenant
|
|
79
79
|
// remove the cookie as this is incompatible with the builder
|
|
80
80
|
// due to builder and admin permissions being removed
|
|
81
|
-
clearCookie(ctx, constants.
|
|
81
|
+
clearCookie(ctx, constants.Cookies.CurrentApp)
|
|
82
82
|
}
|
|
83
83
|
}
|
|
84
84
|
|
|
@@ -5,7 +5,6 @@ import {
|
|
|
5
5
|
BulkUserRequest,
|
|
6
6
|
BulkUserResponse,
|
|
7
7
|
CloudAccount,
|
|
8
|
-
CreateAdminUserRequest,
|
|
9
8
|
InviteUserRequest,
|
|
10
9
|
InviteUsersRequest,
|
|
11
10
|
SearchUsersRequest,
|
|
@@ -68,8 +67,7 @@ const parseBooleanParam = (param: any) => {
|
|
|
68
67
|
}
|
|
69
68
|
|
|
70
69
|
export const adminUser = async (ctx: any) => {
|
|
71
|
-
const { email, password, tenantId } = ctx.request
|
|
72
|
-
.body as CreateAdminUserRequest
|
|
70
|
+
const { email, password, tenantId } = ctx.request.body
|
|
73
71
|
await tenancy.doInTenant(tenantId, async () => {
|
|
74
72
|
// account portal sends a pre-hashed password - honour param to prevent double hashing
|
|
75
73
|
const hashPassword = parseBooleanParam(ctx.request.query.hashPassword)
|
|
@@ -104,7 +102,7 @@ export const adminUser = async (ctx: any) => {
|
|
|
104
102
|
try {
|
|
105
103
|
// always bust checklist beforehand, if an error occurs but can proceed, don't get
|
|
106
104
|
// stuck in a cycle
|
|
107
|
-
await cache.bustCache(cache.
|
|
105
|
+
await cache.bustCache(cache.CacheKeys.CHECKLIST)
|
|
108
106
|
const finalUser = await sdk.users.save(user, {
|
|
109
107
|
hashPassword,
|
|
110
108
|
requirePassword,
|
|
@@ -1,13 +1,16 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
1
|
+
const {
|
|
2
|
+
getWorkspaceParams,
|
|
3
|
+
generateWorkspaceID,
|
|
4
|
+
} = require("@budibase/backend-core/db")
|
|
5
|
+
const { getGlobalDB } = require("@budibase/backend-core/tenancy")
|
|
3
6
|
|
|
4
|
-
|
|
5
|
-
const db =
|
|
7
|
+
exports.save = async function (ctx) {
|
|
8
|
+
const db = getGlobalDB()
|
|
6
9
|
const workspaceDoc = ctx.request.body
|
|
7
10
|
|
|
8
11
|
// workspace does not exist yet
|
|
9
12
|
if (!workspaceDoc._id) {
|
|
10
|
-
workspaceDoc._id =
|
|
13
|
+
workspaceDoc._id = generateWorkspaceID()
|
|
11
14
|
}
|
|
12
15
|
|
|
13
16
|
try {
|
|
@@ -16,38 +19,38 @@ export async function save(ctx: BBContext) {
|
|
|
16
19
|
_id: response.id,
|
|
17
20
|
_rev: response.rev,
|
|
18
21
|
}
|
|
19
|
-
} catch (err
|
|
22
|
+
} catch (err) {
|
|
20
23
|
ctx.throw(err.status, err)
|
|
21
24
|
}
|
|
22
25
|
}
|
|
23
26
|
|
|
24
|
-
|
|
25
|
-
const db =
|
|
27
|
+
exports.fetch = async function (ctx) {
|
|
28
|
+
const db = getGlobalDB()
|
|
26
29
|
const response = await db.allDocs(
|
|
27
|
-
|
|
30
|
+
getWorkspaceParams(undefined, {
|
|
28
31
|
include_docs: true,
|
|
29
32
|
})
|
|
30
33
|
)
|
|
31
34
|
ctx.body = response.rows.map(row => row.doc)
|
|
32
35
|
}
|
|
33
36
|
|
|
34
|
-
|
|
35
|
-
const db =
|
|
37
|
+
exports.find = async function (ctx) {
|
|
38
|
+
const db = getGlobalDB()
|
|
36
39
|
try {
|
|
37
40
|
ctx.body = await db.get(ctx.params.id)
|
|
38
|
-
} catch (err
|
|
41
|
+
} catch (err) {
|
|
39
42
|
ctx.throw(err.status, err)
|
|
40
43
|
}
|
|
41
44
|
}
|
|
42
45
|
|
|
43
|
-
|
|
44
|
-
const db =
|
|
46
|
+
exports.destroy = async function (ctx) {
|
|
47
|
+
const db = getGlobalDB()
|
|
45
48
|
const { id, rev } = ctx.params
|
|
46
49
|
|
|
47
50
|
try {
|
|
48
51
|
await db.remove(id, rev)
|
|
49
52
|
ctx.body = { message: "Workspace deleted successfully" }
|
|
50
|
-
} catch (err
|
|
53
|
+
} catch (err) {
|
|
51
54
|
ctx.throw(err.status, err)
|
|
52
55
|
}
|
|
53
56
|
}
|
|
@@ -1,7 +1,6 @@
|
|
|
1
|
-
|
|
2
|
-
import env from "../../../environment"
|
|
1
|
+
const env = require("../../../environment")
|
|
3
2
|
|
|
4
|
-
|
|
3
|
+
exports.fetch = async ctx => {
|
|
5
4
|
ctx.body = {
|
|
6
5
|
multiTenancy: !!env.MULTI_TENANCY,
|
|
7
6
|
cloud: !env.SELF_HOSTED,
|