@budibase/worker 1.0.200-alpha.3 → 1.0.200

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.
Files changed (40) hide show
  1. package/Dockerfile +0 -3
  2. package/nodemon.json +1 -1
  3. package/package.json +46 -56
  4. package/scripts/dev/manage.js +0 -2
  5. package/scripts/jestSetup.js +0 -9
  6. package/scripts/load/users.js +4 -4
  7. package/src/api/controllers/global/auth.ts +14 -21
  8. package/src/api/controllers/global/configs.js +2 -126
  9. package/src/api/controllers/global/roles.js +3 -3
  10. package/src/api/controllers/global/self.js +3 -12
  11. package/src/api/controllers/global/users.ts +88 -48
  12. package/src/api/routes/global/self.js +2 -2
  13. package/src/api/routes/global/users.js +3 -3
  14. package/src/api/routes/tests/auth.spec.js +16 -38
  15. package/src/api/routes/tests/configs.spec.js +7 -223
  16. package/src/api/routes/tests/email.spec.js +7 -8
  17. package/src/api/routes/tests/realEmail.spec.js +5 -5
  18. package/src/api/routes/tests/users.spec.js +13 -299
  19. package/src/{tests → api/routes/tests/utilities}/TestConfiguration.js +111 -68
  20. package/src/api/routes/tests/utilities/controllers.js +7 -0
  21. package/src/api/routes/tests/utilities/index.js +41 -0
  22. package/src/api/routes/tests/utilities/structures.js +2 -0
  23. package/src/api/utilities/index.js +33 -0
  24. package/src/api/{routes/validation/users.ts → utilities/validation.js} +4 -4
  25. package/src/index.ts +0 -2
  26. package/tsconfig.json +15 -21
  27. package/src/api/routes/tests/self.spec.js +0 -58
  28. package/src/api/routes/validation/index.ts +0 -1
  29. package/src/sdk/index.ts +0 -1
  30. package/src/sdk/users/events.ts +0 -161
  31. package/src/sdk/users/index.ts +0 -1
  32. package/src/sdk/users/users.ts +0 -201
  33. package/src/tests/controllers.js +0 -7
  34. package/src/tests/index.js +0 -12
  35. package/src/tests/mocks/email.js +0 -10
  36. package/src/tests/mocks/index.js +0 -5
  37. package/src/tests/structures/configs.js +0 -76
  38. package/src/tests/structures/index.js +0 -12
  39. package/src/tests/structures/users.ts +0 -28
  40. package/tsconfig.build.json +0 -25
package/Dockerfile CHANGED
@@ -21,7 +21,4 @@ EXPOSE 4001
21
21
  # which are actually needed to get this environment up and running
22
22
  ENV NODE_ENV=production
23
23
  ENV CLUSTER_MODE=${CLUSTER_MODE}
24
- ENV SERVICE=worker-service
25
- ENV POSTHOG_TOKEN=phc_fg5I3nDOf6oJVMHSaycEhpPdlgS8rzXG2r6F2IpxCHS
26
-
27
24
  CMD ["./docker_run.sh"]
package/nodemon.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "watch": ["src", "../backend-core", "../../../budibase-pro/packages/pro"],
3
3
  "ext": "js,ts,json",
4
- "ignore": ["src/**/*.spec.ts", "src/**/*.spec.js", "../backend-core/dist/**/*"],
4
+ "ignore": ["src/**/*.spec.ts", "src/**/*.spec.js"],
5
5
  "exec": "ts-node src/index.ts"
6
6
  }
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.200-alpha.3",
4
+ "version": "1.0.200",
5
5
  "description": "Budibase background service",
6
6
  "main": "src/index.ts",
7
7
  "repository": {
@@ -12,10 +12,8 @@
12
12
  "budibase"
13
13
  ],
