@budibase/backend-core 3.2.4 → 3.2.6
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/dist/index.js.map +1 -1
- package/dist/index.js.meta.json +1 -1
- package/dist/package.json +11 -4
- package/dist/plugins.js.meta.json +1 -1
- package/package.json +11 -4
- package/src/accounts/accounts.ts +0 -82
- package/src/accounts/api.ts +0 -59
- package/src/accounts/index.ts +0 -1
- package/src/auth/auth.ts +0 -210
- package/src/auth/index.ts +0 -1
- package/src/auth/tests/auth.spec.ts +0 -14
- package/src/blacklist/blacklist.ts +0 -54
- package/src/blacklist/index.ts +0 -1
- package/src/blacklist/tests/blacklist.spec.ts +0 -46
- package/src/cache/appMetadata.ts +0 -88
- package/src/cache/base/index.ts +0 -150
- package/src/cache/docWritethrough.ts +0 -105
- package/src/cache/generic.ts +0 -33
- package/src/cache/index.ts +0 -8
- package/src/cache/invite.ts +0 -86
- package/src/cache/passwordReset.ts +0 -49
- package/src/cache/tests/docWritethrough.spec.ts +0 -296
- package/src/cache/tests/user.spec.ts +0 -145
- package/src/cache/tests/writethrough.spec.ts +0 -139
- package/src/cache/user.ts +0 -154
- package/src/cache/writethrough.ts +0 -133
- package/src/configs/configs.ts +0 -263
- package/src/configs/index.ts +0 -1
- package/src/configs/tests/configs.spec.ts +0 -184
- package/src/constants/db.ts +0 -75
- package/src/constants/index.ts +0 -2
- package/src/constants/misc.ts +0 -36
- package/src/context/Context.ts +0 -14
- package/src/context/identity.ts +0 -58
- package/src/context/index.ts +0 -3
- package/src/context/mainContext.ts +0 -422
- package/src/context/tests/index.spec.ts +0 -255
- package/src/context/types.ts +0 -26
- package/src/db/Replication.ts +0 -94
- package/src/db/couch/DatabaseImpl.ts +0 -511
- package/src/db/couch/connections.ts +0 -89
- package/src/db/couch/index.ts +0 -4
- package/src/db/couch/pouchDB.ts +0 -97
- package/src/db/couch/pouchDump.ts +0 -0
- package/src/db/couch/tests/DatabaseImpl.spec.ts +0 -118
- package/src/db/couch/utils.ts +0 -55
- package/src/db/db.ts +0 -34
- package/src/db/errors.ts +0 -14
- package/src/db/index.ts +0 -12
- package/src/db/instrumentation.ts +0 -199
- package/src/db/lucene.ts +0 -721
- package/src/db/searchIndexes/index.ts +0 -1
- package/src/db/searchIndexes/searchIndexes.ts +0 -62
- package/src/db/tests/DatabaseImpl.spec.ts +0 -55
- package/src/db/tests/connections.spec.ts +0 -22
- package/src/db/tests/index.spec.ts +0 -32
- package/src/db/tests/lucene.spec.ts +0 -400
- package/src/db/tests/pouch.spec.js +0 -62
- package/src/db/tests/utils.spec.ts +0 -63
- package/src/db/utils.ts +0 -208
- package/src/db/views.ts +0 -245
- package/src/docIds/conversions.ts +0 -60
- package/src/docIds/ids.ts +0 -126
- package/src/docIds/index.ts +0 -2
- package/src/docIds/newid.ts +0 -5
- package/src/docIds/params.ts +0 -189
- package/src/docUpdates/index.ts +0 -24
- package/src/environment.ts +0 -293
- package/src/errors/errors.ts +0 -119
- package/src/errors/index.ts +0 -1
- package/src/events/analytics.ts +0 -6
- package/src/events/asyncEvents/index.ts +0 -2
- package/src/events/asyncEvents/publisher.ts +0 -12
- package/src/events/asyncEvents/queue.ts +0 -22
- package/src/events/backfill.ts +0 -183
- package/src/events/documentId.ts +0 -56
- package/src/events/events.ts +0 -47
- package/src/events/identification.ts +0 -311
- package/src/events/index.ts +0 -15
- package/src/events/processors/AnalyticsProcessor.ts +0 -64
- package/src/events/processors/AuditLogsProcessor.ts +0 -92
- package/src/events/processors/LoggingProcessor.ts +0 -36
- package/src/events/processors/Processors.ts +0 -52
- package/src/events/processors/async/DocumentUpdateProcessor.ts +0 -38
- package/src/events/processors/index.ts +0 -19
- package/src/events/processors/posthog/PosthogProcessor.ts +0 -118
- package/src/events/processors/posthog/index.ts +0 -3
- package/src/events/processors/posthog/rateLimiting.ts +0 -106
- package/src/events/processors/posthog/tests/PosthogProcessor.spec.ts +0 -164
- package/src/events/processors/types.ts +0 -1
- package/src/events/publishers/account.ts +0 -41
- package/src/events/publishers/ai.ts +0 -21
- package/src/events/publishers/app.ts +0 -168
- package/src/events/publishers/auditLog.ts +0 -26
- package/src/events/publishers/auth.ts +0 -73
- package/src/events/publishers/automation.ts +0 -110
- package/src/events/publishers/backfill.ts +0 -74
- package/src/events/publishers/backup.ts +0 -42
- package/src/events/publishers/datasource.ts +0 -48
- package/src/events/publishers/email.ts +0 -17
- package/src/events/publishers/environmentVariable.ts +0 -38
- package/src/events/publishers/group.ts +0 -99
- package/src/events/publishers/index.ts +0 -25
- package/src/events/publishers/installation.ts +0 -38
- package/src/events/publishers/layout.ts +0 -26
- package/src/events/publishers/license.ts +0 -84
- package/src/events/publishers/org.ts +0 -37
- package/src/events/publishers/plugin.ts +0 -47
- package/src/events/publishers/query.ts +0 -89
- package/src/events/publishers/role.ts +0 -62
- package/src/events/publishers/rows.ts +0 -29
- package/src/events/publishers/screen.ts +0 -36
- package/src/events/publishers/serve.ts +0 -43
- package/src/events/publishers/table.ts +0 -70
- package/src/events/publishers/user.ts +0 -202
- package/src/events/publishers/view.ts +0 -107
- package/src/features/features.ts +0 -277
- package/src/features/index.ts +0 -2
- package/src/features/tests/features.spec.ts +0 -267
- package/src/features/tests/utils.ts +0 -64
- package/src/helpers.ts +0 -9
- package/src/index.ts +0 -59
- package/src/installation.ts +0 -115
- package/src/logging/alerts.ts +0 -26
- package/src/logging/correlation/correlation.ts +0 -15
- package/src/logging/correlation/index.ts +0 -1
- package/src/logging/correlation/middleware.ts +0 -18
- package/src/logging/index.ts +0 -4
- package/src/logging/pino/logger.ts +0 -239
- package/src/logging/pino/middleware.ts +0 -48
- package/src/logging/system.ts +0 -81
- package/src/logging/tests/system.spec.ts +0 -61
- package/src/middleware/adminOnly.ts +0 -9
- package/src/middleware/auditLog.ts +0 -6
- package/src/middleware/authenticated.ts +0 -247
- package/src/middleware/builderOnly.ts +0 -21
- package/src/middleware/builderOrAdmin.ts +0 -21
- package/src/middleware/contentSecurityPolicy.ts +0 -113
- package/src/middleware/csrf.ts +0 -81
- package/src/middleware/errorHandling.ts +0 -43
- package/src/middleware/index.ts +0 -24
- package/src/middleware/internalApi.ts +0 -23
- package/src/middleware/ip.ts +0 -12
- package/src/middleware/joi-validator.ts +0 -58
- package/src/middleware/matchers.ts +0 -39
- package/src/middleware/passport/datasource/google.ts +0 -102
- package/src/middleware/passport/local.ts +0 -54
- package/src/middleware/passport/sso/google.ts +0 -77
- package/src/middleware/passport/sso/oidc.ts +0 -152
- package/src/middleware/passport/sso/sso.ts +0 -138
- package/src/middleware/passport/sso/tests/google.spec.ts +0 -68
- package/src/middleware/passport/sso/tests/oidc.spec.ts +0 -144
- package/src/middleware/passport/sso/tests/sso.spec.ts +0 -197
- package/src/middleware/passport/utils.ts +0 -38
- package/src/middleware/querystringToBody.ts +0 -28
- package/src/middleware/tenancy.ts +0 -36
- package/src/middleware/tests/builder.spec.ts +0 -181
- package/src/middleware/tests/contentSecurityPolicy.spec.ts +0 -75
- package/src/middleware/tests/matchers.spec.ts +0 -100
- package/src/migrations/definitions.ts +0 -40
- package/src/migrations/index.ts +0 -2
- package/src/migrations/migrations.ts +0 -186
- package/src/migrations/tests/__snapshots__/migrations.spec.ts.snap +0 -11
- package/src/migrations/tests/migrations.spec.ts +0 -64
- package/src/objectStore/buckets/app.ts +0 -53
- package/src/objectStore/buckets/global.ts +0 -29
- package/src/objectStore/buckets/index.ts +0 -3
- package/src/objectStore/buckets/plugins.ts +0 -71
- package/src/objectStore/buckets/tests/app.spec.ts +0 -161
- package/src/objectStore/buckets/tests/global.spec.ts +0 -74
- package/src/objectStore/buckets/tests/plugins.spec.ts +0 -111
- package/src/objectStore/cloudfront.ts +0 -41
- package/src/objectStore/index.ts +0 -3
- package/src/objectStore/objectStore.ts +0 -585
- package/src/objectStore/utils.ts +0 -113
- package/src/platform/index.ts +0 -3
- package/src/platform/platformDb.ts +0 -6
- package/src/platform/tenants.ts +0 -101
- package/src/platform/tests/tenants.spec.ts +0 -26
- package/src/platform/users.ts +0 -129
- package/src/plugin/index.ts +0 -1
- package/src/plugin/tests/validation.spec.ts +0 -209
- package/src/plugin/utils.ts +0 -175
- package/src/queue/constants.ts +0 -8
- package/src/queue/inMemoryQueue.ts +0 -189
- package/src/queue/index.ts +0 -2
- package/src/queue/listeners.ts +0 -199
- package/src/queue/queue.ts +0 -84
- package/src/redis/index.ts +0 -6
- package/src/redis/init.ts +0 -118
- package/src/redis/redis.ts +0 -358
- package/src/redis/redlockImpl.ts +0 -155
- package/src/redis/tests/redis.spec.ts +0 -207
- package/src/redis/tests/redlockImpl.spec.ts +0 -105
- package/src/redis/utils.ts +0 -128
- package/src/security/auth.ts +0 -24
- package/src/security/encryption.ts +0 -185
- package/src/security/index.ts +0 -1
- package/src/security/permissions.ts +0 -166
- package/src/security/roles.ts +0 -655
- package/src/security/secrets.ts +0 -20
- package/src/security/sessions.ts +0 -123
- package/src/security/tests/auth.spec.ts +0 -45
- package/src/security/tests/encryption.spec.ts +0 -31
- package/src/security/tests/permissions.spec.ts +0 -146
- package/src/security/tests/secrets.spec.ts +0 -35
- package/src/security/tests/sessions.spec.ts +0 -12
- package/src/sql/designDoc.ts +0 -17
- package/src/sql/index.ts +0 -5
- package/src/sql/sql.ts +0 -1854
- package/src/sql/sqlTable.ts +0 -319
- package/src/sql/utils.ts +0 -193
- package/src/tenancy/db.ts +0 -6
- package/src/tenancy/index.ts +0 -2
- package/src/tenancy/tenancy.ts +0 -148
- package/src/tenancy/tests/tenancy.spec.ts +0 -184
- package/src/timers/index.ts +0 -1
- package/src/timers/timers.ts +0 -22
- package/src/users/db.ts +0 -582
- package/src/users/events.ts +0 -176
- package/src/users/index.ts +0 -4
- package/src/users/lookup.ts +0 -99
- package/src/users/test/db.spec.ts +0 -188
- package/src/users/test/utils.spec.ts +0 -67
- package/src/users/users.ts +0 -353
- package/src/users/utils.ts +0 -81
- package/src/utils/Duration.ts +0 -56
- package/src/utils/hashing.ts +0 -15
- package/src/utils/index.ts +0 -4
- package/src/utils/stringUtils.ts +0 -8
- package/src/utils/tests/Duration.spec.ts +0 -19
- package/src/utils/tests/utils.spec.ts +0 -204
- package/src/utils/utils.ts +0 -249
- package/tests/core/logging.ts +0 -34
- package/tests/core/users/users.spec.js +0 -53
- package/tests/core/utilities/index.ts +0 -7
- package/tests/core/utilities/jestUtils.ts +0 -33
- package/tests/core/utilities/mocks/alerts.ts +0 -4
- package/tests/core/utilities/mocks/date.ts +0 -3
- package/tests/core/utilities/mocks/events.ts +0 -132
- package/tests/core/utilities/mocks/index.ts +0 -9
- package/tests/core/utilities/mocks/licenses.ts +0 -119
- package/tests/core/utilities/queue.ts +0 -9
- package/tests/core/utilities/structures/Chance.ts +0 -20
- package/tests/core/utilities/structures/accounts.ts +0 -80
- package/tests/core/utilities/structures/apps.ts +0 -21
- package/tests/core/utilities/structures/common.ts +0 -7
- package/tests/core/utilities/structures/db.ts +0 -12
- package/tests/core/utilities/structures/documents/index.ts +0 -1
- package/tests/core/utilities/structures/documents/platform/index.ts +0 -1
- package/tests/core/utilities/structures/documents/platform/installation.ts +0 -12
- package/tests/core/utilities/structures/generator.ts +0 -3
- package/tests/core/utilities/structures/index.ts +0 -15
- package/tests/core/utilities/structures/koa.ts +0 -16
- package/tests/core/utilities/structures/licenses.ts +0 -190
- package/tests/core/utilities/structures/plugins.ts +0 -19
- package/tests/core/utilities/structures/quotas.ts +0 -72
- package/tests/core/utilities/structures/scim.ts +0 -80
- package/tests/core/utilities/structures/sso.ts +0 -118
- package/tests/core/utilities/structures/tenants.ts +0 -5
- package/tests/core/utilities/structures/userGroups.ts +0 -10
- package/tests/core/utilities/structures/users.ts +0 -89
- package/tests/core/utilities/testContainerUtils.ts +0 -165
- package/tests/core/utilities/utils/index.ts +0 -2
- package/tests/core/utilities/utils/queue.ts +0 -27
- package/tests/core/utilities/utils/time.ts +0 -3
- package/tests/extra/DBTestConfiguration.ts +0 -36
- package/tests/extra/index.ts +0 -2
- package/tests/extra/testEnv.ts +0 -95
- package/tests/index.ts +0 -2
- package/tests/jestEnv.ts +0 -10
- package/tests/jestSetup.ts +0 -36
package/src/users/events.ts
DELETED
|
@@ -1,176 +0,0 @@
|
|
|
1
|
-
import env from "../environment"
|
|
2
|
-
import * as events from "../events"
|
|
3
|
-
import * as accounts from "../accounts"
|
|
4
|
-
import { getTenantId } from "../context"
|
|
5
|
-
import { User, UserRoles, CloudAccount } from "@budibase/types"
|
|
6
|
-
import { hasBuilderPermissions, hasAdminPermissions } from "./utils"
|
|
7
|
-
|
|
8
|
-
export const handleDeleteEvents = async (user: any) => {
|
|
9
|
-
await events.user.deleted(user)
|
|
10
|
-
|
|
11
|
-
if (hasBuilderPermissions(user)) {
|
|
12
|
-
await events.user.permissionBuilderRemoved(user)
|
|
13
|
-
}
|
|
14
|
-
|
|
15
|
-
if (hasAdminPermissions(user)) {
|
|
16
|
-
await events.user.permissionAdminRemoved(user)
|
|
17
|
-
}
|
|
18
|
-
}
|
|
19
|
-
|
|
20
|
-
const assignAppRoleEvents = async (
|
|
21
|
-
user: User,
|
|
22
|
-
roles: UserRoles,
|
|
23
|
-
existingRoles: UserRoles
|
|
24
|
-
) => {
|
|
25
|
-
for (const [appId, role] of Object.entries(roles)) {
|
|
26
|
-
// app role in existing is not same as new
|
|
27
|
-
if (!existingRoles || existingRoles[appId] !== role) {
|
|
28
|
-
await events.role.assigned(user, role)
|
|
29
|
-
}
|
|
30
|
-
}
|
|
31
|
-
}
|
|
32
|
-
|
|
33
|
-
const unassignAppRoleEvents = async (
|
|
34
|
-
user: User,
|
|
35
|
-
roles: UserRoles,
|
|
36
|
-
existingRoles: UserRoles
|
|
37
|
-
) => {
|
|
38
|
-
if (!existingRoles) {
|
|
39
|
-
return
|
|
40
|
-
}
|
|
41
|
-
for (const [appId, role] of Object.entries(existingRoles)) {
|
|
42
|
-
// app role in new is not same as existing
|
|
43
|
-
if (!roles || roles[appId] !== role) {
|
|
44
|
-
await events.role.unassigned(user, role)
|
|
45
|
-
}
|
|
46
|
-
}
|
|
47
|
-
}
|
|
48
|
-
|
|
49
|
-
const handleAppRoleEvents = async (user: any, existingUser: any) => {
|
|
50
|
-
const roles = user.roles
|
|
51
|
-
const existingRoles = existingUser?.roles
|
|
52
|
-
|
|
53
|
-
await assignAppRoleEvents(user, roles, existingRoles)
|
|
54
|
-
await unassignAppRoleEvents(user, roles, existingRoles)
|
|
55
|
-
}
|
|
56
|
-
|
|
57
|
-
export const handleSaveEvents = async (
|
|
58
|
-
user: User,
|
|
59
|
-
existingUser: User | undefined
|
|
60
|
-
) => {
|
|
61
|
-
const tenantId = getTenantId()
|
|
62
|
-
let tenantAccount: CloudAccount | undefined
|
|
63
|
-
if (!env.SELF_HOSTED && !env.DISABLE_ACCOUNT_PORTAL) {
|
|
64
|
-
tenantAccount = await accounts.getAccountByTenantId(tenantId)
|
|
65
|
-
}
|
|
66
|
-
await events.identification.identifyUser(user, tenantAccount)
|
|
67
|
-
|
|
68
|
-
if (existingUser) {
|
|
69
|
-
await events.user.updated(user)
|
|
70
|
-
|
|
71
|
-
if (isRemovingBuilder(user, existingUser)) {
|
|
72
|
-
await events.user.permissionBuilderRemoved(user)
|
|
73
|
-
}
|
|
74
|
-
|
|
75
|
-
if (isRemovingAdmin(user, existingUser)) {
|
|
76
|
-
await events.user.permissionAdminRemoved(user)
|
|
77
|
-
}
|
|
78
|
-
|
|
79
|
-
if (isOnboardingComplete(user, existingUser)) {
|
|
80
|
-
await events.user.onboardingComplete(user)
|
|
81
|
-
}
|
|
82
|
-
|
|
83
|
-
if (
|
|
84
|
-
!existingUser.forceResetPassword &&
|
|
85
|
-
user.forceResetPassword &&
|
|
86
|
-
user.password
|
|
87
|
-
) {
|
|
88
|
-
await events.user.passwordForceReset(user)
|
|
89
|
-
}
|
|
90
|
-
|
|
91
|
-
if (user.password !== existingUser.password) {
|
|
92
|
-
await events.user.passwordUpdated(user)
|
|
93
|
-
}
|
|
94
|
-
} else {
|
|
95
|
-
await events.user.created(user)
|
|
96
|
-
}
|
|
97
|
-
|
|
98
|
-
if (isAddingBuilder(user, existingUser)) {
|
|
99
|
-
await events.user.permissionBuilderAssigned(user)
|
|
100
|
-
}
|
|
101
|
-
|
|
102
|
-
if (isAddingAdmin(user, existingUser)) {
|
|
103
|
-
await events.user.permissionAdminAssigned(user)
|
|
104
|
-
}
|
|
105
|
-
|
|
106
|
-
await handleAppRoleEvents(user, existingUser)
|
|
107
|
-
}
|
|
108
|
-
|
|
109
|
-
export const isAddingBuilder = (user: any, existingUser: any) => {
|
|
110
|
-
return isAddingPermission(user, existingUser, hasBuilderPermissions)
|
|
111
|
-
}
|
|
112
|
-
|
|
113
|
-
export const isRemovingBuilder = (user: any, existingUser: any) => {
|
|
114
|
-
return isRemovingPermission(user, existingUser, hasBuilderPermissions)
|
|
115
|
-
}
|
|
116
|
-
|
|
117
|
-
const isAddingAdmin = (user: any, existingUser: any) => {
|
|
118
|
-
return isAddingPermission(user, existingUser, hasAdminPermissions)
|
|
119
|
-
}
|
|
120
|
-
|
|
121
|
-
const isRemovingAdmin = (user: any, existingUser: any) => {
|
|
122
|
-
return isRemovingPermission(user, existingUser, hasAdminPermissions)
|
|
123
|
-
}
|
|
124
|
-
|
|
125
|
-
const isOnboardingComplete = (user: any, existingUser: any) => {
|
|
126
|
-
return !existingUser?.onboardedAt && typeof user.onboardedAt === "string"
|
|
127
|
-
}
|
|
128
|
-
|
|
129
|
-
/**
|
|
130
|
-
* Check if a permission is being added to a new or existing user.
|
|
131
|
-
*/
|
|
132
|
-
const isAddingPermission = (
|
|
133
|
-
user: any,
|
|
134
|
-
existingUser: any,
|
|
135
|
-
hasPermission: any
|
|
136
|
-
) => {
|
|
137
|
-
// new user doesn't have the permission
|
|
138
|
-
if (!hasPermission(user)) {
|
|
139
|
-
return false
|
|
140
|
-
}
|
|
141
|
-
|
|
142
|
-
// existing user has the permission
|
|
143
|
-
if (existingUser && hasPermission(existingUser)) {
|
|
144
|
-
return false
|
|
145
|
-
}
|
|
146
|
-
|
|
147
|
-
// permission is being added
|
|
148
|
-
return true
|
|
149
|
-
}
|
|
150
|
-
|
|
151
|
-
/**
|
|
152
|
-
* Check if a permission is being removed from an existing user.
|
|
153
|
-
*/
|
|
154
|
-
const isRemovingPermission = (
|
|
155
|
-
user: any,
|
|
156
|
-
existingUser: any,
|
|
157
|
-
hasPermission: any
|
|
158
|
-
) => {
|
|
159
|
-
// new user has the permission
|
|
160
|
-
if (hasPermission(user)) {
|
|
161
|
-
return false
|
|
162
|
-
}
|
|
163
|
-
|
|
164
|
-
// no existing user or existing user doesn't have the permission
|
|
165
|
-
if (!existingUser) {
|
|
166
|
-
return false
|
|
167
|
-
}
|
|
168
|
-
|
|
169
|
-
// existing user doesn't have the permission
|
|
170
|
-
if (!hasPermission(existingUser)) {
|
|
171
|
-
return false
|
|
172
|
-
}
|
|
173
|
-
|
|
174
|
-
// permission is being removed
|
|
175
|
-
return true
|
|
176
|
-
}
|
package/src/users/index.ts
DELETED
package/src/users/lookup.ts
DELETED
|
@@ -1,99 +0,0 @@
|
|
|
1
|
-
import {
|
|
2
|
-
AccountMetadata,
|
|
3
|
-
PlatformUser,
|
|
4
|
-
PlatformUserByEmail,
|
|
5
|
-
User,
|
|
6
|
-
} from "@budibase/types"
|
|
7
|
-
import * as dbUtils from "../db"
|
|
8
|
-
import { ViewName } from "../constants"
|
|
9
|
-
import { getExistingInvites } from "../cache/invite"
|
|
10
|
-
|
|
11
|
-
/**
|
|
12
|
-
* Apply a system-wide search on emails:
|
|
13
|
-
* - in tenant
|
|
14
|
-
* - cross tenant
|
|
15
|
-
* - accounts
|
|
16
|
-
* return an array of emails that match the supplied emails.
|
|
17
|
-
*/
|
|
18
|
-
export async function searchExistingEmails(emails: string[]) {
|
|
19
|
-
let matchedEmails: string[] = []
|
|
20
|
-
|
|
21
|
-
const existingTenantUsers = await getExistingTenantUsers(emails)
|
|
22
|
-
matchedEmails.push(...existingTenantUsers.map(user => user.email))
|
|
23
|
-
|
|
24
|
-
const existingPlatformUsers = await getExistingPlatformUsers(emails)
|
|
25
|
-
matchedEmails.push(...existingPlatformUsers.map(user => user._id!))
|
|
26
|
-
|
|
27
|
-
const existingAccounts = await getExistingAccounts(emails)
|
|
28
|
-
matchedEmails.push(...existingAccounts.map(account => account.email))
|
|
29
|
-
|
|
30
|
-
const invitedEmails = await getExistingInvites(emails)
|
|
31
|
-
matchedEmails.push(...invitedEmails.map(invite => invite.email))
|
|
32
|
-
|
|
33
|
-
return [...new Set(matchedEmails.map(email => email.toLowerCase()))]
|
|
34
|
-
}
|
|
35
|
-
|
|
36
|
-
// lookup, could be email or userId, either will return a doc
|
|
37
|
-
export async function getPlatformUsers(
|
|
38
|
-
identifier: string
|
|
39
|
-
): Promise<PlatformUser[]> {
|
|
40
|
-
// use the view here and allow to find anyone regardless of casing
|
|
41
|
-
// Use lowercase to ensure email login is case insensitive
|
|
42
|
-
return await dbUtils.queryPlatformView(ViewName.PLATFORM_USERS_LOWERCASE, {
|
|
43
|
-
keys: [identifier.toLowerCase()],
|
|
44
|
-
include_docs: true,
|
|
45
|
-
})
|
|
46
|
-
}
|
|
47
|
-
|
|
48
|
-
export async function getFirstPlatformUser(
|
|
49
|
-
identifier: string
|
|
50
|
-
): Promise<PlatformUser | null> {
|
|
51
|
-
const platformUserDocs = await getPlatformUsers(identifier)
|
|
52
|
-
return platformUserDocs[0] ?? null
|
|
53
|
-
}
|
|
54
|
-
|
|
55
|
-
export async function getExistingTenantUsers(
|
|
56
|
-
emails: string[]
|
|
57
|
-
): Promise<User[]> {
|
|
58
|
-
const lcEmails = emails.map(email => email.toLowerCase())
|
|
59
|
-
const params = {
|
|
60
|
-
keys: lcEmails,
|
|
61
|
-
include_docs: true,
|
|
62
|
-
}
|
|
63
|
-
|
|
64
|
-
const opts = {
|
|
65
|
-
arrayResponse: true,
|
|
66
|
-
}
|
|
67
|
-
|
|
68
|
-
return (await dbUtils.queryGlobalView(
|
|
69
|
-
ViewName.USER_BY_EMAIL,
|
|
70
|
-
params,
|
|
71
|
-
undefined,
|
|
72
|
-
opts
|
|
73
|
-
)) as User[]
|
|
74
|
-
}
|
|
75
|
-
|
|
76
|
-
export async function getExistingPlatformUsers(
|
|
77
|
-
emails: string[]
|
|
78
|
-
): Promise<PlatformUserByEmail[]> {
|
|
79
|
-
const lcEmails = emails.map(email => email.toLowerCase())
|
|
80
|
-
const params = {
|
|
81
|
-
keys: lcEmails,
|
|
82
|
-
include_docs: true,
|
|
83
|
-
}
|
|
84
|
-
return await dbUtils.queryPlatformView(
|
|
85
|
-
ViewName.PLATFORM_USERS_LOWERCASE,
|
|
86
|
-
params
|
|
87
|
-
)
|
|
88
|
-
}
|
|
89
|
-
|
|
90
|
-
export async function getExistingAccounts(
|
|
91
|
-
emails: string[]
|
|
92
|
-
): Promise<AccountMetadata[]> {
|
|
93
|
-
const lcEmails = emails.map(email => email.toLowerCase())
|
|
94
|
-
const params = {
|
|
95
|
-
keys: lcEmails,
|
|
96
|
-
include_docs: true,
|
|
97
|
-
}
|
|
98
|
-
return await dbUtils.queryPlatformView(ViewName.ACCOUNT_BY_EMAIL, params)
|
|
99
|
-
}
|
|
@@ -1,188 +0,0 @@
|
|
|
1
|
-
import { User, UserStatus } from "@budibase/types"
|
|
2
|
-
import { DBTestConfiguration, generator, structures } from "../../../tests"
|
|
3
|
-
import { UserDB } from "../db"
|
|
4
|
-
import { searchExistingEmails } from "../lookup"
|
|
5
|
-
|
|
6
|
-
const db = UserDB
|
|
7
|
-
|
|
8
|
-
const config = new DBTestConfiguration()
|
|
9
|
-
|
|
10
|
-
const quotas = {
|
|
11
|
-
addUsers: jest
|
|
12
|
-
.fn()
|
|
13
|
-
.mockImplementation(
|
|
14
|
-
(_change: number, _creatorsChange: number, cb?: () => Promise<any>) =>
|
|
15
|
-
cb && cb()
|
|
16
|
-
),
|
|
17
|
-
removeUsers: jest
|
|
18
|
-
.fn()
|
|
19
|
-
.mockImplementation(
|
|
20
|
-
(_change: number, _creatorsChange: number, cb?: () => Promise<any>) =>
|
|
21
|
-
cb && cb()
|
|
22
|
-
),
|
|
23
|
-
}
|
|
24
|
-
const groups = {
|
|
25
|
-
addUsers: jest.fn(),
|
|
26
|
-
getBulk: jest.fn(),
|
|
27
|
-
getGroupBuilderAppIds: jest.fn(),
|
|
28
|
-
}
|
|
29
|
-
const features = { isSSOEnforced: jest.fn(), isAppBuildersEnabled: jest.fn() }
|
|
30
|
-
|
|
31
|
-
describe("UserDB", () => {
|
|
32
|
-
beforeAll(() => {
|
|
33
|
-
db.init(quotas, groups, features)
|
|
34
|
-
})
|
|
35
|
-
|
|
36
|
-
describe("save", () => {
|
|
37
|
-
describe("create", () => {
|
|
38
|
-
it("creating a new user will persist it", async () => {
|
|
39
|
-
const email = generator.email({})
|
|
40
|
-
const user: User = structures.users.user({
|
|
41
|
-
email,
|
|
42
|
-
tenantId: config.getTenantId(),
|
|
43
|
-
})
|
|
44
|
-
|
|
45
|
-
await config.doInTenant(async () => {
|
|
46
|
-
const saveUserResponse = await db.save(user)
|
|
47
|
-
|
|
48
|
-
const persistedUser = await db.getUserByEmail(email)
|
|
49
|
-
expect(persistedUser).toEqual({
|
|
50
|
-
...user,
|
|
51
|
-
_id: saveUserResponse._id,
|
|
52
|
-
_rev: expect.stringMatching(/^1-\w+/),
|
|
53
|
-
password: expect.not.stringMatching(user.password!),
|
|
54
|
-
status: UserStatus.ACTIVE,
|
|
55
|
-
createdAt: Date.now(),
|
|
56
|
-
updatedAt: new Date().toISOString(),
|
|
57
|
-
})
|
|
58
|
-
})
|
|
59
|
-
})
|
|
60
|
-
|
|
61
|
-
it("the same email cannot be used twice in the same tenant", async () => {
|
|
62
|
-
const email = generator.email({})
|
|
63
|
-
const user: User = structures.users.user({
|
|
64
|
-
email,
|
|
65
|
-
tenantId: config.getTenantId(),
|
|
66
|
-
})
|
|
67
|
-
|
|
68
|
-
await config.doInTenant(() => db.save(user))
|
|
69
|
-
|
|
70
|
-
await config.doInTenant(() =>
|
|
71
|
-
expect(db.save(user)).rejects.toThrow(
|
|
72
|
-
`Email already in use: '${email}'`
|
|
73
|
-
)
|
|
74
|
-
)
|
|
75
|
-
})
|
|
76
|
-
|
|
77
|
-
it("the same email cannot be used twice in different tenants", async () => {
|
|
78
|
-
const email = generator.email({})
|
|
79
|
-
const user: User = structures.users.user({
|
|
80
|
-
email,
|
|
81
|
-
tenantId: config.getTenantId(),
|
|
82
|
-
})
|
|
83
|
-
|
|
84
|
-
await config.doInTenant(() => db.save(user))
|
|
85
|
-
|
|
86
|
-
config.newTenant()
|
|
87
|
-
await config.doInTenant(() =>
|
|
88
|
-
expect(db.save(user)).rejects.toThrow(
|
|
89
|
-
`Email already in use: '${email}'`
|
|
90
|
-
)
|
|
91
|
-
)
|
|
92
|
-
})
|
|
93
|
-
})
|
|
94
|
-
|
|
95
|
-
describe("update", () => {
|
|
96
|
-
let user: User
|
|
97
|
-
|
|
98
|
-
beforeEach(async () => {
|
|
99
|
-
user = await config.doInTenant(() =>
|
|
100
|
-
db.save(
|
|
101
|
-
structures.users.user({
|
|
102
|
-
email: generator.email({}),
|
|
103
|
-
tenantId: config.getTenantId(),
|
|
104
|
-
})
|
|
105
|
-
)
|
|
106
|
-
)
|
|
107
|
-
})
|
|
108
|
-
|
|
109
|
-
it("can update user properties", async () => {
|
|
110
|
-
await config.doInTenant(async () => {
|
|
111
|
-
const updatedName = generator.first()
|
|
112
|
-
user.firstName = updatedName
|
|
113
|
-
|
|
114
|
-
await db.save(user)
|
|
115
|
-
|
|
116
|
-
const persistedUser = await db.getUserByEmail(user.email)
|
|
117
|
-
expect(persistedUser).toEqual(
|
|
118
|
-
expect.objectContaining({
|
|
119
|
-
_id: user._id,
|
|
120
|
-
email: user.email,
|
|
121
|
-
firstName: updatedName,
|
|
122
|
-
lastName: user.lastName,
|
|
123
|
-
})
|
|
124
|
-
)
|
|
125
|
-
})
|
|
126
|
-
})
|
|
127
|
-
|
|
128
|
-
it("email cannot be updated by default", async () => {
|
|
129
|
-
await config.doInTenant(async () => {
|
|
130
|
-
await expect(
|
|
131
|
-
db.save({ ...user, email: generator.email({}) })
|
|
132
|
-
).rejects.toThrow("Email address cannot be changed")
|
|
133
|
-
})
|
|
134
|
-
})
|
|
135
|
-
|
|
136
|
-
it("email can be updated if specified", async () => {
|
|
137
|
-
await config.doInTenant(async () => {
|
|
138
|
-
const newEmail = generator.email({})
|
|
139
|
-
|
|
140
|
-
await db.save(
|
|
141
|
-
{ ...user, email: newEmail },
|
|
142
|
-
{ allowChangingEmail: true }
|
|
143
|
-
)
|
|
144
|
-
|
|
145
|
-
const persistedUser = await db.getUserByEmail(newEmail)
|
|
146
|
-
expect(persistedUser).toEqual(
|
|
147
|
-
expect.objectContaining({
|
|
148
|
-
_id: user._id,
|
|
149
|
-
email: newEmail,
|
|
150
|
-
lastName: user.lastName,
|
|
151
|
-
_rev: expect.stringMatching(/^2-\w+/),
|
|
152
|
-
})
|
|
153
|
-
)
|
|
154
|
-
})
|
|
155
|
-
})
|
|
156
|
-
|
|
157
|
-
it("updating emails frees previous emails", async () => {
|
|
158
|
-
await config.doInTenant(async () => {
|
|
159
|
-
const previousEmail = user.email
|
|
160
|
-
const newEmail = generator.email({})
|
|
161
|
-
expect(await searchExistingEmails([previousEmail, newEmail])).toEqual(
|
|
162
|
-
[previousEmail]
|
|
163
|
-
)
|
|
164
|
-
|
|
165
|
-
await db.save(
|
|
166
|
-
{ ...user, email: newEmail },
|
|
167
|
-
{ allowChangingEmail: true }
|
|
168
|
-
)
|
|
169
|
-
|
|
170
|
-
expect(await searchExistingEmails([previousEmail, newEmail])).toEqual(
|
|
171
|
-
[newEmail]
|
|
172
|
-
)
|
|
173
|
-
|
|
174
|
-
await db.save(
|
|
175
|
-
structures.users.user({
|
|
176
|
-
email: previousEmail,
|
|
177
|
-
tenantId: config.getTenantId(),
|
|
178
|
-
})
|
|
179
|
-
)
|
|
180
|
-
|
|
181
|
-
expect(await searchExistingEmails([previousEmail, newEmail])).toEqual(
|
|
182
|
-
[previousEmail, newEmail]
|
|
183
|
-
)
|
|
184
|
-
})
|
|
185
|
-
})
|
|
186
|
-
})
|
|
187
|
-
})
|
|
188
|
-
})
|
|
@@ -1,67 +0,0 @@
|
|
|
1
|
-
import { User, UserGroup } from "@budibase/types"
|
|
2
|
-
import { generator, structures } from "../../../tests"
|
|
3
|
-
import { DBTestConfiguration } from "../../../tests/extra"
|
|
4
|
-
import { getGlobalDB } from "../../context"
|
|
5
|
-
import { isCreator } from "../utils"
|
|
6
|
-
|
|
7
|
-
const config = new DBTestConfiguration()
|
|
8
|
-
|
|
9
|
-
describe("Users", () => {
|
|
10
|
-
it("User is a creator if it is configured as a global builder", async () => {
|
|
11
|
-
const user: User = structures.users.user({ builder: { global: true } })
|
|
12
|
-
expect(await isCreator(user)).toBe(true)
|
|
13
|
-
})
|
|
14
|
-
|
|
15
|
-
it("User is a creator if it is configured as a global admin", async () => {
|
|
16
|
-
const user: User = structures.users.user({ admin: { global: true } })
|
|
17
|
-
expect(await isCreator(user)).toBe(true)
|
|
18
|
-
})
|
|
19
|
-
|
|
20
|
-
it("User is a creator if it is configured with creator permission", async () => {
|
|
21
|
-
const user: User = structures.users.user({ builder: { creator: true } })
|
|
22
|
-
expect(await isCreator(user)).toBe(true)
|
|
23
|
-
})
|
|
24
|
-
|
|
25
|
-
it("User is a creator if it is a builder in some application", async () => {
|
|
26
|
-
const user: User = structures.users.user({ builder: { apps: ["app1"] } })
|
|
27
|
-
expect(await isCreator(user)).toBe(true)
|
|
28
|
-
})
|
|
29
|
-
|
|
30
|
-
it("User is a creator if it has CREATOR permission in some application", async () => {
|
|
31
|
-
const user: User = structures.users.user({ roles: { app1: "CREATOR" } })
|
|
32
|
-
expect(await isCreator(user)).toBe(true)
|
|
33
|
-
})
|
|
34
|
-
|
|
35
|
-
it("User is a creator if it has ADMIN permission in some application", async () => {
|
|
36
|
-
const user: User = structures.users.user({ roles: { app1: "ADMIN" } })
|
|
37
|
-
expect(await isCreator(user)).toBe(true)
|
|
38
|
-
})
|
|
39
|
-
|
|
40
|
-
it("User is a creator if it remains to a group with ADMIN permissions", async () => {
|
|
41
|
-
const usersInGroup = 10
|
|
42
|
-
const groupId = "gr_17abffe89e0b40268e755b952f101a59"
|
|
43
|
-
const group: UserGroup = {
|
|
44
|
-
...structures.userGroups.userGroup(),
|
|
45
|
-
...{ _id: groupId, roles: { app1: "ADMIN" } },
|
|
46
|
-
}
|
|
47
|
-
const users: User[] = []
|
|
48
|
-
for (let i = 0; i < usersInGroup; i++) {
|
|
49
|
-
const userId = `us_${generator.guid()}`
|
|
50
|
-
const user: User = structures.users.user({
|
|
51
|
-
_id: userId,
|
|
52
|
-
userGroups: [groupId],
|
|
53
|
-
})
|
|
54
|
-
users.push(user)
|
|
55
|
-
}
|
|
56
|
-
|
|
57
|
-
await config.doInTenant(async () => {
|
|
58
|
-
const db = getGlobalDB()
|
|
59
|
-
await db.put(group)
|
|
60
|
-
for (let user of users) {
|
|
61
|
-
await db.put(user)
|
|
62
|
-
const creator = await isCreator(user)
|
|
63
|
-
expect(creator).toBe(true)
|
|
64
|
-
}
|
|
65
|
-
})
|
|
66
|
-
})
|
|
67
|
-
})
|