@budibase/worker 2.3.18-alpha.3 → 2.3.18-alpha.30

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/jest.config.ts CHANGED
@@ -7,7 +7,7 @@ const config: Config.InitialOptions = {
7
7
  preset: "@trendyol/jest-testcontainers",
8
8
  setupFiles: ["./src/tests/jestEnv.ts"],
9
9
  setupFilesAfterEnv: ["./src/tests/jestSetup.ts"],
10
- collectCoverageFrom: ["src/**/*.{js,ts}"],
10
+ collectCoverageFrom: ["src/**/*.{js,ts}", "../backend-core/src/**/*.{js,ts}"],
11
11
  coverageReporters: ["lcov", "json", "clover"],
12
12
  transform: {
13
13
  "^.+\\.ts?$": "@swc/jest",
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@budibase/worker",
3
3
  "email": "hi@budibase.com",
4
- "version": "2.3.18-alpha.3",
4
+ "version": "2.3.18-alpha.30",
5
5
  "description": "Budibase background service",
6
6
  "main": "src/index.ts",
7
7
  "repository": {
@@ -22,7 +22,7 @@
22
22
  "build:docker": "docker build . -t worker-service --label version=$BUDIBASE_RELEASE_VERSION",
23
23
  "dev:stack:init": "node ./scripts/dev/manage.js init",
24
24
  "dev:builder": "npm run dev:stack:init && nodemon",
25
- "test": "jest --coverage --runInBand",
25
+ "test": "bash scripts/test.sh",
26
26
  "test:watch": "jest --watch",
27
27
  "env:multi:enable": "node scripts/multiTenancy.js enable",
28
28
  "env:multi:disable": "node scripts/multiTenancy.js disable",
@@ -36,10 +36,10 @@
36
36
  "author": "Budibase",
37
37
  "license": "GPL-3.0",
38
38
  "dependencies": {
39
- "@budibase/backend-core": "2.3.18-alpha.3",
40
- "@budibase/pro": "2.3.18-alpha.2",
41
- "@budibase/string-templates": "2.3.18-alpha.3",
42
- "@budibase/types": "2.3.18-alpha.3",
39
+ "@budibase/backend-core": "2.3.18-alpha.30",
40
+ "@budibase/pro": "2.3.18-alpha.29",
41
+ "@budibase/string-templates": "2.3.18-alpha.30",
42
+ "@budibase/types": "2.3.18-alpha.30",
43
43
  "@koa/router": "8.0.8",
44
44
  "@sentry/node": "6.17.7",
45
45
  "@techpass/passport-openidconnect": "0.3.2",
@@ -60,6 +60,7 @@
60
60
  "koa-send": "5.0.1",
61
61
  "koa-session": "5.13.1",
62
62
  "koa-static": "5.0.0",
63
+ "koa-useragent": "^4.1.0",
63
64
  "node-fetch": "2.6.7",
64
65
  "nodemailer": "6.7.2",
65
66
  "passport-google-oauth": "2.0.0",
@@ -100,5 +101,5 @@
100
101
  "typescript": "4.7.3",
101
102
  "update-dotenv": "1.1.1"
102
103
  },
103
- "gitHead": "ee49637f6ff573832f699711c4d00557a50543b1"
104
+ "gitHead": "8f9671e11e846586ec9c022a53daf52f5189b6b5"
104
105
  }
@@ -0,0 +1,12 @@
1
+ #!/bin/bash
2
+
3
+ if [[ -n $CI ]]
4
+ then
5
+ # --runInBand performs better in ci where resources are limited
6
+ echo "jest --coverage --runInBand"
7
+ jest --coverage --runInBand
8
+ else
9
+ # --maxWorkers performs better in development
10
+ echo "jest --coverage --maxWorkers=2"
11
+ jest --coverage --maxWorkers=2
12
+ fi
@@ -2,10 +2,9 @@ import {
2
2
  auth as authCore,
3
3
  constants,
4
4
  context,
5
- db as dbCore,
6
5
  events,
7
- tenancy,
8
6
  utils as utilsCore,
7
+ configs,
9
8
  } from "@budibase/backend-core"
10
9
  import {
11
10
  ConfigType,
@@ -15,6 +14,7 @@ import {
15
14
  SSOUser,
16
15
  PasswordResetRequest,
17
16
  PasswordResetUpdateRequest,
17
+ GoogleInnerConfig,
18
18
  } from "@budibase/types"
19
19
  import env from "../../../environment"
20
20
 
@@ -61,16 +61,16 @@ export const login = async (ctx: Ctx<LoginRequest>, next: any) => {
61
61
  const email = ctx.request.body.username
62
62
 
63
63
  const user = await userSdk.getUserByEmail(email)
64
- if (user && (await userSdk.isPreventSSOPasswords(user))) {
65
- ctx.throw(400, "SSO user cannot login using password")
64
+ if (user && (await userSdk.isPreventPasswordActions(user))) {
65
+ ctx.throw(403, "Invalid credentials")
66
66
  }
67
67
 
68
68
  return passport.authenticate(
69
69
  "local",
70
70
  async (err: any, user: User, info: any) => {
71
71
  await passportCallback(ctx, user, err, info)
72
- await context.identity.doInUserContext(user, async () => {
73
- await events.auth.login("local")
72
+ await context.identity.doInUserContext(user, ctx, async () => {
73
+ await events.auth.login("local", user.email)
74
74
  })
75
75
  ctx.status = 200
76
76
  }
@@ -163,8 +163,8 @@ export const datasourceAuth = async (ctx: any, next: any) => {
163
163
 
164
164
  // GOOGLE SSO
165
165
 
166
- export async function googleCallbackUrl(config?: { callbackURL?: string }) {
167
- return ssoCallbackUrl(tenancy.getGlobalDB(), config, ConfigType.GOOGLE)
166
+ export async function googleCallbackUrl(config?: GoogleInnerConfig) {
167
+ return ssoCallbackUrl(ConfigType.GOOGLE, config)
168
168
  }
169
169
 
170
170
  /**
@@ -172,12 +172,10 @@ export async function googleCallbackUrl(config?: { callbackURL?: string }) {
172
172
  * On a successful login, you will be redirected to the googleAuth callback route.
173
173
  */
174
174
  export const googlePreAuth = async (ctx: any, next: any) => {
175
- const db = tenancy.getGlobalDB()
176
-
177
- const config = await dbCore.getScopedConfig(db, {
178
- type: ConfigType.GOOGLE,
179
- workspace: ctx.query.workspace,
180
- })
175
+ const config = await configs.getGoogleConfig()
176
+ if (!config) {
177
+ return ctx.throw(400, "Google config not found")
178
+ }
181
179
  let callbackUrl = await googleCallbackUrl(config)
182
180
  const strategy = await google.strategyFactory(
183
181
  config,
@@ -193,12 +191,10 @@ export const googlePreAuth = async (ctx: any, next: any) => {
193
191
  }
194
192
 
195
193
  export const googleCallback = async (ctx: any, next: any) => {
196
- const db = tenancy.getGlobalDB()
197
-
198
- const config = await dbCore.getScopedConfig(db, {
199
- type: ConfigType.GOOGLE,
200
- workspace: ctx.query.workspace,
201
- })
194
+ const config = await configs.getGoogleConfig()
195
+ if (!config) {
196
+ return ctx.throw(400, "Google config not found")
197
+ }
202
198
  const callbackUrl = await googleCallbackUrl(config)
203
199
  const strategy = await google.strategyFactory(
204
200
  config,
@@ -211,8 +207,8 @@ export const googleCallback = async (ctx: any, next: any) => {
211
207
  { successRedirect: "/", failureRedirect: "/error" },
212
208
  async (err: any, user: SSOUser, info: any) => {
213
209
  await passportCallback(ctx, user, err, info)
214
- await context.identity.doInUserContext(user, async () => {
215
- await events.auth.login("google-internal")
210
+ await context.identity.doInUserContext(user, ctx, async () => {
211
+ await events.auth.login("google-internal", user.email)
216
212
  })
217
213
  ctx.redirect("/")
218
214
  }
@@ -221,25 +217,20 @@ export const googleCallback = async (ctx: any, next: any) => {
221
217
 
222
218
  // OIDC SSO
223
219
 
224
- export async function oidcCallbackUrl(config?: { callbackURL?: string }) {
225
- return ssoCallbackUrl(tenancy.getGlobalDB(), config, ConfigType.OIDC)
220
+ export async function oidcCallbackUrl() {
221
+ return ssoCallbackUrl(ConfigType.OIDC)
226
222
  }
227
223
 
228
224
  export const oidcStrategyFactory = async (ctx: any, configId: any) => {
229
- const db = tenancy.getGlobalDB()
230
- const config = await dbCore.getScopedConfig(db, {
231
- type: ConfigType.OIDC,
232
- group: ctx.query.group,
233
- })
225
+ const config = await configs.getOIDCConfig()
226
+ if (!config) {
227
+ return ctx.throw(400, "OIDC config not found")
228
+ }
234
229
 
235
- const chosenConfig = config.configs.filter((c: any) => c.uuid === configId)[0]
236
- let callbackUrl = await oidcCallbackUrl(chosenConfig)
230
+ let callbackUrl = await oidcCallbackUrl()
237
231
 
238
232
  //Remote Config
239
- const enrichedConfig = await oidc.fetchStrategyConfig(
240
- chosenConfig,
241
- callbackUrl
242
- )
233
+ const enrichedConfig = await oidc.fetchStrategyConfig(config, callbackUrl)
243
234
  return oidc.strategyFactory(enrichedConfig, userSdk.save)
244
235
  }
245
236
 
@@ -247,23 +238,23 @@ export const oidcStrategyFactory = async (ctx: any, configId: any) => {
247
238
  * The initial call that OIDC authentication makes to take you to the configured OIDC login screen.
248
239
  * On a successful login, you will be redirected to the oidcAuth callback route.
249
240
  */
250
- export const oidcPreAuth = async (ctx: any, next: any) => {
241
+ export const oidcPreAuth = async (ctx: Ctx, next: any) => {
251
242
  const { configId } = ctx.params
243
+ if (!configId) {
244
+ ctx.throw(400, "OIDC config id is required")
245
+ }
252
246
  const strategy = await oidcStrategyFactory(ctx, configId)
253
247
 
254
248
  setCookie(ctx, configId, Cookie.OIDC_CONFIG)
255
249
 
256
- const db = tenancy.getGlobalDB()
257
- const config = await dbCore.getScopedConfig(db, {
258
- type: ConfigType.OIDC,
259
- group: ctx.query.group,
260
- })
261
-
262
- const chosenConfig = config.configs.filter((c: any) => c.uuid === configId)[0]
250
+ const config = await configs.getOIDCConfigById(configId)
251
+ if (!config) {
252
+ return ctx.throw(400, "OIDC config not found")
253
+ }
263
254
 
264
255
  let authScopes =
265
- chosenConfig.scopes?.length > 0
266
- ? chosenConfig.scopes
256
+ config.scopes?.length > 0
257
+ ? config.scopes
267
258
  : ["profile", "email", "offline_access"]
268
259
 
269
260
  return passport.authenticate(strategy, {
@@ -281,8 +272,8 @@ export const oidcCallback = async (ctx: any, next: any) => {
281
272
  { successRedirect: "/", failureRedirect: "/error" },
282
273
  async (err: any, user: SSOUser, info: any) => {
283
274
  await passportCallback(ctx, user, err, info)
284
- await context.identity.doInUserContext(user, async () => {
285
- await events.auth.login("oidc")
275
+ await context.identity.doInUserContext(user, ctx, async () => {
276
+ await events.auth.login("oidc", user.email)
286
277
  })
287
278
  ctx.redirect("/")
288
279
  }
@@ -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
- objectStore,
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
- Database,
15
- Config as ConfigDoc,
15
+ Config,
16
16
  ConfigType,
17
- SSOType,
18
- GoogleConfig,
19
- OIDCConfig,
20
- SettingsConfig,
17
+ Ctx,
18
+ GetPublicOIDCConfigResponse,
19
+ GetPublicSettingsResponse,
20
+ GoogleInnerConfig,
21
21
  isGoogleConfig,
22
22
  isOIDCConfig,
23
23
  isSettingsConfig,
24
24
  isSMTPConfig,
25
- Ctx,
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 (db: Database, config: ConfigDoc) => {
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
- export async function save(ctx: UserCtx) {
129
- const db = tenancy.getGlobalDB()
130
- const { type, workspace, user, config } = ctx.request.body
131
- let eventFns = await getEventFns(db, ctx.request.body)
132
- // Config does not exist yet
133
- if (!ctx.request.body._id) {
134
- ctx.request.body._id = dbCore.generateConfigID({
135
- type,
136
- workspace,
137
- user,
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
- const response = await db.put(ctx.request.body)
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 scopedConfig = await dbCore.getScopedFullConfig(db, {
204
- type: ctx.params.type,
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 oidcConfig: OIDCConfig = await dbCore.getScopedFullConfig(db, {
225
- type: ConfigType.OIDC,
226
- })
254
+ const config = await configs.getOIDCConfig()
227
255
 
228
- if (!oidcConfig) {
229
- ctx.body = {}
256
+ if (!config) {
257
+ ctx.body = []
230
258
  } else {
231
- ctx.body = oidcConfig.config.configs.map(config => ({
232
- logo: config.logo,
233
- name: config.name,
234
- uuid: config.uuid,
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(ctx: Ctx) {
243
- const db = tenancy.getGlobalDB()
244
-
272
+ export async function publicSettings(
273
+ ctx: Ctx<void, GetPublicSettingsResponse>
274
+ ) {
245
275
  try {
246
- // Find the config with the most granular scope based on context
247
- const publicConfig = await dbCore.getScopedFullConfig(db, {
248
- type: ConfigType.SETTINGS,
249
- })
250
-
251
- const googleConfig = await dbCore.getScopedFullConfig(db, {
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.config.logoUrlEtag
284
+ config.logoUrlEtag
275
285
  )
276
286
  }
277
287
 
278
- // google button flag
279
- if (googleConfig && googleConfig.config) {
280
- // activated by default for configs pre-activated flag
281
- config.config.google =
282
- googleConfig.config.activated == null || googleConfig.config.activated
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
- // callback urls
288
- config.config.oidcCallbackUrl = await oidcCallbackUrl()
289
- config.config.googleCallbackUrl = await googleCallbackUrl()
294
+ // oidc
295
+ const oidcConfig = await configs.getOIDCConfig()
296
+ const oidc = oidcConfig?.activated || false
297
+ const _oidcCallbackUrl = await oidcCallbackUrl()
290
298
 
291
- // oidc button flag
292
- if (oidcConfig && oidcConfig.config) {
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 = config
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
- // TODO: right now this only does a global level
323
- const db = tenancy.getGlobalDB()
324
- let cfgStructure = await dbCore.getScopedFullConfig(db, { type })
325
- if (!cfgStructure) {
326
- cfgStructure = {
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
- cfgStructure.config[`${name}Etag`] = etag.replace(/"/g, "")
350
+ config.config[`${name}Etag`] = etag.replace(/"/g, "")
336
351
  }
337
352
 
338
353
  // save the file key
339
- cfgStructure.config[`${name}`] = key
354
+ config.config[`${name}`] = key
340
355
 
341
356
  // write back to db
342
- await db.put(cfgStructure)
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 dbCore.getScopedFullConfig(db, {
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 dbCore.getScopedFullConfig(db, {
384
- type: ConfigType.GOOGLE,
385
- })
395
+ const googleConfig = await configs.getGoogleConfig()
386
396
 
387
397
  // They have set up OIDC
388
- const oidcConfig = await dbCore.getScopedFullConfig(db, {
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()