@budibase/worker 2.4.44-alpha.4 → 2.5.0

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.4.44-alpha.4",
4
+ "version": "2.5.0",
5
5
  "description": "Budibase background service",
6
6
  "main": "src/index.ts",
7
7
  "repository": {
@@ -36,10 +36,10 @@
36
36
  "author": "Budibase",
37
37
  "license": "GPL-3.0",
38
38
  "dependencies": {
39
- "@budibase/backend-core": "2.4.44-alpha.4",
40
- "@budibase/pro": "2.4.44-alpha.3",
41
- "@budibase/string-templates": "2.4.44-alpha.4",
42
- "@budibase/types": "2.4.44-alpha.4",
39
+ "@budibase/backend-core": "^2.5.0",
40
+ "@budibase/pro": "2.4.44",
41
+ "@budibase/string-templates": "^2.5.0",
42
+ "@budibase/types": "^2.5.0",
43
43
  "@koa/router": "8.0.8",
44
44
  "@sentry/node": "6.17.7",
45
45
  "@techpass/passport-openidconnect": "0.3.2",
@@ -79,7 +79,6 @@
79
79
  "@types/jsonwebtoken": "8.5.1",
80
80
  "@types/koa": "2.13.4",
81
81
  "@types/koa__router": "8.0.8",
82
- "@types/lodash": "^4.14.191",
83
82
  "@types/node": "14.18.20",
84
83
  "@types/node-fetch": "2.6.1",
85
84
  "@types/pouchdb": "6.4.0",
@@ -90,7 +89,6 @@
90
89
  "copyfiles": "2.4.1",
91
90
  "eslint": "6.8.0",
92
91
  "jest": "28.1.1",
93
- "lodash": "4.17.21",
94
92
  "nodemon": "2.0.15",
95
93
  "pouchdb-adapter-memory": "7.2.2",
96
94
  "prettier": "2.3.1",
@@ -103,5 +101,5 @@
103
101
  "typescript": "4.7.3",
104
102
  "update-dotenv": "1.1.1"
105
103
  },
106
- "gitHead": "51da16c6a1bb25784659b25308db8ae07a166dc0"
104
+ "gitHead": "aa8ddde74c69b49755866666204c79a27c6c8a2c"
107
105
  }
@@ -177,7 +177,7 @@ export const destroy = async (ctx: any) => {
177
177
  ctx.throw(400, "Unable to delete self.")
178
178
  }
179
179
 
180
- await userSdk.destroy(id)
180
+ await userSdk.destroy(id, ctx.user)
181
181
 
