@budibase/worker 3.31.4 → 3.31.6

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.31.4",
4
+ "version": "3.31.6",
5
5
  "description": "Budibase background service",
6
6
  "main": "src/index.ts",
7
7
  "repository": {
@@ -91,5 +91,5 @@
91
91
  "supertest": "6.3.3",
92
92
  "timekeeper": "2.2.0"
93
93
  },
94
- "gitHead": "7d5a486a8c245870743408abb7d03a33e19c8679"
94
+ "gitHead": "431d595ada96873e3b6ff34e80a2f710f5ad5051"
95
95
  }
@@ -153,6 +153,9 @@ export const changeTenantOwnerEmail = async (
153
153
  export const addSsoSupport = async (
154
154
  ctx: Ctx<AddSSoUserRequest, AddSSoUserResponse>
155
155
  ) => {
156
+ if (!ctx.internal) {
157
+ ctx.throw(403, "Unauthorized")
158
+ }
156
159
  const { email, ssoId } = ctx.request.body
157
160
  try {
158
161
  const [userByEmail] = await users.getExistingPlatformUsers([email])
@@ -367,6 +370,44 @@ export const search = async (
367
370
  }
368
371
 
369
372
  const DEFAULT_USER_LIMIT = 8
373
+ const GLOBAL_PERMISSION_USER_PAGE_LIMIT = 1000
374
+
375
+ const getGlobalPermissionUsers = async () => {
376
+ const globalDb = context.getGlobalDB()
377
+ const globalPermissionUsers = new Map<string, User>()
378
+ let bookmark: string | undefined
379
+ let nextBookmark: string | undefined
380
+
381
+ do {
382
+ const response = await globalDb.find<User>({
383
+ selector: {
384
+ _id: {
385
+ $regex: `^${db.DocumentType.USER}${db.SEPARATOR}`,
386
+ },
387
+ $or: [{ "admin.global": true }, { "builder.global": true }],
388
+ },
389
+ limit: GLOBAL_PERMISSION_USER_PAGE_LIMIT,
390
+ ...(bookmark ? { bookmark } : {}),
391
+ })
392
+
393
+ for (const user of response.docs) {
394
+ if (user?._id) {
395
+ globalPermissionUsers.set(user._id, user)
396
+ }
397
+ }
398
+
399
+ nextBookmark =
400
+ response.docs.length === GLOBAL_PERMISSION_USER_PAGE_LIMIT
401
+ ? response.bookmark
402
+ : undefined
403
+ if (!nextBookmark || nextBookmark === bookmark) {
404
+ break
405
+ }
406
+ bookmark = nextBookmark
407
+ } while (bookmark)
408
+
409
+ return [...globalPermissionUsers.values()]
410
+ }
370
411
 
371
412
  const searchWorkspaceUsers = async (
372
413
  body: SearchUsersRequest
@@ -391,16 +432,7 @@ const searchWorkspaceUsers = async (
391
432
  undefined,
392
433
  { arrayResponse: true }
393
434
  ) as Promise<User[]>,
394
- globalDb
395
- .find<User>({
396
- selector: {
397
- _id: {
398
- $regex: `^${db.DocumentType.USER}${db.SEPARATOR}`,
399
- },
400
- $or: [{ "admin.global": true }, { "builder.global": true }],
401
- },
402
- })
403
- .then(response => response.docs),
435
+ getGlobalPermissionUsers(),
404
436
  globalDb
405
437
  .allDocs<UserGroup>(
406
438
  db.getDocParams(db.DocumentType.GROUP, null, {
package/src/api/index.ts CHANGED
@@ -41,10 +41,6 @@ const PUBLIC_ENDPOINTS = [
41
41
  route: "/api/global/users/init",
42
42
  method: "POST",
43
43
  },
44
- {
45
- route: "/api/global/users/sso",
46
- method: "POST",
47
- },
48
44
  {
49
45
  route: "/api/global/users/invite/accept",
50
46
  method: "POST",
@@ -1,6 +1,11 @@
1
1
  import { InviteUsersResponse, OIDCUser, User } from "@budibase/types"
2
2
 
3
- import { accounts as _accounts, events, tenancy } from "@budibase/backend-core"
3
+ import {
4
+ accounts as _accounts,
5
+ events,
6
+ tenancy,
7
+ withEnv,
8
+ } from "@budibase/backend-core"
4
9
  import { mocks as featureMocks } from "@budibase/backend-core/tests"
5
10
  import { sdk as proSdk } from "@budibase/pro"
6
11
  import * as userSdk from "../../../../sdk/users"
@@ -820,6 +825,16 @@ describe("/api/global/users", () => {
820
825
  .expect(403)
821
826
  })
822
827
 
828
+ it("sso support cannot be used without internal key on self-hosted", async () => {
829
+ const user = await createPasswordUser()
830
+ const ssoId = "fake-ssoId"
831
+ await withEnv({ SELF_HOSTED: true }, () =>
832
+ config.api.users
833
+ .addSsoSupportDefaultAuth(ssoId, user.email)
834
+ .expect(403)
835
+ )
836
+ })
837
+
823
838
  it("if user email doesn't exist, SSO support couldn't be added. Not found error returned", async () => {
824
839
  const ssoId = "fake-ssoId"
825
840
  const email = "fake-email@budibase.com"
@@ -963,6 +978,34 @@ describe("/api/global/users", () => {
963
978
  expect(response.body.data[0].email).toBe(email)
964
979
  })
965
980
 
981
+ it("should include all global admins in workspace search when there are more than 25", async () => {
982
+ const workspaceId = "app_workspace_filter_global_admin_many"
983
+ const globalAdminUsers = await Promise.all(
984
+ Array.from({ length: 30 }).map((_, index) =>
985
+ config.createUser({
986
+ email: `workspace-global-admin-${index}-${structures.users.newEmail()}`,
987
+ admin: { global: true },
988
+ builder: { global: true },
989
+ })
990
+ )
991
+ )
992
+ const globalAdminIds = globalAdminUsers
993
+ .map(user => user._id)
994
+ .filter(Boolean) as string[]
995
+
996
+ const response = await config.api.users.searchUsers({
997
+ workspaceId,
998
+ query: { oneOf: { _id: globalAdminIds } },
999
+ limit: 100,
1000
+ })
1001
+
1002
+ const returnedIds = response.body.data
1003
+ .map((user: User) => user._id)
1004
+ .filter(Boolean)
1005
+ expect(returnedIds).toHaveLength(globalAdminIds.length)
1006
+ expect(returnedIds).toEqual(expect.arrayContaining(globalAdminIds))
1007
+ })
1008
+
966
1009
  it("should return no users when workspaceId is empty", async () => {
967
1010
  const email = structures.users.newEmail()
968
1011
  await config.createUser({ email })