@budibase/backend-core 2.8.29 → 2.8.31-alpha.0

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.
Files changed (132) hide show
  1. package/dist/jest.config.js +10 -4
  2. package/dist/jest.config.js.map +1 -1
  3. package/dist/package.json +14 -26
  4. package/dist/src/auth/auth.js.map +1 -1
  5. package/dist/src/cache/appMetadata.d.ts +7 -1
  6. package/dist/src/cache/appMetadata.js +5 -8
  7. package/dist/src/cache/appMetadata.js.map +1 -1
  8. package/dist/src/cache/user.js.map +1 -1
  9. package/dist/src/constants/db.d.ts +1 -39
  10. package/dist/src/constants/db.js +8 -43
  11. package/dist/src/constants/db.js.map +1 -1
  12. package/dist/src/constants/misc.d.ts +2 -0
  13. package/dist/src/constants/misc.js +2 -0
  14. package/dist/src/constants/misc.js.map +1 -1
  15. package/dist/src/db/constants.d.ts +2 -0
  16. package/dist/src/db/constants.js +13 -0
  17. package/dist/src/db/constants.js.map +1 -0
  18. package/dist/src/db/couch/index.d.ts +1 -0
  19. package/dist/src/db/couch/index.js +1 -0
  20. package/dist/src/db/couch/index.js.map +1 -1
  21. package/dist/src/db/searchIndexes/searchIndexes.js.map +1 -1
  22. package/dist/src/db/utils.js +7 -2
  23. package/dist/src/db/utils.js.map +1 -1
  24. package/dist/src/db/views.d.ts +0 -1
  25. package/dist/src/db/views.js +1 -12
  26. package/dist/src/db/views.js.map +1 -1
  27. package/dist/src/environment.d.ts +11 -4
  28. package/dist/src/environment.js +21 -70
  29. package/dist/src/environment.js.map +1 -1
  30. package/dist/src/events/identification.js +3 -3
  31. package/dist/src/events/identification.js.map +1 -1
  32. package/dist/src/logging/index.d.ts +1 -1
  33. package/dist/src/logging/index.js +2 -3
  34. package/dist/src/logging/index.js.map +1 -1
  35. package/dist/src/logging/pino/logger.js +40 -24
  36. package/dist/src/logging/pino/logger.js.map +1 -1
  37. package/dist/src/logging/system.d.ts +9 -0
  38. package/dist/src/logging/system.js +101 -0
  39. package/dist/src/logging/system.js.map +1 -0
  40. package/dist/src/middleware/adminOnly.d.ts +2 -2
  41. package/dist/src/middleware/adminOnly.js +2 -2
  42. package/dist/src/middleware/adminOnly.js.map +1 -1
  43. package/dist/src/middleware/builderOnly.d.ts +2 -2
  44. package/dist/src/middleware/builderOnly.js +16 -2
  45. package/dist/src/middleware/builderOnly.js.map +1 -1
  46. package/dist/src/middleware/builderOrAdmin.d.ts +2 -2
  47. package/dist/src/middleware/builderOrAdmin.js +17 -4
  48. package/dist/src/middleware/builderOrAdmin.js.map +1 -1
  49. package/dist/src/security/permissions.d.ts +31 -18
  50. package/dist/src/security/permissions.js +46 -57
  51. package/dist/src/security/permissions.js.map +1 -1
  52. package/dist/src/security/roles.js +7 -4
  53. package/dist/src/security/roles.js.map +1 -1
  54. package/dist/src/users/db.d.ts +38 -0
  55. package/dist/src/users/db.js +407 -0
  56. package/dist/src/users/db.js.map +1 -0
  57. package/dist/src/users/events.d.ts +5 -0
  58. package/dist/src/users/events.js +169 -0
  59. package/dist/src/users/events.js.map +1 -0
  60. package/dist/src/users/index.d.ts +4 -0
  61. package/dist/src/users/index.js +23 -0
  62. package/dist/src/users/index.js.map +1 -0
  63. package/dist/src/users/lookup.d.ts +13 -0
  64. package/dist/src/users/lookup.js +112 -0
  65. package/dist/src/users/lookup.js.map +1 -0
  66. package/dist/src/{users.d.ts → users/users.d.ts} +4 -2
  67. package/dist/src/{users.js → users/users.js} +24 -4
  68. package/dist/src/users/users.js.map +1 -0
  69. package/dist/src/users/utils.d.ts +14 -0
  70. package/dist/src/users/utils.js +92 -0
  71. package/dist/src/users/utils.js.map +1 -0
  72. package/dist/tests/core/utilities/jestUtils.d.ts +7 -0
  73. package/dist/tests/core/utilities/jestUtils.js +14 -1
  74. package/dist/tests/core/utilities/jestUtils.js.map +1 -1
  75. package/dist/tests/core/utilities/mocks/events.d.ts +0 -1
  76. package/dist/tests/core/utilities/mocks/events.js +0 -1
  77. package/dist/tests/core/utilities/mocks/events.js.map +1 -1
  78. package/dist/tests/core/utilities/mocks/licenses.d.ts +1 -0
  79. package/dist/tests/core/utilities/mocks/licenses.js +8 -4
  80. package/dist/tests/core/utilities/mocks/licenses.js.map +1 -1
  81. package/dist/tests/core/utilities/structures/accounts.js +3 -3
  82. package/dist/tests/core/utilities/structures/accounts.js.map +1 -1
  83. package/dist/tests/core/utilities/structures/scim.js +1 -5
  84. package/dist/tests/core/utilities/structures/scim.js.map +1 -1
  85. package/dist/tests/core/utilities/structures/sso.js +2 -2
  86. package/dist/tests/core/utilities/structures/sso.js.map +1 -1
  87. package/dist/tests/core/utilities/structures/users.d.ts +3 -1
  88. package/dist/tests/core/utilities/structures/users.js +13 -1
  89. package/dist/tests/core/utilities/structures/users.js.map +1 -1
  90. package/dist/tsconfig.build.tsbuildinfo +1 -1
  91. package/jest.config.ts +1 -2
  92. package/package.json +14 -26
  93. package/scripts/test.sh +2 -2
  94. package/src/auth/auth.ts +1 -1
  95. package/src/cache/appMetadata.ts +10 -8
  96. package/src/cache/tests/writethrough.spec.ts +7 -7
  97. package/src/cache/user.ts +1 -1
  98. package/src/constants/db.ts +4 -42
  99. package/src/constants/misc.ts +2 -0
  100. package/src/db/constants.ts +10 -0
  101. package/src/db/couch/index.ts +1 -0
  102. package/src/db/searchIndexes/searchIndexes.ts +1 -1
  103. package/src/db/utils.ts +9 -3
  104. package/src/db/views.ts +0 -11
  105. package/src/environment.ts +24 -4
  106. package/src/events/identification.ts +3 -2
  107. package/src/logging/index.ts +1 -3
  108. package/src/logging/pino/logger.ts +45 -24
  109. package/src/logging/system.ts +81 -0
  110. package/src/logging/tests/system.spec.ts +61 -0
  111. package/src/middleware/adminOnly.ts +4 -6
  112. package/src/middleware/builderOnly.ts +15 -6
  113. package/src/middleware/builderOrAdmin.ts +16 -8
  114. package/src/middleware/tests/builder.spec.ts +180 -0
  115. package/src/security/permissions.ts +5 -21
  116. package/src/security/roles.ts +1 -1
  117. package/src/security/tests/permissions.spec.ts +1 -1
  118. package/src/users/db.ts +460 -0
  119. package/src/users/events.ts +176 -0
  120. package/src/users/index.ts +4 -0
  121. package/src/users/lookup.ts +102 -0
  122. package/src/{users.ts → users/users.ts} +33 -7
  123. package/src/users/utils.ts +55 -0
  124. package/tests/core/utilities/jestUtils.ts +21 -0
  125. package/tests/core/utilities/mocks/events.ts +0 -2
  126. package/tests/core/utilities/mocks/licenses.ts +7 -3
  127. package/tests/core/utilities/structures/accounts.ts +3 -5
  128. package/tests/core/utilities/structures/scim.ts +4 -5
  129. package/tests/core/utilities/structures/sso.ts +2 -2
  130. package/tests/core/utilities/structures/users.ts +19 -0
  131. package/tsconfig.json +2 -2
  132. package/dist/src/users.js.map +0 -1
