@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.
Files changed (257) hide show
  1. package/dist/index.js +324 -266
  2. package/dist/index.js.map +4 -4
  3. package/dist/index.js.meta.json +1 -1
  4. package/dist/package.json +19 -4
  5. package/dist/plugins.js +1 -1
  6. package/dist/plugins.js.map +1 -1
  7. package/dist/plugins.js.meta.json +1 -1
  8. package/dist/src/security/permissions.d.ts +1 -1
  9. package/dist/tests.js +260 -222
  10. package/dist/tests.js.map +4 -4
  11. package/dist/tests.js.meta.json +1 -1
  12. package/package.json +19 -4
  13. package/__mocks__/aws-sdk.ts +0 -18
  14. package/dist/tsconfig.build.tsbuildinfo +0 -1
  15. package/jest-testcontainers-config.js +0 -8
  16. package/jest.config.ts +0 -35
  17. package/scripts/build.js +0 -6
  18. package/scripts/test.sh +0 -13
  19. package/src/accounts/accounts.ts +0 -82
  20. package/src/accounts/api.ts +0 -59
  21. package/src/accounts/index.ts +0 -1
  22. package/src/auth/auth.ts +0 -208
  23. package/src/auth/index.ts +0 -1
  24. package/src/auth/tests/auth.spec.ts +0 -14
  25. package/src/blacklist/blacklist.ts +0 -54
  26. package/src/blacklist/index.ts +0 -1
  27. package/src/blacklist/tests/blacklist.spec.ts +0 -46
  28. package/src/cache/appMetadata.ts +0 -88
  29. package/src/cache/base/index.ts +0 -92
  30. package/src/cache/generic.ts +0 -30
  31. package/src/cache/index.ts +0 -5
  32. package/src/cache/tests/writethrough.spec.ts +0 -138
  33. package/src/cache/user.ts +0 -69
  34. package/src/cache/writethrough.ts +0 -133
  35. package/src/configs/configs.ts +0 -257
  36. package/src/configs/index.ts +0 -1
  37. package/src/configs/tests/configs.spec.ts +0 -184
  38. package/src/constants/db.ts +0 -63
  39. package/src/constants/index.ts +0 -2
  40. package/src/constants/misc.ts +0 -50
  41. package/src/context/Context.ts +0 -14
  42. package/src/context/identity.ts +0 -58
  43. package/src/context/index.ts +0 -3
  44. package/src/context/mainContext.ts +0 -310
  45. package/src/context/tests/index.spec.ts +0 -147
  46. package/src/context/types.ts +0 -11
  47. package/src/db/Replication.ts +0 -84
  48. package/src/db/constants.ts +0 -10
  49. package/src/db/couch/DatabaseImpl.ts +0 -238
  50. package/src/db/couch/connections.ts +0 -77
  51. package/src/db/couch/index.ts +0 -5
  52. package/src/db/couch/pouchDB.ts +0 -97
  53. package/src/db/couch/pouchDump.ts +0 -0
  54. package/src/db/couch/utils.ts +0 -50
  55. package/src/db/db.ts +0 -39
  56. package/src/db/errors.ts +0 -14
  57. package/src/db/index.ts +0 -12
  58. package/src/db/lucene.ts +0 -732
  59. package/src/db/searchIndexes/index.ts +0 -1
  60. package/src/db/searchIndexes/searchIndexes.ts +0 -62
  61. package/src/db/tests/index.spec.js +0 -25
  62. package/src/db/tests/lucene.spec.ts +0 -298
  63. package/src/db/tests/pouch.spec.js +0 -62
  64. package/src/db/tests/utils.spec.ts +0 -63
  65. package/src/db/utils.ts +0 -207
  66. package/src/db/views.ts +0 -241
  67. package/src/docIds/conversions.ts +0 -59
  68. package/src/docIds/ids.ts +0 -113
  69. package/src/docIds/index.ts +0 -2
  70. package/src/docIds/newid.ts +0 -5
  71. package/src/docIds/params.ts +0 -174
  72. package/src/docUpdates/index.ts +0 -29
  73. package/src/environment.ts +0 -201
  74. package/src/errors/errors.ts +0 -119
  75. package/src/errors/index.ts +0 -1
  76. package/src/events/analytics.ts +0 -6
  77. package/src/events/asyncEvents/index.ts +0 -2
  78. package/src/events/asyncEvents/publisher.ts +0 -12
  79. package/src/events/asyncEvents/queue.ts +0 -22
  80. package/src/events/backfill.ts +0 -183
  81. package/src/events/documentId.ts +0 -56
  82. package/src/events/events.ts +0 -40
  83. package/src/events/identification.ts +0 -310
  84. package/src/events/index.ts +0 -14
  85. package/src/events/processors/AnalyticsProcessor.ts +0 -64
  86. package/src/events/processors/AuditLogsProcessor.ts +0 -93
  87. package/src/events/processors/LoggingProcessor.ts +0 -37
  88. package/src/events/processors/Processors.ts +0 -52
  89. package/src/events/processors/async/DocumentUpdateProcessor.ts +0 -43
  90. package/src/events/processors/index.ts +0 -19
  91. package/src/events/processors/posthog/PosthogProcessor.ts +0 -118
  92. package/src/events/processors/posthog/index.ts +0 -2
  93. package/src/events/processors/posthog/rateLimiting.ts +0 -106
  94. package/src/events/processors/posthog/tests/PosthogProcessor.spec.ts +0 -168
  95. package/src/events/processors/types.ts +0 -1
  96. package/src/events/publishers/account.ts +0 -35
  97. package/src/events/publishers/app.ts +0 -155
  98. package/src/events/publishers/auditLog.ts +0 -26
  99. package/src/events/publishers/auth.ts +0 -73
  100. package/src/events/publishers/automation.ts +0 -110
  101. package/src/events/publishers/backfill.ts +0 -74
  102. package/src/events/publishers/backup.ts +0 -42
  103. package/src/events/publishers/datasource.ts +0 -48
  104. package/src/events/publishers/email.ts +0 -17
  105. package/src/events/publishers/environmentVariable.ts +0 -38
  106. package/src/events/publishers/group.ts +0 -99
  107. package/src/events/publishers/index.ts +0 -24
  108. package/src/events/publishers/installation.ts +0 -38
  109. package/src/events/publishers/layout.ts +0 -26
  110. package/src/events/publishers/license.ts +0 -84
  111. package/src/events/publishers/org.ts +0 -37
  112. package/src/events/publishers/plugin.ts +0 -47
  113. package/src/events/publishers/query.ts +0 -88
  114. package/src/events/publishers/role.ts +0 -62
  115. package/src/events/publishers/rows.ts +0 -29
  116. package/src/events/publishers/screen.ts +0 -36
  117. package/src/events/publishers/serve.ts +0 -43
  118. package/src/events/publishers/table.ts +0 -70
  119. package/src/events/publishers/user.ts +0 -202
  120. package/src/events/publishers/view.ts +0 -107
  121. package/src/featureFlags/index.ts +0 -77
  122. package/src/featureFlags/tests/featureFlags.spec.ts +0 -85
  123. package/src/helpers.ts +0 -9
  124. package/src/index.ts +0 -53
  125. package/src/installation.ts +0 -107
  126. package/src/logging/alerts.ts +0 -26
  127. package/src/logging/correlation/correlation.ts +0 -13
  128. package/src/logging/correlation/index.ts +0 -1
  129. package/src/logging/correlation/middleware.ts +0 -17
  130. package/src/logging/index.ts +0 -4
  131. package/src/logging/pino/logger.ts +0 -232
  132. package/src/logging/pino/middleware.ts +0 -45
  133. package/src/logging/system.ts +0 -81
  134. package/src/logging/tests/system.spec.ts +0 -61
  135. package/src/middleware/adminOnly.ts +0 -9
  136. package/src/middleware/auditLog.ts +0 -6
  137. package/src/middleware/authenticated.ts +0 -193
  138. package/src/middleware/builderOnly.ts +0 -20
  139. package/src/middleware/builderOrAdmin.ts +0 -20
  140. package/src/middleware/csrf.ts +0 -81
  141. package/src/middleware/errorHandling.ts +0 -29
  142. package/src/middleware/index.ts +0 -21
  143. package/src/middleware/internalApi.ts +0 -23
  144. package/src/middleware/joi-validator.ts +0 -45
  145. package/src/middleware/matchers.ts +0 -47
  146. package/src/middleware/passport/datasource/google.ts +0 -95
  147. package/src/middleware/passport/local.ts +0 -54
  148. package/src/middleware/passport/sso/google.ts +0 -77
  149. package/src/middleware/passport/sso/oidc.ts +0 -154
  150. package/src/middleware/passport/sso/sso.ts +0 -165
  151. package/src/middleware/passport/sso/tests/google.spec.ts +0 -67
  152. package/src/middleware/passport/sso/tests/oidc.spec.ts +0 -152
  153. package/src/middleware/passport/sso/tests/sso.spec.ts +0 -197
  154. package/src/middleware/passport/utils.ts +0 -38
  155. package/src/middleware/querystringToBody.ts +0 -28
  156. package/src/middleware/tenancy.ts +0 -36
  157. package/src/middleware/tests/builder.spec.ts +0 -180
  158. package/src/middleware/tests/matchers.spec.ts +0 -134
  159. package/src/migrations/definitions.ts +0 -40
  160. package/src/migrations/index.ts +0 -2
  161. package/src/migrations/migrations.ts +0 -191
  162. package/src/migrations/tests/__snapshots__/migrations.spec.ts.snap +0 -11
  163. package/src/migrations/tests/migrations.spec.ts +0 -64
  164. package/src/objectStore/buckets/app.ts +0 -40
  165. package/src/objectStore/buckets/global.ts +0 -29
  166. package/src/objectStore/buckets/index.ts +0 -3
  167. package/src/objectStore/buckets/plugins.ts +0 -71
  168. package/src/objectStore/buckets/tests/app.spec.ts +0 -171
  169. package/src/objectStore/buckets/tests/global.spec.ts +0 -74
  170. package/src/objectStore/buckets/tests/plugins.spec.ts +0 -111
  171. package/src/objectStore/cloudfront.ts +0 -41
  172. package/src/objectStore/index.ts +0 -3
  173. package/src/objectStore/objectStore.ts +0 -440
  174. package/src/objectStore/utils.ts +0 -27
  175. package/src/platform/index.ts +0 -3
  176. package/src/platform/platformDb.ts +0 -6
  177. package/src/platform/tenants.ts +0 -101
  178. package/src/platform/tests/tenants.spec.ts +0 -26
  179. package/src/platform/users.ts +0 -90
  180. package/src/plugin/index.ts +0 -1
  181. package/src/plugin/tests/validation.spec.ts +0 -83
  182. package/src/plugin/utils.ts +0 -156
  183. package/src/queue/constants.ts +0 -6
  184. package/src/queue/inMemoryQueue.ts +0 -141
  185. package/src/queue/index.ts +0 -2
  186. package/src/queue/listeners.ts +0 -195
  187. package/src/queue/queue.ts +0 -54
  188. package/src/redis/index.ts +0 -6
  189. package/src/redis/init.ts +0 -86
  190. package/src/redis/redis.ts +0 -308
  191. package/src/redis/redlockImpl.ts +0 -139
  192. package/src/redis/utils.ts +0 -117
  193. package/src/security/encryption.ts +0 -179
  194. package/src/security/permissions.ts +0 -159
  195. package/src/security/roles.ts +0 -420
  196. package/src/security/sessions.ts +0 -120
  197. package/src/security/tests/encryption.spec.ts +0 -31
  198. package/src/security/tests/permissions.spec.ts +0 -145
  199. package/src/security/tests/sessions.spec.ts +0 -12
  200. package/src/tenancy/db.ts +0 -6
  201. package/src/tenancy/index.ts +0 -2
  202. package/src/tenancy/tenancy.ts +0 -140
  203. package/src/tenancy/tests/tenancy.spec.ts +0 -184
  204. package/src/timers/index.ts +0 -1
  205. package/src/timers/timers.ts +0 -22
  206. package/src/users/db.ts +0 -460
  207. package/src/users/events.ts +0 -176
  208. package/src/users/index.ts +0 -4
  209. package/src/users/lookup.ts +0 -102
  210. package/src/users/users.ts +0 -276
  211. package/src/users/utils.ts +0 -55
  212. package/src/utils/hashing.ts +0 -14
  213. package/src/utils/index.ts +0 -3
  214. package/src/utils/stringUtils.ts +0 -8
  215. package/src/utils/tests/utils.spec.ts +0 -191
  216. package/src/utils/utils.ts +0 -239
  217. package/tests/core/logging.ts +0 -34
  218. package/tests/core/utilities/index.ts +0 -6
  219. package/tests/core/utilities/jestUtils.ts +0 -30
  220. package/tests/core/utilities/mocks/alerts.ts +0 -3
  221. package/tests/core/utilities/mocks/date.ts +0 -2
  222. package/tests/core/utilities/mocks/events.ts +0 -131
  223. package/tests/core/utilities/mocks/fetch.ts +0 -17
  224. package/tests/core/utilities/mocks/index.ts +0 -10
  225. package/tests/core/utilities/mocks/licenses.ts +0 -107
  226. package/tests/core/utilities/mocks/posthog.ts +0 -7
  227. package/tests/core/utilities/structures/Chance.ts +0 -20
  228. package/tests/core/utilities/structures/accounts.ts +0 -115
  229. package/tests/core/utilities/structures/apps.ts +0 -21
  230. package/tests/core/utilities/structures/common.ts +0 -7
  231. package/tests/core/utilities/structures/db.ts +0 -12
  232. package/tests/core/utilities/structures/documents/index.ts +0 -1
  233. package/tests/core/utilities/structures/documents/platform/index.ts +0 -1
  234. package/tests/core/utilities/structures/documents/platform/installation.ts +0 -12
  235. package/tests/core/utilities/structures/generator.ts +0 -2
  236. package/tests/core/utilities/structures/index.ts +0 -15
  237. package/tests/core/utilities/structures/koa.ts +0 -16
  238. package/tests/core/utilities/structures/licenses.ts +0 -167
  239. package/tests/core/utilities/structures/plugins.ts +0 -19
  240. package/tests/core/utilities/structures/quotas.ts +0 -67
  241. package/tests/core/utilities/structures/scim.ts +0 -80
  242. package/tests/core/utilities/structures/shared.ts +0 -19
  243. package/tests/core/utilities/structures/sso.ts +0 -119
  244. package/tests/core/utilities/structures/tenants.ts +0 -5
  245. package/tests/core/utilities/structures/userGroups.ts +0 -10
  246. package/tests/core/utilities/structures/users.ts +0 -73
  247. package/tests/core/utilities/testContainerUtils.ts +0 -98
  248. package/tests/core/utilities/utils/index.ts +0 -1
  249. package/tests/core/utilities/utils/time.ts +0 -3
  250. package/tests/extra/DBTestConfiguration.ts +0 -36
  251. package/tests/extra/index.ts +0 -2
  252. package/tests/extra/testEnv.ts +0 -95
  253. package/tests/index.ts +0 -1
  254. package/tests/jestEnv.ts +0 -6
  255. package/tests/jestSetup.ts +0 -28
  256. package/tsconfig.build.json +0 -29
  257. package/tsconfig.json +0 -4
@@ -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
- }
@@ -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
- }
@@ -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
- }
@@ -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
- }
@@ -1,3 +0,0 @@
1
- export * from "./hashing"
2
- export * from "./utils"
3
- export * from "./stringUtils"
@@ -1,8 +0,0 @@
1
- export function validEmail(value: string) {
2
- return (
3
- value &&
4
- !!value.match(
5
- /^(([^<>()[\]\\.,;:\s@"]+(\.[^<>()[\]\\.,;:\s@"]+)*)|(".+"))@((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}])|(([a-zA-Z\-0-9]+\.)+[a-zA-Z]{2,}))$/
6
- )
7
- )
8
- }
@@ -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
- })