@budibase/worker 3.18.2 → 3.18.4

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": "3.18.2",
4
+ "version": "3.18.4",
5
5
  "description": "Budibase background service",
6
6
  "main": "src/index.ts",
7
7
  "repository": {
@@ -109,5 +109,5 @@
109
109
  }
110
110
  }
111
111
  },
112
- "gitHead": "43d59f5579dd910575d8aebefb40fae25570c05d"
112
+ "gitHead": "b82c05d3d0949d198b49415d20980e72cc61ca5b"
113
113
  }
@@ -1,18 +1,18 @@
1
1
  import {
2
+ cache,
3
+ context,
2
4
  db as dbCore,
3
5
  roles,
4
- context,
5
- cache,
6
6
  tenancy,
7
7
  } from "@budibase/backend-core"
8
- import sdk from "../../../sdk"
9
8
  import {
10
9
  Ctx,
11
- App,
12
10
  FetchGlobalRolesResponse,
13
11
  FindGlobalRoleResponse,
14
12
  RemoveAppRoleResponse,
13
+ Workspace,
15
14
  } from "@budibase/types"
15
+ import sdk from "../../../sdk"
16
16
 
17
17
  export async function fetch(ctx: Ctx<void, FetchGlobalRolesResponse>) {
18
18
  const tenantId = ctx.user!.tenantId
@@ -43,7 +43,7 @@ export async function find(ctx: Ctx<void, FindGlobalRoleResponse>) {
43
43
  const appId = ctx.params.appId
44
44
  await context.doInAppContext(dbCore.getDevAppID(appId), async () => {
45
45
  const db = context.getAppDB()
46
- const app = await db.get<App>(dbCore.DocumentType.APP_METADATA)
46
+ const app = await db.get<Workspace>(dbCore.DocumentType.APP_METADATA)
47
47
  ctx.body = {
48
48
  roles: await roles.getAllRoles(),
49
49
  name: app.name,
@@ -15,9 +15,6 @@ import {
15
15
  GenerateAPIKeyRequest,
16
16
  GenerateAPIKeyResponse,
17
17
  GetGlobalSelfResponse,
18
- QuotaType,
19
- QuotaUsageType,
20
- StaticQuotaName,
21
18
  UpdateSelfRequest,
22
19
  UpdateSelfResponse,
23
20
  User,
@@ -126,13 +123,6 @@ export async function getSelf(ctx: UserCtx<void, GetGlobalSelfResponse>) {
126
123
  }
127
124
  : undefined
128
125
 
129
- if (flags?.WORKSPACES) {
130
- // TODO: once the flag is clean, we should rename the original object instead
131
- sessionAttributes.license.quotas[QuotaType.USAGE][QuotaUsageType.STATIC][
132
- StaticQuotaName.APPS
133
- ].name = "Workspaces"
134
- }
135
-
136
126
  ctx.body = {
137
127
  ...enrichedUser,
138
128
  ...sessionAttributes,
@@ -1,8 +1,8 @@
1
- import { Ctx, GetEnvironmentResponse, MaintenanceType } from "@budibase/types"
2
- import env from "../../../environment"
3
1
  import { env as coreEnv, db as dbCore } from "@budibase/backend-core"
4
- import nodeFetch from "node-fetch"
5
2
  import { helpers } from "@budibase/shared-core"
3
+ import { Ctx, GetEnvironmentResponse, MaintenanceType } from "@budibase/types"
4
+ import nodeFetch from "node-fetch"
5
+ import env from "../../../environment"
6
6
 
7
7
  let sqsAvailable: boolean
8
8
  async function isSqsAvailable() {
@@ -49,6 +49,10 @@ export const fetch = async (ctx: Ctx<void, GetEnvironmentResponse>) => {
49
49
  isDev: env.isDev() && !env.isTest(),
50
50
  maintenance: [],
51
51
  passwordMinLength: env.PASSWORD_MIN_LENGTH,
52
+ serveDevClientFromStorage:
53
+ env.DEV_USE_CLIENT_FROM_STORAGE !== undefined
54
+ ? !!env.DEV_USE_CLIENT_FROM_STORAGE
55
+ : false,
52
56
  }
53
57
 
54
58
  if (env.SELF_HOSTED) {
@@ -1,7 +1,8 @@
1
1
  import * as controller from "../../controllers/global/roles"
2
- import { builderOrAdminRoutes } from "../endpointGroups"
2
+ import { adminRoutes, builderOrAdminRoutes } from "../endpointGroups"
3
3
 
4
4
  builderOrAdminRoutes
5
5
  .get("/api/global/roles", controller.fetch)
6
6
  .get("/api/global/roles/:appId", controller.find)
7
- .delete("/api/global/roles/:appId", controller.removeAppRole)
7
+
8
+ adminRoutes.delete("/api/global/roles/:appId", controller.removeAppRole)
@@ -1,11 +1,11 @@
1
- import { structures, TestConfiguration } from "../../../../tests"
2
1
  import { context, db, roles } from "@budibase/backend-core"
3
2
  import {
4
- App,
5
- Database,
6
3
  BuiltinPermissionID,
4
+ Database,
7
5
  WithoutDocMetadata,
6
+ Workspace,
8
7
  } from "@budibase/types"
8
+ import { structures, TestConfiguration } from "../../../../tests"
9
9
 
10
10
  jest.mock("@budibase/backend-core", () => {
11
11
  const core = jest.requireActual("@budibase/backend-core")
@@ -35,7 +35,9 @@ async function addAppMetadata() {
35
35
  })
36
36
  }
37
37
 
38
- async function updateAppMetadata(update: Partial<WithoutDocMetadata<App>>) {
38
+ async function updateAppMetadata(
39
+ update: Partial<WithoutDocMetadata<Workspace>>
40
+ ) {
39
41
  const app = await appDb.get("app_metadata")
40
42
  await appDb.put({
41
43
  ...app,
@@ -140,6 +142,18 @@ describe("/api/global/roles", () => {
140
142
  })
141
143
 
142
144
  describe("DELETE /api/global/roles/:appId", () => {
145
+ async function createBuilderUser() {
146
+ const saveResponse = await config.api.users.saveUser(
147
+ structures.users.builderUser(),
148
+ 200
149
+ )
150
+ const { body: user } = await config.api.users.getUser(
151
+ saveResponse.body._id
152
+ )
153
+ await config.login(user)
154
+ return user
155
+ }
156
+
143
157
  it("removes an app role", async () => {
144
158
  let user = structures.users.user()
145
159
  user.roles = {
@@ -151,5 +165,14 @@ describe("/api/global/roles", () => {
151
165
  expect(updatedUser.body.roles).not.toHaveProperty(appId)
152
166
  expect(res.body.message).toEqual("App role removed from all users")
153
167
  })
168
+
169
+ it("should not allow creator users to remove app roles", async () => {
170
+ const builderUser = await createBuilderUser()
171
+
172
+ const res = await config.withUser(builderUser, () =>
173
+ config.api.roles.remove(appId, { status: 403 })
174
+ )
175
+ expect(res.body.message).toBe("Admin user only endpoint.")
176
+ })
154
177
  })
155
178
  })
@@ -1,8 +1,8 @@
1
- import { InviteUsersResponse, User, OIDCUser } from "@budibase/types"
1
+ import { InviteUsersResponse, OIDCUser, User } from "@budibase/types"
2
2
 
3
- import { TestConfiguration, mocks, structures } from "../../../../tests"
4
- import { events, tenancy, accounts as _accounts } from "@budibase/backend-core"
3
+ import { accounts as _accounts, events, tenancy } from "@budibase/backend-core"
5
4
  import * as userSdk from "../../../../sdk/users"
5
+ import { TestConfiguration, mocks, structures } from "../../../../tests"
6
6
 
7
7
  jest.mock("nodemailer")
8
8
  const sendMailMock = mocks.email.mock()
@@ -24,6 +24,16 @@ describe("/api/global/users", () => {
24
24
  jest.clearAllMocks()
25
25
  })
26
26
 
27
+ async function createBuilderUser() {
28
+ const saveResponse = await config.api.users.saveUser(
29
+ structures.users.builderUser(),
30
+ 200
31
+ )
32
+ const { body: user } = await config.api.users.getUser(saveResponse.body._id)
33
+ await config.login(user)
34
+ return user
35
+ }
36
+
27
37
  describe("POST /api/global/users/invite", () => {
28
38
  it("should be able to generate an invitation", async () => {
29
39
  const email = structures.users.newEmail()
@@ -73,6 +83,19 @@ describe("/api/global/users", () => {
73
83
  expect(events.user.invited).toHaveBeenCalledTimes(0)
74
84
  })
75
85
 
86
+ it("should not allow creator users to access single invite endpoint", async () => {
87
+ const user = await createBuilderUser()
88
+
89
+ const { res } = await config.withUser(user, () =>
90
+ config.api.users.sendUserInvite(
91
+ sendMailMock,
92
+ structures.users.newEmail(),
93
+ 403
94
+ )
95
+ )
96
+ expect(res.body.message).toBe("Admin user only endpoint.")
97
+ })
98
+
76
99
  it("should be able to create new user from invite", async () => {
77
100
  const email = structures.users.newEmail()
78
101
  const { code } = await config.api.users.sendUserInvite(
@@ -137,6 +160,22 @@ describe("/api/global/users", () => {
137
160
  expect(sendMailMock).toHaveBeenCalledTimes(0)
138
161
  expect(events.user.invited).toHaveBeenCalledTimes(0)
139
162
  })
163
+
164
+ it("should not allow creator users to access multi-invite endpoint", async () => {
165
+ const user = await createBuilderUser()
166
+
167
+ const request = [
168
+ {
169
+ email: structures.users.newEmail(),
170
+ userInfo: { admin: { global: true } },
171
+ },
172
+ ]
173
+
174
+ const res = await config.withUser(user, () =>
175
+ config.api.users.sendMultiUserInvite(request, 403)
176
+ )
177
+ expect(res.body.message).toBe("Admin user only endpoint.")
178
+ })
140
179
  })
141
180
 
142
181
  describe("POST /api/global/users/bulk", () => {
@@ -1,13 +1,13 @@
1
- import * as controller from "../../controllers/global/users"
2
1
  import { auth } from "@budibase/backend-core"
3
2
  import Joi from "joi"
4
- import { users } from "../validation"
3
+ import * as controller from "../../controllers/global/users"
5
4
  import {
6
- loggedInRoutes,
7
- cloudRestrictedRoutes,
8
- builderOrAdminRoutes,
9
5
  adminRoutes,
6
+ builderOrAdminRoutes,
7
+ cloudRestrictedRoutes,
8
+ loggedInRoutes,
10
9
  } from "../endpointGroups"
10
+ import { users } from "../validation"
11
11
 
12
12
  const OPTIONAL_STRING = Joi.string().optional().allow(null).allow("")
13
13
 
@@ -100,6 +100,10 @@ adminRoutes
100
100
  builderOrAdminRoutes
101
101
  .get("/api/global/users", controller.fetch)
102
102
  .get("/api/global/users/count/:appId", controller.countByApp)
103
+ .get("/api/global/users/invites", controller.getUserInvites)
104
+ .get("/api/global/users/:id", controller.find)
105
+
106
+ adminRoutes
103
107
  .post("/api/global/users/invite", buildInviteValidation(), controller.invite)
104
108
  .post(
105
109
  "/api/global/users/onboard",
@@ -116,8 +120,6 @@ builderOrAdminRoutes
116
120
  controller.removeMultipleInvites
117
121
  )
118
122
  .post("/api/global/users/invite/update/:code", controller.updateInvite)
119
- .get("/api/global/users/invites", controller.getUserInvites)
120
- .get("/api/global/users/:id", controller.find)
121
123
 
122
124
  loggedInRoutes
123
125
  // search can be used by any user now, to retrieve users for user column
@@ -1,5 +1,5 @@
1
- import { TestConfiguration } from "../../../../tests"
2
1
  import { withEnv } from "../../../../environment"
2
+ import { TestConfiguration } from "../../../../tests"
3
3
 
4
4
  jest.unmock("node-fetch")
5
5
 
@@ -29,6 +29,7 @@ describe("/api/system/environment", () => {
29
29
  baseUrl: "http://localhost:10000",
30
30
  offlineMode: false,
31
31
  maintenance: [],
32
+ serveDevClientFromStorage: false,
32
33
  })
33
34
  })
34
35
 
@@ -43,6 +44,7 @@ describe("/api/system/environment", () => {
43
44
  baseUrl: "http://localhost:10000",
44
45
  offlineMode: false,
45
46
  maintenance: [],
47
+ serveDevClientFromStorage: false,
46
48
  })
47
49
  })
48
50
  })
@@ -1,7 +1,7 @@
1
1
  import { env as coreEnv } from "@budibase/backend-core"
2
2
  import { ServiceType } from "@budibase/types"
3
- import { join, resolve } from "path"
4
3
  import cloneDeep from "lodash/cloneDeep"
4
+ import { join, resolve } from "path"
5
5
 
6
6
  coreEnv._set("SERVICE_TYPE", ServiceType.WORKER)
7
7
 
@@ -55,6 +55,7 @@ const environment = {
55
55
  SMTP_FALLBACK_ENABLED: process.env.SMTP_FALLBACK_ENABLED,
56
56
  DISABLE_DEVELOPER_LICENSE: process.env.DISABLE_DEVELOPER_LICENSE,
57
57
  BUDIBASE_ENVIRONMENT: process.env.BUDIBASE_ENVIRONMENT,
58
+ DEV_USE_CLIENT_FROM_STORAGE: process.env.DEV_USE_CLIENT_FROM_STORAGE,
58
59
  // smtp
59
60
  SMTP_USER: process.env.SMTP_USER,
60
61
  SMTP_PASSWORD: process.env.SMTP_PASSWORD,
@@ -1,6 +1,6 @@
1
- import { App } from "@budibase/types"
2
- import { tenancy, db as dbCore, platform } from "@budibase/backend-core"
1
+ import { db as dbCore, platform, tenancy } from "@budibase/backend-core"
3
2
  import { quotas } from "@budibase/pro"
3
+ import { Workspace } from "@budibase/types"
4
4
 
5
5
  export async function deleteTenant(tenantId: string) {
6
6
  await quotas.bustCache()
@@ -21,7 +21,7 @@ async function removeGlobalDB(tenantId: string) {
21
21
 
22
22
  async function removeTenantApps(tenantId: string) {
23
23
  try {
24
- const apps = (await dbCore.getAllApps({ all: true })) as App[]
24
+ const apps = (await dbCore.getAllApps({ all: true })) as Workspace[]
25
25
  const destroyPromises = apps.map(app => {
26
26
  const db = dbCore.getDB(app.appId)
27
27
  return db.destroy()
@@ -7,37 +7,37 @@ mocks.licenses.init(mocks.pro)
7
7
  mocks.licenses.useUnlimited()
8
8
 
9
9
  import * as dbConfig from "../db"
10
-
11
- dbConfig.init()
12
10
  import env from "../environment"
13
11
  import * as controllers from "./controllers"
14
12
 
13
+ dbConfig.init()
14
+
15
15
  import supertest from "supertest"
16
16
 
17
- import { Config } from "../constants"
18
17
  import {
19
- users,
20
- context,
21
- sessions,
22
18
  constants,
19
+ context,
23
20
  env as coreEnv,
24
21
  db as dbCore,
25
22
  encryption,
23
+ sessions,
24
+ users,
26
25
  utils,
27
26
  } from "@budibase/backend-core"
28
- import structures, { CSRF_TOKEN } from "./structures"
29
27
  import {
30
- SaveUserResponse,
31
- User,
32
28
  AuthToken,
33
- SCIMConfig,
34
29
  ConfigType,
30
+ SaveUserResponse,
31
+ SCIMConfig,
35
32
  SMTPConfig,
36
33
  SMTPInnerConfig,
34
+ User,
37
35
  } from "@budibase/types"
38
- import API from "./api"
39
- import jwt, { Secret } from "jsonwebtoken"
40
36
  import http from "http"
37
+ import jwt, { Secret } from "jsonwebtoken"
38
+ import { Config } from "../constants"
39
+ import API from "./api"
40
+ import structures, { CSRF_TOKEN } from "./structures"
41
41
 
42
42
  class TestConfiguration {
43
43
  server: http.Server<typeof http.IncomingMessage, typeof http.ServerResponse> =
@@ -223,11 +223,11 @@ class TestConfiguration {
223
223
  }
224
224
  }
225
225
 
226
- async withUser(user: User, f: () => Promise<void>) {
226
+ async withUser<T>(user: User, f: () => Promise<T>): Promise<T> {
227
227
  const oldUser = this.user
228
228
  this.user = user
229
229
  try {
230
- await f()
230
+ return await f()
231
231
  } finally {
232
232
  this.user = oldUser
233
233
  }