@budibase/worker 2.3.18-alpha.9 → 2.3.18

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 (168) hide show
  1. package/coverage/clover.xml +2199 -0
  2. package/coverage/coverage-final.json +84 -0
  3. package/coverage/lcov-report/base.css +224 -0
  4. package/coverage/lcov-report/block-navigation.js +87 -0
  5. package/coverage/lcov-report/favicon.png +0 -0
  6. package/coverage/lcov-report/index.html +431 -0
  7. package/coverage/lcov-report/prettify.css +1 -0
  8. package/coverage/lcov-report/prettify.js +2 -0
  9. package/coverage/lcov-report/sort-arrow-sprite.png +0 -0
  10. package/coverage/lcov-report/sorter.js +196 -0
  11. package/coverage/lcov-report/src/api/controllers/global/auth.ts.html +934 -0
  12. package/coverage/lcov-report/src/api/controllers/global/configs.ts.html +1348 -0
  13. package/coverage/lcov-report/src/api/controllers/global/email.ts.html +196 -0
  14. package/coverage/lcov-report/src/api/controllers/global/events.ts.html +136 -0
  15. package/coverage/lcov-report/src/api/controllers/global/index.html +251 -0
  16. package/coverage/lcov-report/src/api/controllers/global/license.ts.html +187 -0
  17. package/coverage/lcov-report/src/api/controllers/global/roles.ts.html +283 -0
  18. package/coverage/lcov-report/src/api/controllers/global/self.ts.html +577 -0
  19. package/coverage/lcov-report/src/api/controllers/global/templates.ts.html +316 -0
  20. package/coverage/lcov-report/src/api/controllers/global/users.ts.html +838 -0
  21. package/coverage/lcov-report/src/api/controllers/global/workspaces.ts.html +244 -0
  22. package/coverage/lcov-report/src/api/controllers/system/accounts.ts.html +148 -0
  23. package/coverage/lcov-report/src/api/controllers/system/environment.ts.html +124 -0
  24. package/coverage/lcov-report/src/api/controllers/system/index.html +191 -0
  25. package/coverage/lcov-report/src/api/controllers/system/migrations.ts.html +124 -0
  26. package/coverage/lcov-report/src/api/controllers/system/restore.ts.html +124 -0
  27. package/coverage/lcov-report/src/api/controllers/system/status.ts.html +133 -0
  28. package/coverage/lcov-report/src/api/controllers/system/tenants.ts.html +154 -0
  29. package/coverage/lcov-report/src/api/index.html +116 -0
  30. package/coverage/lcov-report/src/api/index.ts.html +595 -0
  31. package/coverage/lcov-report/src/api/routes/global/auth.ts.html +349 -0
  32. package/coverage/lcov-report/src/api/routes/global/configs.ts.html +457 -0
  33. package/coverage/lcov-report/src/api/routes/global/email.ts.html +193 -0
  34. package/coverage/lcov-report/src/api/routes/global/events.ts.html +109 -0
  35. package/coverage/lcov-report/src/api/routes/global/index.html +251 -0
  36. package/coverage/lcov-report/src/api/routes/global/license.ts.html +124 -0
  37. package/coverage/lcov-report/src/api/routes/global/roles.ts.html +133 -0
  38. package/coverage/lcov-report/src/api/routes/global/self.ts.html +139 -0
  39. package/coverage/lcov-report/src/api/routes/global/templates.ts.html +196 -0
  40. package/coverage/lcov-report/src/api/routes/global/users.ts.html +475 -0
  41. package/coverage/lcov-report/src/api/routes/global/workspaces.ts.html +196 -0
  42. package/coverage/lcov-report/src/api/routes/index.html +116 -0
  43. package/coverage/lcov-report/src/api/routes/index.ts.html +202 -0
  44. package/coverage/lcov-report/src/api/routes/system/accounts.ts.html +142 -0
  45. package/coverage/lcov-report/src/api/routes/system/environment.ts.html +109 -0
  46. package/coverage/lcov-report/src/api/routes/system/index.html +191 -0
  47. package/coverage/lcov-report/src/api/routes/system/migrations.ts.html +142 -0
  48. package/coverage/lcov-report/src/api/routes/system/restore.ts.html +109 -0
  49. package/coverage/lcov-report/src/api/routes/system/status.ts.html +109 -0
  50. package/coverage/lcov-report/src/api/routes/system/tenants.ts.html +124 -0
  51. package/coverage/lcov-report/src/api/routes/validation/index.html +131 -0
  52. package/coverage/lcov-report/src/api/routes/validation/index.ts.html +88 -0
  53. package/coverage/lcov-report/src/api/routes/validation/users.ts.html +235 -0
  54. package/coverage/lcov-report/src/constants/index.html +116 -0
  55. package/coverage/lcov-report/src/constants/index.ts.html +637 -0
  56. package/coverage/lcov-report/src/constants/templates/index.html +116 -0
  57. package/coverage/lcov-report/src/constants/templates/index.ts.html +316 -0
  58. package/coverage/lcov-report/src/db/index.html +116 -0
  59. package/coverage/lcov-report/src/db/index.ts.html +115 -0
  60. package/coverage/lcov-report/src/environment.ts.html +388 -0
  61. package/coverage/lcov-report/src/index.html +131 -0
  62. package/coverage/lcov-report/src/index.ts.html +394 -0
  63. package/coverage/lcov-report/src/middleware/cloudRestricted.ts.html +139 -0
  64. package/coverage/lcov-report/src/middleware/index.html +116 -0
  65. package/coverage/lcov-report/src/migrations/functions/globalInfoSyncUsers.ts.html +145 -0
  66. package/coverage/lcov-report/src/migrations/functions/index.html +116 -0
  67. package/coverage/lcov-report/src/migrations/index.html +116 -0
  68. package/coverage/lcov-report/src/migrations/index.ts.html +271 -0
  69. package/coverage/lcov-report/src/sdk/accounts/accounts.ts.html +262 -0
  70. package/coverage/lcov-report/src/sdk/accounts/index.html +131 -0
  71. package/coverage/lcov-report/src/sdk/accounts/index.ts.html +88 -0
  72. package/coverage/lcov-report/src/sdk/index.html +116 -0
  73. package/coverage/lcov-report/src/sdk/index.ts.html +106 -0
  74. package/coverage/lcov-report/src/sdk/users/events.ts.html +601 -0
  75. package/coverage/lcov-report/src/sdk/users/index.html +146 -0
  76. package/coverage/lcov-report/src/sdk/users/index.ts.html +88 -0
  77. package/coverage/lcov-report/src/sdk/users/users.ts.html +1999 -0
  78. package/coverage/lcov-report/src/tests/TestConfiguration.ts.html +1075 -0
  79. package/coverage/lcov-report/src/tests/api/accounts.ts.html +160 -0
  80. package/coverage/lcov-report/src/tests/api/auth.ts.html +220 -0
  81. package/coverage/lcov-report/src/tests/api/base.ts.html +133 -0
  82. package/coverage/lcov-report/src/tests/api/configs.ts.html +226 -0
  83. package/coverage/lcov-report/src/tests/api/email.ts.html +148 -0
  84. package/coverage/lcov-report/src/tests/api/environment.ts.html +130 -0
  85. package/coverage/lcov-report/src/tests/api/groups.ts.html +163 -0
  86. package/coverage/lcov-report/src/tests/api/index.html +356 -0
  87. package/coverage/lcov-report/src/tests/api/index.ts.html +238 -0
  88. package/coverage/lcov-report/src/tests/api/license.ts.html +136 -0
  89. package/coverage/lcov-report/src/tests/api/migrations.ts.html +151 -0
  90. package/coverage/lcov-report/src/tests/api/restore.ts.html +127 -0
  91. package/coverage/lcov-report/src/tests/api/roles.ts.html +181 -0
  92. package/coverage/lcov-report/src/tests/api/self.ts.html +163 -0
  93. package/coverage/lcov-report/src/tests/api/status.ts.html +121 -0
  94. package/coverage/lcov-report/src/tests/api/templates.ts.html +175 -0
  95. package/coverage/lcov-report/src/tests/api/tenants.ts.html +130 -0
  96. package/coverage/lcov-report/src/tests/api/users.ts.html +514 -0
  97. package/coverage/lcov-report/src/tests/controllers.ts.html +100 -0
  98. package/coverage/lcov-report/src/tests/index.html +146 -0
  99. package/coverage/lcov-report/src/tests/index.ts.html +103 -0
  100. package/coverage/lcov-report/src/tests/mocks/email.ts.html +115 -0
  101. package/coverage/lcov-report/src/tests/mocks/index.html +131 -0
  102. package/coverage/lcov-report/src/tests/mocks/index.ts.html +106 -0
  103. package/coverage/lcov-report/src/tests/structures/configs.ts.html +313 -0
  104. package/coverage/lcov-report/src/tests/structures/groups.ts.html +118 -0
  105. package/coverage/lcov-report/src/tests/structures/index.html +161 -0
  106. package/coverage/lcov-report/src/tests/structures/index.ts.html +151 -0
  107. package/coverage/lcov-report/src/tests/structures/users.ts.html +196 -0
  108. package/coverage/lcov-report/src/utilities/appService.ts.html +208 -0
  109. package/coverage/lcov-report/src/utilities/email.ts.html +850 -0
  110. package/coverage/lcov-report/src/utilities/fileSystem.ts.html +100 -0
  111. package/coverage/lcov-report/src/utilities/index.html +206 -0
  112. package/coverage/lcov-report/src/utilities/index.ts.html +112 -0
  113. package/coverage/lcov-report/src/utilities/redis.ts.html +424 -0
  114. package/coverage/lcov-report/src/utilities/templates.ts.html +232 -0
  115. package/coverage/lcov-report/src/utilities/users.ts.html +133 -0
  116. package/coverage/lcov.info +4187 -0
  117. package/jest.config.ts +17 -13
  118. package/package.json +8 -11
  119. package/scripts/dev/manage.js +0 -1
  120. package/src/api/controllers/global/auth.ts +70 -77
  121. package/src/api/controllers/global/self.ts +44 -28
  122. package/src/api/controllers/global/users.ts +25 -65
  123. package/src/api/controllers/system/accounts.ts +5 -7
  124. package/src/api/controllers/system/tenants.ts +8 -4
  125. package/src/api/index.ts +20 -4
  126. package/src/api/routes/global/auth.ts +7 -10
  127. package/src/api/routes/global/tests/auth.spec.ts +17 -226
  128. package/src/api/routes/global/tests/configs.spec.ts +5 -5
  129. package/src/api/routes/global/tests/roles.spec.ts +14 -20
  130. package/src/api/routes/global/tests/self.spec.ts +4 -3
  131. package/src/api/routes/global/tests/users.spec.ts +27 -24
  132. package/src/api/routes/system/tenants.ts +1 -1
  133. package/src/api/routes/system/tests/accounts.spec.ts +4 -4
  134. package/src/api/routes/system/tests/migrations.spec.ts +2 -2
  135. package/src/api/routes/system/tests/restore.spec.ts +2 -2
  136. package/src/api/routes/system/tests/status.spec.ts +5 -5
  137. package/src/environment.ts +1 -15
  138. package/src/index.ts +7 -12
  139. package/src/middleware/tests/tenancy.spec.ts +4 -4
  140. package/src/migrations/functions/globalInfoSyncUsers.ts +3 -4
  141. package/src/sdk/accounts/{metadata.ts → accounts.ts} +1 -0
  142. package/src/sdk/accounts/index.ts +1 -2
  143. package/src/sdk/users/events.ts +0 -4
  144. package/src/sdk/users/index.ts +0 -1
  145. package/src/sdk/users/users.ts +46 -53
  146. package/src/tests/TestConfiguration.ts +62 -41
  147. package/src/tests/api/auth.ts +14 -42
  148. package/src/tests/api/base.ts +1 -2
  149. package/src/tests/api/configs.ts +2 -2
  150. package/src/tests/api/restore.ts +0 -1
  151. package/src/tests/api/users.ts +2 -2
  152. package/src/tests/jestEnv.ts +1 -2
  153. package/src/tests/jestSetup.ts +6 -10
  154. package/src/tests/structures/index.ts +4 -0
  155. package/src/tests/structures/users.ts +37 -0
  156. package/src/utilities/email.ts +3 -3
  157. package/src/utilities/redis.ts +0 -2
  158. package/__mocks__/node-fetch.ts +0 -23
  159. package/jest-testcontainers-config.js +0 -8
  160. package/scripts/test.sh +0 -12
  161. package/src/ddApm.ts +0 -7
  162. package/src/elasticApm.ts +0 -10
  163. package/src/sdk/auth/auth.ts +0 -86
  164. package/src/sdk/auth/index.ts +0 -1
  165. package/src/sdk/tenants/index.ts +0 -1
  166. package/src/sdk/tenants/tenants.ts +0 -76
  167. package/src/sdk/users/tests/users.spec.ts +0 -52
  168. package/src/tests/logging.ts +0 -34