14
14
  "scripts": {
15
- "prebuild": "rimraf dist/",
16
- "build": "tsc -p tsconfig.build.json",
15
+ "build": "rimraf dist/ && tsc",
17
16
  "postbuild": "copyfiles -u 1 src/**/*.hbs dist/",
18
- "build:dev": "yarn prebuild && tsc --build --watch --preserveWatchOutput",
19
17
  "run:docker": "node dist/index.js",
20
18
  "run:docker:cluster": "pm2-runtime start pm2.config.js",
21
19
  "build:docker": "docker build . -t worker-service --label version=$BUDIBASE_RELEASE_VERSION",
@@ -34,71 +32,63 @@
34
32
  "author": "Budibase",
35
33
  "license": "GPL-3.0",
36
34
  "dependencies": {
37
- "@budibase/backend-core": "^1.0.200-alpha.3",
38
- "@budibase/pro": "1.0.200-alpha.2",
39
- "@budibase/string-templates": "^1.0.200-alpha.3",
40
- "@koa/router": "8.0.8",
35
+ "@budibase/backend-core": "^1.0.200",
36
+ "@budibase/pro": "1.0.199",
37
+ "@budibase/string-templates": "^1.0.200",
38
+ "@koa/router": "^8.0.0",
41
39
  "@sentry/node": "6.17.7",
42
- "@techpass/passport-openidconnect": "0.3.2",
43
- "@types/global-agent": "2.1.1",
44
- "aws-sdk": "2.1030.0",
45
- "bcryptjs": "2.4.3",
46
- "dotenv": "8.6.0",
47
- "global-agent": "3.0.0",
48
- "got": "11.8.3",
49
- "joi": "17.6.0",
50
- "koa": "2.13.4",
51
- "koa-body": "4.2.0",
52
- "koa-compress": "4.0.1",
53
- "koa-passport": "4.1.4",
54
- "koa-pino-logger": "3.0.0",
55
- "koa-send": "5.0.1",
56
- "koa-session": "5.13.1",
57
- "koa-static": "5.0.0",
58
- "node-fetch": "2.6.7",
59
- "nodemailer": "6.7.2",
60
- "passport-google-oauth": "2.0.0",
61
- "passport-jwt": "4.0.0",
62
- "passport-local": "1.0.0",
63
- "pino-pretty": "4.8.0",
40
+ "@techpass/passport-openidconnect": "^0.3.0",
41
+ "@types/global-agent": "^2.1.1",
42
+ "aws-sdk": "^2.811.0",
43
+ "bcryptjs": "^2.4.3",
44
+ "dotenv": "^8.2.0",
45
+ "global-agent": "^3.0.0",
46
+ "got": "^11.8.1",
47
+ "joi": "^17.4.0",
48
+ "koa": "^2.7.0",
49
+ "koa-body": "^4.2.0",
50
+ "koa-compress": "^4.0.1",
51
+ "koa-passport": "^4.1.4",
52
+ "koa-pino-logger": "^3.0.0",
53
+ "koa-send": "^5.0.0",
54
+ "koa-session": "^5.12.0",
55
+ "koa-static": "^5.0.0",
56
+ "node-fetch": "^2.6.1",
57
+ "nodemailer": "^6.5.0",
58
+ "passport-google-oauth": "^2.0.0",
59
+ "passport-jwt": "^4.0.0",
60
+ "passport-local": "^1.0.0",
61
+ "pino-pretty": "^4.0.0",
64
62
  "pouchdb": "7.3.0",
65
- "pouchdb-all-dbs": "1.1.1",
66
- "server-destroy": "1.0.1"
63
+ "pouchdb-all-dbs": "^1.0.2",
64
+ "server-destroy": "^1.0.1"
67
65
  },
68
66
  "devDependencies": {
69
- "@budibase/types": "^1.0.200-alpha.3",
70
- "@types/jest": "26.0.23",
71
- "@types/koa": "2.13.4",
72
- "@types/koa-router": "7.4.4",
73
- "@types/koa__router": "8.0.11",
74
- "@types/node": "14.18.20",
67
+ "@types/jest": "^26.0.23",
68
+ "@types/koa": "^2.13.3",
69
+ "@types/koa-router": "^7.4.2",
70
+ "@types/koa__router": "^8.0.11",
71
+ "@types/node": "^15.12.4",
75
72
  "@typescript-eslint/parser": "5.12.0",
76
- "copyfiles": "2.4.1",
77
- "eslint": "6.8.0",
78
- "jest": "27.4.7",
79
- "nodemon": "2.0.15",
80
- "pouchdb-adapter-memory": "7.2.2",
73
+ "copyfiles": "^2.4.1",
74
+ "eslint": "^6.8.0",
75
+ "jest": "^27.0.5",
76
+ "nodemon": "^2.0.7",
77
+ "pouchdb-adapter-memory": "^7.2.2",
81
78
  "prettier": "2.3.1",
82
- "rimraf": "3.0.2",
83
- "supertest": "6.2.2",
84
- "timekeeper": "2.2.0",
85
- "ts-jest": "27.1.3",
86
- "ts-node": "10.4.0",
87
- "tsconfig-paths": "4.0.0",
79
+ "rimraf": "^3.0.2",
80
+ "supertest": "^6.1.3",
81
+ "ts-jest": "^27.0.3",
82
+ "ts-node": "^10.0.0",
88
83
  "typescript": "4.5.5",
89
- "update-dotenv": "1.1.1"
84
+ "update-dotenv": "^1.1.1"
90
85
  },
91
86
  "jest": {
92
87
  "preset": "ts-jest",
93
88
  "testEnvironment": "node",
94
- "moduleNameMapper": {
95
- "@budibase/backend-core/(.*)": "<rootDir>/../backend-core/$1",
96
- "@budibase/backend-core": "<rootDir>/../backend-core/src",
97
- "@budibase/types": "<rootDir>/../types/src"
98
- },
99
89
  "setupFiles": [
100
90
  "./scripts/jestSetup.js"
101
91
  ]
102
92
  },
103
- "gitHead": "48dd23473a5d9572c5127cdfa5df65e0f652d0fd"
93
+ "gitHead": "94c375fdeac1d1252d6bd4f867d7cfce346dd60b"
104
94
  }
