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