@budibase/worker 2.33.2 → 2.33.3

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 CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@budibase/worker",
3
3
  "email": "hi@budibase.com",
4
- "version": "2.33.2",
4
+ "version": "2.33.3",
5
5
  "description": "Budibase background service",
6
6
  "main": "src/index.ts",
7
7
  "repository": {
@@ -37,10 +37,10 @@
37
37
  "author": "Budibase",
38
38
  "license": "GPL-3.0",
39
39
  "dependencies": {
40
- "@budibase/backend-core": "2.33.2",
41
- "@budibase/pro": "2.33.2",
42
- "@budibase/string-templates": "2.33.2",
43
- "@budibase/types": "2.33.2",
40
+ "@budibase/backend-core": "2.33.3",
41
+ "@budibase/pro": "2.33.3",
42
+ "@budibase/string-templates": "2.33.3",
43
+ "@budibase/types": "2.33.3",
44
44
  "@koa/router": "8.0.8",
45
45
  "@techpass/passport-openidconnect": "0.3.3",
46
46
  "@types/global-agent": "2.1.1",
@@ -107,5 +107,5 @@
107
107
  }
108
108
  }
109
109
  },
110
- "gitHead": "72e28bac4ad58c8cf88badd8582545ba6f9aa671"
110
+ "gitHead": "59d2531535e610f1ef961cb35e09bb1d477ff563"
111
111
  }