@@ -0,0 +1,102 @@
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
+ }
@@ -11,10 +11,16 @@ import {
11
11
  SEPARATOR,
12
12
  UNICODE_MAX,
13
13
  ViewName,
14
- } from "./db"
15
- import { BulkDocsResponse, SearchUsersRequest, User } from "@budibase/types"
16
- import { getGlobalDB } from "./context"
17
- import * as context from "./context"
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"
18
24
 
19
25
  type GetOpts = { cleanup?: boolean }
20
26
 
@@ -67,9 +73,9 @@ export const bulkUpdateGlobalUsers = async (users: User[]) => {
67
73
 
68
74
  export async function getById(id: string, opts?: GetOpts): Promise<User> {
69
75
  const db = context.getGlobalDB()
70
- let user = await db.get(id)
76
+ let user = await db.get<User>(id)
71
77
  if (opts?.cleanup) {
72
- user = removeUserPassword(user)
78
+ user = removeUserPassword(user) as User
73
79
  }
74
80
  return user
75
81
  }
@@ -178,7 +184,7 @@ export const getGlobalUserByAppPage = (appId: string, user: User) => {
178
184
  * Performs a starts with search on the global email view.
179
185
  */
180
186
  export const searchGlobalUsersByEmail = async (
181
- email: string,
187
+ email: string | unknown,
182
188
  opts: any,
183
189
  getOpts?: GetOpts
184
190
  ) => {
@@ -248,3 +254,23 @@ export async function getUserCount() {
248
254
  })
249
255
  return response.total_rows
250
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
+ }
@@ -0,0 +1,55 @@
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
+ }
@@ -1,3 +1,5 @@
1
+ import { db } from "../../../src"
2
+
1
3
  export function expectFunctionWasCalledTimesWith(
2
4
  jestFunction: any,
3
5
  times: number,
@@ -7,3 +9,22 @@ export function expectFunctionWasCalledTimesWith(
7
9
  jestFunction.mock.calls.filter((call: any) => call[0] === argument).length
8
10
  ).toBe(times)
9
11
  }
