@budibase/worker 2.1.40-alpha.4 → 2.1.41

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 (208) hide show
  1. package/package.json +24 -14
  2. package/{src/tests/jestSetup.ts → scripts/jestSetup.js} +3 -12
  3. package/scripts/localdomain.js +7 -33
  4. package/src/api/controllers/global/auth.ts +43 -51
  5. package/src/api/controllers/global/{configs.ts → configs.js} +114 -119
  6. package/src/api/controllers/global/{email.ts → email.js} +5 -6
  7. package/src/api/controllers/global/roles.js +68 -0
  8. package/src/api/controllers/global/self.ts +2 -2
  9. package/src/api/controllers/global/users.ts +2 -4
  10. package/src/api/controllers/global/{workspaces.ts → workspaces.js} +18 -15
  11. package/src/api/controllers/system/{environment.ts → environment.js} +2 -3
  12. package/src/api/controllers/system/restore.ts +1 -1
  13. package/src/api/controllers/system/{status.ts → status.js} +3 -4
  14. package/src/api/controllers/system/tenants.ts +51 -8
  15. package/src/api/index.ts +8 -31
  16. package/src/api/routes/global/{auth.ts → auth.js} +48 -31
  17. package/src/api/routes/global/{configs.ts → configs.js} +23 -22
  18. package/src/api/routes/global/{email.ts → email.js} +10 -9
  19. package/src/api/routes/global/license.ts +1 -1
  20. package/src/api/routes/global/roles.js +12 -0
  21. package/src/api/routes/global/self.ts +2 -2
  22. package/src/api/routes/global/templates.ts +4 -4
  23. package/src/api/routes/global/tests/auth.spec.ts +64 -134
  24. package/src/api/routes/global/tests/configs.spec.ts +35 -34
  25. package/src/api/routes/global/tests/email.spec.ts +3 -4
  26. package/src/api/routes/global/tests/realEmail.spec.ts +3 -2
  27. package/src/api/routes/global/tests/self.spec.ts +4 -3
  28. package/src/api/routes/global/tests/users.spec.ts +59 -51
  29. package/src/api/routes/global/{users.ts → users.js} +32 -26
  30. package/src/api/routes/global/{workspaces.ts → workspaces.js} +10 -9
  31. package/src/api/routes/index.ts +1 -2
  32. package/src/api/routes/system/accounts.ts +1 -1
  33. package/src/api/routes/system/environment.js +8 -0
  34. package/src/api/routes/system/migrations.ts +1 -1
  35. package/src/api/routes/system/restore.ts +1 -1
  36. package/src/api/routes/system/status.js +8 -0
  37. package/src/api/routes/system/tenants.js +12 -0
  38. package/src/api/routes/system/tests/accounts.spec.ts +6 -5
  39. package/src/api/routes/validation/users.ts +3 -3
  40. package/src/constants/{index.ts → index.js} +64 -57
  41. package/src/constants/templates/{index.ts → index.js} +19 -23
  42. package/src/db/index.js +11 -0
  43. package/src/environment.ts +7 -9
  44. package/src/index.ts +16 -15
  45. package/src/middleware/{cloudRestricted.ts → cloudRestricted.js} +4 -5
  46. package/src/tests/TestConfiguration.ts +50 -99
  47. package/src/tests/api/accounts.ts +8 -5
  48. package/src/tests/api/auth.ts +6 -3
  49. package/src/tests/api/configs.ts +8 -15
  50. package/src/tests/api/email.ts +6 -3
  51. package/src/tests/api/index.ts +0 -15
  52. package/src/tests/api/self.ts +6 -11
  53. package/src/tests/api/users.ts +8 -40
  54. package/src/tests/controllers.js +7 -0
  55. package/src/tests/index.ts +1 -5
  56. package/src/tests/structures/accounts.ts +24 -0
  57. package/src/tests/structures/{configs.ts → configs.js} +11 -11
  58. package/src/tests/structures/index.ts +3 -5
  59. package/src/tests/structures/users.ts +0 -1
  60. package/src/utilities/appService.js +33 -0
  61. package/src/utilities/{email.ts → email.js} +45 -78
  62. package/src/utilities/fileSystem.js +5 -0
  63. package/src/utilities/{index.ts → index.js} +1 -1
  64. package/src/utilities/{redis.ts → redis.js} +24 -29
  65. package/src/utilities/templates.js +49 -0
  66. package/src/utilities/users.js +17 -0
  67. package/tsconfig.build.json +3 -2
  68. package/tsconfig.json +1 -3
  69. package/__mocks__/aws-sdk.ts +0 -15
  70. package/__mocks__/oauth.ts +0 -57
  71. package/coverage/clover.xml +0 -2153
  72. package/coverage/coverage-final.json +0 -78
  73. package/coverage/lcov-report/base.css +0 -224
  74. package/coverage/lcov-report/block-navigation.js +0 -87
  75. package/coverage/lcov-report/favicon.png +0 -0
  76. package/coverage/lcov-report/index.html +0 -431
  77. package/coverage/lcov-report/prettify.css +0 -1
  78. package/coverage/lcov-report/prettify.js +0 -2
  79. package/coverage/lcov-report/sort-arrow-sprite.png +0 -0
  80. package/coverage/lcov-report/sorter.js +0 -196
  81. package/coverage/lcov-report/src/api/controllers/global/auth.ts.html +0 -925
  82. package/coverage/lcov-report/src/api/controllers/global/configs.ts.html +0 -1405
  83. package/coverage/lcov-report/src/api/controllers/global/email.ts.html +0 -196
  84. package/coverage/lcov-report/src/api/controllers/global/index.html +0 -236
  85. package/coverage/lcov-report/src/api/controllers/global/license.ts.html +0 -187
  86. package/coverage/lcov-report/src/api/controllers/global/roles.ts.html +0 -283
  87. package/coverage/lcov-report/src/api/controllers/global/self.ts.html +0 -577
  88. package/coverage/lcov-report/src/api/controllers/global/templates.ts.html +0 -316
  89. package/coverage/lcov-report/src/api/controllers/global/users.ts.html +0 -796
  90. package/coverage/lcov-report/src/api/controllers/global/workspaces.ts.html +0 -244
  91. package/coverage/lcov-report/src/api/controllers/system/accounts.ts.html +0 -148
  92. package/coverage/lcov-report/src/api/controllers/system/environment.ts.html +0 -124
  93. package/coverage/lcov-report/src/api/controllers/system/index.html +0 -191
  94. package/coverage/lcov-report/src/api/controllers/system/migrations.ts.html +0 -124
  95. package/coverage/lcov-report/src/api/controllers/system/restore.ts.html +0 -124
  96. package/coverage/lcov-report/src/api/controllers/system/status.ts.html +0 -133
  97. package/coverage/lcov-report/src/api/controllers/system/tenants.ts.html +0 -154
  98. package/coverage/lcov-report/src/api/index.html +0 -116
  99. package/coverage/lcov-report/src/api/index.ts.html +0 -583
  100. package/coverage/lcov-report/src/api/routes/global/auth.ts.html +0 -349
  101. package/coverage/lcov-report/src/api/routes/global/configs.ts.html +0 -457
  102. package/coverage/lcov-report/src/api/routes/global/email.ts.html +0 -193
  103. package/coverage/lcov-report/src/api/routes/global/index.html +0 -236
  104. package/coverage/lcov-report/src/api/routes/global/license.ts.html +0 -124
  105. package/coverage/lcov-report/src/api/routes/global/roles.ts.html +0 -133
  106. package/coverage/lcov-report/src/api/routes/global/self.ts.html +0 -139
  107. package/coverage/lcov-report/src/api/routes/global/templates.ts.html +0 -196
  108. package/coverage/lcov-report/src/api/routes/global/users.ts.html +0 -409
  109. package/coverage/lcov-report/src/api/routes/global/workspaces.ts.html +0 -196
  110. package/coverage/lcov-report/src/api/routes/index.html +0 -116
  111. package/coverage/lcov-report/src/api/routes/index.ts.html +0 -196
  112. package/coverage/lcov-report/src/api/routes/system/accounts.ts.html +0 -142
  113. package/coverage/lcov-report/src/api/routes/system/environment.ts.html +0 -109
  114. package/coverage/lcov-report/src/api/routes/system/index.html +0 -191
  115. package/coverage/lcov-report/src/api/routes/system/migrations.ts.html +0 -142
  116. package/coverage/lcov-report/src/api/routes/system/restore.ts.html +0 -109
  117. package/coverage/lcov-report/src/api/routes/system/status.ts.html +0 -109
  118. package/coverage/lcov-report/src/api/routes/system/tenants.ts.html +0 -124
  119. package/coverage/lcov-report/src/api/routes/validation/index.html +0 -131
  120. package/coverage/lcov-report/src/api/routes/validation/index.ts.html +0 -88
  121. package/coverage/lcov-report/src/api/routes/validation/users.ts.html +0 -235
  122. package/coverage/lcov-report/src/constants/index.html +0 -116
  123. package/coverage/lcov-report/src/constants/index.ts.html +0 -613
  124. package/coverage/lcov-report/src/constants/templates/index.html +0 -116
  125. package/coverage/lcov-report/src/constants/templates/index.ts.html +0 -316
  126. package/coverage/lcov-report/src/db/index.html +0 -116
  127. package/coverage/lcov-report/src/db/index.ts.html +0 -115
  128. package/coverage/lcov-report/src/environment.ts.html +0 -373
  129. package/coverage/lcov-report/src/index.html +0 -131
  130. package/coverage/lcov-report/src/index.ts.html +0 -394
  131. package/coverage/lcov-report/src/middleware/cloudRestricted.ts.html +0 -139
  132. package/coverage/lcov-report/src/middleware/index.html +0 -116
  133. package/coverage/lcov-report/src/migrations/functions/globalInfoSyncUsers.ts.html +0 -145
  134. package/coverage/lcov-report/src/migrations/functions/index.html +0 -116
  135. package/coverage/lcov-report/src/migrations/index.html +0 -116
  136. package/coverage/lcov-report/src/migrations/index.ts.html +0 -271
  137. package/coverage/lcov-report/src/sdk/accounts/accounts.ts.html +0 -262
  138. package/coverage/lcov-report/src/sdk/accounts/index.html +0 -131
  139. package/coverage/lcov-report/src/sdk/accounts/index.ts.html +0 -88
  140. package/coverage/lcov-report/src/sdk/index.html +0 -116
  141. package/coverage/lcov-report/src/sdk/index.ts.html +0 -106
  142. package/coverage/lcov-report/src/sdk/users/events.ts.html +0 -577
  143. package/coverage/lcov-report/src/sdk/users/index.html +0 -146
  144. package/coverage/lcov-report/src/sdk/users/index.ts.html +0 -88
  145. package/coverage/lcov-report/src/sdk/users/users.ts.html +0 -1903
  146. package/coverage/lcov-report/src/tests/TestConfiguration.ts.html +0 -1051
  147. package/coverage/lcov-report/src/tests/api/accounts.ts.html +0 -160
  148. package/coverage/lcov-report/src/tests/api/auth.ts.html +0 -220
  149. package/coverage/lcov-report/src/tests/api/base.ts.html +0 -133
  150. package/coverage/lcov-report/src/tests/api/configs.ts.html +0 -226
  151. package/coverage/lcov-report/src/tests/api/email.ts.html +0 -148
  152. package/coverage/lcov-report/src/tests/api/environment.ts.html +0 -130
  153. package/coverage/lcov-report/src/tests/api/index.html +0 -296
  154. package/coverage/lcov-report/src/tests/api/index.ts.html +0 -205
  155. package/coverage/lcov-report/src/tests/api/migrations.ts.html +0 -151
  156. package/coverage/lcov-report/src/tests/api/restore.ts.html +0 -127
  157. package/coverage/lcov-report/src/tests/api/self.ts.html +0 -163
  158. package/coverage/lcov-report/src/tests/api/status.ts.html +0 -121
  159. package/coverage/lcov-report/src/tests/api/tenants.ts.html +0 -130
  160. package/coverage/lcov-report/src/tests/api/users.ts.html +0 -511
  161. package/coverage/lcov-report/src/tests/controllers.ts.html +0 -100
  162. package/coverage/lcov-report/src/tests/index.html +0 -146
  163. package/coverage/lcov-report/src/tests/index.ts.html +0 -139
  164. package/coverage/lcov-report/src/tests/mocks/email.js.html +0 -115
  165. package/coverage/lcov-report/src/tests/mocks/index.html +0 -131
  166. package/coverage/lcov-report/src/tests/mocks/index.ts.html +0 -106
  167. package/coverage/lcov-report/src/tests/structures/configs.ts.html +0 -313
  168. package/coverage/lcov-report/src/tests/structures/groups.ts.html +0 -118
  169. package/coverage/lcov-report/src/tests/structures/index.html +0 -161
  170. package/coverage/lcov-report/src/tests/structures/index.ts.html +0 -151
  171. package/coverage/lcov-report/src/tests/structures/users.ts.html +0 -196
  172. package/coverage/lcov-report/src/utilities/appService.ts.html +0 -181
  173. package/coverage/lcov-report/src/utilities/email.ts.html +0 -850
  174. package/coverage/lcov-report/src/utilities/fileSystem.ts.html +0 -100
  175. package/coverage/lcov-report/src/utilities/index.html +0 -206
  176. package/coverage/lcov-report/src/utilities/index.ts.html +0 -112
  177. package/coverage/lcov-report/src/utilities/redis.ts.html +0 -424
  178. package/coverage/lcov-report/src/utilities/templates.ts.html +0 -232
  179. package/coverage/lcov-report/src/utilities/users.ts.html +0 -133
  180. package/coverage/lcov.info +0 -3958
  181. package/jest.config.ts +0 -29
  182. package/src/api/controllers/global/roles.ts +0 -66
  183. package/src/api/routes/global/roles.ts +0 -16
  184. package/src/api/routes/global/tests/license.spec.ts +0 -31
  185. package/src/api/routes/global/tests/roles.spec.ts +0 -27
  186. package/src/api/routes/global/tests/templates.spec.ts +0 -35
  187. package/src/api/routes/global/tests/workspaces.spec.ts +0 -29
  188. package/src/api/routes/system/environment.ts +0 -8
  189. package/src/api/routes/system/status.ts +0 -8
  190. package/src/api/routes/system/tenants.ts +0 -13
  191. package/src/api/routes/system/tests/environment.spec.ts +0 -29
  192. package/src/api/routes/system/tests/migrations.spec.ts +0 -63
  193. package/src/api/routes/system/tests/restore.spec.ts +0 -36
  194. package/src/api/routes/system/tests/status.spec.ts +0 -48
  195. package/src/api/routes/system/tests/tenants.spec.ts +0 -61
  196. package/src/db/index.ts +0 -10
  197. package/src/middleware/tests/tenancy.spec.ts +0 -73
  198. package/src/tests/api/base.ts +0 -16
  199. package/src/tests/api/environment.ts +0 -15
  200. package/src/tests/api/migrations.ts +0 -22
  201. package/src/tests/api/restore.ts +0 -14
  202. package/src/tests/api/status.ts +0 -12
  203. package/src/tests/api/tenants.ts +0 -15
  204. package/src/tests/controllers.ts +0 -5
  205. package/src/utilities/appService.ts +0 -32
  206. package/src/utilities/fileSystem.ts +0 -5
  207. package/src/utilities/templates.ts +0 -49
  208. package/src/utilities/users.ts +0 -16
