@budibase/worker 3.13.8 → 3.13.10
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/package.json +2 -2
- package/src/api/controllers/global/roles.ts +20 -18
- package/src/api/controllers/global/users.ts +26 -0
- package/src/api/index.ts +4 -0
- package/src/api/routes/global/tests/groups.spec.ts +17 -0
- package/src/api/routes/global/users.ts +16 -0
- package/src/tests/api/groups.ts +14 -1
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@budibase/worker",
|
|
3
3
|
"email": "hi@budibase.com",
|
|
4
|
-
"version": "3.13.
|
|
4
|
+
"version": "3.13.10",
|
|
5
5
|
"description": "Budibase background service",
|
|
6
6
|
"main": "src/index.ts",
|
|
7
7
|
"repository": {
|
|
@@ -113,5 +113,5 @@
|
|
|
113
113
|
}
|
|
114
114
|
}
|
|
115
115
|
},
|
|
116
|
-
"gitHead": "
|
|
116
|
+
"gitHead": "9d6b86cc387bd1e3cc4ec8f3a1c7f8f3a94d1205"
|
|
117
117
|
}
|
|
@@ -16,25 +16,27 @@ import {
|
|
|
16
16
|
|
|
17
17
|
export async function fetch(ctx: Ctx<void, FetchGlobalRolesResponse>) {
|
|
18
18
|
const tenantId = ctx.user!.tenantId
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
const roleList = await Promise.all(promises)
|
|
27
|
-
const response: any = {}
|
|
28
|
-
for (let app of apps) {
|
|
29
|
-
const deployedAppId = dbCore.getProdAppID(app.appId)
|
|
30
|
-
response[deployedAppId] = {
|
|
31
|
-
roles: roleList.shift(),
|
|
32
|
-
name: app.name,
|
|
33
|
-
version: app.version,
|
|
34
|
-
url: app.url,
|
|
19
|
+
await context.doInTenant(tenantId, async () => {
|
|
20
|
+
// always use the dev apps as they'll be most up to date (true)
|
|
21
|
+
const apps = await dbCore.getAllApps({ all: true })
|
|
22
|
+
const promises = []
|
|
23
|
+
for (let app of apps) {
|
|
24
|
+
// use dev app IDs
|
|
25
|
+
promises.push(roles.getAllRoles(app.appId))
|
|
35
26
|
}
|
|
36
|
-
|
|
37
|
-
|
|
27
|
+
const roleList = await Promise.all(promises)
|
|
28
|
+
const response: any = {}
|
|
29
|
+
for (let app of apps) {
|
|
30
|
+
const deployedAppId = dbCore.getProdAppID(app.appId)
|
|
31
|
+
response[deployedAppId] = {
|
|
32
|
+
roles: roleList.shift(),
|
|
33
|
+
name: app.name,
|
|
34
|
+
version: app.version,
|
|
35
|
+
url: app.url,
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
ctx.body = response
|
|
39
|
+
})
|
|
38
40
|
}
|
|
39
41
|
|
|
40
42
|
export async function find(ctx: Ctx<void, FindGlobalRoleResponse>) {
|
|
@@ -7,6 +7,7 @@ import {
|
|
|
7
7
|
AddSSoUserResponse,
|
|
8
8
|
BulkUserRequest,
|
|
9
9
|
BulkUserResponse,
|
|
10
|
+
ChangeTenantOwnerEmailRequest,
|
|
10
11
|
CheckInviteResponse,
|
|
11
12
|
CountUserResponse,
|
|
12
13
|
CreateAdminUserRequest,
|
|
@@ -106,6 +107,31 @@ export const save = async (ctx: UserCtx<UnsavedUser, SaveUserResponse>) => {
|
|
|
106
107
|
}
|
|
107
108
|
}
|
|
108
109
|
|
|
110
|
+
export const changeTenantOwnerEmail = async (
|
|
111
|
+
ctx: Ctx<ChangeTenantOwnerEmailRequest, void>
|
|
112
|
+
) => {
|
|
113
|
+
const { newAccountEmail, originalEmail, tenantIds } = ctx.request.body
|
|
114
|
+
try {
|
|
115
|
+
for (const tenantId of tenantIds) {
|
|
116
|
+
await tenancy.doInTenant(tenantId, async () => {
|
|
117
|
+
const tenantUser = await userSdk.db.getUserByEmail(originalEmail)
|
|
118
|
+
if (!tenantUser) {
|
|
119
|
+
return
|
|
120
|
+
}
|
|
121
|
+
tenantUser.email = newAccountEmail
|
|
122
|
+
await userSdk.db.save(tenantUser, {
|
|
123
|
+
currentUserId: tenantUser._id,
|
|
124
|
+
isAccountHolder: true,
|
|
125
|
+
allowChangingEmail: true,
|
|
126
|
+
})
|
|
127
|
+
})
|
|
128
|
+
}
|
|
129
|
+
ctx.status = 200
|
|
130
|
+
} catch (err: any) {
|
|
131
|
+
ctx.throw(err.status || 400, err)
|
|
132
|
+
}
|
|
133
|
+
}
|
|
134
|
+
|
|
109
135
|
export const addSsoSupport = async (
|
|
110
136
|
ctx: Ctx<AddSSoUserRequest, AddSSoUserResponse>
|
|
111
137
|
) => {
|
package/src/api/index.ts
CHANGED
|
@@ -120,6 +120,10 @@ const NO_TENANCY_ENDPOINTS = [
|
|
|
120
120
|
route: "/api/global/users/accountholder",
|
|
121
121
|
method: "GET",
|
|
122
122
|
},
|
|
123
|
+
{
|
|
124
|
+
route: "/api/global/users/tenant/owner",
|
|
125
|
+
method: "PUT",
|
|
126
|
+
},
|
|
123
127
|
]
|
|
124
128
|
|
|
125
129
|
// most public endpoints are gets, but some are posts
|
|
@@ -294,6 +294,23 @@ describe("/api/global/groups", () => {
|
|
|
294
294
|
})
|
|
295
295
|
})
|
|
296
296
|
|
|
297
|
+
describe("role filtering", () => {
|
|
298
|
+
it("should filter out roles for non-existent apps when enriching group", async () => {
|
|
299
|
+
const fakeAppId = "app_fake"
|
|
300
|
+
const group = structures.groups.UserGroup()
|
|
301
|
+
|
|
302
|
+
const { body: savedGroup } = await config.api.groups.saveGroup(group)
|
|
303
|
+
await config.api.groups.updateGroupApps(savedGroup._id, {
|
|
304
|
+
add: [{ appId: fakeAppId, roleId: "BASIC" }],
|
|
305
|
+
})
|
|
306
|
+
const { body: retrievedGroup } = await config.api.groups.find(
|
|
307
|
+
savedGroup._id
|
|
308
|
+
)
|
|
309
|
+
|
|
310
|
+
expect(Object.keys(retrievedGroup.roles)).not.toContain(fakeAppId)
|
|
311
|
+
})
|
|
312
|
+
})
|
|
313
|
+
|
|
297
314
|
describe("with global builder role", () => {
|
|
298
315
|
let builder: User
|
|
299
316
|
let group: UserGroup
|
|
@@ -59,6 +59,16 @@ function buildInviteAcceptValidation() {
|
|
|
59
59
|
}).required().unknown(true))
|
|
60
60
|
}
|
|
61
61
|
|
|
62
|
+
function buildChangeTenantOwnerEmailValidation() {
|
|
63
|
+
return auth.joiValidator.body(
|
|
64
|
+
Joi.object({
|
|
65
|
+
newAccountEmail: Joi.string().required(),
|
|
66
|
+
originalEmail: Joi.string().required(),
|
|
67
|
+
tenantIds: Joi.array().items(Joi.string()).required(),
|
|
68
|
+
}).required()
|
|
69
|
+
)
|
|
70
|
+
}
|
|
71
|
+
|
|
62
72
|
router
|
|
63
73
|
.post(
|
|
64
74
|
"/api/global/users",
|
|
@@ -140,5 +150,11 @@ router
|
|
|
140
150
|
.get("/api/global/users/tenant/:id", controller.tenantUserLookup)
|
|
141
151
|
// global endpoint but needs to come at end (blocks other endpoints otherwise)
|
|
142
152
|
.get("/api/global/users/:id", auth.builderOrAdmin, controller.find)
|
|
153
|
+
.put(
|
|
154
|
+
"/api/global/users/tenant/owner",
|
|
155
|
+
cloudRestricted,
|
|
156
|
+
buildChangeTenantOwnerEmailValidation(),
|
|
157
|
+
controller.changeTenantOwnerEmail
|
|
158
|
+
)
|
|
143
159
|
|
|
144
160
|
export default router
|
package/src/tests/api/groups.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { UserGroup } from "@budibase/types"
|
|
1
|
+
import { UserGroup, UpdateGroupAppRequest } from "@budibase/types"
|
|
2
2
|
import { TestAPI } from "./base"
|
|
3
3
|
|
|
4
4
|
export class GroupsAPI extends TestAPI {
|
|
@@ -53,6 +53,19 @@ export class GroupsAPI extends TestAPI {
|
|
|
53
53
|
.expect(expect)
|
|
54
54
|
}
|
|
55
55
|
|
|
56
|
+
updateGroupApps = (
|
|
57
|
+
groupId: string,
|
|
58
|
+
body: UpdateGroupAppRequest,
|
|
59
|
+
{ expect } = { expect: 200 }
|
|
60
|
+
) => {
|
|
61
|
+
return this.request
|
|
62
|
+
.post(`/api/global/groups/${groupId}/apps`)
|
|
63
|
+
.send(body)
|
|
64
|
+
.set(this.config.defaultHeaders())
|
|
65
|
+
.expect("Content-Type", /json/)
|
|
66
|
+
.expect(expect)
|
|
67
|
+
}
|
|
68
|
+
|
|
56
69
|
fetch = ({ expect } = { expect: 200 }) => {
|
|
57
70
|
return this.request
|
|
58
71
|
.get(`/api/global/groups`)
|