12
+
13
+ export const expectAnyInternalColsAttributes: {
14
+ [K in (typeof db.CONSTANT_INTERNAL_ROW_COLS)[number]]: any
15
+ } = {
16
+ tableId: expect.anything(),
17
+ type: expect.anything(),
18
+ _id: expect.anything(),
19
+ _rev: expect.anything(),
20
+ createdAt: expect.anything(),
21
+ updatedAt: expect.anything(),
22
+ }
23
+
24
+ export const expectAnyExternalColsAttributes: {
25
+ [K in (typeof db.CONSTANT_EXTERNAL_ROW_COLS)[number]]: any
26
+ } = {
27
+ tableId: expect.anything(),
28
+ _id: expect.anything(),
29
+ _rev: expect.anything(),
30
+ }
@@ -1,5 +1,3 @@
1
- import * as events from "../../../../src/events"
2
-
3
1
  beforeAll(async () => {
4
2
  const processors = await import("../../../../src/events/processors")
5
3
  const events = await import("../../../../src/events")
@@ -1,5 +1,5 @@
1
1
  import { Feature, License, Quotas } from "@budibase/types"
2
- import _ from "lodash"
2
+ import cloneDeep from "lodash/cloneDeep"
3
3
 
4
4
  let CLOUD_FREE_LICENSE: License
5
5
  let UNLIMITED_LICENSE: License
@@ -58,7 +58,7 @@ export const useCloudFree = () => {
58
58
  // FEATURES
59
59
 
60
60
  const useFeature = (feature: Feature) => {
61
- const license = _.cloneDeep(UNLIMITED_LICENSE)
61
+ const license = cloneDeep(UNLIMITED_LICENSE)
62
62
  const opts: UseLicenseOpts = {
63
63
  features: [feature],
64
64
  }
@@ -94,10 +94,14 @@ export const useSyncAutomations = () => {
94
94
  return useFeature(Feature.SYNC_AUTOMATIONS)
95
95
  }
96
96
 
97
+ export const useAppBuilders = () => {
98
+ return useFeature(Feature.APP_BUILDERS)
99
+ }
100
+
97
101
  // QUOTAS
98
102
 
99
103
  export const setAutomationLogsQuota = (value: number) => {
100
- const license = _.cloneDeep(UNLIMITED_LICENSE)
104
+ const license = cloneDeep(UNLIMITED_LICENSE)
101
105
  license.quotas.constant.automationLogRetentionDays.value = value
102
106
  return useLicense(license)
103
107
  }
@@ -11,7 +11,7 @@ import {
11
11
  CreateAccount,
12
12
  CreatePassswordAccount,
13
13
  } from "@budibase/types"
14
- import _ from "lodash"
14
+ import sample from "lodash/sample"
15
15
 
16
16
  export const account = (partial: Partial<Account> = {}): Account => {
17
17
  return {
@@ -46,13 +46,11 @@ export const cloudAccount = (): CloudAccount => {
46
46
  }
47
47
 
48
48
  function providerType(): AccountSSOProviderType {
49
- return _.sample(
50
- Object.values(AccountSSOProviderType)
51
- ) as AccountSSOProviderType
49
+ return sample(Object.values(AccountSSOProviderType)) as AccountSSOProviderType
52
50
  }
53
51
 
54
52
  function provider(): AccountSSOProvider {
55
- return _.sample(Object.values(AccountSSOProvider)) as AccountSSOProvider
53
+ return sample(Object.values(AccountSSOProvider)) as AccountSSOProvider
56
54
  }
57
55
 
58
56
  export function ssoAccount(account: Account = cloudAccount()): SSOAccount {
@@ -1,7 +1,6 @@
1
1
  import { ScimCreateGroupRequest, ScimCreateUserRequest } from "@budibase/types"
2
2
  import { uuid } from "./common"
3
3
  import { generator } from "./generator"
4
- import _ from "lodash"
5
4
 
6
5
  interface CreateUserRequestFields {
7
6
  externalId: string
@@ -20,10 +19,10 @@ export function createUserRequest(userData?: Partial<CreateUserRequestFields>) {
20
19
  username: generator.name(),
21
20
  }
22
21
 
23
- const { externalId, email, firstName, lastName, username } = _.assign(
24
- defaultValues,
25
- userData
26
- )
22
+ const { externalId, email, firstName, lastName, username } = {
23
+ ...defaultValues,
24
+ ...userData,
25
+ }
27
26
 
28
27
  let user: ScimCreateUserRequest = {
29
28
  schemas: [
@@ -15,7 +15,7 @@ import { generator } from "./generator"
15
15
  import { email, uuid } from "./common"
16
16
  import * as shared from "./shared"
17
17
  import { user } from "./shared"
18
- import _ from "lodash"
18
+ import sample from "lodash/sample"
19
19
 
20
20
  export function OAuth(): OAuth2 {
21
21
  return {
@@ -47,7 +47,7 @@ export function authDetails(userDoc?: User): SSOAuthDetails {
47
47
  }
48
48
 
49
49
  export function providerType(): SSOProviderType {
50
- return _.sample(Object.values(SSOProviderType)) as SSOProviderType
50
+ return sample(Object.values(SSOProviderType)) as SSOProviderType
51
51
  }
52
52
 
53
53
  export function ssoProfile(user?: User): SSOProfile {
@@ -1,5 +1,6 @@
1
1
  import {
2
2
  AdminUser,
3
+ AdminOnlyUser,
3
4
  BuilderUser,
4
5
  SSOAuthDetails,
5
6
  SSOUser,
@@ -21,6 +22,15 @@ export const adminUser = (userProps?: any): AdminUser => {
21
22
  }
22
23
  }
23
24
 
25
+ export const adminOnlyUser = (userProps?: any): AdminOnlyUser => {
26
+ return {
27
+ ...user(userProps),
28
+ admin: {
29
+ global: true,
30
+ },
31
+ }
32
+ }
33
+
24
34
  export const builderUser = (userProps?: any): BuilderUser => {
25
35
  return {
26
36
  ...user(userProps),
@@ -30,6 +40,15 @@ export const builderUser = (userProps?: any): BuilderUser => {
30
40
  }
31
41
  }
32
42
 
43
+ export const appBuilderUser = (appId: string, userProps?: any): BuilderUser => {
44
+ return {
45
+ ...user(userProps),
46
+ builder: {
47
+ apps: [appId],
48
+ },
49
+ }
50
+ }
51
+
33
52
  export function ssoUser(
34
53
  opts: { user?: any; details?: SSOAuthDetails } = {}
35
54
  ): SSOUser {
package/tsconfig.json CHANGED
@@ -4,9 +4,9 @@
4
4
  "composite": true,
5
5
  "baseUrl": ".",
6
6
  "paths": {
7
- "@budibase/types": ["../types/src"]
7
+ "@budibase/types": ["../types/src"],
8
+ "@budibase/shared-core": ["../shared-core/src"]
8
9
  }
9
10
  },
10
-
11
11
  "exclude": ["node_modules", "dist"]
12
12
  }
@@ -1 +0,0 @@
1
- {"version":3,"file":"users.js","sourceRoot":"","sources":["../../src/users.ts"],"names":[],"mappings":"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"}