@@ -6,12 +6,14 @@ import {
6
6
  mocks,
7
7
  structures,
8
8
  TENANT_1,
9
+ API,
9
10
  } from "../../../../tests"
10
11
  const sendMailMock = mocks.email.mock()
11
12
  import { events, tenancy } from "@budibase/backend-core"
12
13
 
13
14
  describe("/api/global/users", () => {
14
15
  const config = new TestConfiguration()
16
+ const api = new API(config)
15
17
 
16
18
  beforeAll(async () => {
17
19
  await config.beforeAll()
@@ -28,10 +30,7 @@ describe("/api/global/users", () => {
28
30
  describe("invite", () => {
29
31
  it("should be able to generate an invitation", async () => {
30
32
  const email = structures.users.newEmail()
31
- const { code, res } = await config.api.users.sendUserInvite(
32
- sendMailMock,
33
- email
34
- )
33
+ const { code, res } = await api.users.sendUserInvite(sendMailMock, email)
35
34
 
36
35
  expect(res.body).toEqual({ message: "Invitation has been sent." })
37
36
  expect(sendMailMock).toHaveBeenCalled()
@@ -40,7 +39,7 @@ describe("/api/global/users", () => {
40
39
  })
41
40
 
42
41
  it("should not be able to generate an invitation for existing user", async () => {
43
- const { code, res } = await config.api.users.sendUserInvite(
42
+ const { code, res } = await api.users.sendUserInvite(
44
43
  sendMailMock,
45
44
  config.defaultUser!.email,
46
45
  400
@@ -54,12 +53,9 @@ describe("/api/global/users", () => {
54
53
 
55
54
  it("should be able to create new user from invite", async () => {
56
55
  const email = structures.users.newEmail()
57
- const { code } = await config.api.users.sendUserInvite(
58
- sendMailMock,
59
- email
60
- )
56
+ const { code } = await api.users.sendUserInvite(sendMailMock, email)
61
57
 
62
- const res = await config.api.users.acceptInvite(code)
58
+ const res = await api.users.acceptInvite(code)
63
59
 
64
60
  expect(res.body._id).toBeDefined()
65
61
  const user = await config.getUser(email)
@@ -78,7 +74,7 @@ describe("/api/global/users", () => {
78
74
  })
79
75
  const request = [newUserInvite(), newUserInvite()]
80
76
 
81
- const res = await config.api.users.sendMultiUserInvite(request)
77
+ const res = await api.users.sendMultiUserInvite(request)
82
78
 
83
79
  const body = res.body as InviteUsersResponse
84
80
  expect(body.successful.length).toBe(2)
@@ -90,7 +86,7 @@ describe("/api/global/users", () => {
90
86
  it("should not be able to generate an invitation for existing user", async () => {
91
87
  const request = [{ email: config.defaultUser!.email, userInfo: {} }]
92
88
 
93
- const res = await config.api.users.sendMultiUserInvite(request)
89
+ const res = await api.users.sendMultiUserInvite(request)
94
90
 
95
91
  const body = res.body as InviteUsersResponse
96
92
  expect(body.successful.length).toBe(0)
@@ -106,7 +102,7 @@ describe("/api/global/users", () => {
106
102
  const user = await config.createUser()
107
103
  jest.clearAllMocks()
108
104
 
109
- const response = await config.api.users.bulkCreateUsers([user])
105
+ const response = await api.users.bulkCreateUsers([user])
110
106
 
111
107
  expect(response.created?.successful.length).toBe(0)
112
108
  expect(response.created?.unsuccessful.length).toBe(1)
@@ -119,7 +115,7 @@ describe("/api/global/users", () => {
119
115
  jest.resetAllMocks()
120
116
 
121
117
  await tenancy.doInTenant(TENANT_1, async () => {
122
- const response = await config.api.users.bulkCreateUsers([user])
118
+ const response = await api.users.bulkCreateUsers([user])
123
119
 
124
120
  expect(response.created?.successful.length).toBe(0)
125
121
  expect(response.created?.unsuccessful.length).toBe(1)
@@ -130,11 +126,11 @@ describe("/api/global/users", () => {
130
126
 
131
127
  it("should ignore accounts using the same email", async () => {
132
128
  const account = structures.accounts.account()
133
- const resp = await config.api.accounts.saveMetadata(account)
129
+ const resp = await api.accounts.saveMetadata(account)
134
130
  const user = structures.users.user({ email: resp.email })
135
131
  jest.clearAllMocks()
136
132
 
137
- const response = await config.api.users.bulkCreateUsers([user])
133
+ const response = await api.users.bulkCreateUsers([user])
138
134
 
139
135
  expect(response.created?.successful.length).toBe(0)
140
136
  expect(response.created?.unsuccessful.length).toBe(1)
@@ -147,11 +143,7 @@ describe("/api/global/users", () => {
147
143
  const admin = structures.users.adminUser()
148
144
  const user = structures.users.user()
149
145
 
150
- const response = await config.api.users.bulkCreateUsers([
151
- builder,
152
- admin,
153
- user,
154
- ])
146
+ const response = await api.users.bulkCreateUsers([builder, admin, user])
155
147
 
156
148
  expect(response.created?.successful.length).toBe(3)
157
149
  expect(response.created?.successful[0].email).toBe(builder.email)
@@ -168,7 +160,7 @@ describe("/api/global/users", () => {
168
160
  it("should be able to create a basic user", async () => {
169
161
  const user = structures.users.user()
170
162
 
171
- await config.api.users.saveUser(user)
163
+ await api.users.saveUser(user)
172
164
 
173
165
  expect(events.user.created).toBeCalledTimes(1)
174
166
  expect(events.user.updated).not.toBeCalled()
@@ -179,7 +171,7 @@ describe("/api/global/users", () => {
179
171
  it("should be able to create an admin user", async () => {
180
172
  const user = structures.users.adminUser()
181
173
 
182
- await config.api.users.saveUser(user)
174
+ await api.users.saveUser(user)
183
175
 
184
176
  expect(events.user.created).toBeCalledTimes(1)
185
177
  expect(events.user.updated).not.toBeCalled()
@@ -190,7 +182,7 @@ describe("/api/global/users", () => {
190
182
  it("should be able to create a builder user", async () => {
191
183
  const user = structures.users.builderUser()
192
184
 
193
- await config.api.users.saveUser(user)
185
+ await api.users.saveUser(user)
194
186
 
195
187
  expect(events.user.created).toBeCalledTimes(1)
196
188
  expect(events.user.updated).not.toBeCalled()
@@ -205,7 +197,7 @@ describe("/api/global/users", () => {
205
197
  app_456: "role2",
206
198
  }
207
199
 
208
- await config.api.users.saveUser(user)
200
+ await api.users.saveUser(user)
209
201
 
210
202
  const savedUser = await config.getUser(user.email)
211
203
  expect(events.user.created).toBeCalledTimes(1)
@@ -221,7 +213,7 @@ describe("/api/global/users", () => {
221
213
  delete user._id
222
214
  delete user._rev
223
215
 
224
- const response = await config.api.users.saveUser(user, 400)
216
+ const response = await api.users.saveUser(user, 400)
225
217
 
226
218
  expect(response.body.message).toBe(`Unavailable`)
227
219
  expect(events.user.created).toBeCalledTimes(0)
@@ -233,7 +225,7 @@ describe("/api/global/users", () => {
233
225
 
234
226
  await tenancy.doInTenant(TENANT_1, async () => {
235
227
  delete user._id
236
- const response = await config.api.users.saveUser(user, 400)
228
+ const response = await api.users.saveUser(user, 400)
237
229
 
238
230
  expect(response.body.message).toBe(`Unavailable`)
239
231
  expect(events.user.created).toBeCalledTimes(0)
@@ -245,7 +237,7 @@ describe("/api/global/users", () => {
245
237
  const account = structures.accounts.cloudAccount()
246
238
  mocks.accounts.getAccount.mockReturnValueOnce(account)
247
239
 
248
- const response = await config.api.users.saveUser(user, 400)
240
+ const response = await api.users.saveUser(user, 400)
249
241
 
250
242
  expect(response.body.message).toBe(`Unavailable`)
251
243
  expect(events.user.created).toBeCalledTimes(0)
@@ -253,23 +245,31 @@ describe("/api/global/users", () => {
253
245
 
254
246
  it("should not be able to create a user with the same email and different casing", async () => {
255
247
  const user = structures.users.user()
256
- await config.api.users.saveUser(user)
248
+ await api.users.saveUser(user)
257
249
 
258
250
  user.email = user.email.toUpperCase()
259
- await config.api.users.saveUser(user, 400)
251
+ await api.users.saveUser(user, 400)
260
252
 
261
253
  expect(events.user.created).toBeCalledTimes(1)
262
254
  })
263
255
 
264
256
  it("should not be able to bulk create a user with the same email and different casing", async () => {
265
257
  const user = structures.users.user()
266
- await config.api.users.saveUser(user)
258
+ await api.users.saveUser(user)
267
259
 
268
260
  user.email = user.email.toUpperCase()
269
- await config.api.users.bulkCreateUsers([user])
261
+ await api.users.bulkCreateUsers([user])
270
262
 
271
263
  expect(events.user.created).toBeCalledTimes(1)
272
264
  })
265
+
266
+ it("should not allow a non-admin user to create a new user", async () => {
267
+ const nonAdmin = await config.createUser(structures.users.builderUser())
268
+ await config.createSession(nonAdmin)
269
+
270
+ const newUser = structures.users.user()
271
+ await api.users.saveUser(newUser, 403, config.authHeaders(nonAdmin))
272
+ })
273
273
  })
274
274
 
275
275
  describe("update", () => {
@@ -277,7 +277,7 @@ describe("/api/global/users", () => {
277
277
  const user = await config.createUser()
278
278
  jest.clearAllMocks()
279
279
 
280
- await config.api.users.saveUser(user)
280
+ await api.users.saveUser(user)
281
281
 
282
282
  expect(events.user.created).not.toBeCalled()
283
283
  expect(events.user.updated).toBeCalledTimes(1)
@@ -292,7 +292,7 @@ describe("/api/global/users", () => {
292
292
 
293
293
  user.forceResetPassword = true
294
294
  user.password = "tempPassword"
295
- await config.api.users.saveUser(user)
295
+ await api.users.saveUser(user)
296
296
 
297
297
  expect(events.user.created).not.toBeCalled()
298
298
  expect(events.user.updated).toBeCalledTimes(1)
@@ -305,7 +305,7 @@ describe("/api/global/users", () => {
305
305
  const user = await config.createUser()
306
306
  jest.clearAllMocks()
307
307
 
308
- await config.api.users.saveUser(structures.users.adminUser(user))
308
+ await api.users.saveUser(structures.users.adminUser(user))
309
309
 
310
310
  expect(events.user.created).not.toBeCalled()
311
311
  expect(events.user.updated).toBeCalledTimes(1)
@@ -317,7 +317,7 @@ describe("/api/global/users", () => {
317
317
  const user = await config.createUser()
318
318
  jest.clearAllMocks()
319
319
 
320
- await config.api.users.saveUser(structures.users.builderUser(user))
320
+ await api.users.saveUser(structures.users.builderUser(user))
321
321
 
322
322
  expect(events.user.created).not.toBeCalled()
323
323
  expect(events.user.updated).toBeCalledTimes(1)
@@ -331,7 +331,7 @@ describe("/api/global/users", () => {
331
331
  user.admin!.global = false
332
332
  user.builder!.global = false
333
333
 
334
- await config.api.users.saveUser(user)
334
+ await api.users.saveUser(user)
335
335
 
336
336
  expect(events.user.created).not.toBeCalled()
337
337
  expect(events.user.updated).toBeCalledTimes(1)
@@ -344,7 +344,7 @@ describe("/api/global/users", () => {
344
344
  jest.clearAllMocks()
345
345
  user.builder!.global = false
346
346
 
347
- await config.api.users.saveUser(user)
347
+ await api.users.saveUser(user)
348
348
 
349
349
  expect(events.user.created).not.toBeCalled()
350
350
  expect(events.user.updated).toBeCalledTimes(1)
@@ -360,7 +360,7 @@ describe("/api/global/users", () => {
360
360
  app_456: "role2",
361
361
  }
362
362
 
363
- await config.api.users.saveUser(user)
363
+ await api.users.saveUser(user)
364
364
 
365
365
  const savedUser = await config.getUser(user.email)
366
366
  expect(events.user.created).not.toBeCalled()
@@ -380,7 +380,7 @@ describe("/api/global/users", () => {
380
380
  jest.clearAllMocks()
381
381
  user.roles = {}
382
382
 
383
- await config.api.users.saveUser(user)
383
+ await api.users.saveUser(user)
384
384
 
385
385
  const savedUser = await config.getUser(user.email)
386
386
  expect(events.user.created).not.toBeCalled()
@@ -403,7 +403,7 @@ describe("/api/global/users", () => {
403
403
  app_456: "role2-edit",
404
404
  }
405
405
 
406
- await config.api.users.saveUser(user)
406
+ await api.users.saveUser(user)
407
407
 
408
408
  const savedUser = await config.getUser(user.email)
409
409
  expect(events.user.created).not.toBeCalled()
@@ -419,20 +419,28 @@ describe("/api/global/users", () => {
419
419
  const user = await config.createUser(structures.users.user({ email }))
420
420
  user.email = "new@test.com"
421
421
 
422
- const response = await config.api.users.saveUser(user, 400)
422
+ const response = await api.users.saveUser(user, 400)
423
423
 
424
424
  const dbUser = await config.getUser(email)
425
425
  user.email = email
426
426
  expect(user).toStrictEqual(dbUser)
427
427
  expect(response.body.message).toBe("Email address cannot be changed")
428
428
  })
429
+
430
+ it("should allow a non-admin user to update an existing user", async () => {
431
+ const existingUser = await config.createUser(structures.users.user())
432
+ const nonAdmin = await config.createUser(structures.users.builderUser())
433
+ await config.createSession(nonAdmin)
434
+
435
+ await api.users.saveUser(existingUser, 200, config.authHeaders(nonAdmin))
436
+ })
429
437
  })
430
438
 
431
439
  describe("bulk (delete)", () => {
432
440
  it("should not be able to bulk delete current user", async () => {
433
441
  const user = await config.defaultUser!
434
442
 
435
- const response = await config.api.users.bulkDeleteUsers([user._id!], 400)
443
+ const response = await api.users.bulkDeleteUsers([user._id!], 400)
436
444
 
437
445
  expect(response.message).toBe("Unable to delete self.")
438
446
  expect(events.user.deleted).not.toBeCalled()
@@ -444,7 +452,7 @@ describe("/api/global/users", () => {
444
452
  account.budibaseUserId = user._id!
445
453
  mocks.accounts.getAccountByTenantId.mockReturnValue(account)
446
454
 
447
- const response = await config.api.users.bulkDeleteUsers([user._id!])
455
+ const response = await api.users.bulkDeleteUsers([user._id!])
448
456
 
449
457
  expect(response.deleted?.successful.length).toBe(0)
450
458
  expect(response.deleted?.unsuccessful.length).toBe(1)
@@ -462,7 +470,7 @@ describe("/api/global/users", () => {
462
470
  const builder = structures.users.builderUser()
463
471
  const admin = structures.users.adminUser()
464
472
  const user = structures.users.user()
465
- const createdUsers = await config.api.users.bulkCreateUsers([
473
+ const createdUsers = await api.users.bulkCreateUsers([
466
474
  builder,
467
475
  admin,
468
476
  user,
@@ -471,7 +479,7 @@ describe("/api/global/users", () => {
471
479
  const toDelete = createdUsers.created?.successful.map(
472
480
  u => u._id!
473
481
  ) as string[]
474
- const response = await config.api.users.bulkDeleteUsers(toDelete)
482
+ const response = await api.users.bulkDeleteUsers(toDelete)
475
483
 
476
484
  expect(response.deleted?.successful.length).toBe(3)
477
485
  expect(response.deleted?.unsuccessful.length).toBe(0)
@@ -486,7 +494,7 @@ describe("/api/global/users", () => {
486
494
  const user = await config.createUser()
487
495
  jest.clearAllMocks()
488
496
 
489
- await config.api.users.deleteUser(user._id!)
497
+ await api.users.deleteUser(user._id!)
490
498
 
491
499
  expect(events.user.deleted).toBeCalledTimes(1)
492
500
  expect(events.user.permissionBuilderRemoved).not.toBeCalled()
@@ -497,7 +505,7 @@ describe("/api/global/users", () => {
497
505
  const user = await config.createUser(structures.users.adminUser())
498
506
  jest.clearAllMocks()
499
507
 
500
- await config.api.users.deleteUser(user._id!)
508
+ await api.users.deleteUser(user._id!)
501
509
 
502
510
  expect(events.user.deleted).toBeCalledTimes(1)
503
511
  expect(events.user.permissionBuilderRemoved).toBeCalledTimes(1)
@@ -508,7 +516,7 @@ describe("/api/global/users", () => {
508
516
  const user = await config.createUser(structures.users.builderUser())
509
517
  jest.clearAllMocks()
510
518
 
511
- await config.api.users.deleteUser(user._id!)
519
+ await api.users.deleteUser(user._id!)
512
520
 
513
521
  expect(events.user.deleted).toBeCalledTimes(1)
514
522
  expect(events.user.permissionBuilderRemoved).toBeCalledTimes(1)
@@ -520,7 +528,7 @@ describe("/api/global/users", () => {
520
528
  const account = structures.accounts.cloudAccount()
521
529
  mocks.accounts.getAccount.mockReturnValueOnce(account)
522
530
 
523
- const response = await config.api.users.deleteUser(user._id!, 400)
531
+ const response = await api.users.deleteUser(user._id!, 400)
524
532
 
525
533
  expect(response.body.message).toBe("Account holder cannot be deleted")
526
534
  })
@@ -531,7 +539,7 @@ describe("/api/global/users", () => {
531
539
  account.email = user.email
532
540
  mocks.accounts.getAccount.mockReturnValueOnce(account)
533
541
 
534
- const response = await config.api.users.deleteUser(user._id!, 400)
542
+ const response = await api.users.deleteUser(user._id!, 400)
535
543
 
536
544
  expect(response.body.message).toBe("Unable to delete self.")
537
545
  })
@@ -1,15 +1,17 @@
1
- import Router from "@koa/router"
2
- import * as controller from "../../controllers/global/users"
3
- import { auth } from "@budibase/backend-core"
4
- import Joi from "joi"
5
- import cloudRestricted from "../../../middleware/cloudRestricted"
6
- import { users } from "../validation"
7
- import * as selfController from "../../controllers/global/self"
1
+ const Router = require("@koa/router")
2
+ const controller = require("../../controllers/global/users")
3
+ const { joiValidator } = require("@budibase/backend-core/auth")
4
+ const { adminOnly } = require("@budibase/backend-core/auth")
5
+ const Joi = require("joi")
6
+ const cloudRestricted = require("../../../middleware/cloudRestricted")
7
+ const { users } = require("../validation")
8
+ const selfController = require("../../controllers/global/self")
9
+ const { builderOrAdmin } = require("@budibase/backend-core/auth")
8
10
 
9
- const router: Router = new Router()
11
+ const router = new Router()
10
12
 
11
13
  function buildAdminInitValidation() {
12
- return auth.joiValidator.body(
14
+ return joiValidator.body(
13
15
  Joi.object({
14
16
  email: Joi.string().required(),
15
17
  password: Joi.string(),
@@ -22,7 +24,7 @@ function buildAdminInitValidation() {
22
24
 
23
25
  function buildInviteValidation() {
24
26
  // prettier-ignore
25
- return auth.joiValidator.body(Joi.object({
27
+ return joiValidator.body(Joi.object({
26
28
  email: Joi.string().required(),
27
29
  userInfo: Joi.object().optional(),
28
30
  }).required())
@@ -30,7 +32,7 @@ function buildInviteValidation() {
30
32
 
31
33
  function buildInviteMultipleValidation() {
32
34
  // prettier-ignore
33
- return auth.joiValidator.body(Joi.array().required().items(
35
+ return joiValidator.body(Joi.array().required().items(
34
36
  Joi.object({
35
37
  email: Joi.string(),
36
38
  userInfo: Joi.object().optional(),
@@ -38,9 +40,17 @@ function buildInviteMultipleValidation() {
38
40
  ))
39
41
  }
40
42
 
43
+ const createUserAdminOnly = (ctx, next) => {
44
+ if (!ctx.request.body._id) {
45
+ return adminOnly(ctx, next)
46
+ } else {
47
+ return builderOrAdmin(ctx, next)
48
+ }
49
+ }
50
+
41
51
  function buildInviteAcceptValidation() {
42
52
  // prettier-ignore
43
- return auth.joiValidator.body(Joi.object({
53
+ return joiValidator.body(Joi.object({
44
54
  inviteCode: Joi.string().required(),
45
55
  password: Joi.string().required(),
46
56
  }).required().unknown(true))
@@ -49,35 +59,31 @@ function buildInviteAcceptValidation() {
49
59
  router
50
60
  .post(
51
61
  "/api/global/users",
52
- auth.adminOnly,
62
+ createUserAdminOnly,
53
63
  users.buildUserSaveValidation(),
54
64
  controller.save
55
65
  )
56
66
  .post(
57
67
  "/api/global/users/bulk",
58
- auth.adminOnly,
68
+ adminOnly,
59
69
  users.buildUserBulkUserValidation(),
60
70
  controller.bulkUpdate
61
71
  )
62
72
 
63
- .get("/api/global/users", auth.builderOrAdmin, controller.fetch)
64
- .post("/api/global/users/search", auth.builderOrAdmin, controller.search)
65
- .delete("/api/global/users/:id", auth.adminOnly, controller.destroy)
66
- .get(
67
- "/api/global/users/count/:appId",
68
- auth.builderOrAdmin,
69
- controller.countByApp
70
- )
73
+ .get("/api/global/users", builderOrAdmin, controller.fetch)
74
+ .post("/api/global/users/search", builderOrAdmin, controller.search)
75
+ .delete("/api/global/users/:id", adminOnly, controller.destroy)
76
+ .get("/api/global/users/count/:appId", builderOrAdmin, controller.countByApp)
71
77
  .get("/api/global/roles/:appId")
72
78
  .post(
73
79
  "/api/global/users/invite",
74
- auth.adminOnly,
80
+ adminOnly,
75
81
  buildInviteValidation(),
76
82
  controller.invite
77
83
  )
78
84
  .post(
79
85
  "/api/global/users/multi/invite",
80
- auth.adminOnly,
86
+ adminOnly,
81
87
  buildInviteMultipleValidation(),
82
88
  controller.inviteMultiple
83
89
  )
@@ -96,7 +102,7 @@ router
96
102
  )
97
103
  .get("/api/global/users/tenant/:id", controller.tenantUserLookup)
98
104
  // global endpoint but needs to come at end (blocks other endpoints otherwise)
99
- .get("/api/global/users/:id", auth.builderOrAdmin, controller.find)
105
+ .get("/api/global/users/:id", builderOrAdmin, controller.find)
100
106
  // DEPRECATED - use new versions with self API
101
107
  .get("/api/global/users/self", selfController.getSelf)
102
108
  .post(
@@ -105,4 +111,4 @@ router
105
111
  selfController.updateSelf
106
112
  )
107
113
 
108
- export = router
114
+ module.exports = router
@@ -1,13 +1,14 @@
1
- import Router from "@koa/router"
2
- import * as controller from "../../controllers/global/workspaces"
3
- import { auth } from "@budibase/backend-core"
4
- import Joi from "joi"
1
+ const Router = require("@koa/router")
2
+ const controller = require("../../controllers/global/workspaces")
3
+ const { joiValidator } = require("@budibase/backend-core/auth")
4
+ const { adminOnly } = require("@budibase/backend-core/auth")
5
+ const Joi = require("joi")
5
6
 
6
- const router: Router = new Router()
7
+ const router = new Router()
7
8
 
8
9
  function buildWorkspaceSaveValidation() {
9
10
  // prettier-ignore
10
- return auth.joiValidator.body(Joi.object({
11
+ return joiValidator.body(Joi.object({
11
12
  _id: Joi.string().optional(),
12
13
  _rev: Joi.string().optional(),
13
14
  name: Joi.string().required(),
@@ -26,12 +27,12 @@ function buildWorkspaceSaveValidation() {
26
27
  router
27
28
  .post(
28
29
  "/api/global/workspaces",
29
- auth.adminOnly,
30
+ adminOnly,
30
31
  buildWorkspaceSaveValidation(),
31
32
  controller.save
32
33
  )
33
- .delete("/api/global/workspaces/:id", auth.adminOnly, controller.destroy)
34
+ .delete("/api/global/workspaces/:id", adminOnly, controller.destroy)
34
35
  .get("/api/global/workspaces", controller.fetch)
35
36
  .get("/api/global/workspaces/:id", controller.find)
36
37
 
37
- export = router
38
+ module.exports = router
@@ -1,4 +1,3 @@
1
- import Router from "@koa/router"
2
1
  import { api } from "@budibase/pro"
3
2
  import userRoutes from "./global/users"
4
3
  import configRoutes from "./global/configs"
@@ -17,7 +16,7 @@ import accountRoutes from "./system/accounts"
17
16
  import restoreRoutes from "./system/restore"
18
17
 
19
18
  let userGroupRoutes = api.groups
20
- export const routes: Router[] = [
19
+ export const routes = [
21
20
  configRoutes,
22
21
  userRoutes,
23
22
  workspaceRoutes,
@@ -2,7 +2,7 @@ import Router from "@koa/router"
2
2
  import * as controller from "../../controllers/system/accounts"
3
3
  import { middleware } from "@budibase/backend-core"
4
4
 
5
- const router: Router = new Router()
5
+ const router = new Router()
6
6
 
7
7
  router
8
8
  .put(
@@ -0,0 +1,8 @@
1
+ const Router = require("@koa/router")
2
+ const controller = require("../../controllers/system/environment")
3
+
4
+ const router = new Router()
5
+
6
+ router.get("/api/system/environment", controller.fetch)
7
+
8
+ module.exports = router
@@ -2,7 +2,7 @@ import Router from "@koa/router"
2
2
  import * as migrationsController from "../../controllers/system/migrations"
3
3
  import { auth } from "@budibase/backend-core"
4
4
 
5
- const router: Router = new Router()
5
+ const router = new Router()
6
6
 
7
7
  router
8
8
  .post(
@@ -1,7 +1,7 @@
1
1
  import * as controller from "../../controllers/system/restore"
2
2
  import Router from "@koa/router"
3
3
 
4
- const router: Router = new Router()
4
+ const router = new Router()
5
5
 
6
6
  router.post("/api/system/restored", controller.systemRestored)
7
7
 
@@ -0,0 +1,8 @@
1
+ const Router = require("@koa/router")
2
+ const controller = require("../../controllers/system/status")
3
+
4
+ const router = new Router()
5
+
6
+ router.get("/api/system/status", controller.fetch)
7
+
8
+ module.exports = router
@@ -0,0 +1,12 @@
1
+ const Router = require("@koa/router")
2
+ const controller = require("../../controllers/system/tenants")
3
+ const { adminOnly } = require("@budibase/backend-core/auth")
4
+
5
+ const router = new Router()
6
+
7
+ router
8
+ .get("/api/system/tenants/:tenantId/exists", controller.exists)
9
+ .get("/api/system/tenants", adminOnly, controller.fetch)
10
+ .delete("/api/system/tenants/:tenantId", adminOnly, controller.delete)
11
+
12
+ module.exports = router
@@ -1,9 +1,10 @@
1
1
  import sdk from "../../../../sdk"
2
- import { TestConfiguration, structures } from "../../../../tests"
2
+ import { TestConfiguration, structures, API } from "../../../../tests"
3
3
  import { v4 as uuid } from "uuid"
4
4
 
5
5
  describe("accounts", () => {
6
6
  const config = new TestConfiguration()
7
+ const api = new API(config)
7
8
 
8
9
  beforeAll(async () => {
9
10
  await config.beforeAll()
@@ -22,7 +23,7 @@ describe("accounts", () => {
22
23
  it("saves account metadata", async () => {
23
24
  let account = structures.accounts.account()
24
25
 
25
- const response = await config.api.accounts.saveMetadata(account)
26
+ const response = await api.accounts.saveMetadata(account)
26
27
 
27
28
  const id = sdk.accounts.formatAccountMetadataId(account.accountId)
28
29
  const metadata = await sdk.accounts.getMetadata(id)
@@ -33,9 +34,9 @@ describe("accounts", () => {
33
34
  describe("destroyMetadata", () => {
34
35
  it("destroys account metadata", async () => {
35
36
  const account = structures.accounts.account()
36
- await config.api.accounts.saveMetadata(account)
37
+ await api.accounts.saveMetadata(account)
37
38
 
38
- await config.api.accounts.destroyMetadata(account.accountId)
39
+ await api.accounts.destroyMetadata(account.accountId)
39
40
 
40
41
  const deleted = await sdk.accounts.getMetadata(account.accountId)
41
42
  expect(deleted).toBe(undefined)
@@ -44,7 +45,7 @@ describe("accounts", () => {
44
45
  it("destroys account metadata that does not exist", async () => {
45
46
  const id = uuid()
46
47
 
47
- const response = await config.api.accounts.destroyMetadata(id)
48
+ const response = await api.accounts.destroyMetadata(id)
48
49
 
49
50
  expect(response.status).toBe(204)
50
51
  })