@budibase/worker 1.0.219-alpha.7 → 1.0.219

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": "1.0.219-alpha.7",
4
+ "version": "1.0.219",
5
5
  "description": "Budibase background service",
6
6
  "main": "src/index.ts",
7
7
  "repository": {
@@ -34,10 +34,9 @@
34
34
  "author": "Budibase",
35
35
  "license": "GPL-3.0",
36
36
  "dependencies": {
37
- "@budibase/backend-core": "^1.0.219-alpha.7",
38
- "@budibase/pro": "1.0.219-alpha.6",
39
- "@budibase/string-templates": "^1.0.219-alpha.7",
40
- "@budibase/types": "^1.0.219-alpha.7",
37
+ "@budibase/backend-core": "^1.0.219",
38
+ "@budibase/pro": "1.0.218",
39
+ "@budibase/string-templates": "^1.0.219",
41
40
  "@koa/router": "8.0.8",
42
41
  "@sentry/node": "6.17.7",
43
42
  "@techpass/passport-openidconnect": "0.3.2",
@@ -67,6 +66,7 @@
67
66
  "server-destroy": "1.0.1"
68
67
  },
69
68
  "devDependencies": {
69
+ "@budibase/types": "^1.0.219",
70
70
  "@types/jest": "26.0.23",
71
71
  "@types/koa": "2.13.4",
72
72
  "@types/koa-router": "7.4.4",
@@ -100,5 +100,5 @@
100
100
  "./scripts/jestSetup.js"
101
101
  ]
102
102
  },
103
- "gitHead": "57e5d6fa3b84deffdd8ec86c3b1b9ff8ebaab101"
103
+ "gitHead": "231b038a3c99f730dd27a595f870663dd84b7837"
104
104
  }
@@ -1,22 +1,49 @@
1
1
  const core = require("@budibase/backend-core")
2
+ const { getScopedConfig } = require("@budibase/backend-core/db")
3
+ const { google } = require("@budibase/backend-core/middleware")
4
+ const { oidc } = require("@budibase/backend-core/middleware")
2
5
  const { Configs, EmailTemplatePurpose } = require("../../../constants")
3
6
  const { sendEmail, isEmailConfigured } = require("../../../utilities/email")
4
7
  const { setCookie, getCookie, clearCookie, hash, platformLogout } = core.utils
5
8
  const { Cookies, Headers } = core.constants
6
- const { passport, ssoCallbackUrl, google, oidc } = core.auth
9
+ const { passport } = core.auth
7
10
  const { checkResetPasswordCode } = require("../../../utilities/redis")
8
- const { getGlobalDB } = require("@budibase/backend-core/tenancy")
11
+ const {
12
+ getGlobalDB,
13
+ getTenantId,
14
+ isMultiTenant,
15
+ } = require("@budibase/backend-core/tenancy")
9
16
  const env = require("../../../environment")
10
17
  import { events, users as usersCore, context } from "@budibase/backend-core"
11
18
  import { users } from "../../../sdk"
12
19
  import { User } from "@budibase/types"
13
20
 
21
+ const ssoCallbackUrl = async (config: any, type: any) => {
22
+ // incase there is a callback URL from before
23
+ if (config && config.callbackURL) {
24
+ return config.callbackURL
25
+ }
26
+
27
+ const db = getGlobalDB()
28
+ const publicConfig = await getScopedConfig(db, {
29
+ type: Configs.SETTINGS,
30
+ })
31
+
32
+ let callbackUrl = `/api/global/auth`
33
+ if (isMultiTenant()) {
34
+ callbackUrl += `/${getTenantId()}`
35
+ }
36
+ callbackUrl += `/${type}/callback`
37
+
38
+ return `${publicConfig.platformUrl}${callbackUrl}`
39
+ }
40
+
14
41
  export const googleCallbackUrl = async (config: any) => {
15
- return ssoCallbackUrl(getGlobalDB(), config, "google")
42
+ return ssoCallbackUrl(config, "google")
16
43
  }
