@budibase/worker 3.14.0 → 3.14.1
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
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@budibase/worker",
|
|
3
3
|
"email": "hi@budibase.com",
|
|
4
|
-
"version": "3.14.
|
|
4
|
+
"version": "3.14.1",
|
|
5
5
|
"description": "Budibase background service",
|
|
6
6
|
"main": "src/index.ts",
|
|
7
7
|
"repository": {
|
|
@@ -115,5 +115,5 @@
|
|
|
115
115
|
}
|
|
116
116
|
}
|
|
117
117
|
},
|
|
118
|
-
"gitHead": "
|
|
118
|
+
"gitHead": "95576e7a88dbb8563210818dd3d451b60770b901"
|
|
119
119
|
}
|
|
@@ -30,6 +30,7 @@ import {
|
|
|
30
30
|
LockType,
|
|
31
31
|
LookupAccountHolderResponse,
|
|
32
32
|
LookupTenantUserResponse,
|
|
33
|
+
OIDCUser,
|
|
33
34
|
SaveUserResponse,
|
|
34
35
|
SearchUsersRequest,
|
|
35
36
|
SearchUsersResponse,
|
|
@@ -114,11 +115,20 @@ export const changeTenantOwnerEmail = async (
|
|
|
114
115
|
try {
|
|
115
116
|
for (const tenantId of tenantIds) {
|
|
116
117
|
await tenancy.doInTenant(tenantId, async () => {
|
|
117
|
-
const tenantUser = await userSdk.db.getUserByEmail(
|
|
118
|
+
const tenantUser = (await userSdk.db.getUserByEmail(
|
|
119
|
+
originalEmail
|
|
120
|
+
)) as OIDCUser
|
|
118
121
|
if (!tenantUser) {
|
|
119
122
|
return
|
|
120
123
|
}
|
|
121
124
|
tenantUser.email = newAccountEmail
|
|
125
|
+
|
|
126
|
+
tenantUser.provider = undefined
|
|
127
|
+
tenantUser.providerType = undefined
|
|
128
|
+
tenantUser.thirdPartyProfile = undefined
|
|
129
|
+
tenantUser.profile = undefined
|
|
130
|
+
tenantUser.oauth2 = undefined
|
|
131
|
+
|
|
122
132
|
await userSdk.db.save(tenantUser, {
|
|
123
133
|
currentUserId: tenantUser._id,
|
|
124
134
|
isAccountHolder: true,
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { InviteUsersResponse, User } from "@budibase/types"
|
|
1
|
+
import { InviteUsersResponse, User, OIDCUser } from "@budibase/types"
|
|
2
2
|
|
|
3
3
|
import { TestConfiguration, mocks, structures } from "../../../../tests"
|
|
4
4
|
import { events, tenancy, accounts as _accounts } from "@budibase/backend-core"
|
|
@@ -800,4 +800,162 @@ describe("/api/global/users", () => {
|
|
|
800
800
|
expect(response.unsuccessful.length).toBe(1)
|
|
801
801
|
})
|
|
802
802
|
})
|
|
803
|
+
|
|
804
|
+
describe("PUT /api/global/users/tenant/owner", () => {
|
|
805
|
+
it("should successfully change tenant owner email for existing user", async () => {
|
|
806
|
+
const originalEmail = `original-${structures.uuid()}@example.com`
|
|
807
|
+
const newEmail = `new-${structures.uuid()}@example.com`
|
|
808
|
+
const tenantId = config.getTenantId()
|
|
809
|
+
|
|
810
|
+
const user = await config.doInTenant(async () => {
|
|
811
|
+
return await userSdk.db.save(
|
|
812
|
+
{
|
|
813
|
+
email: originalEmail,
|
|
814
|
+
tenantId,
|
|
815
|
+
} as any,
|
|
816
|
+
{ requirePassword: false, isAccountHolder: true }
|
|
817
|
+
)
|
|
818
|
+
})
|
|
819
|
+
|
|
820
|
+
await config.api.users.changeTenantOwnerEmail(newEmail, originalEmail, [
|
|
821
|
+
tenantId,
|
|
822
|
+
])
|
|
823
|
+
|
|
824
|
+
const updatedUser = await config.doInTenant(async () => {
|
|
825
|
+
return await userSdk.db.getUser(user._id!)
|
|
826
|
+
})
|
|
827
|
+
|
|
828
|
+
expect(updatedUser).toBeDefined()
|
|
829
|
+
expect(updatedUser!.email).toBe(newEmail)
|
|
830
|
+
})
|
|
831
|
+
|
|
832
|
+
it("should handle multiple tenants", async () => {
|
|
833
|
+
const originalEmail = `original-${structures.uuid()}@example.com`
|
|
834
|
+
const newEmail = `new-${structures.uuid()}@example.com`
|
|
835
|
+
const tenant1 = config.getTenantId()
|
|
836
|
+
const tenant2 = structures.tenant.id()
|
|
837
|
+
|
|
838
|
+
const user1 = await config.doInTenant(async () => {
|
|
839
|
+
return await userSdk.db.save(
|
|
840
|
+
{
|
|
841
|
+
email: originalEmail,
|
|
842
|
+
tenantId: tenant1,
|
|
843
|
+
} as any,
|
|
844
|
+
{ requirePassword: false, isAccountHolder: true }
|
|
845
|
+
)
|
|
846
|
+
})
|
|
847
|
+
|
|
848
|
+
const user2 = await config.doInSpecificTenant(tenant2, async () => {
|
|
849
|
+
return await userSdk.db.save(
|
|
850
|
+
{
|
|
851
|
+
email: originalEmail,
|
|
852
|
+
tenantId: tenant2,
|
|
853
|
+
} as any,
|
|
854
|
+
{ requirePassword: false, isAccountHolder: true }
|
|
855
|
+
)
|
|
856
|
+
})
|
|
857
|
+
|
|
858
|
+
await config.api.users.changeTenantOwnerEmail(newEmail, originalEmail, [
|
|
859
|
+
tenant1,
|
|
860
|
+
tenant2,
|
|
861
|
+
])
|
|
862
|
+
|
|
863
|
+
const updatedUser1 = await config.doInTenant(async () => {
|
|
864
|
+
return await userSdk.db.getUser(user1._id!)
|
|
865
|
+
})
|
|
866
|
+
|
|
867
|
+
const updatedUser2 = await config.doInSpecificTenant(
|
|
868
|
+
tenant2,
|
|
869
|
+
async () => {
|
|
870
|
+
return await userSdk.db.getUser(user2._id!)
|
|
871
|
+
}
|
|
872
|
+
)
|
|
873
|
+
|
|
874
|
+
expect(updatedUser1).toBeDefined()
|
|
875
|
+
expect(updatedUser1!.email).toBe(newEmail)
|
|
876
|
+
expect(updatedUser2).toBeDefined()
|
|
877
|
+
expect(updatedUser2!.email).toBe(newEmail)
|
|
878
|
+
})
|
|
879
|
+
|
|
880
|
+
it("should not fail if user doesn't exist in tenant", async () => {
|
|
881
|
+
const originalEmail = `nonexistent-${structures.uuid()}@example.com`
|
|
882
|
+
const newEmail = `new-${structures.uuid()}@example.com`
|
|
883
|
+
const tenantId = config.getTenantId()
|
|
884
|
+
|
|
885
|
+
await config.api.users.changeTenantOwnerEmail(newEmail, originalEmail, [
|
|
886
|
+
tenantId,
|
|
887
|
+
])
|
|
888
|
+
|
|
889
|
+
const user = await config.doInTenant(async () => {
|
|
890
|
+
return await userSdk.db.getUserByEmail(newEmail)
|
|
891
|
+
})
|
|
892
|
+
|
|
893
|
+
expect(user).toBeUndefined()
|
|
894
|
+
})
|
|
895
|
+
|
|
896
|
+
it("should handle empty tenant list", async () => {
|
|
897
|
+
const originalEmail = `original-${structures.uuid()}@example.com`
|
|
898
|
+
const newEmail = `new-${structures.uuid()}@example.com`
|
|
899
|
+
|
|
900
|
+
await config.api.users.changeTenantOwnerEmail(newEmail, originalEmail, [])
|
|
901
|
+
})
|
|
902
|
+
|
|
903
|
+
it("should clear all OIDC-related fields", async () => {
|
|
904
|
+
const originalEmail = `original-${structures.uuid()}@example.com`
|
|
905
|
+
const newEmail = `new-${structures.uuid()}@example.com`
|
|
906
|
+
const tenantId = config.getTenantId()
|
|
907
|
+
const profile = {}
|
|
908
|
+
const provider = "oidc"
|
|
909
|
+
const providerType = "oidc"
|
|
910
|
+
const thirdPartyProfile = {}
|
|
911
|
+
const oauth2 = {}
|
|
912
|
+
|
|
913
|
+
await config.doInTenant(async () => {
|
|
914
|
+
await userSdk.db.save(
|
|
915
|
+
{
|
|
916
|
+
email: originalEmail,
|
|
917
|
+
tenantId,
|
|
918
|
+
profile,
|
|
919
|
+
provider,
|
|
920
|
+
providerType,
|
|
921
|
+
thirdPartyProfile,
|
|
922
|
+
oauth2,
|
|
923
|
+
} as any,
|
|
924
|
+
{ requirePassword: false, isAccountHolder: true }
|
|
925
|
+
)
|
|
926
|
+
})
|
|
927
|
+
|
|
928
|
+
await config.api.users.changeTenantOwnerEmail(newEmail, originalEmail, [
|
|
929
|
+
tenantId,
|
|
930
|
+
])
|
|
931
|
+
|
|
932
|
+
const updatedUser = (await config.doInTenant(async () => {
|
|
933
|
+
return await userSdk.db.getUserByEmail(newEmail)
|
|
934
|
+
})) as OIDCUser
|
|
935
|
+
|
|
936
|
+
expect(updatedUser).toBeDefined()
|
|
937
|
+
expect(updatedUser!.email).toBe(newEmail)
|
|
938
|
+
expect(updatedUser.profile).toBe(undefined)
|
|
939
|
+
expect(updatedUser.provider).toBe(undefined)
|
|
940
|
+
expect(updatedUser.providerType).toBe(undefined)
|
|
941
|
+
expect(updatedUser.thirdPartyProfile).toBe(undefined)
|
|
942
|
+
expect(updatedUser.oauth2).toBe(undefined)
|
|
943
|
+
})
|
|
944
|
+
|
|
945
|
+
it("should require internal API headers", async () => {
|
|
946
|
+
const originalEmail = `original-${structures.uuid()}@example.com`
|
|
947
|
+
const newEmail = `new-${structures.uuid()}@example.com`
|
|
948
|
+
const tenantId = config.getTenantId()
|
|
949
|
+
|
|
950
|
+
await config.request
|
|
951
|
+
.put(`/api/global/users/tenant/owner`)
|
|
952
|
+
.send({
|
|
953
|
+
newAccountEmail: newEmail,
|
|
954
|
+
originalEmail,
|
|
955
|
+
tenantIds: [tenantId],
|
|
956
|
+
})
|
|
957
|
+
.set(config.defaultHeaders())
|
|
958
|
+
.expect(403)
|
|
959
|
+
})
|
|
960
|
+
})
|
|
803
961
|
})
|
|
@@ -138,9 +138,9 @@ class TestConfiguration {
|
|
|
138
138
|
|
|
139
139
|
// TENANCY
|
|
140
140
|
|
|
141
|
-
doInTenant(task:
|
|
142
|
-
return context.doInTenant(this.tenantId, () => {
|
|
143
|
-
return task()
|
|
141
|
+
async doInTenant<T>(task: () => Promise<T>): Promise<T> {
|
|
142
|
+
return await context.doInTenant(this.tenantId, async () => {
|
|
143
|
+
return await task()
|
|
144
144
|
})
|
|
145
145
|
}
|
|
146
146
|
|
|
@@ -171,6 +171,15 @@ class TestConfiguration {
|
|
|
171
171
|
}
|
|
172
172
|
}
|
|
173
173
|
|
|
174
|
+
async doInSpecificTenant<T>(
|
|
175
|
+
tenantId: string,
|
|
176
|
+
task: () => Promise<T>
|
|
177
|
+
): Promise<T> {
|
|
178
|
+
return await context.doInTenant(tenantId, async () => {
|
|
179
|
+
return await task()
|
|
180
|
+
})
|
|
181
|
+
}
|
|
182
|
+
|
|
174
183
|
// AUTH
|
|
175
184
|
|
|
176
185
|
async _createSession({
|
package/src/tests/api/users.ts
CHANGED
|
@@ -214,4 +214,17 @@ export class UserAPI extends TestAPI {
|
|
|
214
214
|
|
|
215
215
|
return resp.body as InviteUsersResponse
|
|
216
216
|
}
|
|
217
|
+
|
|
218
|
+
changeTenantOwnerEmail = (
|
|
219
|
+
newAccountEmail: string,
|
|
220
|
+
originalEmail: string,
|
|
221
|
+
tenantIds: string[],
|
|
222
|
+
status = 200
|
|
223
|
+
) => {
|
|
224
|
+
return this.request
|
|
225
|
+
.put(`/api/global/users/tenant/owner`)
|
|
226
|
+
.send({ newAccountEmail, originalEmail, tenantIds })
|
|
227
|
+
.set(this.config.internalAPIHeaders())
|
|
228
|
+
.expect(status)
|
|
229
|
+
}
|
|
217
230
|
}
|