@budibase/worker 2.22.12 → 2.22.14

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
@@ -2,7 +2,7 @@ import { Config } from "@jest/types"
2
2
  import * as fs from "fs"
3
3
 
4
4
  const config: Config.InitialOptions = {
5
- preset: "@trendyol/jest-testcontainers",
5
+ globalSetup: "./../../globalSetup.ts",
6
6
  setupFiles: ["./src/tests/jestEnv.ts"],
7
7
  setupFilesAfterEnv: ["./src/tests/jestSetup.ts"],
8
8
  collectCoverageFrom: ["src/**/*.{js,ts}", "../backend-core/src/**/*.{js,ts}"],
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@budibase/worker",
3
3
  "email": "hi@budibase.com",
4
- "version": "2.22.12",
4
+ "version": "2.22.14",
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.22.12",
41
- "@budibase/pro": "2.22.12",
42
- "@budibase/string-templates": "2.22.12",
43
- "@budibase/types": "2.22.12",
40
+ "@budibase/backend-core": "2.22.14",
41
+ "@budibase/pro": "2.22.14",
42
+ "@budibase/string-templates": "2.22.14",
43
+ "@budibase/types": "2.22.14",
44
44
  "@koa/router": "8.0.8",
45
45
  "@techpass/passport-openidconnect": "0.3.2",
46
46
  "@types/global-agent": "2.1.1",
@@ -75,7 +75,6 @@
75
75
  "devDependencies": {
76
76
  "@swc/core": "1.3.71",
77
77
  "@swc/jest": "0.2.27",
78
- "@trendyol/jest-testcontainers": "2.1.1",
79
78
  "@types/jest": "29.5.5",
80
79
  "@types/jsonwebtoken": "9.0.3",
81
80
  "@types/koa": "2.13.4",
@@ -109,5 +108,5 @@
109
108
  }
110
109
  }
111
110
  },
112
- "gitHead": "f8c374b0bfe6868c5aa13b086d97e80a15ee72d9"
111
+ "gitHead": "ed44967cf2d47b2f6dad178938af28b68d4124ee"
113
112
  }