@@ -44,9 +44,7 @@ const getEventFns = async (config: Config, existing?: Config) => {
44
44
  fns.push(events.email.SMTPCreated)
45
45
  } else if (isAIConfig(config)) {
46
46
  fns.push(() => events.ai.AIConfigCreated)
47
- fns.push(() =>
48
- pro.quotas.updateCustomAIConfigCount(Object.keys(config.config).length)
49
- )
47
+ fns.push(() => pro.quotas.addCustomAIConfig())
50
48
  } else if (isGoogleConfig(config)) {
51
49
  fns.push(() => events.auth.SSOCreated(ConfigType.GOOGLE))
52
50
  if (config.config.activated) {
@@ -85,9 +83,6 @@ const getEventFns = async (config: Config, existing?: Config) => {
85
83
  fns.push(events.email.SMTPUpdated)
86
84
  } else if (isAIConfig(config)) {
87
85
  fns.push(() => events.ai.AIConfigUpdated)
88
- fns.push(() =>
89
- pro.quotas.updateCustomAIConfigCount(Object.keys(config.config).length)
90
- )
91
86
  } else if (isGoogleConfig(config)) {
92
87
  fns.push(() => events.auth.SSOUpdated(ConfigType.GOOGLE))
93
88
  if (!existing.config.activated && config.config.activated) {
@@ -253,7 +248,7 @@ export async function save(ctx: UserCtx<Config>) {
253
248
  if (existingConfig) {
254
249
  await verifyAIConfig(config, existingConfig)
255
250
  }
256
- await pro.quotas.updateCustomAIConfigCount(Object.keys(config).length)
251
+ await pro.quotas.addCustomAIConfig()
257
252
  break
258
253
  }
259
254
  } catch (err: any) {
@@ -342,29 +337,43 @@ export async function find(ctx: UserCtx) {
342
337
  let scopedConfig = await configs.getConfig(type)
343
338
 
344
339
  if (scopedConfig) {
345
- if (type === ConfigType.OIDC_LOGOS) {
346
- enrichOIDCLogos(scopedConfig)
347
- }
348
-
349
- if (type === ConfigType.AI) {
350
- await pro.sdk.ai.enrichAIConfig(scopedConfig)
351
- // Strip out the API Keys from the response so they don't show in the UI
352
- for (const key in scopedConfig.config) {
353
- if (scopedConfig.config[key].apiKey) {
354
- scopedConfig.config[key].apiKey = PASSWORD_REPLACEMENT
355
- }
356
- }
357
- }
358
- ctx.body = scopedConfig
340
+ await handleConfigType(type, scopedConfig)
341
+ } else if (type === ConfigType.AI) {
342
+ scopedConfig = { config: {} } as AIConfig
343
+ await handleAIConfig(scopedConfig)
359
344
  } else {
360
- // don't throw an error, there simply is nothing to return
345
+ // If no config found and not AI type, just return an empty body
361
346
  ctx.body = {}
347
+ return
362
348
  }
349
+
350
+ ctx.body = scopedConfig
363
351
  } catch (err: any) {
364
352
  ctx.throw(err?.status || 400, err)
365
353
  }
366
354
  }
367
355
 
356
+ async function handleConfigType(type: ConfigType, config: Config) {
357
+ if (type === ConfigType.OIDC_LOGOS) {
358
+ enrichOIDCLogos(config)
359
+ } else if (type === ConfigType.AI) {
360
+ await handleAIConfig(config)
361
+ }
362
+ }
363
+
364
+ async function handleAIConfig(config: AIConfig) {
365
+ await pro.sdk.ai.enrichAIConfig(config)
366
+ stripApiKeys(config)
367
+ }
368
+
369
+ function stripApiKeys(config: AIConfig) {
370
+ for (const key in config?.config) {
371
+ if (config.config[key].apiKey) {
372
+ config.config[key].apiKey = PASSWORD_REPLACEMENT
373
+ }
374
+ }
375
+ }
376
+
368
377
  export async function publicOidc(ctx: Ctx<void, GetPublicOIDCConfigResponse>) {
369
378
  try {
370
379
  // Find the config with the most granular scope based on context
@@ -508,6 +517,9 @@ export async function destroy(ctx: UserCtx) {
508
517
  try {
509
518
  await db.remove(id, rev)
510
519
  await cache.destroy(cache.CacheKey.CHECKLIST)
520
+ if (id === configs.generateConfigID(ConfigType.AI)) {
521
+ await pro.quotas.removeCustomAIConfig()
522
+ }
511
523
  ctx.body = { message: "Config deleted successfully" }
512
524
  } catch (err: any) {
513
525
  ctx.throw(err.status, err)
@@ -13,10 +13,6 @@ describe("Global configs controller", () => {
13
13
  await config.afterAll()
14
14
  })
15
15
 
16
- afterEach(() => {
17
- jest.resetAllMocks()
18
- })
19
-
20
16
  it("Should strip secrets when pulling AI config", async () => {
21
17
  const data = structures.configs.ai()
22
18
  await config.api.configs.saveConfig(data)
@@ -1,4 +1,4 @@
1
- import { Ctx, MaintenanceType } from "@budibase/types"
1
+ import { Ctx, MaintenanceType, FeatureFlag } from "@budibase/types"
2
2
  import env from "../../../environment"
3
3
  import { env as coreEnv, db as dbCore, features } from "@budibase/backend-core"
4
4
  import nodeFetch from "node-fetch"
@@ -29,7 +29,10 @@ async function isSqsAvailable() {
29
29
  }
30
30
 
31
31
  async function isSqsMissing() {
32
- return (await features.flags.isEnabled("SQS")) && !(await isSqsAvailable())
32
+ return (
33
+ (await features.flags.isEnabled(FeatureFlag.SQS)) &&
34
+ !(await isSqsAvailable())
35
+ )
33
36
  }
34
37
 
35
38
  export const fetch = async (ctx: Ctx) => {
@@ -1,6 +1,6 @@
1
1
  import { structures, TestConfiguration } from "../../../../tests"
2
2
  import { context, db, permissions, roles } from "@budibase/backend-core"
3
- import { Database } from "@budibase/types"
3
+ import { App, Database } from "@budibase/types"
4
4
 
5
5
  jest.mock("@budibase/backend-core", () => {
6
6
  const core = jest.requireActual("@budibase/backend-core")
@@ -30,6 +30,14 @@ async function addAppMetadata() {
30
30
  })
31
31
  }
32
32
 
33
+ async function updateAppMetadata(update: Partial<Omit<App, "_id" | "_rev">>) {
34
+ const app = await appDb.get("app_metadata")
35
+ await appDb.put({
36
+ ...app,
37
+ ...update,
38
+ })
39
+ }
40
+
33
41
  describe("/api/global/roles", () => {
34
42
  const config = new TestConfiguration()
35
43
 
@@ -69,6 +77,53 @@ describe("/api/global/roles", () => {
69
77
  expect(res.body[appId].roles.length).toEqual(5)
70
78
  expect(res.body[appId].roles.map((r: any) => r._id)).toContain(ROLE_NAME)
71
79
  })
80
+
81
+ it.each(["3.0.0", "3.0.1", "3.1.0", "3.0.0+2146.b125a7c"])(
82
+ "exclude POWER roles after v3 (%s)",
83
+ async creationVersion => {
84
+ await updateAppMetadata({ creationVersion })
85
+ const res = await config.api.roles.get()
86
+ expect(res.body).toBeDefined()
87
+ expect(res.body[appId].roles.map((r: any) => r._id)).toEqual([
88
+ ROLE_NAME,
89
+ roles.BUILTIN_ROLE_IDS.ADMIN,
90
+ roles.BUILTIN_ROLE_IDS.BASIC,
91
+ roles.BUILTIN_ROLE_IDS.PUBLIC,
92
+ ])
93
+ }
94
+ )
95
+
96
+ it.each(["2.9.0", "1.0.0", "0.0.0", "2.32.17+2146.b125a7c"])(
97
+ "include POWER roles before v3 (%s)",
98
+ async creationVersion => {
99
+ await updateAppMetadata({ creationVersion })
100
+ const res = await config.api.roles.get()
101
+ expect(res.body).toBeDefined()
102
+ expect(res.body[appId].roles.map((r: any) => r._id)).toEqual([
103
+ ROLE_NAME,
104
+ roles.BUILTIN_ROLE_IDS.ADMIN,
105
+ roles.BUILTIN_ROLE_IDS.POWER,
106
+ roles.BUILTIN_ROLE_IDS.BASIC,
107
+ roles.BUILTIN_ROLE_IDS.PUBLIC,
108
+ ])
109
+ }
110
+ )
111
+
112
+ it.each(["invalid", ""])(
113
+ "include POWER roles when the version is corrupted (%s)",
114
+ async creationVersion => {
115
+ await updateAppMetadata({ creationVersion })
116
+ const res = await config.api.roles.get()
117
+
118
+ expect(res.body[appId].roles.map((r: any) => r._id)).toEqual([
119
+ ROLE_NAME,
120
+ roles.BUILTIN_ROLE_IDS.ADMIN,
121
+ roles.BUILTIN_ROLE_IDS.POWER,
122
+ roles.BUILTIN_ROLE_IDS.BASIC,
123
+ roles.BUILTIN_ROLE_IDS.PUBLIC,
124
+ ])
125
+ }
126
+ )
72
127
  })
73
128
 
74
129
  describe("GET api/global/roles/:appId", () => {