@@ -6,11 +6,12 @@ import {
6
6
  cache,
7
7
  constants,
8
8
  db as dbUtils,
9
+ deprovisioning,
9
10
  events,
10
11
  HTTPError,
12
+ migrations,
11
13
  sessions,
12
14
  tenancy,
13
- platform,
14
15
  users as usersCore,
15
16
  utils,
16
17
  ViewName,
@@ -20,22 +21,21 @@ import {
20
21
  AllDocsResponse,
21
22
  BulkUserResponse,
22
23
  CloudAccount,
24
+ CreateUserResponse,
23
25
  InviteUsersRequest,
24
26
  InviteUsersResponse,
25
- isSSOAccount,
26
- isSSOUser,
27
+ MigrationType,
27
28
  PlatformUser,
28
29
  PlatformUserByEmail,
29
30
  RowResponse,
30
31
  SearchUsersRequest,
31
- UpdateSelf,
32
32
  User,
33
- SaveUserOpts,
33
+ ThirdPartyUser,
34
+ isUser,
34
35
  } from "@budibase/types"
35
36
  import { sendEmail } from "../../utilities/email"
36
37
  import { EmailTemplatePurpose } from "../../constants"
37
38
  import { groups as groupsSdk } from "@budibase/pro"
38
- import * as accountSdk from "../accounts"
39
39
 
40
40
  const PAGE_LIMIT = 8
41
41
 
@@ -94,23 +94,26 @@ export const paginatedUsers = async ({
94
94
  })
95
95
  }
