@budibase/backend-core 2.9.19-alpha.0 → 2.9.20
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 +324 -266
- package/dist/index.js.map +4 -4
- package/dist/index.js.meta.json +1 -1
- package/dist/package.json +19 -4
- package/dist/plugins.js +1 -1
- package/dist/plugins.js.map +1 -1
- package/dist/plugins.js.meta.json +1 -1
- package/dist/src/security/permissions.d.ts +1 -1
- package/dist/tests.js +260 -222
- package/dist/tests.js.map +4 -4
- package/dist/tests.js.meta.json +1 -1
- package/package.json +19 -4
- package/__mocks__/aws-sdk.ts +0 -18
- package/dist/tsconfig.build.tsbuildinfo +0 -1
- package/jest-testcontainers-config.js +0 -8
- package/jest.config.ts +0 -35
- package/scripts/build.js +0 -6
- package/scripts/test.sh +0 -13
- 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 -208
- 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 -92
- package/src/cache/generic.ts +0 -30
- package/src/cache/index.ts +0 -5
- package/src/cache/tests/writethrough.spec.ts +0 -138
- package/src/cache/user.ts +0 -69
- package/src/cache/writethrough.ts +0 -133
- package/src/configs/configs.ts +0 -257
- package/src/configs/index.ts +0 -1
- package/src/configs/tests/configs.spec.ts +0 -184
- package/src/constants/db.ts +0 -63
- package/src/constants/index.ts +0 -2
- package/src/constants/misc.ts +0 -50
- 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 -310
- package/src/context/tests/index.spec.ts +0 -147
- package/src/context/types.ts +0 -11
- package/src/db/Replication.ts +0 -84
- package/src/db/constants.ts +0 -10
- package/src/db/couch/DatabaseImpl.ts +0 -238
- package/src/db/couch/connections.ts +0 -77
- package/src/db/couch/index.ts +0 -5
- package/src/db/couch/pouchDB.ts +0 -97
- package/src/db/couch/pouchDump.ts +0 -0
- package/src/db/couch/utils.ts +0 -50
- package/src/db/db.ts +0 -39
- package/src/db/errors.ts +0 -14
- package/src/db/index.ts +0 -12
- package/src/db/lucene.ts +0 -732
- package/src/db/searchIndexes/index.ts +0 -1
- package/src/db/searchIndexes/searchIndexes.ts +0 -62
- package/src/db/tests/index.spec.js +0 -25
- package/src/db/tests/lucene.spec.ts +0 -298
- package/src/db/tests/pouch.spec.js +0 -62
- package/src/db/tests/utils.spec.ts +0 -63
- package/src/db/utils.ts +0 -207
- package/src/db/views.ts +0 -241
- package/src/docIds/conversions.ts +0 -59
- package/src/docIds/ids.ts +0 -113
- package/src/docIds/index.ts +0 -2
- package/src/docIds/newid.ts +0 -5
- package/src/docIds/params.ts +0 -174
- package/src/docUpdates/index.ts +0 -29
- package/src/environment.ts +0 -201
- 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 -40
- package/src/events/identification.ts +0 -310
- package/src/events/index.ts +0 -14
- package/src/events/processors/AnalyticsProcessor.ts +0 -64
- package/src/events/processors/AuditLogsProcessor.ts +0 -93
- package/src/events/processors/LoggingProcessor.ts +0 -37
- package/src/events/processors/Processors.ts +0 -52
- package/src/events/processors/async/DocumentUpdateProcessor.ts +0 -43
- 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 -2
- package/src/events/processors/posthog/rateLimiting.ts +0 -106
- package/src/events/processors/posthog/tests/PosthogProcessor.spec.ts +0 -168
- package/src/events/processors/types.ts +0 -1
- package/src/events/publishers/account.ts +0 -35
- package/src/events/publishers/app.ts +0 -155
- 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 -24
- 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 -88
- 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/featureFlags/index.ts +0 -77
- package/src/featureFlags/tests/featureFlags.spec.ts +0 -85
- package/src/helpers.ts +0 -9
- package/src/index.ts +0 -53
- package/src/installation.ts +0 -107
- package/src/logging/alerts.ts +0 -26
- package/src/logging/correlation/correlation.ts +0 -13
- package/src/logging/correlation/index.ts +0 -1
- package/src/logging/correlation/middleware.ts +0 -17
- package/src/logging/index.ts +0 -4
- package/src/logging/pino/logger.ts +0 -232
- package/src/logging/pino/middleware.ts +0 -45
- 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 -193
- package/src/middleware/builderOnly.ts +0 -20
- package/src/middleware/builderOrAdmin.ts +0 -20
- package/src/middleware/csrf.ts +0 -81
- package/src/middleware/errorHandling.ts +0 -29
- package/src/middleware/index.ts +0 -21
- package/src/middleware/internalApi.ts +0 -23
- package/src/middleware/joi-validator.ts +0 -45
- package/src/middleware/matchers.ts +0 -47
- package/src/middleware/passport/datasource/google.ts +0 -95
- 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 -154
- package/src/middleware/passport/sso/sso.ts +0 -165
- package/src/middleware/passport/sso/tests/google.spec.ts +0 -67
- package/src/middleware/passport/sso/tests/oidc.spec.ts +0 -152
- 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 -180
- package/src/middleware/tests/matchers.spec.ts +0 -134
- package/src/migrations/definitions.ts +0 -40
- package/src/migrations/index.ts +0 -2
- package/src/migrations/migrations.ts +0 -191
- 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 -40
- 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 -171
- 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 -440
- package/src/objectStore/utils.ts +0 -27
- 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 -90
- package/src/plugin/index.ts +0 -1
- package/src/plugin/tests/validation.spec.ts +0 -83
- package/src/plugin/utils.ts +0 -156
- package/src/queue/constants.ts +0 -6
- package/src/queue/inMemoryQueue.ts +0 -141
- package/src/queue/index.ts +0 -2
- package/src/queue/listeners.ts +0 -195
- package/src/queue/queue.ts +0 -54
- package/src/redis/index.ts +0 -6
- package/src/redis/init.ts +0 -86
- package/src/redis/redis.ts +0 -308
- package/src/redis/redlockImpl.ts +0 -139
- package/src/redis/utils.ts +0 -117
- package/src/security/encryption.ts +0 -179
- package/src/security/permissions.ts +0 -159
- package/src/security/roles.ts +0 -420
- package/src/security/sessions.ts +0 -120
- package/src/security/tests/encryption.spec.ts +0 -31
- package/src/security/tests/permissions.spec.ts +0 -145
- package/src/security/tests/sessions.spec.ts +0 -12
- package/src/tenancy/db.ts +0 -6
- package/src/tenancy/index.ts +0 -2
- package/src/tenancy/tenancy.ts +0 -140
- 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 -460
- package/src/users/events.ts +0 -176
- package/src/users/index.ts +0 -4
- package/src/users/lookup.ts +0 -102
- package/src/users/users.ts +0 -276
- package/src/users/utils.ts +0 -55
- package/src/utils/hashing.ts +0 -14
- package/src/utils/index.ts +0 -3
- package/src/utils/stringUtils.ts +0 -8
- package/src/utils/tests/utils.spec.ts +0 -191
- package/src/utils/utils.ts +0 -239
- package/tests/core/logging.ts +0 -34
- package/tests/core/utilities/index.ts +0 -6
- package/tests/core/utilities/jestUtils.ts +0 -30
- package/tests/core/utilities/mocks/alerts.ts +0 -3
- package/tests/core/utilities/mocks/date.ts +0 -2
- package/tests/core/utilities/mocks/events.ts +0 -131
- package/tests/core/utilities/mocks/fetch.ts +0 -17
- package/tests/core/utilities/mocks/index.ts +0 -10
- package/tests/core/utilities/mocks/licenses.ts +0 -107
- package/tests/core/utilities/mocks/posthog.ts +0 -7
- package/tests/core/utilities/structures/Chance.ts +0 -20
- package/tests/core/utilities/structures/accounts.ts +0 -115
- 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 -2
- 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 -167
- package/tests/core/utilities/structures/plugins.ts +0 -19
- package/tests/core/utilities/structures/quotas.ts +0 -67
- package/tests/core/utilities/structures/scim.ts +0 -80
- package/tests/core/utilities/structures/shared.ts +0 -19
- package/tests/core/utilities/structures/sso.ts +0 -119
- 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 -73
- package/tests/core/utilities/testContainerUtils.ts +0 -98
- package/tests/core/utilities/utils/index.ts +0 -1
- 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 -1
- package/tests/jestEnv.ts +0 -6
- package/tests/jestSetup.ts +0 -28
- package/tsconfig.build.json +0 -29
- package/tsconfig.json +0 -4
package/src/users/lookup.ts
DELETED
|
@@ -1,102 +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
|
-
|
|
10
|
-
/**
|
|
11
|
-
* Apply a system-wide search on emails:
|
|
12
|
-
* - in tenant
|
|
13
|
-
* - cross tenant
|
|
14
|
-
* - accounts
|
|
15
|
-
* return an array of emails that match the supplied emails.
|
|
16
|
-
*/
|
|
17
|
-
export async function searchExistingEmails(emails: string[]) {
|
|
18
|
-
let matchedEmails: string[] = []
|
|
19
|
-
|
|
20
|
-
const existingTenantUsers = await getExistingTenantUsers(emails)
|
|
21
|
-
matchedEmails.push(...existingTenantUsers.map(user => user.email))
|
|
22
|
-
|
|
23
|
-
const existingPlatformUsers = await getExistingPlatformUsers(emails)
|
|
24
|
-
matchedEmails.push(...existingPlatformUsers.map(user => user._id!))
|
|
25
|
-
|
|
26
|
-
const existingAccounts = await getExistingAccounts(emails)
|
|
27
|
-
matchedEmails.push(...existingAccounts.map(account => account.email))
|
|
28
|
-
|
|
29
|
-
return [...new Set(matchedEmails.map(email => email.toLowerCase()))]
|
|
30
|
-
}
|
|
31
|
-
|
|
32
|
-
// lookup, could be email or userId, either will return a doc
|
|
33
|
-
export async function getPlatformUser(
|
|
34
|
-
identifier: string
|
|
35
|
-
): Promise<PlatformUser | null> {
|
|
36
|
-
// use the view here and allow to find anyone regardless of casing
|
|
37
|
-
// Use lowercase to ensure email login is case insensitive
|
|
38
|
-
return (await dbUtils.queryPlatformView(ViewName.PLATFORM_USERS_LOWERCASE, {
|
|
39
|
-
keys: [identifier.toLowerCase()],
|
|
40
|
-
include_docs: true,
|
|
41
|
-
})) as PlatformUser
|
|
42
|
-
}
|
|
43
|
-
|
|
44
|
-
export async function getExistingTenantUsers(
|
|
45
|
-
emails: string[]
|
|
46
|
-
): Promise<User[]> {
|
|
47
|
-
const lcEmails = emails.map(email => email.toLowerCase())
|
|
48
|
-
const params = {
|
|
49
|
-
keys: lcEmails,
|
|
50
|
-
include_docs: true,
|
|
51
|
-
}
|
|
52
|
-
|
|
53
|
-
const opts = {
|
|
54
|
-
arrayResponse: true,
|
|
55
|
-
}
|
|
56
|
-
|
|
57
|
-
return (await dbUtils.queryGlobalView(
|
|
58
|
-
ViewName.USER_BY_EMAIL,
|
|
59
|
-
params,
|
|
60
|
-
undefined,
|
|
61
|
-
opts
|
|
62
|
-
)) as User[]
|
|
63
|
-
}
|
|
64
|
-
|
|
65
|
-
export async function getExistingPlatformUsers(
|
|
66
|
-
emails: string[]
|
|
67
|
-
): Promise<PlatformUserByEmail[]> {
|
|
68
|
-
const lcEmails = emails.map(email => email.toLowerCase())
|
|
69
|
-
const params = {
|
|
70
|
-
keys: lcEmails,
|
|
71
|
-
include_docs: true,
|
|
72
|
-
}
|
|
73
|
-
|
|
74
|
-
const opts = {
|
|
75
|
-
arrayResponse: true,
|
|
76
|
-
}
|
|
77
|
-
return (await dbUtils.queryPlatformView(
|
|
78
|
-
ViewName.PLATFORM_USERS_LOWERCASE,
|
|
79
|
-
params,
|
|
80
|
-
opts
|
|
81
|
-
)) as PlatformUserByEmail[]
|
|
82
|
-
}
|
|
83
|
-
|
|
84
|
-
export async function getExistingAccounts(
|
|
85
|
-
emails: string[]
|
|
86
|
-
): Promise<AccountMetadata[]> {
|
|
87
|
-
const lcEmails = emails.map(email => email.toLowerCase())
|
|
88
|
-
const params = {
|
|
89
|
-
keys: lcEmails,
|
|
90
|
-
include_docs: true,
|
|
91
|
-
}
|
|
92
|
-
|
|
93
|
-
const opts = {
|
|
94
|
-
arrayResponse: true,
|
|
95
|
-
}
|
|
96
|
-
|
|
97
|
-
return (await dbUtils.queryPlatformView(
|
|
98
|
-
ViewName.ACCOUNT_BY_EMAIL,
|
|
99
|
-
params,
|
|
100
|
-
opts
|
|
101
|
-
)) as AccountMetadata[]
|
|
102
|
-
}
|
package/src/users/users.ts
DELETED
|
@@ -1,276 +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
|
-
SearchUsersRequest,
|
|
18
|
-
User,
|
|
19
|
-
ContextUser,
|
|
20
|
-
} from "@budibase/types"
|
|
21
|
-
import { getGlobalDB } from "../context"
|
|
22
|
-
import * as context from "../context"
|
|
23
|
-
import { user as userCache } from "../cache"
|
|
24
|
-
|
|
25
|
-
type GetOpts = { cleanup?: boolean }
|
|
26
|
-
|
|
27
|
-
function removeUserPassword(users: User | User[]) {
|
|
28
|
-
if (Array.isArray(users)) {
|
|
29
|
-
return users.map(user => {
|
|
30
|
-
if (user) {
|
|
31
|
-
delete user.password
|
|
32
|
-
return user
|
|
33
|
-
}
|
|
34
|
-
})
|
|
35
|
-
} else if (users) {
|
|
36
|
-
delete users.password
|
|
37
|
-
return users
|
|
38
|
-
}
|
|
39
|
-
return users
|
|
40
|
-
}
|
|
41
|
-
|
|
42
|
-
export const bulkGetGlobalUsersById = async (
|
|
43
|
-
userIds: string[],
|
|
44
|
-
opts?: GetOpts
|
|
45
|
-
) => {
|
|
46
|
-
const db = getGlobalDB()
|
|
47
|
-
let users = (
|
|
48
|
-
await db.allDocs({
|
|
49
|
-
keys: userIds,
|
|
50
|
-
include_docs: true,
|
|
51
|
-
})
|
|
52
|
-
).rows.map(row => row.doc) as User[]
|
|
53
|
-
if (opts?.cleanup) {
|
|
54
|
-
users = removeUserPassword(users) as User[]
|
|
55
|
-
}
|
|
56
|
-
return users
|
|
57
|
-
}
|
|
58
|
-
|
|
59
|
-
export const getAllUserIds = async () => {
|
|
60
|
-
const db = getGlobalDB()
|
|
61
|
-
const startKey = `${DocumentType.USER}${SEPARATOR}`
|
|
62
|
-
const response = await db.allDocs({
|
|
63
|
-
startkey: startKey,
|
|
64
|
-
endkey: `${startKey}${UNICODE_MAX}`,
|
|
65
|
-
})
|
|
66
|
-
return response.rows.map(row => row.id)
|
|
67
|
-
}
|
|
68
|
-
|
|
69
|
-
export const bulkUpdateGlobalUsers = async (users: User[]) => {
|
|
70
|
-
const db = getGlobalDB()
|
|
71
|
-
return (await db.bulkDocs(users)) as BulkDocsResponse
|
|
72
|
-
}
|
|
73
|
-
|
|
74
|
-
export async function getById(id: string, opts?: GetOpts): Promise<User> {
|
|
75
|
-
const db = context.getGlobalDB()
|
|
76
|
-
let user = await db.get<User>(id)
|
|
77
|
-
if (opts?.cleanup) {
|
|
78
|
-
user = removeUserPassword(user) as User
|
|
79
|
-
}
|
|
80
|
-
return user
|
|
81
|
-
}
|
|
82
|
-
|
|
83
|
-
/**
|
|
84
|
-
* Given an email address this will use a view to search through
|
|
85
|
-
* all the users to find one with this email address.
|
|
86
|
-
*/
|
|
87
|
-
export const getGlobalUserByEmail = async (
|
|
88
|
-
email: String,
|
|
89
|
-
opts?: GetOpts
|
|
90
|
-
): Promise<User | undefined> => {
|
|
91
|
-
if (email == null) {
|
|
92
|
-
throw "Must supply an email address to view"
|
|
93
|
-
}
|
|
94
|
-
|
|
95
|
-
const response = await queryGlobalView<User>(ViewName.USER_BY_EMAIL, {
|
|
96
|
-
key: email.toLowerCase(),
|
|
97
|
-
include_docs: true,
|
|
98
|
-
})
|
|
99
|
-
|
|
100
|
-
if (Array.isArray(response)) {
|
|
101
|
-
// shouldn't be able to happen, but need to handle just in case
|
|
102
|
-
throw new Error(`Multiple users found with email address: ${email}`)
|
|
103
|
-
}
|
|
104
|
-
|
|
105
|
-
let user = response as User
|
|
106
|
-
if (opts?.cleanup) {
|
|
107
|
-
user = removeUserPassword(user) as User
|
|
108
|
-
}
|
|
109
|
-
|
|
110
|
-
return user
|
|
111
|
-
}
|
|
112
|
-
|
|
113
|
-
export const searchGlobalUsersByApp = async (
|
|
114
|
-
appId: any,
|
|
115
|
-
opts: any,
|
|
116
|
-
getOpts?: GetOpts
|
|
117
|
-
) => {
|
|
118
|
-
if (typeof appId !== "string") {
|
|
119
|
-
throw new Error("Must provide a string based app ID")
|
|
120
|
-
}
|
|
121
|
-
const params = getUsersByAppParams(appId, {
|
|
122
|
-
include_docs: true,
|
|
123
|
-
})
|
|
124
|
-
params.startkey = opts && opts.startkey ? opts.startkey : params.startkey
|
|
125
|
-
let response = await queryGlobalView(ViewName.USER_BY_APP, params)
|
|
126
|
-
|
|
127
|
-
if (!response) {
|
|
128
|
-
response = []
|
|
129
|
-
}
|
|
130
|
-
let users: User[] = Array.isArray(response) ? response : [response]
|
|
131
|
-
if (getOpts?.cleanup) {
|
|
132
|
-
users = removeUserPassword(users) as User[]
|
|
133
|
-
}
|
|
134
|
-
return users
|
|
135
|
-
}
|
|
136
|
-
|
|
137
|
-
/*
|
|
138
|
-
Return any user who potentially has access to the application
|
|
139
|
-
Admins, developers and app users with the explicitly role.
|
|
140
|
-
*/
|
|
141
|
-
export const searchGlobalUsersByAppAccess = async (appId: any, opts: any) => {
|
|
142
|
-
const roleSelector = `roles.${appId}`
|
|
143
|
-
|
|
144
|
-
let orQuery: any[] = [
|
|
145
|
-
{
|
|
146
|
-
"builder.global": true,
|
|
147
|
-
},
|
|
148
|
-
{
|
|
149
|
-
"admin.global": true,
|
|
150
|
-
},
|
|
151
|
-
]
|
|
152
|
-
|
|
153
|
-
if (appId) {
|
|
154
|
-
const roleCheck = {
|
|
155
|
-
[roleSelector]: {
|
|
156
|
-
$exists: true,
|
|
157
|
-
},
|
|
158
|
-
}
|
|
159
|
-
orQuery.push(roleCheck)
|
|
160
|
-
}
|
|
161
|
-
|
|
162
|
-
let searchOptions = {
|
|
163
|
-
selector: {
|
|
164
|
-
$or: orQuery,
|
|
165
|
-
_id: {
|
|
166
|
-
$regex: "^us_",
|
|
167
|
-
},
|
|
168
|
-
},
|
|
169
|
-
limit: opts?.limit || 50,
|
|
170
|
-
}
|
|
171
|
-
|
|
172
|
-
const resp = await directCouchFind(context.getGlobalDBName(), searchOptions)
|
|
173
|
-
return resp?.rows
|
|
174
|
-
}
|
|
175
|
-
|
|
176
|
-
export const getGlobalUserByAppPage = (appId: string, user: User) => {
|
|
177
|
-
if (!user) {
|
|
178
|
-
return
|
|
179
|
-
}
|
|
180
|
-
return generateAppUserID(getProdAppID(appId)!, user._id!)
|
|
181
|
-
}
|
|
182
|
-
|
|
183
|
-
/**
|
|
184
|
-
* Performs a starts with search on the global email view.
|
|
185
|
-
*/
|
|
186
|
-
export const searchGlobalUsersByEmail = async (
|
|
187
|
-
email: string | unknown,
|
|
188
|
-
opts: any,
|
|
189
|
-
getOpts?: GetOpts
|
|
190
|
-
) => {
|
|
191
|
-
if (typeof email !== "string") {
|
|
192
|
-
throw new Error("Must provide a string to search by")
|
|
193
|
-
}
|
|
194
|
-
const lcEmail = email.toLowerCase()
|
|
195
|
-
// handle if passing up startkey for pagination
|
|
196
|
-
const startkey = opts && opts.startkey ? opts.startkey : lcEmail
|
|
197
|
-
let response = await queryGlobalView<User>(ViewName.USER_BY_EMAIL, {
|
|
198
|
-
...opts,
|
|
199
|
-
startkey,
|
|
200
|
-
endkey: `${lcEmail}${UNICODE_MAX}`,
|
|
201
|
-
})
|
|
202
|
-
if (!response) {
|
|
203
|
-
response = []
|
|
204
|
-
}
|
|
205
|
-
let users: User[] = Array.isArray(response) ? response : [response]
|
|
206
|
-
if (getOpts?.cleanup) {
|
|
207
|
-
users = removeUserPassword(users) as User[]
|
|
208
|
-
}
|
|
209
|
-
return users
|
|
210
|
-
}
|
|
211
|
-
|
|
212
|
-
const PAGE_LIMIT = 8
|
|
213
|
-
export const paginatedUsers = async ({
|
|
214
|
-
page,
|
|
215
|
-
email,
|
|
216
|
-
appId,
|
|
217
|
-
}: SearchUsersRequest = {}) => {
|
|
218
|
-
const db = getGlobalDB()
|
|
219
|
-
// get one extra document, to have the next page
|
|
220
|
-
const opts: any = {
|
|
221
|
-
include_docs: true,
|
|
222
|
-
limit: PAGE_LIMIT + 1,
|
|
223
|
-
}
|
|
224
|
-
// add a startkey if the page was specified (anchor)
|
|
225
|
-
if (page) {
|
|
226
|
-
opts.startkey = page
|
|
227
|
-
}
|
|
228
|
-
// property specifies what to use for the page/anchor
|
|
229
|
-
let userList: User[],
|
|
230
|
-
property = "_id",
|
|
231
|
-
getKey
|
|
232
|
-
if (appId) {
|
|
233
|
-
userList = await searchGlobalUsersByApp(appId, opts)
|
|
234
|
-
getKey = (doc: any) => getGlobalUserByAppPage(appId, doc)
|
|
235
|
-
} else if (email) {
|
|
236
|
-
userList = await searchGlobalUsersByEmail(email, opts)
|
|
237
|
-
property = "email"
|
|
238
|
-
} else {
|
|
239
|
-
// no search, query allDocs
|
|
240
|
-
const response = await db.allDocs(getGlobalUserParams(null, opts))
|
|
241
|
-
userList = response.rows.map((row: any) => row.doc)
|
|
242
|
-
}
|
|
243
|
-
return pagination(userList, PAGE_LIMIT, {
|
|
244
|
-
paginate: true,
|
|
245
|
-
property,
|
|
246
|
-
getKey,
|
|
247
|
-
})
|
|
248
|
-
}
|
|
249
|
-
|
|
250
|
-
export async function getUserCount() {
|
|
251
|
-
const response = await queryGlobalViewRaw(ViewName.USER_BY_EMAIL, {
|
|
252
|
-
limit: 0, // to be as fast as possible - we just want the total rows count
|
|
253
|
-
include_docs: false,
|
|
254
|
-
})
|
|
255
|
-
return response.total_rows
|
|
256
|
-
}
|
|
257
|
-
|
|
258
|
-
// used to remove the builder/admin permissions, for processing the
|
|
259
|
-
// user as an app user (they may have some specific role/group
|
|
260
|
-
export function removePortalUserPermissions(user: User | ContextUser) {
|
|
261
|
-
delete user.admin
|
|
262
|
-
delete user.builder
|
|
263
|
-
return user
|
|
264
|
-
}
|
|
265
|
-
|
|
266
|
-
export function cleanseUserObject(user: User | ContextUser, base?: User) {
|
|
267
|
-
delete user.admin
|
|
268
|
-
delete user.builder
|
|
269
|
-
delete user.roles
|
|
270
|
-
if (base) {
|
|
271
|
-
user.admin = base.admin
|
|
272
|
-
user.builder = base.builder
|
|
273
|
-
user.roles = base.roles
|
|
274
|
-
}
|
|
275
|
-
return user
|
|
276
|
-
}
|
package/src/users/utils.ts
DELETED
|
@@ -1,55 +0,0 @@
|
|
|
1
|
-
import { CloudAccount } from "@budibase/types"
|
|
2
|
-
import * as accountSdk from "../accounts"
|
|
3
|
-
import env from "../environment"
|
|
4
|
-
import { getPlatformUser } from "./lookup"
|
|
5
|
-
import { EmailUnavailableError } from "../errors"
|
|
6
|
-
import { getTenantId } from "../context"
|
|
7
|
-
import { sdk } from "@budibase/shared-core"
|
|
8
|
-
import { getAccountByTenantId } from "../accounts"
|
|
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 validateUniqueUser(email: string, tenantId: string) {
|
|
20
|
-
// check budibase users in other tenants
|
|
21
|
-
if (env.MULTI_TENANCY) {
|
|
22
|
-
const tenantUser = await getPlatformUser(email)
|
|
23
|
-
if (tenantUser != null && tenantUser.tenantId !== tenantId) {
|
|
24
|
-
throw new EmailUnavailableError(email)
|
|
25
|
-
}
|
|
26
|
-
}
|
|
27
|
-
|
|
28
|
-
// check root account users in account portal
|
|
29
|
-
if (!env.SELF_HOSTED && !env.DISABLE_ACCOUNT_PORTAL) {
|
|
30
|
-
const account = await accountSdk.getAccount(email)
|
|
31
|
-
if (account && account.verified && account.tenantId !== tenantId) {
|
|
32
|
-
throw new EmailUnavailableError(email)
|
|
33
|
-
}
|
|
34
|
-
}
|
|
35
|
-
}
|
|
36
|
-
|
|
37
|
-
/**
|
|
38
|
-
* For the given user id's, return the account holder if it is in the ids.
|
|
39
|
-
*/
|
|
40
|
-
export async function getAccountHolderFromUserIds(
|
|
41
|
-
userIds: string[]
|
|
42
|
-
): Promise<CloudAccount | undefined> {
|
|
43
|
-
if (!env.SELF_HOSTED && !env.DISABLE_ACCOUNT_PORTAL) {
|
|
44
|
-
const tenantId = getTenantId()
|
|
45
|
-
const account = await getAccountByTenantId(tenantId)
|
|
46
|
-
if (!account) {
|
|
47
|
-
throw new Error(`Account not found for tenantId=${tenantId}`)
|
|
48
|
-
}
|
|
49
|
-
|
|
50
|
-
const budibaseUserId = account.budibaseUserId
|
|
51
|
-
if (userIds.includes(budibaseUserId)) {
|
|
52
|
-
return account
|
|
53
|
-
}
|
|
54
|
-
}
|
|
55
|
-
}
|
package/src/utils/hashing.ts
DELETED
|
@@ -1,14 +0,0 @@
|
|
|
1
|
-
import env from "../environment"
|
|
2
|
-
export * from "../docIds/newid"
|
|
3
|
-
const bcrypt = env.JS_BCRYPT ? require("bcryptjs") : require("bcrypt")
|
|
4
|
-
|
|
5
|
-
const SALT_ROUNDS = env.SALT_ROUNDS || 10
|
|
6
|
-
|
|
7
|
-
export async function hash(data: string) {
|
|
8
|
-
const salt = await bcrypt.genSalt(SALT_ROUNDS)
|
|
9
|
-
return bcrypt.hash(data, salt)
|
|
10
|
-
}
|
|
11
|
-
|
|
12
|
-
export async function compare(data: string, encrypted: string) {
|
|
13
|
-
return bcrypt.compare(data, encrypted)
|
|
14
|
-
}
|
package/src/utils/index.ts
DELETED
package/src/utils/stringUtils.ts
DELETED
|
@@ -1,191 +0,0 @@
|
|
|
1
|
-
import { structures } from "../../../tests"
|
|
2
|
-
import { DBTestConfiguration } from "../../../tests/extra"
|
|
3
|
-
import * as utils from "../../utils"
|
|
4
|
-
import * as db from "../../db"
|
|
5
|
-
import { Header } from "../../constants"
|
|
6
|
-
import { newid } from "../../utils"
|
|
7
|
-
import env from "../../environment"
|
|
8
|
-
import { BBContext } from "@budibase/types"
|
|
9
|
-
|
|
10
|
-
describe("utils", () => {
|
|
11
|
-
const config = new DBTestConfiguration()
|
|
12
|
-
|
|
13
|
-
describe("getAppIdFromCtx", () => {
|
|
14
|
-
it("gets appId from header", async () => {
|
|
15
|
-
const ctx = structures.koa.newContext()
|
|
16
|
-
const expected = db.generateAppID()
|
|
17
|
-
ctx.request.headers = {
|
|
18
|
-
[Header.APP_ID]: expected,
|
|
19
|
-
}
|
|
20
|
-
|
|
21
|
-
const actual = await utils.getAppIdFromCtx(ctx)
|
|
22
|
-
expect(actual).toBe(expected)
|
|
23
|
-
})
|
|
24
|
-
|
|
25
|
-
it("gets appId from body", async () => {
|
|
26
|
-
const ctx = structures.koa.newContext()
|
|
27
|
-
const expected = db.generateAppID()
|
|
28
|
-
ctx.request.body = {
|
|
29
|
-
appId: expected,
|
|
30
|
-
}
|
|
31
|
-
|
|
32
|
-
const actual = await utils.getAppIdFromCtx(ctx)
|
|
33
|
-
expect(actual).toBe(expected)
|
|
34
|
-
})
|
|
35
|
-
|
|
36
|
-
it("gets appId from path", async () => {
|
|
37
|
-
const ctx = structures.koa.newContext()
|
|
38
|
-
const expected = db.generateAppID()
|
|
39
|
-
ctx.path = `/apps/${expected}`
|
|
40
|
-
|
|
41
|
-
const actual = await utils.getAppIdFromCtx(ctx)
|
|
42
|
-
expect(actual).toBe(expected)
|
|
43
|
-
})
|
|
44
|
-
|
|
45
|
-
it("gets appId from url", async () => {
|
|
46
|
-
await config.doInTenant(async () => {
|
|
47
|
-
const url = "http://test.com"
|
|
48
|
-
env._set("PLATFORM_URL", url)
|
|
49
|
-
|
|
50
|
-
const ctx = structures.koa.newContext()
|
|
51
|
-
ctx.host = `${config.tenantId}.test.com`
|
|
52
|
-
|
|
53
|
-
const expected = db.generateAppID(config.tenantId)
|
|
54
|
-
const app = structures.apps.app(expected)
|
|
55
|
-
|
|
56
|
-
// set custom url
|
|
57
|
-
const appUrl = newid()
|
|
58
|
-
app.url = `/${appUrl}`
|
|
59
|
-
ctx.path = `/app/${appUrl}`
|
|
60
|
-
|
|
61
|
-
// save the app
|
|
62
|
-
const database = db.getDB(expected)
|
|
63
|
-
await database.put(app)
|
|
64
|
-
|
|
65
|
-
const actual = await utils.getAppIdFromCtx(ctx)
|
|
66
|
-
expect(actual).toBe(expected)
|
|
67
|
-
})
|
|
68
|
-
})
|
|
69
|
-
|
|
70
|
-
it("doesn't get appId from url when previewing", async () => {
|
|
71
|
-
const ctx = structures.koa.newContext()
|
|
72
|
-
const appId = db.generateAppID()
|
|
73
|
-
const app = structures.apps.app(appId)
|
|
74
|
-
|
|
75
|
-
// set custom url
|
|
76
|
-
const appUrl = "preview"
|
|
77
|
-
app.url = `/${appUrl}`
|
|
78
|
-
ctx.path = `/app/${appUrl}`
|
|
79
|
-
|
|
80
|
-
// save the app
|
|
81
|
-
const database = db.getDB(appId)
|
|
82
|
-
await database.put(app)
|
|
83
|
-
|
|
84
|
-
const actual = await utils.getAppIdFromCtx(ctx)
|
|
85
|
-
expect(actual).toBe(undefined)
|
|
86
|
-
})
|
|
87
|
-
|
|
88
|
-
it("gets appId from referer", async () => {
|
|
89
|
-
const ctx = structures.koa.newContext()
|
|
90
|
-
const expected = db.generateAppID()
|
|
91
|
-
ctx.request.headers = {
|
|
92
|
-
referer: `http://test.com/builder/app/${expected}/design/screen_123/screens`,
|
|
93
|
-
}
|
|
94
|
-
|
|
95
|
-
const actual = await utils.getAppIdFromCtx(ctx)
|
|
96
|
-
expect(actual).toBe(expected)
|
|
97
|
-
})
|
|
98
|
-
|
|
99
|
-
it("doesn't get appId from referer when not builder", async () => {
|
|
100
|
-
const ctx = structures.koa.newContext()
|
|
101
|
-
const appId = db.generateAppID()
|
|
102
|
-
ctx.request.headers = {
|
|
103
|
-
referer: `http://test.com/foo/app/${appId}/bar`,
|
|
104
|
-
}
|
|
105
|
-
|
|
106
|
-
const actual = await utils.getAppIdFromCtx(ctx)
|
|
107
|
-
expect(actual).toBe(undefined)
|
|
108
|
-
})
|
|
109
|
-
})
|
|
110
|
-
|
|
111
|
-
describe("isServingBuilder", () => {
|
|
112
|
-
let ctx: BBContext
|
|
113
|
-
|
|
114
|
-
const expectResult = (result: boolean) =>
|
|
115
|
-
expect(utils.isServingBuilder(ctx)).toBe(result)
|
|
116
|
-
|
|
117
|
-
beforeEach(() => {
|
|
118
|
-
ctx = structures.koa.newContext()
|
|
119
|
-
})
|
|
120
|
-
|
|
121
|
-
it("returns true if current path is in builder", async () => {
|
|
122
|
-
ctx.path = "/builder/app/app_"
|
|
123
|
-
expectResult(true)
|
|
124
|
-
})
|
|
125
|
-
|
|
126
|
-
it("returns false if current path doesn't have '/' suffix", async () => {
|
|
127
|
-
ctx.path = "/builder/app"
|
|
128
|
-
expectResult(false)
|
|
129
|
-
|
|
130
|
-
ctx.path = "/xx"
|
|
131
|
-
expectResult(false)
|
|
132
|
-
})
|
|
133
|
-
})
|
|
134
|
-
|
|
135
|
-
describe("isServingBuilderPreview", () => {
|
|
136
|
-
let ctx: BBContext
|
|
137
|
-
|
|
138
|
-
const expectResult = (result: boolean) =>
|
|
139
|
-
expect(utils.isServingBuilderPreview(ctx)).toBe(result)
|
|
140
|
-
|
|
141
|
-
beforeEach(() => {
|
|
142
|
-
ctx = structures.koa.newContext()
|
|
143
|
-
})
|
|
144
|
-
|
|
145
|
-
it("returns true if current path is in builder preview", async () => {
|
|
146
|
-
ctx.path = "/app/preview/xx"
|
|
147
|
-
expectResult(true)
|
|
148
|
-
})
|
|
149
|
-
|
|
150
|
-
it("returns false if current path is not in builder preview", async () => {
|
|
151
|
-
ctx.path = "/builder"
|
|
152
|
-
expectResult(false)
|
|
153
|
-
|
|
154
|
-
ctx.path = "/xx"
|
|
155
|
-
expectResult(false)
|
|
156
|
-
})
|
|
157
|
-
})
|
|
158
|
-
|
|
159
|
-
describe("isPublicAPIRequest", () => {
|
|
160
|
-
let ctx: BBContext
|
|
161
|
-
|
|
162
|
-
const expectResult = (result: boolean) =>
|
|
163
|
-
expect(utils.isPublicApiRequest(ctx)).toBe(result)
|
|
164
|
-
|
|
165
|
-
beforeEach(() => {
|
|
166
|
-
ctx = structures.koa.newContext()
|
|
167
|
-
})
|
|
168
|
-
|
|
169
|
-
it("returns true if current path remains to public API", async () => {
|
|
170
|
-
ctx.path = "/api/public/v1/invoices"
|
|
171
|
-
expectResult(true)
|
|
172
|
-
|
|
173
|
-
ctx.path = "/api/public/v1"
|
|
174
|
-
expectResult(true)
|
|
175
|
-
|
|
176
|
-
ctx.path = "/api/public/v2"
|
|
177
|
-
expectResult(true)
|
|
178
|
-
|
|
179
|
-
ctx.path = "/api/public/v21"
|
|
180
|
-
expectResult(true)
|
|
181
|
-
})
|
|
182
|
-
|
|
183
|
-
it("returns false if current path doesn't remain to public API", async () => {
|
|
184
|
-
ctx.path = "/api/public"
|
|
185
|
-
expectResult(false)
|
|
186
|
-
|
|
187
|
-
ctx.path = "/xx"
|
|
188
|
-
expectResult(false)
|
|
189
|
-
})
|
|
190
|
-
})
|
|
191
|
-
})
|