@@ -3,6 +3,7 @@ import env from "../../../environment"
3
3
  import {
4
4
  AcceptUserInviteRequest,
5
5
  AcceptUserInviteResponse,
6
+ AddSSoUserRequest,
6
7
  BulkUserRequest,
7
8
  BulkUserResponse,
8
9
  CloudAccount,
@@ -15,6 +16,7 @@ import {
15
16
  LockName,
16
17
  LockType,
17
18
  MigrationType,
19
+ PlatformUserByEmail,
18
20
  SaveUserResponse,
19
21
  SearchUsersRequest,
20
22
  User,
@@ -53,6 +55,25 @@ export const save = async (ctx: UserCtx<User, SaveUserResponse>) => {
53
55
  }
54
56
  }
55
57
 
58
+ export const addSsoSupport = async (ctx: Ctx<AddSSoUserRequest>) => {
59
+ const { email, ssoId } = ctx.request.body
60
+ try {
61
+ // Status is changed to 404 from getUserDoc if user is not found
62
+ let userByEmail = (await platform.users.getUserDoc(
63
+ email
64
+ )) as PlatformUserByEmail
65
+ await platform.users.addSsoUser(
66
+ ssoId,
67
+ email,
68
+ userByEmail.userId,
69
+ userByEmail.tenantId
70
+ )
71
+ ctx.status = 200
72
+ } catch (err: any) {
73
+ ctx.throw(err.status || 400, err)
74
+ }
75
+ }
76
+
56
77
  const bulkDelete = async (userIds: string[], currentUserId: string) => {
57
78
  if (userIds?.indexOf(currentUserId) !== -1) {
58
79
  throw new Error("Unable to delete self.")
@@ -127,8 +148,8 @@ export const adminUser = async (
127
148
  try {
128
149
  const finalUser = await userSdk.db.createAdminUser(
129
150
  email,
130
- password,
131
151
  tenantId,
152
+ password,
132
153
  {
133
154
  ssoId,
134
155
  hashPassword,
package/src/api/index.ts CHANGED
@@ -41,6 +41,10 @@ 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
+ },
44
48
  {
45
49
  route: "/api/global/users/invite/accept",
46
50
  method: "POST",
@@ -81,6 +85,11 @@ const NO_TENANCY_ENDPOINTS = [
81
85
  route: "/api/global/users/init",
82
86
  method: "POST",
83
87
  },
88
+ // tenant is retrieved from the user found by the requested email
89
+ {
90
+ route: "/api/global/users/sso",
91
+ method: "POST",
92
+ },
84
93
  // deprecated single tenant sso callback
85
94
  {
86
95
  route: "/api/admin/auth/google/callback",
@@ -520,10 +520,51 @@ describe("/api/global/users", () => {
520
520
  })
521
521
  }
522
522
 
523
+ function createPasswordUser() {
524
+ return config.doInTenant(() => {
525
+ const user = structures.users.user()
526
+ return userSdk.db.save(user)
527
+ })
528
+ }
529
+
523
530
  it("should be able to update an sso user that has no password", async () => {
524
531
  const user = await createSSOUser()
525
532
  await config.api.users.saveUser(user)
526
533
  })
534
+
535
+ it("sso support couldn't be used by admin. It is cloud restricted and needs internal key", async () => {
536
+ const user = await config.createUser()
537
+ const ssoId = "fake-ssoId"
538
+ await config.api.users
539
+ .addSsoSupportDefaultAuth(ssoId, user.email)
540
+ .expect("Content-Type", /json/)
541
+ .expect(403)
542
+ })
543
+
544
+ it("if user email doesn't exist, SSO support couldn't be added. Not found error returned", async () => {
545
+ const ssoId = "fake-ssoId"
546
+ const email = "fake-email@budibase.com"
547
+ await config.api.users
548
+ .addSsoSupportInternalAPIAuth(ssoId, email)
549
+ .expect("Content-Type", /json/)
550
+ .expect(404)
551
+ })
552
+
553
+ it("if user email exist, SSO support is added", async () => {
554
+ const user = await createPasswordUser()
555
+ const ssoId = "fakessoId"
556
+ await config.api.users
557
+ .addSsoSupportInternalAPIAuth(ssoId, user.email)
558
+ .expect(200)
559
+ })
560
+
561
+ it("if user ssoId is already assigned, no change will be applied", async () => {
562
+ const user = await createSSOUser()
563
+ user.ssoId = "testssoId"
564
+ await config.api.users
565
+ .addSsoSupportInternalAPIAuth(user.ssoId, user.email)
566
+ .expect(200)
567
+ })
527
568
  })
528
569
  })
529
570
 
@@ -7,12 +7,13 @@ import { users } from "../validation"
7
7
  import * as selfController from "../../controllers/global/self"
8
8
 
9
9
  const router: Router = new Router()
10
+ const OPTIONAL_STRING = Joi.string().optional().allow(null).allow("")
10
11
 
11
12
  function buildAdminInitValidation() {
12
13
  return auth.joiValidator.body(
13
14
  Joi.object({
14
15
  email: Joi.string().required(),
15
- password: Joi.string(),
16
+ password: OPTIONAL_STRING,
16
17
  tenantId: Joi.string().required(),
17
18
  ssoId: Joi.string(),
18
19
  })
@@ -64,6 +65,12 @@ router
64
65
  users.buildUserSaveValidation(),
65
66
  controller.save
66
67
  )
68
+ .post(
69
+ "/api/global/users/sso",
70
+ cloudRestricted,
71
+ users.buildAddSsoSupport(),
72
+ controller.addSsoSupport
73
+ )
67
74
  .post(
68
75
  "/api/global/users/bulk",
69
76
  auth.adminOnly,
@@ -41,6 +41,15 @@ export const buildUserSaveValidation = () => {
41
41
  return auth.joiValidator.body(Joi.object(schema).required().unknown(true))
42
42
  }
43
43
 
44
+ export const buildAddSsoSupport = () => {
45
+ return auth.joiValidator.body(
46
+ Joi.object({
47
+ ssoId: Joi.string().required(),
48
+ email: Joi.string().required(),
49
+ }).required()
50
+ )
51
+ }
52
+
44
53
  export const buildUserBulkUserValidation = (isSelf = false) => {
45
54
  if (!isSelf) {
46
55
  schema = {
@@ -127,6 +127,20 @@ export class UserAPI extends TestAPI {
127
127
  .expect(status ? status : 200)
128
128
  }
129
129
 
130
+ addSsoSupportInternalAPIAuth = (ssoId: string, email: string) => {
131
+ return this.request
132
+ .post(`/api/global/users/sso`)
133
+ .send({ ssoId, email })
134
+ .set(this.config.internalAPIHeaders())
135
+ }
136
+
137
+ addSsoSupportDefaultAuth = (ssoId: string, email: string) => {
138
+ return this.request
139
+ .post(`/api/global/users/sso`)
140
+ .send({ ssoId, email })
141
+ .set(this.config.defaultHeaders())
142
+ }
143
+
130
144
  deleteUser = (userId: string, status?: number) => {
131
145
  return this.request
132
146
  .delete(`/api/global/users/${userId}`)
@@ -11,3 +11,5 @@ process.env.INTERNAL_API_KEY = "tet"
11
11
  process.env.DISABLE_ACCOUNT_PORTAL = "0"
12
12
  process.env.MOCK_REDIS = "1"
13
13
  process.env.BUDIBASE_VERSION = "0.0.0+jest"
14
+ process.env.COUCH_DB_PASSWORD = "budibase"
15
+ process.env.COUCH_DB_USER = "budibase"
@@ -1,142 +0,0 @@
1
- {
2
- // Use IntelliSense to learn about possible attributes.
3
- // Hover to view descriptions of existing attributes.
4
- // For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387
5
- "version": "0.2.0",
6
- "configurations": [
7
- {
8
- "name": "Start Server",
9
- "type": "node",
10
- "request": "launch",
11
- "runtimeExecutable": "node",
12
- "runtimeArgs": ["--nolazy", "-r", "ts-node/register/transpile-only"],
13
- "args": ["src/index.ts"],
14
- "cwd": "${workspaceRoot}",
15
- },
16
- {
17
- "type": "node",
18
- "request": "launch",
19
- "name": "Jest - All",
20
- "program": "${workspaceFolder}/node_modules/.bin/jest",
21
- "args": [],
22
- "console": "integratedTerminal",
23
- "internalConsoleOptions": "neverOpen",
24
- "disableOptimisticBPs": true,
25
- "windows": {
26
- "program": "${workspaceFolder}/node_modules/jest-cli/bin/jest",
27
- }
28
- },
29
- {
30
- "type": "node",
31
- "request": "launch",
32
- "name": "Jest - Users",
33
- "program": "${workspaceFolder}/node_modules/.bin/jest",
34
- "args": ["user.spec", "--runInBand"],
35
- "console": "integratedTerminal",
36
- "internalConsoleOptions": "neverOpen",
37
- "disableOptimisticBPs": true,
38
- "windows": {
39
- "program": "${workspaceFolder}/node_modules/jest-cli/bin/jest",
40
- }
41
- },
42
- {
43
- "type": "node",
44
- "request": "launch",
45
- "name": "Jest - Instances",
46
- "program": "${workspaceFolder}/node_modules/.bin/jest",
47
- "args": ["instance.spec", "--runInBand"],
48
- "console": "integratedTerminal",
49
- "internalConsoleOptions": "neverOpen",
50
- "disableOptimisticBPs": true,
51
- "windows": {
52
- "program": "${workspaceFolder}/node_modules/jest-cli/bin/jest",
53
- }
54
- },
55
- {
56
- "type": "node",
57
- "request": "launch",
58
- "name": "Jest - Roles",
59
- "program": "${workspaceFolder}/node_modules/.bin/jest",
60
- "args": ["role.spec", "--runInBand"],
61
- "console": "integratedTerminal",
62
- "internalConsoleOptions": "neverOpen",
63
- "disableOptimisticBPs": true,
64
- "windows": {
65
- "program": "${workspaceFolder}/node_modules/jest-cli/bin/jest",
66
- }
67
- },
68
- {
69
- "type": "node",
70
- "request": "launch",
71
- "name": "Jest - Records",
72
- "program": "${workspaceFolder}/node_modules/.bin/jest",
73
- "args": ["record.spec", "--runInBand"],
74
- "console": "integratedTerminal",
75
- "internalConsoleOptions": "neverOpen",
76
- "disableOptimisticBPs": true,
77
- "windows": {
78
- "program": "${workspaceFolder}/node_modules/jest-cli/bin/jest",
79
- }
80
- },
81
- {
82
- "type": "node",
83
- "request": "launch",
84
- "name": "Jest - Models",
85
- "program": "${workspaceFolder}/node_modules/.bin/jest",
86
- "args": ["table.spec", "--runInBand"],
87
- "console": "integratedTerminal",
88
- "internalConsoleOptions": "neverOpen",
89
- "disableOptimisticBPs": true,
90
- "windows": {
91
- "program": "${workspaceFolder}/node_modules/jest-cli/bin/jest",
92
- }
93
- },
94
- {
95
- "type": "node",
96
- "request": "launch",
97
- "name": "Jest - Views",
98
- "program": "${workspaceFolder}/node_modules/.bin/jest",
99
- "args": ["view.spec", "--runInBand"],
100
- "console": "integratedTerminal",
101
- "internalConsoleOptions": "neverOpen",
102
- "disableOptimisticBPs": true,
103
- "windows": {
104
- "program": "${workspaceFolder}/node_modules/jest-cli/bin/jest",
105
- }
106
- },
107
- {
108
- "type": "node",
109
- "request": "launch",
110
- "name": "Jest - Applications",
111
- "program": "${workspaceFolder}/node_modules/.bin/jest",
112
- "args": ["application.spec", "--runInBand"],
113
- "console": "integratedTerminal",
114
- "internalConsoleOptions": "neverOpen",
115
- "disableOptimisticBPs": true,
116
- "windows": {
117
- "program": "${workspaceFolder}/node_modules/jest-cli/bin/jest",
118
- }
119
- },
120
- {
121
- "type": "node",
122
- "request": "launch",
123
- "name": "Jest Builder",
124
- "program": "${workspaceFolder}/node_modules/.bin/jest",
125
- "args": ["builder", "--runInBand"],
126
- "console": "integratedTerminal",
127
- "internalConsoleOptions": "neverOpen",
128
- "disableOptimisticBPs": true,
129
- "windows": {
130
- "program": "${workspaceFolder}/node_modules/jest-cli/bin/jest",
131
- }
132
- },
133
- {
134
- "type": "node",
135
- "request": "launch",
136
- "name": "Initialise Budibase",
137
- "program": "yarn",
138
- "args": ["run", "initialise"],
139
- "console": "externalTerminal"
140
- }
141
- ]
142
- }
@@ -1,8 +0,0 @@
1
- const { join } = require("path")
2
- require("dotenv").config({
3
- path: join(__dirname, "..", "..", "hosting", ".env"),
4
- })
5
-
6
- const jestTestcontainersConfigGenerator = require("../../jestTestcontainersConfigGenerator")
7
-
8
- module.exports = jestTestcontainersConfigGenerator()