17
44
 
18
45
  export const oidcCallbackUrl = async (config: any) => {
19
- return ssoCallbackUrl(getGlobalDB(), config, "oidc")
46
+ return ssoCallbackUrl(config, "oidc")
20
47
  }
21
48
 
22
49
  async function authInternal(ctx: any, user: any, err = null, info = null) {
@@ -171,8 +198,6 @@ export const googlePreAuth = async (ctx: any, next: any) => {
171
198
 
172
199
  return passport.authenticate(strategy, {
173
200
  scope: ["profile", "email"],
174
- accessType: "offline",
175
- prompt: "consent",
176
201
  })(ctx, next)
177
202
  }
178
203
 
@@ -199,7 +224,7 @@ export const googleAuth = async (ctx: any, next: any) => {
199
224
  )(ctx, next)
200
225
  }
201
226
 
202
- export const oidcStrategyFactory = async (ctx: any, configId: any) => {
227
+ async function oidcStrategyFactory(ctx: any, configId: any) {
203
228
  const db = getGlobalDB()
204
229
  const config = await core.db.getScopedConfig(db, {
205
230
  type: Configs.OIDC,
@@ -209,12 +234,7 @@ export const oidcStrategyFactory = async (ctx: any, configId: any) => {
209
234
  const chosenConfig = config.configs.filter((c: any) => c.uuid === configId)[0]
210
235
  let callbackUrl = await exports.oidcCallbackUrl(chosenConfig)
211
236
 
212
- //Remote Config
213
- const enrichedConfig = await oidc.fetchStrategyConfig(
214
- chosenConfig,
215
- callbackUrl
216
- )
217
- return oidc.strategyFactory(enrichedConfig, users.save)
237
+ return oidc.strategyFactory(chosenConfig, callbackUrl, users.save)
218
238
  }
219
239
 
220
240
  /**
@@ -229,7 +249,7 @@ export const oidcPreAuth = async (ctx: any, next: any) => {
229
249
 
230
250
  return passport.authenticate(strategy, {
231
251
  // required 'openid' scope is added by oidc strategy factory
232
- scope: ["profile", "email", "offline_access"], //auth0 offline_access scope required for the refresh token behaviour.
252
+ scope: ["profile", "email"],
233
253
  })(ctx, next)
234
254
  }
235
255
 
@@ -1,6 +1,7 @@
1
1
  const {
2
2
  generateConfigID,
3
3
  getConfigParams,
4
+ getGlobalUserParams,
4
5
  getScopedFullConfig,
5
6
  getAllApps,
6
7
  } = require("@budibase/backend-core/db")
@@ -19,7 +20,6 @@ const {
19
20
  bustCache,
20
21
  } = require("@budibase/backend-core/cache")
21
22
  const { events } = require("@budibase/backend-core")
22
- const { checkAnyUserExists } = require("../../../utilities/users")
23
23
 
24
24
  const BB_TENANT_CDN = "https://tenants.cdn.budi.live"
25
25
 
@@ -405,7 +405,12 @@ exports.configChecklist = async function (ctx) {
405
405
  })
406
406
 
407
407
  // They have set up an global user
408
- const userExists = await checkAnyUserExists()
408
+ const users = await db.allDocs(
409
+ getGlobalUserParams(null, {
410
+ include_docs: true,
411
+ limit: 1,
412
+ })
413
+ )
409
414
  return {
410
415
  apps: {
411
416
  checked: apps.length > 0,
@@ -418,7 +423,7 @@ exports.configChecklist = async function (ctx) {
418
423
  link: "/builder/portal/manage/email",
419
424
  },
420
425
  adminUser: {
421
- checked: userExists,
426
+ checked: users && users.rows.length >= 1,
422
427
  label: "Create your first user",
423
428
  link: "/builder/portal/manage/users",
424
429
  },
@@ -7,7 +7,7 @@ const {
7
7
  const { doInAppContext, getAppDB } = require("@budibase/backend-core/context")
8
8
  const { user: userCache } = require("@budibase/backend-core/cache")
9
9
  const { getGlobalDB } = require("@budibase/backend-core/tenancy")
10
- const { allUsers } = require("../../../sdk/users")
10
+ const { users } = require("../../../sdk")
11
11
 
12
12
  exports.fetch = async ctx => {
13
13
  const tenantId = ctx.user.tenantId
@@ -49,10 +49,10 @@ exports.find = async ctx => {
49
49
  exports.removeAppRole = async ctx => {
50
50
  const { appId } = ctx.params
51
51
  const db = getGlobalDB()
52
- const users = await allUsers(ctx)
52
+ const allUsers = await users.allUsers(ctx)
53
53
  const bulk = []
54
54
  const cacheInvalidations = []
55
- for (let user of users) {
55
+ for (let user of allUsers) {
56
56
  if (user.roles[appId]) {
57
57
  cacheInvalidations.push(userCache.invalidateUser(user._id))
58
58
  delete user.roles[appId]
@@ -8,15 +8,16 @@ import {
8
8
  events,
9
9
  errors,
10
10
  accounts,
11
+ db as dbUtils,
11
12
  users as usersCore,
12
13
  tenancy,
13
14
  cache,
14
15
  } from "@budibase/backend-core"
15
- import { checkAnyUserExists } from "../../../utilities/users"
16
16
 
17
17
  export const save = async (ctx: any) => {
18
18
  try {
19
- ctx.body = await users.save(ctx.request.body)
19
+ const user = await users.save(ctx.request.body)
20
+ ctx.body = user
20
21
  } catch (err: any) {
21
22
  ctx.throw(err.status || 400, err)
22
23
  }
@@ -38,8 +39,15 @@ export const adminUser = async (ctx: any) => {
38
39
  ctx.throw(403, "Organisation already exists.")
39
40
  }
40
41
 
41
- const userExists = await checkAnyUserExists()
42
- if (userExists) {
42
+ const response = await tenancy.doWithGlobalDB(tenantId, async (db: any) => {
43
+ return db.allDocs(
44
+ dbUtils.getGlobalUserParams(null, {
45
+ include_docs: true,
46
+ })
47
+ )
48
+ })
49
+
50
+ if (response.rows.some((row: any) => row.doc.admin)) {
43
51
  ctx.throw(
44
52
  403,
45
53
  "You cannot initialise once an global user has been created."
@@ -88,17 +96,6 @@ export const destroy = async (ctx: any) => {
88
96
  }
89
97
  }
90
98
 
91
- export const search = async (ctx: any) => {
92
- const paginated = await users.paginatedUsers(ctx.request.body)
93
- // user hashed password shouldn't ever be returned
94
- for (let user of paginated.data) {
95
- if (user) {
96
- delete user.password
97
- }
98
- }
99
- ctx.body = paginated
100
- }
101
-
102
99
  // called internally by app server user fetch
103
100
  export const fetch = async (ctx: any) => {
104
101
  const all = await users.allUsers()
@@ -46,7 +46,6 @@ router
46
46
  controller.save
47
47
  )
48
48
  .get("/api/global/users", builderOrAdmin, controller.fetch)
49
- .post("/api/global/users/search", builderOrAdmin, controller.search)
50
49
  .delete("/api/global/users/:id", adminOnly, controller.destroy)
51
50
  .get("/api/global/roles/:appId")
52
51
  .post(
@@ -77,30 +77,27 @@ describe("/api/global/auth", () => {
77
77
  describe("oidc", () => {
78
78
  const auth = require("@budibase/backend-core/auth")
79
79
 
80
- const passportSpy = jest.spyOn(auth.passport, "authenticate")
81
- let oidcConf
82
- let chosenConfig
83
- let configId
84
-
85
80
  // mock the oidc strategy implementation and return value
86
81
  let strategyFactory = jest.fn()
87
82
  let mockStrategyReturn = jest.fn()
88
- let mockStrategyConfig = jest.fn()
89
- auth.oidc.fetchStrategyConfig = mockStrategyConfig
90
-
91
83
  strategyFactory.mockReturnValue(mockStrategyReturn)
92
84
  auth.oidc.strategyFactory = strategyFactory
93
85
 
86
+ const passportSpy = jest.spyOn(auth.passport, "authenticate")
87
+ let oidcConf
88
+ let chosenConfig
89
+ let configId
90
+
94
91
  beforeEach(async () => {
95
92
  oidcConf = await config.saveOIDCConfig()
96
93
  chosenConfig = oidcConf.config.configs[0]
97
94
  configId = chosenConfig.uuid
98
- mockStrategyConfig.mockReturnValue(chosenConfig)
99
95
  })
100
96
 
101
97
  afterEach(() => {
102
98
  expect(strategyFactory).toBeCalledWith(
103
99
  chosenConfig,
100
+ `http://localhost:10000/api/global/auth/${TENANT_ID}/oidc/callback`,
104
101
  expect.any(Function)
105
102
  )
106
103
  })
@@ -110,7 +107,7 @@ describe("/api/global/auth", () => {
110
107
  await request.get(`/api/global/auth/${TENANT_ID}/oidc/configs/${configId}`)
111
108
 
112
109
  expect(passportSpy).toBeCalledWith(mockStrategyReturn, {
113
- scope: ["profile", "email", "offline_access"]
110
+ scope: ["profile", "email"],
114
111
  })
115
112
  expect(passportSpy.mock.calls.length).toBe(1);
116
113
  })
@@ -17,8 +17,9 @@ import {
17
17
  } from "@budibase/backend-core"
18
18
  import { MigrationType } from "@budibase/types"
19
19
 
20
- const PAGE_LIMIT = 8
21
-
20
+ /**
21
+ * Retrieves all users from the current tenancy.
22
+ */
22
23
  export const allUsers = async () => {
23
24
  const db = tenancy.getGlobalDB()
24
25
  const response = await db.allDocs(
@@ -29,37 +30,6 @@ export const allUsers = async () => {
29
30
  return response.rows.map((row: any) => row.doc)
30
31
  }
31
32
 
32
- export const paginatedUsers = async ({
33
- page,
34
- search,
35
- }: { page?: string; search?: string } = {}) => {
36
- const db = tenancy.getGlobalDB()
37
- // get one extra document, to have the next page
38
- const opts: any = {
39
- include_docs: true,
40
- limit: PAGE_LIMIT + 1,
41
- }
42
- // add a startkey if the page was specified (anchor)
43
- if (page) {
44
- opts.startkey = page
45
- }
46
- // property specifies what to use for the page/anchor
47
- let userList, property
48
- // no search, query allDocs
49
- if (!search) {
50
- const response = await db.allDocs(dbUtils.getGlobalUserParams(null, opts))
51
- userList = response.rows.map((row: any) => row.doc)
52
- property = "_id"
53
- } else {
54
- userList = await usersCore.searchGlobalUsersByEmail(search, opts)
55
- property = "email"
56
- }
57
- return dbUtils.pagination(userList, PAGE_LIMIT, {
58
- paginate: true,
59
- property,
60
- })
61
- }
62
-
63
33
  /**
64
34
  * Gets a user by ID from the global database, based on the current tenancy.
65
35
  */
@@ -1,17 +0,0 @@
1
- const { getGlobalDB } = require("@budibase/backend-core/tenancy")
2
- const { getGlobalUserParams } = require("@budibase/backend-core/db")
3
-
4
- exports.checkAnyUserExists = async () => {
5
- try {
6
- const db = getGlobalDB()
7
- const users = await db.allDocs(
8
- getGlobalUserParams(null, {
9
- include_docs: true,
10
- limit: 1,
11
- })
12
- )
13
- return users && users.rows.length >= 1
14
- } catch (err) {
15
- throw new Error("Unable to retrieve user list")
16
- }
17
- }