@@ -26,8 +26,6 @@ async function init() {
26
26
  ACCOUNT_PORTAL_API_KEY: "budibase",
27
27
  PLATFORM_URL: "http://localhost:10000",
28
28
  APPS_URL: "http://localhost:4001",
29
- SERVICE: "worker-service",
30
- DEPLOYMENT_ENVIRONMENT: "development",
31
29
  }
32
30
  let envFile = ""
33
31
  Object.keys(envFileJson).forEach(key => {
@@ -5,12 +5,3 @@ env._set("NODE_ENV", "jest")
5
5
  env._set("JWT_SECRET", "test-jwtsecret")
6
6
  env._set("LOG_LEVEL", "silent")
7
7
  env._set("MULTI_TENANCY", true)
8
-
9
- const { mocks } = require("@budibase/backend-core/tests")
10
-
11
- // mock all dates to 2020-01-01T00:00:00.000Z
12
- // use tk.reset() to use real dates in individual tests
13
- const tk = require("timekeeper")
14
- tk.freeze(mocks.date.MOCK_DATE)
15
-
16
- global.console.log = jest.fn() // console.log are ignored in tests
@@ -6,7 +6,7 @@ const {
6
6
  generateGlobalUserID,
7
7
  } = require("@budibase/backend-core/db")
8
8
  const { doInTenant, getGlobalDB } = require("@budibase/backend-core/tenancy")
9
- const users = require("../../src/sdk/users")
9
+ const { internalSaveUser } = require("@budibase/backend-core/utils")
10
10
  const { publicApiUserFix } = require("../../src/utilities/users")
11
11
  const { hash } = require("@budibase/backend-core/utils")
12
12
 
@@ -73,15 +73,15 @@ async function run() {
73
73
  },
74
74
  })