182
182
  ctx.body = {
183
183
  message: `User ${id} deleted.`,
@@ -197,7 +197,7 @@ export const search = async (ctx: any) => {
197
197
  if (body.paginated === false) {
198
198
  await getAppUsers(ctx)
199
199
  } else {
200
- const paginated = await userSdk.core.paginatedUsers(body)
200
+ const paginated = await userSdk.paginatedUsers(body)
201
201
  // user hashed password shouldn't ever be returned
202
202
  for (let user of paginated.data) {
203
203
  if (user) {
@@ -58,13 +58,6 @@ function oidcValidation() {
58
58
  }).unknown(true)
59
59
  }
60
60
 
61
- function scimValidation() {
62
- // prettier-ignore
63
- return Joi.object({
64
- enabled: Joi.boolean().required(),
65
- }).unknown(true)
66
- }
67
-
68
61
  function buildConfigSaveValidation() {
69
62
  // prettier-ignore
70
63
  return auth.joiValidator.body(Joi.object({
@@ -81,8 +74,7 @@ function buildConfigSaveValidation() {
81
74
  { is: ConfigType.SETTINGS, then: settingValidation() },
82
75
  { is: ConfigType.ACCOUNT, then: Joi.object().unknown(true) },
83
76
  { is: ConfigType.GOOGLE, then: googleValidation() },
84
- { is: ConfigType.OIDC, then: oidcValidation() },
85
- { is: ConfigType.SCIM, then: scimValidation() }
77
+ { is: ConfigType.OIDC, then: oidcValidation() }
86
78
  ],
87
79
  }),
88
80
  }).required().unknown(true),
@@ -1,5 +1,5 @@
1
1
  import Router from "@koa/router"
2
- import { api as pro } from "@budibase/pro"
2
+ import { api } from "@budibase/pro"
3
3
  import userRoutes from "./global/users"
4
4
  import configRoutes from "./global/configs"
5
5
  import workspaceRoutes from "./global/workspaces"
@@ -17,6 +17,9 @@ import migrationRoutes from "./system/migrations"
17
17
  import accountRoutes from "./system/accounts"
18
18
  import restoreRoutes from "./system/restore"
19
19
 
20
+ let userGroupRoutes = api.groups
21
+ let auditLogRoutes = api.auditLogs
22
+
20
23
  export const routes: Router[] = [
21
24
  configRoutes,
22
25
  userRoutes,
@@ -30,11 +33,10 @@ export const routes: Router[] = [
30
33
  statusRoutes,
31
34
  selfRoutes,
32
35
  licenseRoutes,
33
- pro.groups,
34
- pro.auditLogs,
36
+ userGroupRoutes,
37
+ auditLogRoutes,
35
38
  migrationRoutes,
36
39
  accountRoutes,
37
40
  restoreRoutes,
38
41
  eventRoutes,
39
- pro.scim,
40
42
  ]
package/src/index.ts CHANGED
@@ -35,8 +35,6 @@ const logger = require("koa-pino-logger")
35
35
  const { userAgent } = require("koa-useragent")
36
36
 
37
37
  import destroyable from "server-destroy"
38
- import { initPro } from "./initPro"
39
- import { handleScimBody } from "./middleware/handleScimBody"
40
38
 
41
39
  // configure events to use the pro audit log write
42
40
  // can't integrate directly into backend-core due to cyclic issues
@@ -56,9 +54,7 @@ const app: Application = new Koa()
56
54
  app.keys = ["secret", "key"]
57
55
 
58
56
  // set up top level koa middleware
59
- app.use(handleScimBody)
60
57
  app.use(koaBody({ multipart: true }))
61
-
62
58
  app.use(koaSession(app))
63
59
  app.use(middleware.logging)
64
60
  app.use(logger(logging.pinoSettings()))
@@ -112,7 +108,6 @@ const shutdown = () => {
112
108
 
113
109
  export default server.listen(parseInt(env.PORT || "4002"), async () => {
114
110
  console.log(`Worker running on ${JSON.stringify(server.address())}`)
115
- await initPro()
116
111
  await redis.init()
117
112
  })
118
113
 
@@ -15,7 +15,6 @@ import {
15
15
  utils,
16
16
  ViewName,
17
17
  env as coreEnv,
18
- context,
19
18
  } from "@budibase/backend-core"
20
19
  import {
21
20
  AccountMetadata,
@@ -38,6 +37,8 @@ import { EmailTemplatePurpose } from "../../constants"
38
37
  import * as pro from "@budibase/pro"
39
38
  import * as accountSdk from "../accounts"
40
39
 
40
+ const PAGE_LIMIT = 8
41
+
41
42
  export const allUsers = async () => {
42
43
  const db = tenancy.getGlobalDB()
43
44
  const response = await db.allDocs(
@@ -67,6 +68,43 @@ export const getUsersByAppAccess = async (appId?: string) => {
67
68
  return response
68
69
  }
69
70
 
71
+ export const paginatedUsers = async ({
72
+ page,
73
+ email,
74
+ appId,
75
+ }: SearchUsersRequest = {}) => {
76
+ const db = tenancy.getGlobalDB()
77
+ // get one extra document, to have the next page
78
+ const opts: any = {
79
+ include_docs: true,
80
+ limit: PAGE_LIMIT + 1,
81
+ }
82
+ // add a startkey if the page was specified (anchor)
83
+ if (page) {
84
+ opts.startkey = page
85
+ }
86
+ // property specifies what to use for the page/anchor
87
+ let userList,
88
+ property = "_id",
89
+ getKey
90
+ if (appId) {
91
+ userList = await usersCore.searchGlobalUsersByApp(appId, opts)
92
+ getKey = (doc: any) => usersCore.getGlobalUserByAppPage(appId, doc)
93
+ } else if (email) {
94
+ userList = await usersCore.searchGlobalUsersByEmail(email, opts)
95
+ property = "email"
96
+ } else {
97
+ // no search, query allDocs
98
+ const response = await db.allDocs(dbUtils.getGlobalUserParams(null, opts))
99
+ userList = response.rows.map((row: any) => row.doc)
100
+ }
101
+ return dbUtils.pagination(userList, PAGE_LIMIT, {
102
+ paginate: true,
103
+ property,
104
+ getKey,
105
+ })
106
+ }
107
+
70
108
  export async function getUserByEmail(email: string) {
71
109
  return usersCore.getGlobalUserByEmail(email)
72
110
  }
@@ -538,7 +576,7 @@ export const bulkDelete = async (
538
576
  return response
539
577
  }
540
578
 
541
- export const destroy = async (id: string) => {
579
+ export const destroy = async (id: string, currentUser: any) => {
542
580
  const db = tenancy.getGlobalDB()
543
581
  const dbUser = (await db.get(id)) as User
544
582
  const userId = dbUser._id as string
@@ -548,7 +586,7 @@ export const destroy = async (id: string) => {
548
586
  const email = dbUser.email
549
587
  const account = await accounts.getAccount(email)
550
588
  if (account) {
551
- if (dbUser.userId === context.getIdentity()!._id) {
589
+ if (email === currentUser.email) {
552
590
  throw new HTTPError('Please visit "Account" to delete this user', 400)
553
591
  } else {
554
592
  throw new HTTPError("Account holder cannot be deleted", 400)
@@ -20,18 +20,9 @@ import {
20
20
  auth,
21
21
  constants,
22
22
  env as coreEnv,
23
- db as dbCore,
24
- encryption,
25
- utils,
26
23
  } from "@budibase/backend-core"
27
24
  import structures, { CSRF_TOKEN } from "./structures"
28
- import {
29
- SaveUserResponse,
30
- User,
31
- AuthToken,
32
- SCIMConfig,
33
- ConfigType,
34
- } from "@budibase/types"
25
+ import { SaveUserResponse, User, AuthToken } from "@budibase/types"
35
26
  import API from "./api"
36
27
 
37
28
  class TestConfiguration {
@@ -40,7 +31,6 @@ class TestConfiguration {
40
31
  api: API
41
32
  tenantId: string
42
33
  user?: User
43
- apiKey?: string
44
34
  userPassword = "test"
45
35
 
46
36
  constructor(opts: { openServer: boolean } = { openServer: true }) {
@@ -59,12 +49,6 @@ class TestConfiguration {
59
49
  this.api = new API(this)
60
50
  }
61
51
 
62
- async useNewTenant() {
63
- this.tenantId = structures.tenant.id()
64
-
65
- await this.beforeAll()
66
- }
67
-
68
52
  getRequest() {
69
53
  return this.request
70
54
  }
@@ -217,12 +201,6 @@ class TestConfiguration {
217
201
  return { [constants.Header.API_KEY]: coreEnv.INTERNAL_API_KEY }
218
202
  }
219
203
 
220
- bearerAPIHeaders() {
221
- return {
222
- [constants.Header.AUTHORIZATION]: `Bearer ${this.apiKey}`,
223
- }
224
- }
225
-
226
204
  adminOnlyResponse = () => {
227
205
  return { message: "Admin user only endpoint.", status: 403 }
228
206
  }
@@ -235,20 +213,6 @@ class TestConfiguration {
235
213
  })
236
214
  await context.doInTenant(this.tenantId!, async () => {
237
215
  this.user = await this.createUser(user)
238
-
239
- const db = context.getGlobalDB()
240
-
241
- const id = dbCore.generateDevInfoID(this.user._id)
242
- // TODO: dry
243
- this.apiKey = encryption.encrypt(
244
- `${this.tenantId}${dbCore.SEPARATOR}${utils.newid()}`
245
- )
246
- const devInfo = {
247
- _id: id,
248
- userId: this.user._id,
249
- apiKey: this.apiKey,
250
- }
251
- await db.put(devInfo)
252
216
  })
253
217
  }
254
218
 
@@ -341,19 +305,6 @@ class TestConfiguration {
341
305
  controllers.config.save
342
306
  )
343
307
  }
344
-
345
- // CONFIGS - SCIM
346
-
347
- async setSCIMConfig(enabled: boolean) {
348
- await this.deleteConfig(Config.SCIM)
349
- const config: SCIMConfig = {
350
- type: ConfigType.SCIM,
351
- config: { enabled },
352
- }
353
-
354
- await this._req(config, null, controllers.config.save)
355
- return config
356
- }
357
308
  }
358
309
 
359
310
  export default TestConfiguration
@@ -15,9 +15,6 @@ import { RolesAPI } from "./roles"
15
15
  import { TemplatesAPI } from "./templates"
16
16
  import { LicenseAPI } from "./license"
17
17
  import { AuditLogAPI } from "./auditLogs"
18
- import { ScimUsersAPI } from "./scim/users"
19
- import { ScimGroupsAPI } from "./scim/groups"
20
-
21
18
  export default class API {
22
19
  accounts: AccountAPI
23
20
  auth: AuthAPI
@@ -35,8 +32,6 @@ export default class API {
35
32
  templates: TemplatesAPI
36
33
  license: LicenseAPI
37
34
  auditLogs: AuditLogAPI
38
- scimUsersAPI: ScimUsersAPI
39
- scimGroupsAPI: ScimGroupsAPI
40
35
 
41
36
  constructor(config: TestConfiguration) {
42
37
  this.accounts = new AccountAPI(config)
@@ -55,7 +50,5 @@ export default class API {
55
50
  this.templates = new TemplatesAPI(config)
56
51
  this.license = new LicenseAPI(config)
57
52
  this.auditLogs = new AuditLogAPI(config)
58
- this.scimUsersAPI = new ScimUsersAPI(config)
59
- this.scimGroupsAPI = new ScimGroupsAPI(config)
60
53
  }
61
54
  }