@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/users.ts
DELETED
|
@@ -1,353 +0,0 @@
|
|
|
1
|
-
import {
|
|
2
|
-
directCouchFind,
|
|
3
|
-
DocumentType,
|
|
4
|
-
generateAppUserID,
|
|
5
|
-
getGlobalUserParams,
|
|
6
|
-
getProdAppID,
|
|
7
|
-
getUsersByAppParams,
|
|
8
|
-
pagination,
|
|
9
|
-
queryGlobalView,
|
|
10
|
-
queryGlobalViewRaw,
|
|
11
|
-
SEPARATOR,
|
|
12
|
-
UNICODE_MAX,
|
|
13
|
-
ViewName,
|
|
14
|
-
} from "../db"
|
|
15
|
-
import {
|
|
16
|
-
BulkDocsResponse,
|
|
17
|
-
ContextUser,
|
|
18
|
-
CouchFindOptions,
|
|
19
|
-
DatabaseQueryOpts,
|
|
20
|
-
SearchUsersRequest,
|
|
21
|
-
User,
|
|
22
|
-
} from "@budibase/types"
|
|
23
|
-
import * as context from "../context"
|
|
24
|
-
import { getGlobalDB } from "../context"
|
|
25
|
-
import { isCreator } from "./utils"
|
|
26
|
-
import { UserDB } from "./db"
|
|
27
|
-
import { dataFilters } from "@budibase/shared-core"
|
|
28
|
-
|
|
29
|
-
type GetOpts = { cleanup?: boolean }
|
|
30
|
-
|
|
31
|
-
function removeUserPassword(users: User | User[]) {
|
|
32
|
-
if (Array.isArray(users)) {
|
|
33
|
-
return users.map(user => {
|
|
34
|
-
if (user) {
|
|
35
|
-
delete user.password
|
|
36
|
-
return user
|
|
37
|
-
}
|
|
38
|
-
})
|
|
39
|
-
} else if (users) {
|
|
40
|
-
delete users.password
|
|
41
|
-
return users
|
|
42
|
-
}
|
|
43
|
-
return users
|
|
44
|
-
}
|
|
45
|
-
|
|
46
|
-
export async function bulkGetGlobalUsersById(
|
|
47
|
-
userIds: string[],
|
|
48
|
-
opts?: GetOpts
|
|
49
|
-
) {
|
|
50
|
-
const db = getGlobalDB()
|
|
51
|
-
let users = (
|
|
52
|
-
await db.allDocs({
|
|
53
|
-
keys: userIds,
|
|
54
|
-
include_docs: true,
|
|
55
|
-
})
|
|
56
|
-
).rows.map(row => row.doc) as User[]
|
|
57
|
-
if (opts?.cleanup) {
|
|
58
|
-
users = removeUserPassword(users) as User[]
|
|
59
|
-
}
|
|
60
|
-
return users
|
|
61
|
-
}
|
|
62
|
-
|
|
63
|
-
export async function getAllUserIds() {
|
|
64
|
-
const db = getGlobalDB()
|
|
65
|
-
const startKey = `${DocumentType.USER}${SEPARATOR}`
|
|
66
|
-
const response = await db.allDocs({
|
|
67
|
-
startkey: startKey,
|
|
68
|
-
endkey: `${startKey}${UNICODE_MAX}`,
|
|
69
|
-
})
|
|
70
|
-
return response.rows.map(row => row.id)
|
|
71
|
-
}
|
|
72
|
-
|
|
73
|
-
export async function getAllUsers(): Promise<User[]> {
|
|
74
|
-
const db = getGlobalDB()
|
|
75
|
-
const startKey = `${DocumentType.USER}${SEPARATOR}`
|
|
76
|
-
const response = await db.allDocs({
|
|
77
|
-
startkey: startKey,
|
|
78
|
-
endkey: `${startKey}${UNICODE_MAX}`,
|
|
79
|
-
include_docs: true,
|
|
80
|
-
})
|
|
81
|
-
return response.rows.map(row => row.doc) as User[]
|
|
82
|
-
}
|
|
83
|
-
|
|
84
|
-
export async function bulkUpdateGlobalUsers(users: User[]) {
|
|
85
|
-
const db = getGlobalDB()
|
|
86
|
-
return (await db.bulkDocs(users)) as BulkDocsResponse
|
|
87
|
-
}
|
|
88
|
-
|
|
89
|
-
export async function getById(id: string, opts?: GetOpts): Promise<User> {
|
|
90
|
-
const db = context.getGlobalDB()
|
|
91
|
-
let user = await db.get<User>(id)
|
|
92
|
-
if (opts?.cleanup) {
|
|
93
|
-
user = removeUserPassword(user) as User
|
|
94
|
-
}
|
|
95
|
-
return user
|
|
96
|
-
}
|
|
97
|
-
|
|
98
|
-
/**
|
|
99
|
-
* Given an email address this will use a view to search through
|
|
100
|
-
* all the users to find one with this email address.
|
|
101
|
-
*/
|
|
102
|
-
export async function getGlobalUserByEmail(
|
|
103
|
-
email: String,
|
|
104
|
-
opts?: GetOpts
|
|
105
|
-
): Promise<User | undefined> {
|
|
106
|
-
if (email == null) {
|
|
107
|
-
throw "Must supply an email address to view"
|
|
108
|
-
}
|
|
109
|
-
|
|
110
|
-
const response = await queryGlobalView<User>(ViewName.USER_BY_EMAIL, {
|
|
111
|
-
key: email.toLowerCase(),
|
|
112
|
-
include_docs: true,
|
|
113
|
-
})
|
|
114
|
-
|
|
115
|
-
if (Array.isArray(response)) {
|
|
116
|
-
// shouldn't be able to happen, but need to handle just in case
|
|
117
|
-
throw new Error(`Multiple users found with email address: ${email}`)
|
|
118
|
-
}
|
|
119
|
-
|
|
120
|
-
let user = response as User
|
|
121
|
-
if (opts?.cleanup) {
|
|
122
|
-
user = removeUserPassword(user) as User
|
|
123
|
-
}
|
|
124
|
-
|
|
125
|
-
return user
|
|
126
|
-
}
|
|
127
|
-
|
|
128
|
-
export async function doesUserExist(email: string) {
|
|
129
|
-
try {
|
|
130
|
-
const user = await getGlobalUserByEmail(email)
|
|
131
|
-
if (Array.isArray(user) || user != null) {
|
|
132
|
-
return true
|
|
133
|
-
}
|
|
134
|
-
} catch (err) {
|
|
135
|
-
return false
|
|
136
|
-
}
|
|
137
|
-
return false
|
|
138
|
-
}
|
|
139
|
-
|
|
140
|
-
export async function searchGlobalUsersByApp(
|
|
141
|
-
appId: any,
|
|
142
|
-
opts: DatabaseQueryOpts,
|
|
143
|
-
getOpts?: GetOpts
|
|
144
|
-
) {
|
|
145
|
-
if (typeof appId !== "string") {
|
|
146
|
-
throw new Error("Must provide a string based app ID")
|
|
147
|
-
}
|
|
148
|
-
const params = getUsersByAppParams(appId, {
|
|
149
|
-
include_docs: true,
|
|
150
|
-
})
|
|
151
|
-
params.startkey = opts && opts.startkey ? opts.startkey : params.startkey
|
|
152
|
-
let response = await queryGlobalView<User>(ViewName.USER_BY_APP, params)
|
|
153
|
-
|
|
154
|
-
if (!response) {
|
|
155
|
-
response = []
|
|
156
|
-
}
|
|
157
|
-
let users: User[] = Array.isArray(response) ? response : [response]
|
|
158
|
-
if (getOpts?.cleanup) {
|
|
159
|
-
users = removeUserPassword(users) as User[]
|
|
160
|
-
}
|
|
161
|
-
return users
|
|
162
|
-
}
|
|
163
|
-
|
|
164
|
-
/*
|
|
165
|
-
Return any user who potentially has access to the application
|
|
166
|
-
Admins, developers and app users with the explicitly role.
|
|
167
|
-
*/
|
|
168
|
-
export async function searchGlobalUsersByAppAccess(
|
|
169
|
-
appId: any,
|
|
170
|
-
opts?: { limit?: number }
|
|
171
|
-
) {
|
|
172
|
-
const roleSelector = `roles.${appId}`
|
|
173
|
-
|
|
174
|
-
let orQuery: any[] = [
|
|
175
|
-
{
|
|
176
|
-
"builder.global": true,
|
|
177
|
-
},
|
|
178
|
-
{
|
|
179
|
-
"admin.global": true,
|
|
180
|
-
},
|
|
181
|
-
]
|
|
182
|
-
|
|
183
|
-
if (appId) {
|
|
184
|
-
const roleCheck = {
|
|
185
|
-
[roleSelector]: {
|
|
186
|
-
$exists: true,
|
|
187
|
-
},
|
|
188
|
-
}
|
|
189
|
-
orQuery.push(roleCheck)
|
|
190
|
-
}
|
|
191
|
-
|
|
192
|
-
let searchOptions: CouchFindOptions = {
|
|
193
|
-
selector: {
|
|
194
|
-
$or: orQuery,
|
|
195
|
-
_id: {
|
|
196
|
-
$regex: "^us_",
|
|
197
|
-
},
|
|
198
|
-
},
|
|
199
|
-
limit: opts?.limit || 50,
|
|
200
|
-
}
|
|
201
|
-
|
|
202
|
-
const resp = await directCouchFind(context.getGlobalDBName(), searchOptions)
|
|
203
|
-
return resp.rows
|
|
204
|
-
}
|
|
205
|
-
|
|
206
|
-
export function getGlobalUserByAppPage(appId: string, user: User) {
|
|
207
|
-
if (!user) {
|
|
208
|
-
return
|
|
209
|
-
}
|
|
210
|
-
return generateAppUserID(getProdAppID(appId)!, user._id!)
|
|
211
|
-
}
|
|
212
|
-
|
|
213
|
-
/**
|
|
214
|
-
* Performs a starts with search on the global email view.
|
|
215
|
-
*/
|
|
216
|
-
export async function searchGlobalUsersByEmail(
|
|
217
|
-
email: string | unknown,
|
|
218
|
-
opts: any,
|
|
219
|
-
getOpts?: GetOpts
|
|
220
|
-
) {
|
|
221
|
-
if (typeof email !== "string") {
|
|
222
|
-
throw new Error("Must provide a string to search by")
|
|
223
|
-
}
|
|
224
|
-
const lcEmail = email.toLowerCase()
|
|
225
|
-
// handle if passing up startkey for pagination
|
|
226
|
-
const startkey = opts && opts.startkey ? opts.startkey : lcEmail
|
|
227
|
-
let response = await queryGlobalView<User>(ViewName.USER_BY_EMAIL, {
|
|
228
|
-
...opts,
|
|
229
|
-
startkey,
|
|
230
|
-
endkey: `${lcEmail}${UNICODE_MAX}`,
|
|
231
|
-
})
|
|
232
|
-
if (!response) {
|
|
233
|
-
response = []
|
|
234
|
-
}
|
|
235
|
-
let users: User[] = Array.isArray(response) ? response : [response]
|
|
236
|
-
if (getOpts?.cleanup) {
|
|
237
|
-
users = removeUserPassword(users) as User[]
|
|
238
|
-
}
|
|
239
|
-
return users
|
|
240
|
-
}
|
|
241
|
-
|
|
242
|
-
const PAGE_LIMIT = 8
|
|
243
|
-
export async function paginatedUsers({
|
|
244
|
-
bookmark,
|
|
245
|
-
query,
|
|
246
|
-
appId,
|
|
247
|
-
limit,
|
|
248
|
-
}: SearchUsersRequest = {}) {
|
|
249
|
-
const db = getGlobalDB()
|
|
250
|
-
const pageSize = limit ?? PAGE_LIMIT
|
|
251
|
-
const pageLimit = pageSize + 1
|
|
252
|
-
// get one extra document, to have the next page
|
|
253
|
-
const opts: DatabaseQueryOpts = {
|
|
254
|
-
include_docs: true,
|
|
255
|
-
limit: pageLimit,
|
|
256
|
-
}
|
|
257
|
-
// add a startkey if the page was specified (anchor)
|
|
258
|
-
if (bookmark) {
|
|
259
|
-
opts.startkey = bookmark
|
|
260
|
-
}
|
|
261
|
-
// property specifies what to use for the page/anchor
|
|
262
|
-
let userList: User[],
|
|
263
|
-
property = "_id",
|
|
264
|
-
getKey
|
|
265
|
-
if (query?.equal?._id) {
|
|
266
|
-
userList = [await getById(query.equal._id)]
|
|
267
|
-
} else if (appId) {
|
|
268
|
-
userList = await searchGlobalUsersByApp(appId, opts)
|
|
269
|
-
getKey = (doc: any) => getGlobalUserByAppPage(appId, doc)
|
|
270
|
-
} else if (query?.string?.email) {
|
|
271
|
-
userList = await searchGlobalUsersByEmail(query?.string?.email, opts)
|
|
272
|
-
property = "email"
|
|
273
|
-
} else if (query?.oneOf?._id) {
|
|
274
|
-
userList = await bulkGetGlobalUsersById(query?.oneOf?._id, {
|
|
275
|
-
cleanup: true,
|
|
276
|
-
})
|
|
277
|
-
} else if (query) {
|
|
278
|
-
// TODO: this should use SQS search, but the logic is built in the 'server' package. Using the in-memory filtering to get this working meanwhile
|
|
279
|
-
const response = await db.allDocs<User>(
|
|
280
|
-
getGlobalUserParams(null, { ...opts, limit: undefined })
|
|
281
|
-
)
|
|
282
|
-
userList = response.rows.map(row => row.doc!)
|
|
283
|
-
userList = dataFilters.search(userList, { query, limit: opts.limit }).rows
|
|
284
|
-
} else {
|
|
285
|
-
// no search, query allDocs
|
|
286
|
-
const response = await db.allDocs<User>(getGlobalUserParams(null, opts))
|
|
287
|
-
userList = response.rows.map(row => row.doc!)
|
|
288
|
-
}
|
|
289
|
-
return pagination(userList, pageSize, {
|
|
290
|
-
paginate: true,
|
|
291
|
-
property,
|
|
292
|
-
getKey,
|
|
293
|
-
})
|
|
294
|
-
}
|
|
295
|
-
|
|
296
|
-
export async function getUserCount() {
|
|
297
|
-
const response = await queryGlobalViewRaw(ViewName.USER_BY_EMAIL, {
|
|
298
|
-
limit: 0, // to be as fast as possible - we just want the total rows count
|
|
299
|
-
include_docs: false,
|
|
300
|
-
})
|
|
301
|
-
return response.total_rows
|
|
302
|
-
}
|
|
303
|
-
|
|
304
|
-
export async function getCreatorCount() {
|
|
305
|
-
let creators = 0
|
|
306
|
-
async function iterate(startPage?: string) {
|
|
307
|
-
const page = await paginatedUsers({ bookmark: startPage })
|
|
308
|
-
const creatorsEval = await Promise.all(page.data.map(isCreator))
|
|
309
|
-
creators += creatorsEval.filter(creator => !!creator).length
|
|
310
|
-
if (page.hasNextPage) {
|
|
311
|
-
await iterate(page.nextPage)
|
|
312
|
-
}
|
|
313
|
-
}
|
|
314
|
-
await iterate()
|
|
315
|
-
return creators
|
|
316
|
-
}
|
|
317
|
-
|
|
318
|
-
// used to remove the builder/admin permissions, for processing the
|
|
319
|
-
// user as an app user (they may have some specific role/group
|
|
320
|
-
export function removePortalUserPermissions(user: User | ContextUser) {
|
|
321
|
-
delete user.admin
|
|
322
|
-
delete user.builder
|
|
323
|
-
return user
|
|
324
|
-
}
|
|
325
|
-
|
|
326
|
-
export function cleanseUserObject(user: User | ContextUser, base?: User) {
|
|
327
|
-
delete user.admin
|
|
328
|
-
delete user.builder
|
|
329
|
-
delete user.roles
|
|
330
|
-
if (base) {
|
|
331
|
-
user.admin = base.admin
|
|
332
|
-
user.builder = base.builder
|
|
333
|
-
user.roles = base.roles
|
|
334
|
-
}
|
|
335
|
-
return user
|
|
336
|
-
}
|
|
337
|
-
|
|
338
|
-
export async function addAppBuilder(user: User, appId: string) {
|
|
339
|
-
const prodAppId = getProdAppID(appId)
|
|
340
|
-
user.builder ??= {}
|
|
341
|
-
user.builder.creator = true
|
|
342
|
-
user.builder.apps ??= []
|
|
343
|
-
user.builder.apps.push(prodAppId)
|
|
344
|
-
await UserDB.save(user, { hashPassword: false })
|
|
345
|
-
}
|
|
346
|
-
|
|
347
|
-
export async function removeAppBuilder(user: User, appId: string) {
|
|
348
|
-
const prodAppId = getProdAppID(appId)
|
|
349
|
-
if (user.builder && user.builder.apps?.includes(prodAppId)) {
|
|
350
|
-
user.builder.apps = user.builder.apps.filter(id => id !== prodAppId)
|
|
351
|
-
}
|
|
352
|
-
await UserDB.save(user, { hashPassword: false })
|
|
353
|
-
}
|
package/src/users/utils.ts
DELETED
|
@@ -1,81 +0,0 @@
|
|
|
1
|
-
import { ContextUser, User, UserGroup, UserIdentifier } from "@budibase/types"
|
|
2
|
-
import * as accountSdk from "../accounts"
|
|
3
|
-
import env from "../environment"
|
|
4
|
-
import { getExistingAccounts, getFirstPlatformUser } from "./lookup"
|
|
5
|
-
import { EmailUnavailableError } from "../errors"
|
|
6
|
-
import { sdk } from "@budibase/shared-core"
|
|
7
|
-
import { BUILTIN_ROLE_IDS } from "../security/roles"
|
|
8
|
-
import * as context from "../context"
|
|
9
|
-
|
|
10
|
-
// extract from shared-core to make easily accessible from backend-core
|
|
11
|
-
export const isBuilder = sdk.users.isBuilder
|
|
12
|
-
export const isAdmin = sdk.users.isAdmin
|
|
13
|
-
export const isGlobalBuilder = sdk.users.isGlobalBuilder
|
|
14
|
-
export const isAdminOrBuilder = sdk.users.isAdminOrBuilder
|
|
15
|
-
export const hasAdminPermissions = sdk.users.hasAdminPermissions
|
|
16
|
-
export const hasBuilderPermissions = sdk.users.hasBuilderPermissions
|
|
17
|
-
export const hasAppBuilderPermissions = sdk.users.hasAppBuilderPermissions
|
|
18
|
-
|
|
19
|
-
export async function isCreator(user?: User | ContextUser) {
|
|
20
|
-
const isCreatorByUserDefinition = sdk.users.isCreator(user)
|
|
21
|
-
if (!isCreatorByUserDefinition && user) {
|
|
22
|
-
return await isCreatorByGroupMembership(user)
|
|
23
|
-
}
|
|
24
|
-
return isCreatorByUserDefinition
|
|
25
|
-
}
|
|
26
|
-
|
|
27
|
-
async function isCreatorByGroupMembership(user?: User | ContextUser) {
|
|
28
|
-
const userGroups = user?.userGroups || []
|
|
29
|
-
if (userGroups.length > 0) {
|
|
30
|
-
const db = context.getGlobalDB()
|
|
31
|
-
const groups: UserGroup[] = []
|
|
32
|
-
for (let groupId of userGroups) {
|
|
33
|
-
try {
|
|
34
|
-
const group = await db.get<UserGroup>(groupId)
|
|
35
|
-
groups.push(group)
|
|
36
|
-
} catch (e: any) {
|
|
37
|
-
if (e.error !== "not_found") {
|
|
38
|
-
throw e
|
|
39
|
-
}
|
|
40
|
-
}
|
|
41
|
-
}
|
|
42
|
-
return groups.some(group =>
|
|
43
|
-
Object.values(group.roles || {}).includes(BUILTIN_ROLE_IDS.ADMIN)
|
|
44
|
-
)
|
|
45
|
-
}
|
|
46
|
-
return false
|
|
47
|
-
}
|
|
48
|
-
|
|
49
|
-
export async function validateUniqueUser(email: string, tenantId: string) {
|
|
50
|
-
// check budibase users in other tenants
|
|
51
|
-
if (env.MULTI_TENANCY) {
|
|
52
|
-
const tenantUser = await getFirstPlatformUser(email)
|
|
53
|
-
if (tenantUser != null && tenantUser.tenantId !== tenantId) {
|
|
54
|
-
throw new EmailUnavailableError(email)
|
|
55
|
-
}
|
|
56
|
-
}
|
|
57
|
-
|
|
58
|
-
// check root account users in account portal
|
|
59
|
-
if (!env.SELF_HOSTED && !env.DISABLE_ACCOUNT_PORTAL) {
|
|
60
|
-
const account = await accountSdk.getAccount(email)
|
|
61
|
-
if (account && account.verified && account.tenantId !== tenantId) {
|
|
62
|
-
throw new EmailUnavailableError(email)
|
|
63
|
-
}
|
|
64
|
-
}
|
|
65
|
-
}
|
|
66
|
-
|
|
67
|
-
/**
|
|
68
|
-
* For a list of users, return the account holder if there is an email match.
|
|
69
|
-
*/
|
|
70
|
-
export async function getAccountHolderFromUsers(
|
|
71
|
-
users: Array<UserIdentifier>
|
|
72
|
-
): Promise<UserIdentifier | undefined> {
|
|
73
|
-
if (!env.SELF_HOSTED && !env.DISABLE_ACCOUNT_PORTAL) {
|
|
74
|
-
const accountMetadata = await getExistingAccounts(
|
|
75
|
-
users.map(user => user.email)
|
|
76
|
-
)
|
|
77
|
-
return users.find(user =>
|
|
78
|
-
accountMetadata.map(metadata => metadata.email).includes(user.email)
|
|
79
|
-
)
|
|
80
|
-
}
|
|
81
|
-
}
|
package/src/utils/Duration.ts
DELETED
|
@@ -1,56 +0,0 @@
|
|
|
1
|
-
export enum DurationType {
|
|
2
|
-
MILLISECONDS = "milliseconds",
|
|
3
|
-
SECONDS = "seconds",
|
|
4
|
-
MINUTES = "minutes",
|
|
5
|
-
HOURS = "hours",
|
|
6
|
-
DAYS = "days",
|
|
7
|
-
}
|
|
8
|
-
|
|
9
|
-
const conversion: Record<DurationType, number> = {
|
|
10
|
-
milliseconds: 1,
|
|
11
|
-
seconds: 1000,
|
|
12
|
-
minutes: 60 * 1000,
|
|
13
|
-
hours: 60 * 60 * 1000,
|
|
14
|
-
days: 24 * 60 * 60 * 1000,
|
|
15
|
-
}
|
|
16
|
-
|
|
17
|
-
export class Duration {
|
|
18
|
-
static convert(from: DurationType, to: DurationType, duration: number) {
|
|
19
|
-
const milliseconds = duration * conversion[from]
|
|
20
|
-
return milliseconds / conversion[to]
|
|
21
|
-
}
|
|
22
|
-
|
|
23
|
-
static from(from: DurationType, duration: number) {
|
|
24
|
-
return {
|
|
25
|
-
to: (to: DurationType) => {
|
|
26
|
-
return Duration.convert(from, to, duration)
|
|
27
|
-
},
|
|
28
|
-
toMs: () => {
|
|
29
|
-
return Duration.convert(from, DurationType.MILLISECONDS, duration)
|
|
30
|
-
},
|
|
31
|
-
toSeconds: () => {
|
|
32
|
-
return Duration.convert(from, DurationType.SECONDS, duration)
|
|
33
|
-
},
|
|
34
|
-
}
|
|
35
|
-
}
|
|
36
|
-
|
|
37
|
-
static fromSeconds(duration: number) {
|
|
38
|
-
return Duration.from(DurationType.SECONDS, duration)
|
|
39
|
-
}
|
|
40
|
-
|
|
41
|
-
static fromMinutes(duration: number) {
|
|
42
|
-
return Duration.from(DurationType.MINUTES, duration)
|
|
43
|
-
}
|
|
44
|
-
|
|
45
|
-
static fromHours(duration: number) {
|
|
46
|
-
return Duration.from(DurationType.HOURS, duration)
|
|
47
|
-
}
|
|
48
|
-
|
|
49
|
-
static fromDays(duration: number) {
|
|
50
|
-
return Duration.from(DurationType.DAYS, duration)
|
|
51
|
-
}
|
|
52
|
-
|
|
53
|
-
static fromMilliseconds(duration: number) {
|
|
54
|
-
return Duration.from(DurationType.MILLISECONDS, duration)
|
|
55
|
-
}
|
|
56
|
-
}
|
package/src/utils/hashing.ts
DELETED
|
@@ -1,15 +0,0 @@
|
|
|
1
|
-
import env from "../environment"
|
|
2
|
-
|
|
3
|
-
export * from "../docIds/newid"
|
|
4
|
-
const bcrypt = env.JS_BCRYPT ? require("bcryptjs") : require("bcrypt")
|
|
5
|
-
|
|
6
|
-
const SALT_ROUNDS = env.SALT_ROUNDS || 10
|
|
7
|
-
|
|
8
|
-
export async function hash(data: string) {
|
|
9
|
-
const salt = await bcrypt.genSalt(SALT_ROUNDS)
|
|
10
|
-
return bcrypt.hash(data, salt)
|
|
11
|
-
}
|
|
12
|
-
|
|
13
|
-
export async function compare(data: string, encrypted: string) {
|
|
14
|
-
return bcrypt.compare(data, encrypted)
|
|
15
|
-
}
|
package/src/utils/index.ts
DELETED
package/src/utils/stringUtils.ts
DELETED
|
@@ -1,19 +0,0 @@
|
|
|
1
|
-
import { Duration, DurationType } from "../Duration"
|
|
2
|
-
|
|
3
|
-
describe("duration", () => {
|
|
4
|
-
it("should convert minutes to milliseconds", () => {
|
|
5
|
-
expect(Duration.fromMinutes(5).toMs()).toBe(300000)
|
|
6
|
-
})
|
|
7
|
-
|
|
8
|
-
it("should convert seconds to milliseconds", () => {
|
|
9
|
-
expect(Duration.fromSeconds(30).toMs()).toBe(30000)
|
|
10
|
-
})
|
|
11
|
-
|
|
12
|
-
it("should convert days to milliseconds", () => {
|
|
13
|
-
expect(Duration.fromDays(1).toMs()).toBe(86400000)
|
|
14
|
-
})
|
|
15
|
-
|
|
16
|
-
it("should convert minutes to days", () => {
|
|
17
|
-
expect(Duration.fromMinutes(1440).to(DurationType.DAYS)).toBe(1)
|
|
18
|
-
})
|
|
19
|
-
})
|