75
75
  userSavePromises.push(
76
- users.save(ctx.request.body, {
76
+ internalSaveUser(ctx.request.body, TENANT_ID, {
77
77
  hashPassword: false,
78
78
  requirePassword: true,
79
79
  bulkCreate: true,
80
80
  })
81
81
  )
82
82
  }
83
- const allUsers = await Promise.all(userSavePromises)
84
- await db.bulkDocs(allUsers)
83
+ const users = await Promise.all(userSavePromises)
84
+ await db.bulkDocs(users)
85
85
  console.log(`${i + BATCH_SIZE} users have been created.`)
86
86
  }
87
87
  })
@@ -4,7 +4,14 @@ const { google } = require("@budibase/backend-core/middleware")
4
4
  const { oidc } = require("@budibase/backend-core/middleware")
5
5
  const { Configs, EmailTemplatePurpose } = require("../../../constants")
6
6
  const { sendEmail, isEmailConfigured } = require("../../../utilities/email")
7
- const { setCookie, getCookie, clearCookie, hash, platformLogout } = core.utils
7
+ const {
8
+ setCookie,
9
+ getCookie,
10
+ clearCookie,
11
+ getGlobalUserByEmail,
12
+ hash,
13
+ platformLogout,
14
+ } = core.utils
8
15
  const { Cookies, Headers } = core.constants
9
16
  const { passport } = core.auth
10
17
  const { checkResetPasswordCode } = require("../../../utilities/redis")
@@ -14,9 +21,7 @@ const {
14
21
  isMultiTenant,
15
22
  } = require("@budibase/backend-core/tenancy")
16
23
  const env = require("../../../environment")
17
- import { events, users as usersCore, context } from "@budibase/backend-core"
18
- import { users } from "../../../sdk"
19
- import { User } from "@budibase/types"
24
+ import { users } from "@budibase/pro"
20
25
 
