@budibase/worker 2.3.19 → 2.3.21-alpha.0
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/__mocks__/node-fetch.ts +23 -0
- package/jest-testcontainers-config.js +8 -0
- package/jest.config.ts +14 -18
- package/package.json +12 -8
- package/scripts/dev/manage.js +1 -0
- package/scripts/test.sh +12 -0
- package/src/api/controllers/global/auth.ts +109 -111
- package/src/api/controllers/global/configs.ts +150 -142
- package/src/api/controllers/global/self.ts +28 -44
- package/src/api/controllers/global/users.ts +211 -32
- package/src/api/controllers/system/accounts.ts +7 -5
- package/src/api/controllers/system/tenants.ts +4 -8
- package/src/api/index.ts +4 -20
- package/src/api/routes/global/auth.ts +10 -7
- package/src/api/routes/global/configs.ts +6 -12
- package/src/api/routes/global/tests/auditLogs.spec.ts +111 -0
- package/src/api/routes/global/tests/auth.spec.ts +217 -18
- package/src/api/routes/global/tests/configs.spec.ts +93 -65
- package/src/api/routes/global/tests/realEmail.spec.ts +1 -0
- package/src/api/routes/global/tests/roles.spec.ts +20 -14
- package/src/api/routes/global/tests/self.spec.ts +3 -4
- package/src/api/routes/global/tests/users.spec.ts +29 -28
- package/src/api/routes/global/users.ts +19 -14
- package/src/api/routes/index.ts +3 -0
- package/src/api/routes/system/tenants.ts +1 -1
- package/src/api/routes/system/tests/accounts.spec.ts +4 -4
- package/src/api/routes/system/tests/migrations.spec.ts +2 -2
- package/src/api/routes/system/tests/restore.spec.ts +2 -2
- package/src/api/routes/system/tests/status.spec.ts +5 -5
- package/src/db/index.ts +8 -2
- package/src/ddApm.ts +7 -0
- package/src/elasticApm.ts +10 -0
- package/src/environment.ts +4 -0
- package/src/index.ts +29 -8
- package/src/middleware/tests/tenancy.spec.ts +4 -4
- package/src/migrations/functions/globalInfoSyncUsers.ts +4 -3
- package/src/sdk/accounts/index.ts +2 -1
- package/src/sdk/accounts/{accounts.ts → metadata.ts} +0 -1
- package/src/sdk/auth/auth.ts +86 -0
- package/src/sdk/auth/index.ts +1 -0
- package/src/sdk/tenants/index.ts +1 -0
- package/src/sdk/tenants/tenants.ts +76 -0
- package/src/sdk/users/events.ts +4 -0
- package/src/sdk/users/index.ts +1 -0
- package/src/sdk/users/tests/users.spec.ts +76 -0
- package/src/sdk/users/users.ts +86 -53
- package/src/tests/TestConfiguration.ts +41 -62
- package/src/tests/api/auditLogs.ts +26 -0
- package/src/tests/api/auth.ts +44 -14
- package/src/tests/api/base.ts +2 -1
- package/src/tests/api/configs.ts +9 -1
- package/src/tests/api/email.ts +1 -0
- package/src/tests/api/index.ts +3 -0
- package/src/tests/api/restore.ts +1 -0
- package/src/tests/api/users.ts +2 -2
- package/src/tests/jestEnv.ts +2 -1
- package/src/tests/jestSetup.ts +10 -6
- package/src/tests/logging.ts +34 -0
- package/src/tests/structures/configs.ts +20 -13
- package/src/tests/structures/index.ts +0 -4
- package/src/utilities/email.ts +22 -68
- package/src/utilities/redis.ts +42 -2
- package/src/utilities/templates.ts +4 -9
- package/coverage/clover.xml +0 -2199
- package/coverage/coverage-final.json +0 -84
- 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 -934
- package/coverage/lcov-report/src/api/controllers/global/configs.ts.html +0 -1348
- package/coverage/lcov-report/src/api/controllers/global/email.ts.html +0 -196
- package/coverage/lcov-report/src/api/controllers/global/events.ts.html +0 -136
- package/coverage/lcov-report/src/api/controllers/global/index.html +0 -251
- 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 -838
- 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 -595
- 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/events.ts.html +0 -109
- package/coverage/lcov-report/src/api/routes/global/index.html +0 -251
- 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 -475
- 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 -202
- 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 -637
- 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 -388
- 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 -601
- 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 -1999
- package/coverage/lcov-report/src/tests/TestConfiguration.ts.html +0 -1075
- 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/groups.ts.html +0 -163
- package/coverage/lcov-report/src/tests/api/index.html +0 -356
- package/coverage/lcov-report/src/tests/api/index.ts.html +0 -238
- package/coverage/lcov-report/src/tests/api/license.ts.html +0 -136
- 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/roles.ts.html +0 -181
- 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/templates.ts.html +0 -175
- package/coverage/lcov-report/src/tests/api/tenants.ts.html +0 -130
- package/coverage/lcov-report/src/tests/api/users.ts.html +0 -514
- 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 -103
- package/coverage/lcov-report/src/tests/mocks/email.ts.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 -208
- 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 -4187
- package/src/tests/structures/users.ts +0 -37
|
@@ -2,38 +2,37 @@ import * as email from "../../../utilities/email"
|
|
|
2
2
|
import env from "../../../environment"
|
|
3
3
|
import { googleCallbackUrl, oidcCallbackUrl } from "./auth"
|
|
4
4
|
import {
|
|
5
|
-
events,
|
|
6
5
|
cache,
|
|
7
|
-
|
|
8
|
-
tenancy,
|
|
6
|
+
configs,
|
|
9
7
|
db as dbCore,
|
|
10
8
|
env as coreEnv,
|
|
9
|
+
events,
|
|
10
|
+
objectStore,
|
|
11
|
+
tenancy,
|
|
11
12
|
} from "@budibase/backend-core"
|
|
12
13
|
import { checkAnyUserExists } from "../../../utilities/users"
|
|
13
14
|
import {
|
|
14
|
-
|
|
15
|
-
Config as ConfigDoc,
|
|
15
|
+
Config,
|
|
16
16
|
ConfigType,
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
17
|
+
Ctx,
|
|
18
|
+
GetPublicOIDCConfigResponse,
|
|
19
|
+
GetPublicSettingsResponse,
|
|
20
|
+
GoogleInnerConfig,
|
|
21
21
|
isGoogleConfig,
|
|
22
22
|
isOIDCConfig,
|
|
23
23
|
isSettingsConfig,
|
|
24
24
|
isSMTPConfig,
|
|
25
|
-
|
|
25
|
+
OIDCConfigs,
|
|
26
|
+
SettingsInnerConfig,
|
|
27
|
+
SSOConfig,
|
|
28
|
+
SSOConfigType,
|
|
26
29
|
UserCtx,
|
|
27
30
|
} from "@budibase/types"
|
|
31
|
+
import * as pro from "@budibase/pro"
|
|
28
32
|
|
|
29
|
-
const getEventFns = async (
|
|
33
|
+
const getEventFns = async (config: Config, existing?: Config) => {
|
|
30
34
|
const fns = []
|
|
31
35
|
|
|
32
|
-
let existing
|
|
33
|
-
if (config._id) {
|
|
34
|
-
existing = await db.get(config._id)
|
|
35
|
-
}
|
|
36
|
-
|
|
37
36
|
if (!existing) {
|
|
38
37
|
if (isSMTPConfig(config)) {
|
|
39
38
|
fns.push(events.email.SMTPCreated)
|
|
@@ -125,31 +124,96 @@ const getEventFns = async (db: Database, config: ConfigDoc) => {
|
|
|
125
124
|
return fns
|
|
126
125
|
}
|
|
127
126
|
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
127
|
+
type SSOConfigs = { [key in SSOConfigType]: SSOConfig | undefined }
|
|
128
|
+
|
|
129
|
+
async function getSSOConfigs(): Promise<SSOConfigs> {
|
|
130
|
+
const google = await configs.getGoogleConfig()
|
|
131
|
+
const oidc = await configs.getOIDCConfig()
|
|
132
|
+
return {
|
|
133
|
+
[ConfigType.GOOGLE]: google,
|
|
134
|
+
[ConfigType.OIDC]: oidc,
|
|
135
|
+
}
|
|
136
|
+
}
|
|
137
|
+
|
|
138
|
+
async function hasActivatedConfig(ssoConfigs?: SSOConfigs) {
|
|
139
|
+
if (!ssoConfigs) {
|
|
140
|
+
ssoConfigs = await getSSOConfigs()
|
|
141
|
+
}
|
|
142
|
+
return !!Object.values(ssoConfigs).find(c => c?.activated)
|
|
143
|
+
}
|
|
144
|
+
|
|
145
|
+
async function verifySettingsConfig(config: SettingsInnerConfig) {
|
|
146
|
+
if (config.isSSOEnforced) {
|
|
147
|
+
const valid = await hasActivatedConfig()
|
|
148
|
+
if (!valid) {
|
|
149
|
+
throw new Error("Cannot enforce SSO without an activated configuration")
|
|
150
|
+
}
|
|
151
|
+
}
|
|
152
|
+
}
|
|
153
|
+
|
|
154
|
+
async function verifySSOConfig(type: SSOConfigType, config: SSOConfig) {
|
|
155
|
+
const settings = await configs.getSettingsConfig()
|
|
156
|
+
if (settings.isSSOEnforced && !config.activated) {
|
|
157
|
+
// config is being saved as deactivated
|
|
158
|
+
// ensure there is at least one other activated sso config
|
|
159
|
+
const ssoConfigs = await getSSOConfigs()
|
|
160
|
+
|
|
161
|
+
// overwrite the config being updated
|
|
162
|
+
// to reflect the desired state
|
|
163
|
+
ssoConfigs[type] = config
|
|
164
|
+
|
|
165
|
+
const activated = await hasActivatedConfig(ssoConfigs)
|
|
166
|
+
if (!activated) {
|
|
167
|
+
throw new Error(
|
|
168
|
+
"Configuration cannot be deactivated while SSO is enforced"
|
|
169
|
+
)
|
|
170
|
+
}
|
|
171
|
+
}
|
|
172
|
+
}
|
|
173
|
+
|
|
174
|
+
async function verifyGoogleConfig(config: GoogleInnerConfig) {
|
|
175
|
+
await verifySSOConfig(ConfigType.GOOGLE, config)
|
|
176
|
+
}
|
|
177
|
+
|
|
178
|
+
async function verifyOIDCConfig(config: OIDCConfigs) {
|
|
179
|
+
await verifySSOConfig(ConfigType.OIDC, config.configs[0])
|
|
180
|
+
}
|
|
181
|
+
|
|
182
|
+
export async function save(ctx: UserCtx<Config>) {
|
|
183
|
+
const body = ctx.request.body
|
|
184
|
+
const type = body.type
|
|
185
|
+
const config = body.config
|
|
186
|
+
|
|
187
|
+
const existingConfig = await configs.getConfig(type)
|
|
188
|
+
let eventFns = await getEventFns(ctx.request.body, existingConfig)
|
|
189
|
+
|
|
190
|
+
if (existingConfig) {
|
|
191
|
+
body._rev = existingConfig._rev
|
|
139
192
|
}
|
|
193
|
+
|
|
140
194
|
try {
|
|
141
195
|
// verify the configuration
|
|
142
196
|
switch (type) {
|
|
143
197
|
case ConfigType.SMTP:
|
|
144
198
|
await email.verifyConfig(config)
|
|
145
199
|
break
|
|
200
|
+
case ConfigType.SETTINGS:
|
|
201
|
+
await verifySettingsConfig(config)
|
|
202
|
+
break
|
|
203
|
+
case ConfigType.GOOGLE:
|
|
204
|
+
await verifyGoogleConfig(config)
|
|
205
|
+
break
|
|
206
|
+
case ConfigType.OIDC:
|
|
207
|
+
await verifyOIDCConfig(config)
|
|
208
|
+
break
|
|
146
209
|
}
|
|
147
210
|
} catch (err: any) {
|
|
148
211
|
ctx.throw(400, err)
|
|
149
212
|
}
|
|
150
213
|
|
|
151
214
|
try {
|
|
152
|
-
|
|
215
|
+
body._id = configs.generateConfigID(type)
|
|
216
|
+
const response = await configs.save(body)
|
|
153
217
|
await cache.bustCache(cache.CacheKey.CHECKLIST)
|
|
154
218
|
await cache.bustCache(cache.CacheKey.ANALYTICS_ENABLED)
|
|
155
219
|
|
|
@@ -167,44 +231,11 @@ export async function save(ctx: UserCtx) {
|
|
|
167
231
|
}
|
|
168
232
|
}
|
|
169
233
|
|
|
170
|
-
export async function fetch(ctx: UserCtx) {
|
|
171
|
-
const db = tenancy.getGlobalDB()
|
|
172
|
-
const response = await db.allDocs(
|
|
173
|
-
dbCore.getConfigParams(
|
|
174
|
-
{ type: ctx.params.type },
|
|
175
|
-
{
|
|
176
|
-
include_docs: true,
|
|
177
|
-
}
|
|
178
|
-
)
|
|
179
|
-
)
|
|
180
|
-
ctx.body = response.rows.map(row => row.doc)
|
|
181
|
-
}
|
|
182
|
-
|
|
183
|
-
/**
|
|
184
|
-
* Gets the most granular config for a particular configuration type.
|
|
185
|
-
* The hierarchy is type -> workspace -> user.
|
|
186
|
-
*/
|
|
187
234
|
export async function find(ctx: UserCtx) {
|
|
188
|
-
const db = tenancy.getGlobalDB()
|
|
189
|
-
|
|
190
|
-
const { userId, workspaceId } = ctx.query
|
|
191
|
-
if (workspaceId && userId) {
|
|
192
|
-
const workspace = await db.get(workspaceId as string)
|
|
193
|
-
const userInWorkspace = workspace.users.some(
|
|
194
|
-
(workspaceUser: any) => workspaceUser === userId
|
|
195
|
-
)
|
|
196
|
-
if (!ctx.user!.admin && !userInWorkspace) {
|
|
197
|
-
ctx.throw(400, `User is not in specified workspace: ${workspace}.`)
|
|
198
|
-
}
|
|
199
|
-
}
|
|
200
|
-
|
|
201
235
|
try {
|
|
202
236
|
// Find the config with the most granular scope based on context
|
|
203
|
-
const
|
|
204
|
-
|
|
205
|
-
user: userId,
|
|
206
|
-
workspace: workspaceId,
|
|
207
|
-
})
|
|
237
|
+
const type = ctx.params.type
|
|
238
|
+
const scopedConfig = await configs.getConfig(type)
|
|
208
239
|
|
|
209
240
|
if (scopedConfig) {
|
|
210
241
|
ctx.body = scopedConfig
|
|
@@ -217,85 +248,70 @@ export async function find(ctx: UserCtx) {
|
|
|
217
248
|
}
|
|
218
249
|
}
|
|
219
250
|
|
|
220
|
-
export async function publicOidc(ctx: Ctx) {
|
|
221
|
-
const db = tenancy.getGlobalDB()
|
|
251
|
+
export async function publicOidc(ctx: Ctx<void, GetPublicOIDCConfigResponse>) {
|
|
222
252
|
try {
|
|
223
253
|
// Find the config with the most granular scope based on context
|
|
224
|
-
const
|
|
225
|
-
type: ConfigType.OIDC,
|
|
226
|
-
})
|
|
254
|
+
const config = await configs.getOIDCConfig()
|
|
227
255
|
|
|
228
|
-
if (!
|
|
229
|
-
ctx.body =
|
|
256
|
+
if (!config) {
|
|
257
|
+
ctx.body = []
|
|
230
258
|
} else {
|
|
231
|
-
ctx.body =
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
259
|
+
ctx.body = [
|
|
260
|
+
{
|
|
261
|
+
logo: config.logo,
|
|
262
|
+
name: config.name,
|
|
263
|
+
uuid: config.uuid,
|
|
264
|
+
},
|
|
265
|
+
]
|
|
236
266
|
}
|
|
237
267
|
} catch (err: any) {
|
|
238
268
|
ctx.throw(err.status, err)
|
|
239
269
|
}
|
|
240
270
|
}
|
|
241
271
|
|
|
242
|
-
export async function publicSettings(
|
|
243
|
-
|
|
244
|
-
|
|
272
|
+
export async function publicSettings(
|
|
273
|
+
ctx: Ctx<void, GetPublicSettingsResponse>
|
|
274
|
+
) {
|
|
245
275
|
try {
|
|
246
|
-
//
|
|
247
|
-
const
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
type: ConfigType.GOOGLE,
|
|
253
|
-
})
|
|
254
|
-
|
|
255
|
-
const oidcConfig = await dbCore.getScopedFullConfig(db, {
|
|
256
|
-
type: ConfigType.OIDC,
|
|
257
|
-
})
|
|
258
|
-
|
|
259
|
-
let config
|
|
260
|
-
if (!publicConfig) {
|
|
261
|
-
config = {
|
|
262
|
-
config: {},
|
|
263
|
-
}
|
|
264
|
-
} else {
|
|
265
|
-
config = publicConfig
|
|
266
|
-
}
|
|
267
|
-
|
|
268
|
-
// enrich the logo url
|
|
269
|
-
// empty url means deleted
|
|
270
|
-
if (config.config.logoUrl && config.config.logoUrl !== "") {
|
|
271
|
-
config.config.logoUrl = objectStore.getGlobalFileUrl(
|
|
276
|
+
// settings
|
|
277
|
+
const configDoc = await configs.getSettingsConfigDoc()
|
|
278
|
+
const config = configDoc.config
|
|
279
|
+
// enrich the logo url - empty url means deleted
|
|
280
|
+
if (config.logoUrl && config.logoUrl !== "") {
|
|
281
|
+
config.logoUrl = objectStore.getGlobalFileUrl(
|
|
272
282
|
"settings",
|
|
273
283
|
"logoUrl",
|
|
274
|
-
config.
|
|
284
|
+
config.logoUrlEtag
|
|
275
285
|
)
|
|
276
286
|
}
|
|
277
287
|
|
|
278
|
-
// google
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
} else {
|
|
284
|
-
config.config.google = false
|
|
285
|
-
}
|
|
288
|
+
// google
|
|
289
|
+
const googleConfig = await configs.getGoogleConfig()
|
|
290
|
+
const preActivated = googleConfig?.activated == null
|
|
291
|
+
const google = preActivated || !!googleConfig?.activated
|
|
292
|
+
const _googleCallbackUrl = await googleCallbackUrl(googleConfig)
|
|
286
293
|
|
|
287
|
-
//
|
|
288
|
-
|
|
289
|
-
|
|
294
|
+
// oidc
|
|
295
|
+
const oidcConfig = await configs.getOIDCConfig()
|
|
296
|
+
const oidc = oidcConfig?.activated || false
|
|
297
|
+
const _oidcCallbackUrl = await oidcCallbackUrl()
|
|
290
298
|
|
|
291
|
-
//
|
|
292
|
-
|
|
293
|
-
config.config.oidc = oidcConfig.config.configs[0].activated
|
|
294
|
-
} else {
|
|
295
|
-
config.config.oidc = false
|
|
296
|
-
}
|
|
299
|
+
// sso enforced
|
|
300
|
+
const isSSOEnforced = await pro.features.isSSOEnforced({ config })
|
|
297
301
|
|
|
298
|
-
ctx.body =
|
|
302
|
+
ctx.body = {
|
|
303
|
+
type: ConfigType.SETTINGS,
|
|
304
|
+
_id: configDoc._id,
|
|
305
|
+
_rev: configDoc._rev,
|
|
306
|
+
config: {
|
|
307
|
+
...config,
|
|
308
|
+
google,
|
|
309
|
+
oidc,
|
|
310
|
+
isSSOEnforced,
|
|
311
|
+
oidcCallbackUrl: _oidcCallbackUrl,
|
|
312
|
+
googleCallbackUrl: _googleCallbackUrl,
|
|
313
|
+
},
|
|
314
|
+
}
|
|
299
315
|
} catch (err: any) {
|
|
300
316
|
ctx.throw(err.status, err)
|
|
301
317
|
}
|
|
@@ -319,12 +335,11 @@ export async function upload(ctx: UserCtx) {
|
|
|
319
335
|
})
|
|
320
336
|
|
|
321
337
|
// add to configuration structure
|
|
322
|
-
|
|
323
|
-
|
|
324
|
-
|
|
325
|
-
|
|
326
|
-
|
|
327
|
-
_id: dbCore.generateConfigID({ type }),
|
|
338
|
+
let config = await configs.getConfig(type)
|
|
339
|
+
if (!config) {
|
|
340
|
+
config = {
|
|
341
|
+
_id: configs.generateConfigID(type),
|
|
342
|
+
type,
|
|
328
343
|
config: {},
|
|
329
344
|
}
|
|
330
345
|
}
|
|
@@ -332,14 +347,14 @@ export async function upload(ctx: UserCtx) {
|
|
|
332
347
|
// save the Etag for cache bursting
|
|
333
348
|
const etag = result.ETag
|
|
334
349
|
if (etag) {
|
|
335
|
-
|
|
350
|
+
config.config[`${name}Etag`] = etag.replace(/"/g, "")
|
|
336
351
|
}
|
|
337
352
|
|
|
338
353
|
// save the file key
|
|
339
|
-
|
|
354
|
+
config.config[`${name}`] = key
|
|
340
355
|
|
|
341
356
|
// write back to db
|
|
342
|
-
await
|
|
357
|
+
await configs.save(config)
|
|
343
358
|
|
|
344
359
|
ctx.body = {
|
|
345
360
|
message: "File has been uploaded and url stored to config.",
|
|
@@ -360,7 +375,6 @@ export async function destroy(ctx: UserCtx) {
|
|
|
360
375
|
}
|
|
361
376
|
|
|
362
377
|
export async function configChecklist(ctx: Ctx) {
|
|
363
|
-
const db = tenancy.getGlobalDB()
|
|
364
378
|
const tenantId = tenancy.getTenantId()
|
|
365
379
|
|
|
366
380
|
try {
|
|
@@ -375,19 +389,13 @@ export async function configChecklist(ctx: Ctx) {
|
|
|
375
389
|
}
|
|
376
390
|
|
|
377
391
|
// They have set up SMTP
|
|
378
|
-
const smtpConfig = await
|
|
379
|
-
type: ConfigType.SMTP,
|
|
380
|
-
})
|
|
392
|
+
const smtpConfig = await configs.getSMTPConfig()
|
|
381
393
|
|
|
382
394
|
// They have set up Google Auth
|
|
383
|
-
const googleConfig = await
|
|
384
|
-
type: ConfigType.GOOGLE,
|
|
385
|
-
})
|
|
395
|
+
const googleConfig = await configs.getGoogleConfig()
|
|
386
396
|
|
|
387
397
|
// They have set up OIDC
|
|
388
|
-
const oidcConfig = await
|
|
389
|
-
type: ConfigType.OIDC,
|
|
390
|
-
})
|
|
398
|
+
const oidcConfig = await configs.getOIDCConfig()
|
|
391
399
|
|
|
392
400
|
// They have set up a global user
|
|
393
401
|
const userExists = await checkAnyUserExists()
|
|
@@ -1,18 +1,22 @@
|
|
|
1
|
-
import
|
|
1
|
+
import * as userSdk from "../../../sdk/users"
|
|
2
2
|
import {
|
|
3
|
-
events,
|
|
4
3
|
featureFlags,
|
|
5
4
|
tenancy,
|
|
6
5
|
constants,
|
|
7
6
|
db as dbCore,
|
|
8
7
|
utils,
|
|
9
|
-
cache,
|
|
10
8
|
encryption,
|
|
9
|
+
auth as authCore,
|
|
11
10
|
} from "@budibase/backend-core"
|
|
12
11
|
import env from "../../../environment"
|
|
13
12
|
import { groups } from "@budibase/pro"
|
|
14
|
-
|
|
15
|
-
|
|
13
|
+
import {
|
|
14
|
+
UpdateSelfRequest,
|
|
15
|
+
UpdateSelfResponse,
|
|
16
|
+
UpdateSelf,
|
|
17
|
+
UserCtx,
|
|
18
|
+
} from "@budibase/types"
|
|
19
|
+
const { getCookie, clearCookie, newid } = utils
|
|
16
20
|
|
|
17
21
|
function newTestApiKey() {
|
|
18
22
|
return env.ENCRYPTED_TEST_PUBLIC_API_KEY
|
|
@@ -93,17 +97,6 @@ const addSessionAttributesToUser = (ctx: any) => {
|
|
|
93
97
|
ctx.body.csrfToken = ctx.user.csrfToken
|
|
94
98
|
}
|
|
95
99
|
|
|
96
|
-
const sanitiseUserUpdate = (ctx: any) => {
|
|
97
|
-
const allowed = ["firstName", "lastName", "password", "forceResetPassword"]
|
|
98
|
-
const resp: { [key: string]: any } = {}
|
|
99
|
-
for (let [key, value] of Object.entries(ctx.request.body)) {
|
|
100
|
-
if (allowed.includes(key)) {
|
|
101
|
-
resp[key] = value
|
|
102
|
-
}
|
|
103
|
-
}
|
|
104
|
-
return resp
|
|
105
|
-
}
|
|
106
|
-
|
|
107
100
|
export async function getSelf(ctx: any) {
|
|
108
101
|
if (!ctx.user) {
|
|
109
102
|
ctx.throw(403, "User not logged in")
|
|
@@ -116,7 +109,7 @@ export async function getSelf(ctx: any) {
|
|
|
116
109
|
checkCurrentApp(ctx)
|
|
117
110
|
|
|
118
111
|
// get the main body of the user
|
|
119
|
-
const user = await
|
|
112
|
+
const user = await userSdk.getUser(userId)
|
|
120
113
|
ctx.body = await groups.enrichUserRolesFromGroups(user)
|
|
121
114
|
|
|
122
115
|
// add the feature flags for this tenant
|
|
@@ -126,39 +119,30 @@ export async function getSelf(ctx: any) {
|
|
|
126
119
|
addSessionAttributesToUser(ctx)
|
|
127
120
|
}
|
|
128
121
|
|
|
129
|
-
export async function updateSelf(
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
122
|
+
export async function updateSelf(
|
|
123
|
+
ctx: UserCtx<UpdateSelfRequest, UpdateSelfResponse>
|
|
124
|
+
) {
|
|
125
|
+
const body = ctx.request.body
|
|
126
|
+
const update: UpdateSelf = {
|
|
127
|
+
firstName: body.firstName,
|
|
128
|
+
lastName: body.lastName,
|
|
129
|
+
password: body.password,
|
|
130
|
+
forceResetPassword: body.forceResetPassword,
|
|
131
|
+
}
|
|
132
|
+
|
|
133
|
+
const user = await userSdk.updateSelf(ctx.user._id!, update)
|
|
134
|
+
|
|
135
|
+
if (update.password) {
|
|
139
136
|
// Log all other sessions out apart from the current one
|
|
140
|
-
await platformLogout({
|
|
137
|
+
await authCore.platformLogout({
|
|
141
138
|
ctx,
|
|
142
|
-
userId: ctx.user._id
|
|
139
|
+
userId: ctx.user._id!,
|
|
143
140
|
keepActiveSession: true,
|
|
144
141
|
})
|
|
145
142
|
}
|
|
146
143
|
|
|
147
|
-
const response = await db.put({
|
|
148
|
-
...user,
|
|
149
|
-
...userUpdateObj,
|
|
150
|
-
})
|
|
151
|
-
await userCache.invalidateUser(user._id)
|
|
152
144
|
ctx.body = {
|
|
153
|
-
_id:
|
|
154
|
-
_rev:
|
|
155
|
-
}
|
|
156
|
-
|
|
157
|
-
// remove the old password from the user before sending events
|
|
158
|
-
user._rev = response.rev
|
|
159
|
-
delete user.password
|
|
160
|
-
await events.user.updated(user)
|
|
161
|
-
if (passwordChange) {
|
|
162
|
-
await events.user.passwordUpdated(user)
|
|
145
|
+
_id: user._id!,
|
|
146
|
+
_rev: user._rev!,
|
|
163
147
|
}
|
|
164
148
|
}
|