96
96
 
97
- export async function getUserByEmail(email: string) {
98
- return usersCore.getGlobalUserByEmail(email)
99
- }
100
-
101
97
  /**
102
98
  * Gets a user by ID from the global database, based on the current tenancy.
103
99
  */
104
100
  export const getUser = async (userId: string) => {
105
- const user = await usersCore.getById(userId)
101
+ const db = tenancy.getGlobalDB()
102
+ let user = await db.get(userId)
106
103
  if (user) {
107
104
  delete user.password
108
105
  }
109
106
  return user
110
107
  }
111
108
 
109
+ export interface SaveUserOpts {
110
+ hashPassword?: boolean
111
+ requirePassword?: boolean
112
+ currentUserId?: string
113
+ }
114
+
112
115
  const buildUser = async (
113
- user: User,
116
+ user: User | ThirdPartyUser,
114
117
  opts: SaveUserOpts = {
115
118
  hashPassword: true,
116
119
  requirePassword: true,
@@ -118,13 +121,11 @@ const buildUser = async (
118
121
  tenantId: string,
119
122
  dbUser?: any
120
123
  ): Promise<User> => {
121
- let { password, _id } = user
124
+ let fullUser = user as User
125
+ let { password, _id } = fullUser
122
126
 
123
127
  let hashedPassword
124
128
  if (password) {
125
- if (await isPreventSSOPasswords(user)) {
126
- throw new HTTPError("SSO user cannot set password", 400)
127
- }
128
129
  hashedPassword = opts.hashPassword ? await utils.hash(password) : password
129
130
  } else if (dbUser) {
130
131
  hashedPassword = dbUser.password
@@ -134,10 +135,10 @@ const buildUser = async (
134
135
 
135
136
  _id = _id || dbUtils.generateGlobalUserID()
136
137
 
137
- const fullUser = {
138
+ fullUser = {
138
139
  createdAt: Date.now(),
139
140
  ...dbUser,
140
- ...user,
141
+ ...fullUser,
141
142
  _id,
142
143
  password: hashedPassword,
143
144
  tenantId,
@@ -188,36 +189,10 @@ const validateUniqueUser = async (email: string, tenantId: string) => {
188
189
  }
189
190
  }
190
191
 
191
- export async function isPreventSSOPasswords(user: User) {
192
- // when in maintenance mode we allow sso users with the admin role
193
- // to perform any password action - this prevents lockout
194
- if (env.ENABLE_SSO_MAINTENANCE_MODE && user.admin?.global) {
195
- return false
196
- }
197
-
198
- // Check local sso
199
- if (isSSOUser(user)) {
200
- return true
201
- }
202
-
203
- // Check account sso
204
- const account = await accountSdk.api.getAccount(user.email)
205
- return !!(account && isSSOAccount(account))
206
- }
207
-
208
- export async function updateSelf(id: string, data: UpdateSelf) {
209
- let user = await getUser(id)
210
- user = {
211
- ...user,
212
- ...data,
213
- }
214
- return save(user)
215
- }
216
-
217
192
  export const save = async (
218
- user: User,
193
+ user: User | ThirdPartyUser,
219
194
  opts: SaveUserOpts = {}
220
- ): Promise<User> => {
195
+ ): Promise<CreateUserResponse> => {
221
196
  // default booleans to true
222
197
  if (opts.hashPassword == null) {
223
198
  opts.hashPassword = true
@@ -289,7 +264,7 @@ export const save = async (
289
264
  builtUser._rev = response.rev
290
265
 
291
266
  await eventHelpers.handleSaveEvents(builtUser, dbUser)
292
- await platform.users.addUser(tenantId, builtUser._id!, builtUser.email)
267
+ await addTenant(tenantId, _id, email)
293
268
  await cache.user.invalidateUser(response.id)
294
269
 
295
270
  // let server know to sync user
@@ -297,8 +272,11 @@ export const save = async (
297
272
 
298
273
  await Promise.all(groupPromises)
299
274
 
300
- // finally returned the saved user from the db
301
- return db.get(builtUser._id!)
275
+ return {
276
+ _id: response.id,
277
+ _rev: response.rev,
278
+ email,
279
+ }
302
280
  } catch (err: any) {
303
281
  if (err.status === 409) {
304
282
  throw "User exists already"
@@ -308,6 +286,21 @@ export const save = async (
308
286
  }
309
287
  }
310
288
 
289
+ export const addTenant = async (
290
+ tenantId: string,
291
+ _id: string,
292
+ email: string
293
+ ) => {
294
+ if (env.MULTI_TENANCY) {
295
+ const afterCreateTenant = () =>
296
+ migrations.backPopulateMigrations({
297
+ type: MigrationType.GLOBAL,
298
+ tenantId,
299
+ })
300
+ await tenancy.tryAddTenant(tenantId, _id, email, afterCreateTenant)
301
+ }
302
+ }
303
+
311
304
  const getExistingTenantUsers = async (emails: string[]): Promise<User[]> => {
312
305
  const lcEmails = emails.map(email => email.toLowerCase())
313
306
  const params = {
@@ -439,7 +432,7 @@ export const bulkCreate = async (
439
432
  for (const user of usersToBulkSave) {
440
433
  // TODO: Refactor to bulk insert users into the info db
441
434
  // instead of relying on looping tenant creation
442
- await platform.users.addUser(tenantId, user._id, user.email)
435
+ await addTenant(tenantId, user._id, user.email)
443
436
  await eventHelpers.handleSaveEvents(user, undefined)
444
437
  await apps.syncUserInApps(user._id)
445
438
  }
@@ -557,7 +550,7 @@ export const bulkDelete = async (
557
550
 
558
551
  export const destroy = async (id: string, currentUser: any) => {
559
552
  const db = tenancy.getGlobalDB()
560
- const dbUser = (await db.get(id)) as User
553
+ const dbUser = await db.get(id)
561
554
  const userId = dbUser._id as string
562
555
 
563
556
  if (!env.SELF_HOSTED && !env.DISABLE_ACCOUNT_PORTAL) {
@@ -573,7 +566,7 @@ export const destroy = async (id: string, currentUser: any) => {
573
566
  }
574
567
  }
575
568
 
576
- await platform.users.removeUser(dbUser)
569
+ await deprovisioning.removeUserFromInfoDB(dbUser)
577
570
 
578
571
  await db.remove(userId, dbUser._rev)
579
572
 
@@ -586,7 +579,7 @@ export const destroy = async (id: string, currentUser: any) => {
586
579
 
587
580
  const bulkDeleteProcessing = async (dbUser: User) => {
588
581
  const userId = dbUser._id as string
589
- await platform.users.removeUser(dbUser)
582
+ await deprovisioning.removeUserFromInfoDB(dbUser)
590
583
  await eventHelpers.handleDeleteEvents(dbUser)
591
584
  await cache.user.invalidateUser(userId)
592
585
  await sessions.invalidateSessions(userId, { reason: "bulk-deletion" })
@@ -15,29 +15,39 @@ const supertest = require("supertest")
15
15
  import { Config } from "../constants"
16
16
  import {
17
17
  users,
18
- context,
18
+ tenancy,
19
19
  sessions,
20
20
  auth,
21
21
  constants,
22
22
  env as coreEnv,
23
23
  } from "@budibase/backend-core"
24
- import structures, { CSRF_TOKEN } from "./structures"
25
- import { SaveUserResponse, User, AuthToken } from "@budibase/types"
24
+ import structures, { TENANT_ID, TENANT_1, CSRF_TOKEN } from "./structures"
25
+ import { CreateUserResponse, User, AuthToken } from "@budibase/types"
26
26
  import API from "./api"
27
27
 
28
+ enum Mode {
29
+ CLOUD = "cloud",
30
+ SELF = "self",
31
+ }
32
+
28
33
  class TestConfiguration {
29
34
  server: any
30
35
  request: any
31
36
  api: API
32
- tenantId: string
33
- user?: User
34
- userPassword = "test"
35
-
36
- constructor(opts: { openServer: boolean } = { openServer: true }) {
37
- // default to cloud hosting
38
- this.cloudHosted()
37
+ defaultUser?: User
38
+ tenant1User?: User
39
39
 
40
- this.tenantId = structures.tenant.id()
40
+ constructor(
41
+ opts: { openServer: boolean; mode: Mode } = {
42
+ openServer: true,
43
+ mode: Mode.CLOUD,
44
+ }
45
+ ) {
46
+ if (opts.mode === Mode.CLOUD) {
47
+ this.modeCloud()
48
+ } else if (opts.mode === Mode.SELF) {
49
+ this.modeSelf()
50
+ }
41
51
 
42
52
  if (opts.openServer) {
43
53
  env.PORT = "0" // random port
@@ -53,19 +63,26 @@ class TestConfiguration {
53
63
  return this.request
54
64
  }
55
65
 
56
- // HOSTING
66
+ // MODES
67
+
68
+ setMultiTenancy = (value: boolean) => {
69
+ env._set("MULTI_TENANCY", value)
70
+ coreEnv._set("MULTI_TENANCY", value)
71
+ }
57
72
 
58
73
  setSelfHosted = (value: boolean) => {
59
74
  env._set("SELF_HOSTED", value)
60
75
  coreEnv._set("SELF_HOSTED", value)
61
76
  }
62
77
 
63
- cloudHosted = () => {
78
+ modeCloud = () => {
64
79
  this.setSelfHosted(false)
80
+ this.setMultiTenancy(true)
65
81
  }
66
82
 
67
- selfHosted = () => {
83
+ modeSelf = () => {
68
84
  this.setSelfHosted(true)
85
+ this.setMultiTenancy(false)
69
86
  }
70
87
 
71
88
  // UTILS
@@ -86,7 +103,7 @@ class TestConfiguration {
86
103
  if (params) {
87
104
  request.params = params
88
105
  }
89
- await context.doInTenant(this.getTenantId(), () => {
106
+ await tenancy.doInTenant(this.getTenantId(), () => {
90
107
  return controlFunc(request)
91
108
  })
92
109
  return request.body
@@ -95,13 +112,13 @@ class TestConfiguration {
95
112
  // SETUP / TEARDOWN
96
113
 
97
114
  async beforeAll() {
98
- try {
99
- await this.createDefaultUser()
100
- await this.createSession(this.user!)
101
- } catch (e: any) {
102
- console.error(e)
103
- throw new Error(e.message)
104
- }
115
+ await this.createDefaultUser()
116
+ await this.createSession(this.defaultUser!)
117
+
118
+ await tenancy.doInTenant(TENANT_1, async () => {
119
+ await this.createTenant1User()
120
+ await this.createSession(this.tenant1User!)
121
+ })
105
122
  }
106
123
 
107
124
  async afterAll() {
@@ -112,12 +129,6 @@ class TestConfiguration {
112
129
 
113
130
  // TENANCY
114
131
 
115
- doInTenant(task: any) {
116
- return context.doInTenant(this.tenantId, () => {
117
- return task()
118
- })
119
- }
120
-
121
132
  createTenant = async (): Promise<User> => {
122
133
  // create user / new tenant
123
134
  const res = await this.api.users.createAdminUser()
@@ -139,9 +150,9 @@ class TestConfiguration {
139
150
 
140
151
  getTenantId() {
141
152
  try {
142
- return context.getTenantId()
143
- } catch (e) {
144
- return this.tenantId!
153
+ return tenancy.getTenantId()
154
+ } catch (e: any) {
155
+ return TENANT_ID
145
156
  }
146
157
  }
147
158
 
@@ -189,11 +200,14 @@ class TestConfiguration {
189
200
  }
190
201
 
191
202
  defaultHeaders() {
192
- return this.authHeaders(this.user!)
193
- }
194
-
195
- tenantIdHeaders() {
196
- return { [constants.Header.TENANT_ID]: this.tenantId }
203
+ const tenantId = this.getTenantId()
204
+ if (tenantId === TENANT_ID) {
205
+ return this.authHeaders(this.defaultUser!)
206
+ } else if (tenantId === TENANT_1) {
207
+ return this.authHeaders(this.tenant1User!)
208
+ } else {
209
+ throw new Error("could not determine auth headers to use")
210
+ }
197
211
  }
198
212
 
199
213
  internalAPIHeaders() {
@@ -208,15 +222,22 @@ class TestConfiguration {
208
222
 
209
223
  async createDefaultUser() {
210
224
  const user = structures.users.adminUser({
211
- password: this.userPassword,
225
+ email: "test@test.com",
226
+ password: "test",
212
227
  })
213
- await context.doInTenant(this.tenantId!, async () => {
214
- this.user = await this.createUser(user)
228
+ this.defaultUser = await this.createUser(user)
229
+ }
230
+
231
+ async createTenant1User() {
232
+ const user = structures.users.adminUser({
233
+ email: "tenant1@test.com",
234
+ password: "test",
215
235
  })
236
+ this.tenant1User = await this.createUser(user)
216
237
  }
217
238
 
218
239
  async getUser(email: string): Promise<User> {
219
- return context.doInTenant(this.getTenantId(), () => {
240
+ return tenancy.doInTenant(this.getTenantId(), () => {
220
241
  return users.getGlobalUserByEmail(email)
221
242
  })
222
243
  }
@@ -226,7 +247,7 @@ class TestConfiguration {
226
247
  user = structures.users.user()
227
248
  }
228
249
  const response = await this._req(user, null, controllers.users.save)
229
- const body = response as SaveUserResponse
250
+ const body = response as CreateUserResponse
230
251
  return this.getUser(body.email)
231
252
  }
232
253
 
@@ -1,39 +1,20 @@
1
1
  import TestConfiguration from "../TestConfiguration"
2
- import { TestAPI, TestAPIOpts } from "./base"
2
+ import { TestAPI } from "./base"
3
3
 
4
4
  export class AuthAPI extends TestAPI {
5
5
  constructor(config: TestConfiguration) {
6
6
  super(config)
7
7
  }
8
8
 
9
- updatePassword = (
10
- resetCode: string,
11
- password: string,
12
- opts?: TestAPIOpts
13
- ) => {
9
+ updatePassword = (code: string) => {
14
10
  return this.request
15
11
  .post(`/api/global/auth/${this.config.getTenantId()}/reset/update`)
16
12
  .send({
17
- password,
18
- resetCode,
13
+ password: "newpassword",
14
+ resetCode: code,
19
15
  })
20
16
  .expect("Content-Type", /json/)
21
- .expect(opts?.status ? opts.status : 200)
22
- }
23
-
24
- login = (
25
- tenantId: string,
26
- email: string,
27
- password: string,
28
- opts?: TestAPIOpts
29
- ) => {
30
- return this.request
31
- .post(`/api/global/auth/${tenantId}/login`)
32
- .send({
33
- username: email,
34
- password: password,
35
- })
36
- .expect(opts?.status ? opts.status : 200)
17
+ .expect(200)
37
18
  }
38
19
 
39
20
  logout = () => {
@@ -43,31 +24,22 @@ export class AuthAPI extends TestAPI {
43
24
  .expect(200)
44
25
  }
45
26
 
46
- requestPasswordReset = async (
47
- sendMailMock: any,
48
- email: string,
49
- opts?: TestAPIOpts
50
- ) => {
27
+ requestPasswordReset = async (sendMailMock: any) => {
51
28
  await this.config.saveSmtpConfig()
52
29
  await this.config.saveSettingsConfig()
53
-
30
+ await this.config.createUser()
54
31
  const res = await this.request
55
32
  .post(`/api/global/auth/${this.config.getTenantId()}/reset`)
56
33
  .send({
57
- email: email,
34
+ email: "test@test.com",
58
35
  })
59
36
  .expect("Content-Type", /json/)
60
- .expect(opts?.status ? opts.status : 200)
61
-
62
- let code: string | undefined
63
- if (res.status === 200) {
64
- const emailCall = sendMailMock.mock.calls[0][0]
65
- const parts = emailCall.html.split(
66
- `http://localhost:10000/builder/auth/reset?code=`
67
- )
68
- code = parts[1].split('"')[0].split("&")[0]
69
- }
70
-
37
+ .expect(200)
38
+ const emailCall = sendMailMock.mock.calls[0][0]
39
+ const parts = emailCall.html.split(
40
+ `http://localhost:10000/builder/auth/reset?code=`
41
+ )
42
+ const code = parts[1].split('"')[0].split("&")[0]
71
43
  return { code, res }
72
44
  }
73
45
  }
@@ -1,5 +1,4 @@
1
1
  import TestConfiguration from "../TestConfiguration"
2
- import { SuperTest, Test } from "supertest"
3
2
 
4
3
  export interface TestAPIOpts {
5
4
  headers?: any
@@ -8,7 +7,7 @@ export interface TestAPIOpts {
8
7
 
9
8
  export abstract class TestAPI {
10
9
  config: TestConfiguration
11
- request: SuperTest<Test>
10
+ request: any
12
11
 
13
12
  protected constructor(config: TestConfiguration) {
14
13
  this.config = config
@@ -10,8 +10,8 @@ export class ConfigAPI extends TestAPI {
10
10
  return this.request
11
11
  .get(`/api/global/configs/checklist`)
12
12
  .set(this.config.defaultHeaders())
13
- .expect(200)
14
13
  .expect("Content-Type", /json/)
14
+ .expect(200)
15
15
  }
16
16
 
17
17
  saveConfig = (data: any) => {
@@ -19,8 +19,8 @@ export class ConfigAPI extends TestAPI {
19
19
  .post(`/api/global/configs`)
20
20
  .send(data)
21
21
  .set(this.config.defaultHeaders())
22
- .expect(200)
23
22
  .expect("Content-Type", /json/)
23
+ .expect(200)
24
24
  }
25
25
 
26
26
  OIDCCallback = (configId: string, preAuthRes: any) => {
@@ -9,7 +9,6 @@ export class RestoreAPI extends TestAPI {
9
9
  restored = (opts?: TestAPIOpts) => {
10
10
  return this.request
11
11
  .post(`/api/system/restored`)
12
- .set(this.config.tenantIdHeaders())
13
12
  .expect(opts?.status ? opts.status : 200)
14
13
  }
15
14
  }
@@ -26,8 +26,8 @@ export class UserAPI extends TestAPI {
26
26
  email,
27
27
  })
28
28
  .set(this.config.defaultHeaders())
29
- .expect(status)
30
29
  .expect("Content-Type", /json/)
30
+ .expect(status)
31
31
 
32
32
  if (status !== 200) {
33
33
  return { code: undefined, res }
@@ -100,7 +100,7 @@ export class UserAPI extends TestAPI {
100
100
  request = {
101
101
  email: structures.email(),
102
102
  password: generator.string(),
103
- tenantId: structures.tenant.id(),
103
+ tenantId: structures.uuid(),
104
104
  }
105
105
  }
106
106
  const res = await this.request
@@ -1,8 +1,7 @@
1
1
  process.env.SELF_HOSTED = "0"
2
2
  process.env.NODE_ENV = "jest"
3
3
  process.env.JWT_SECRET = "test-jwtsecret"
4
- process.env.LOG_LEVEL = process.env.LOG_LEVEL || "error"
5
- process.env.ENABLE_4XX_HTTP_LOGGING = "0"
4
+ process.env.LOG_LEVEL = "silent"
6
5
  process.env.MULTI_TENANCY = "1"
7
6
  process.env.MINIO_URL = "http://localhost"
8
7
  process.env.MINIO_ACCESS_KEY = "test"
@@ -1,8 +1,4 @@
1
- import "./logging"
2
-
3
- import { mocks, testContainerUtils } from "@budibase/backend-core/tests"
4
- import env from "../environment"
5
- import { env as coreEnv } from "@budibase/backend-core"
1
+ import { mocks } from "@budibase/backend-core/tests"
6
2
 
7
3
  // must explicitly enable fetch mock
8
4
  mocks.fetch.enable()
@@ -12,12 +8,12 @@ mocks.fetch.enable()
12
8
  const tk = require("timekeeper")
13
9
  tk.freeze(mocks.date.MOCK_DATE)
14
10
 
11
+ if (!process.env.DEBUG) {
12
+ global.console.log = jest.fn() // console.log are ignored in tests
13
+ }
14
+
15
15
  if (!process.env.CI) {
16
16
  // set a longer timeout in dev for debugging
17
17
  // 100 seconds
18
- jest.setTimeout(100 * 1000)
19
- } else {
20
- jest.setTimeout(10 * 1000)
18
+ jest.setTimeout(100000)
21
19
  }
22
-
23
- testContainerUtils.setupEnv(env, coreEnv)
@@ -1,16 +1,20 @@
1
1
  import { structures } from "@budibase/backend-core/tests"
2
2
  import * as configs from "./configs"
3
+ import * as users from "./users"
3
4
  import * as groups from "./groups"
4
5
  import { v4 as uuid } from "uuid"
5
6
 
6
7
  export const TENANT_ID = "default"
8
+ export const TENANT_1 = "tenant1"
7
9
  export const CSRF_TOKEN = "e3727778-7af0-4226-b5eb-f43cbe60a306"
8
10
 
9
11
  const pkg = {
10
12
  ...structures,
11
13
  uuid,
12
14
  configs,
15
+ users,
13
16
  TENANT_ID,
17
+ TENANT_1,
14
18
  CSRF_TOKEN,
15
19
  groups,
16
20
  }
@@ -0,0 +1,37 @@
1
+ export const email = "test@test.com"
2
+ import { AdminUser, BuilderUser, User } from "@budibase/types"
3
+ import { v4 as uuid } from "uuid"
4
+
5
+ export const newEmail = () => {
6
+ return `${uuid()}@test.com`
7
+ }
8
+
9
+ export const user = (userProps?: any): User => {
10
+ return {
11
+ email: newEmail(),
12
+ password: "test",
13
+ roles: { app_test: "admin" },
14
+ ...userProps,
15
+ }
16
+ }
17
+
18
+ export const adminUser = (userProps?: any): AdminUser => {
19
+ return {
20
+ ...user(userProps),
21
+ admin: {
22
+ global: true,
23
+ },
24
+ builder: {
25
+ global: true,
26
+ },
27
+ }
28
+ }
29
+
30
+ export const builderUser = (userProps?: any): BuilderUser => {
31
+ return {
32
+ ...user(userProps),
33
+ builder: {
34
+ global: true,
35
+ },
36
+ }
37
+ }
@@ -26,7 +26,7 @@ type SendEmailOpts = {
26
26
  automation?: boolean
27
27
  }
28
28
 
29
- const TEST_MODE = env.ENABLE_EMAIL_TEST_MODE && env.isDev()
29
+ const TEST_MODE = false
30
30
  const TYPE = TemplateType.EMAIL
31
31
 
32
32
  const FULL_EMAIL_PURPOSES = [
@@ -62,8 +62,8 @@ function createSMTPTransport(config: any) {
62
62
  host: "smtp.ethereal.email",
63
63
  secure: false,
64
64
  auth: {
65
- user: "wyatt.zulauf29@ethereal.email",
66
- pass: "tEwDtHBWWxusVWAPfa",
65
+ user: "don.bahringer@ethereal.email",
66
+ pass: "yCKSH8rWyUPbnhGYk9",
67
67
  },
68
68
  }
69
69
  }
@@ -54,8 +54,6 @@ export async function init() {
54
54
  export async function shutdown() {
55
55
  if (pwResetClient) await pwResetClient.finish()
56
56
  if (invitationClient) await invitationClient.finish()
57
- // shutdown core clients
58
- await redis.clients.shutdown()
59
57
  console.log("Redis shutdown")
60
58
  }
61
59