21
26
  const ssoCallbackUrl = async (config: any, type: any) => {
22
27
  // incase there is a callback URL from before
@@ -70,11 +75,8 @@ async function authInternal(ctx: any, user: any, err = null, info = null) {
70
75
  export const authenticate = async (ctx: any, next: any) => {
71
76
  return passport.authenticate(
72
77
  "local",
73
- async (err: any, user: User, info: any) => {
78
+ async (err: any, user: any, info: any) => {
74
79
  await authInternal(ctx, user, err, info)
75
- await context.identity.doInUserContext(user, async () => {
76
- await events.auth.login("local")
77
- })
78
80
  ctx.status = 200
79
81
  }
80
82
  )(ctx, next)
@@ -108,14 +110,13 @@ export const reset = async (ctx: any) => {
108
110
  )
109
111
  }
110
112
  try {
111
- const user = (await usersCore.getGlobalUserByEmail(email)) as User
113
+ const user = await getGlobalUserByEmail(email)
112
114
  // only if user exists, don't error though if they don't
113
115
  if (user) {
114
116
  await sendEmail(email, EmailTemplatePurpose.PASSWORD_RECOVERY, {
115
117
  user,
116
118
  subject: "{{ company }} platform password reset",
117
119
  })
118
- await events.user.passwordResetRequested(user)
119
120
  }
120
121
  } catch (err) {
121
122
  console.log(err)
@@ -140,11 +141,7 @@ export const resetUpdate = async (ctx: any) => {
140
141
  ctx.body = {
141
142
  message: "password reset successfully.",
142
143
  }
143
- // remove password from the user before sending events
144
- delete user.password
145
- await events.user.passwordReset(user)
146
144
  } catch (err) {
147
- console.error(err)
148
145
  ctx.throw(400, "Cannot reset password.")
149
146
  }
150
147
  }
@@ -214,11 +211,9 @@ export const googleAuth = async (ctx: any, next: any) => {
214
211
  return passport.authenticate(
215
212
  strategy,
216
213
  { successRedirect: "/", failureRedirect: "/error" },
217
- async (err: any, user: User, info: any) => {
214
+ async (err: any, user: any, info: any) => {
218
215
  await authInternal(ctx, user, err, info)
219
- await context.identity.doInUserContext(user, async () => {
220
- await events.auth.login("google-internal")
221
- })
216
+
222
217
  ctx.redirect("/")
223
218
  }
224
219
  )(ctx, next)
@@ -262,9 +257,7 @@ export const oidcAuth = async (ctx: any, next: any) => {
262
257
  { successRedirect: "/", failureRedirect: "/error" },
263
258
  async (err: any, user: any, info: any) => {
264
259
  await authInternal(ctx, user, err, info)
265
- await context.identity.doInUserContext(user, async () => {
266
- await events.auth.login("oidc")
267
- })
260
+
268
261
  ctx.redirect("/")
269
262
  }
270
263
  )(ctx, next)
@@ -19,132 +19,13 @@ const {
19
19
  CacheKeys,
20
20
  bustCache,
21
21
  } = require("@budibase/backend-core/cache")
22
- const { events } = require("@budibase/backend-core")
23
22
 
24
23
  const BB_TENANT_CDN = "https://tenants.cdn.budi.live"
25
24
 
26
- const getEventFns = async (db, config) => {
27
- const fns = []
28
- const type = config.type
29
-
30
- let existing
31
- if (config._id) {
32
- existing = await db.get(config._id)
33
- }
34
-
35
- if (!existing) {
36
- switch (config.type) {
37
- case Configs.SMTP: {
38
- fns.push(events.email.SMTPCreated)
39
- break
40
- }
41
- case Configs.GOOGLE: {
42
- fns.push(() => events.auth.SSOCreated(type))
43
- if (config.config.activated) {
44
- fns.push(() => events.auth.SSOActivated(type))
45
- }
46
- break
47
- }
48
- case Configs.OIDC: {
49
- fns.push(() => events.auth.SSOCreated(type))
50
- if (config.config.configs[0].activated) {
51
- fns.push(() => events.auth.SSOActivated(type))
52
- }
53
- break
54
- }
55
- case Configs.SETTINGS: {
56
- // company
57
- const company = config.config.company
58
- if (company && company !== "Budibase") {
59
- fns.push(events.org.nameUpdated)
60
- }
61
-
62
- // logo
63
- const logoUrl = config.config.logoUrl
64
- if (logoUrl) {
65
- fns.push(events.org.logoUpdated)
66
- }
67
-
68
- // platform url
69
- const platformUrl = config.config.platformUrl
70
- if (
71
- platformUrl &&
72
- platformUrl !== "http://localhost:10000" &&
73
- env.SELF_HOSTED
74
- ) {
75
- fns.push(events.org.platformURLUpdated)
76
- }
77
- break
78
- }
79
- }
80
- } else {
81
- switch (config.type) {
82
- case Configs.SMTP: {
83
- fns.push(events.email.SMTPUpdated)
84
- break
85
- }
86
- case Configs.GOOGLE: {
87
- fns.push(() => events.auth.SSOUpdated(type))
88
- if (!existing.config.activated && config.config.activated) {
89
- fns.push(() => events.auth.SSOActivated(type))
90
- } else if (existing.config.activated && !config.config.activated) {
91
- fns.push(() => events.auth.SSODeactivated(type))
92
- }
93
- break
94
- }
95
- case Configs.OIDC: {
96
- fns.push(() => events.auth.SSOUpdated(type))
97
- if (
98
- !existing.config.configs[0].activated &&
99
- config.config.configs[0].activated
100
- ) {
101
- fns.push(() => events.auth.SSOActivated(type))
102
- } else if (
103
- existing.config.configs[0].activated &&
104
- !config.config.configs[0].activated
105
- ) {
106
- fns.push(() => events.auth.SSODeactivated(type))
107
- }
108
- break
109
- }
110
- case Configs.SETTINGS: {
111
- // company
112
- const existingCompany = existing.config.company
113
- const company = config.config.company
114
- if (company && company !== "Budibase" && existingCompany !== company) {
115
- fns.push(events.org.nameUpdated)
116
- }
117
-
118
- // logo
119
- const existingLogoUrl = existing.config.logoUrl
120
- const logoUrl = config.config.logoUrl
121
- if (logoUrl && existingLogoUrl !== logoUrl) {
122
- fns.push(events.org.logoUpdated)
123
- }
124
-
125
- // platform url
126
- const existingPlatformUrl = existing.config.platformUrl
127
- const platformUrl = config.config.platformUrl
128
- if (
129
- platformUrl &&
130
- platformUrl !== "http://localhost:10000" &&
131
- existingPlatformUrl !== platformUrl &&
132
- env.SELF_HOSTED
133
- ) {
134
- fns.push(events.org.platformURLUpdated)
135
- }
136
- break
137
- }
138
- }
139
- }
140
-
141
- return fns
142
- }
143
-
144
25
  exports.save = async function (ctx) {
145
26
  const db = getGlobalDB()
146
27
  const { type, workspace, user, config } = ctx.request.body
147
- let eventFns = await getEventFns(db, ctx.request.body)
28
+
148
29
  // Config does not exist yet
149
30
  if (!ctx.request.body._id) {
150
31
  ctx.request.body._id = generateConfigID({
@@ -153,6 +34,7 @@ exports.save = async function (ctx) {
153
34
  user,
154
35
  })
155
36
  }
37
+
156
38
  try {
157
39
  // verify the configuration
158
40
  switch (type) {
@@ -167,12 +49,6 @@ exports.save = async function (ctx) {
167
49
  try {
168
50
  const response = await db.put(ctx.request.body)
169
51
  await bustCache(CacheKeys.CHECKLIST)
170
- await bustCache(CacheKeys.ANALYTICS_ENABLED)
171
-
172
- for (const fn of eventFns) {
173
- await fn()
174
- }
175
-
176
52
  ctx.body = {
177
53
  type,
178
54
  _id: response.id,
@@ -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 { users } = require("../../../sdk")
10
+ const { allUsers } = require("../../utilities")
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 allUsers = await users.allUsers(ctx)
52
+ const users = await allUsers(ctx)
53
53
  const bulk = []
54
54
  const cacheInvalidations = []
55
- for (let user of allUsers) {
55
+ for (let user of users) {
56
56
  if (user.roles[appId]) {
57
57
  cacheInvalidations.push(userCache.invalidateUser(user._id))
58
58
  delete user.roles[appId]
@@ -13,9 +13,9 @@ const {
13
13
  } = require("@budibase/backend-core/utils")
14
14
  const { encrypt } = require("@budibase/backend-core/encryption")
15
15
  const { newid } = require("@budibase/backend-core/utils")
16
- const { users } = require("../../../sdk")
16
+ const { getUser } = require("../../utilities")
17
17
  const { Cookies } = require("@budibase/backend-core/constants")
18
- const { events, featureFlags } = require("@budibase/backend-core")
18
+ const { featureFlags } = require("@budibase/backend-core")
19
19
 
20
20
  function newApiKey() {
21
21
  return encrypt(`${getTenantId()}${SEPARATOR}${newid()}`)
@@ -104,7 +104,7 @@ exports.getSelf = async ctx => {
104
104
  checkCurrentApp(ctx)
105
105
 
106
106
  // get the main body of the user
107
- ctx.body = await users.getUser(userId)
107
+ ctx.body = await getUser(userId)
108
108
 
109
109
  // add the feature flags for this tenant
110
110
  const tenantId = getTenantId()
@@ -116,10 +116,8 @@ exports.getSelf = async ctx => {
116
116
  exports.updateSelf = async ctx => {
117
117
  const db = getGlobalDB()
118
118
  const user = await db.get(ctx.user._id)
119
- let passwordChange = false
120
119
  if (ctx.request.body.password) {
121
120
  // changing password
122
- passwordChange = true
123
121
  ctx.request.body.password = await hash(ctx.request.body.password)
124
122
  // Log all other sessions out apart from the current one
125
123
  await platformLogout({
@@ -142,11 +140,4 @@ exports.updateSelf = async ctx => {
142
140
  _id: response.id,
143
141
  _rev: response.rev,
144
142
  }
145
-
146
- // remove the old password from the user before sending events
147
- delete user.password
148
- await events.user.updated(user)
149
- if (passwordChange) {
150
- await events.user.passwordUpdated(user)
151
- }
152
143
  }