@budibase/backend-core 3.2.5 → 3.2.7

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 (276) hide show
  1. package/dist/index.js +7 -1
  2. package/dist/index.js.map +2 -2
  3. package/dist/index.js.meta.json +1 -1
  4. package/dist/package.json +11 -4
  5. package/dist/plugins.js.meta.json +1 -1
  6. package/dist/src/environment.d.ts +1 -0
  7. package/dist/src/environment.js +6 -1
  8. package/dist/src/environment.js.map +1 -1
  9. package/package.json +11 -4
  10. package/src/accounts/accounts.ts +0 -82
  11. package/src/accounts/api.ts +0 -59
  12. package/src/accounts/index.ts +0 -1
  13. package/src/auth/auth.ts +0 -210
  14. package/src/auth/index.ts +0 -1
  15. package/src/auth/tests/auth.spec.ts +0 -14
  16. package/src/blacklist/blacklist.ts +0 -54
  17. package/src/blacklist/index.ts +0 -1
  18. package/src/blacklist/tests/blacklist.spec.ts +0 -46
  19. package/src/cache/appMetadata.ts +0 -88
  20. package/src/cache/base/index.ts +0 -150
  21. package/src/cache/docWritethrough.ts +0 -105
  22. package/src/cache/generic.ts +0 -33
  23. package/src/cache/index.ts +0 -8
  24. package/src/cache/invite.ts +0 -86
  25. package/src/cache/passwordReset.ts +0 -49
  26. package/src/cache/tests/docWritethrough.spec.ts +0 -296
  27. package/src/cache/tests/user.spec.ts +0 -145
  28. package/src/cache/tests/writethrough.spec.ts +0 -139
  29. package/src/cache/user.ts +0 -154
  30. package/src/cache/writethrough.ts +0 -133
  31. package/src/configs/configs.ts +0 -263
  32. package/src/configs/index.ts +0 -1
  33. package/src/configs/tests/configs.spec.ts +0 -184
  34. package/src/constants/db.ts +0 -75
  35. package/src/constants/index.ts +0 -2
  36. package/src/constants/misc.ts +0 -36
  37. package/src/context/Context.ts +0 -14
  38. package/src/context/identity.ts +0 -58
  39. package/src/context/index.ts +0 -3
  40. package/src/context/mainContext.ts +0 -422
  41. package/src/context/tests/index.spec.ts +0 -255
  42. package/src/context/types.ts +0 -26
  43. package/src/db/Replication.ts +0 -94
  44. package/src/db/couch/DatabaseImpl.ts +0 -511
  45. package/src/db/couch/connections.ts +0 -89
  46. package/src/db/couch/index.ts +0 -4
  47. package/src/db/couch/pouchDB.ts +0 -97
  48. package/src/db/couch/pouchDump.ts +0 -0
  49. package/src/db/couch/tests/DatabaseImpl.spec.ts +0 -118
  50. package/src/db/couch/utils.ts +0 -55
  51. package/src/db/db.ts +0 -34
  52. package/src/db/errors.ts +0 -14
  53. package/src/db/index.ts +0 -12
  54. package/src/db/instrumentation.ts +0 -199
  55. package/src/db/lucene.ts +0 -721
  56. package/src/db/searchIndexes/index.ts +0 -1
  57. package/src/db/searchIndexes/searchIndexes.ts +0 -62
  58. package/src/db/tests/DatabaseImpl.spec.ts +0 -55
  59. package/src/db/tests/connections.spec.ts +0 -22
  60. package/src/db/tests/index.spec.ts +0 -32
  61. package/src/db/tests/lucene.spec.ts +0 -400
  62. package/src/db/tests/pouch.spec.js +0 -62
  63. package/src/db/tests/utils.spec.ts +0 -63
  64. package/src/db/utils.ts +0 -208
  65. package/src/db/views.ts +0 -245
  66. package/src/docIds/conversions.ts +0 -60
  67. package/src/docIds/ids.ts +0 -126
  68. package/src/docIds/index.ts +0 -2
  69. package/src/docIds/newid.ts +0 -5
  70. package/src/docIds/params.ts +0 -189
  71. package/src/docUpdates/index.ts +0 -24
  72. package/src/environment.ts +0 -293
  73. package/src/errors/errors.ts +0 -119
  74. package/src/errors/index.ts +0 -1
  75. package/src/events/analytics.ts +0 -6
  76. package/src/events/asyncEvents/index.ts +0 -2
  77. package/src/events/asyncEvents/publisher.ts +0 -12
  78. package/src/events/asyncEvents/queue.ts +0 -22
  79. package/src/events/backfill.ts +0 -183
  80. package/src/events/documentId.ts +0 -56
  81. package/src/events/events.ts +0 -47
  82. package/src/events/identification.ts +0 -311
  83. package/src/events/index.ts +0 -15
  84. package/src/events/processors/AnalyticsProcessor.ts +0 -64
  85. package/src/events/processors/AuditLogsProcessor.ts +0 -92
  86. package/src/events/processors/LoggingProcessor.ts +0 -36
  87. package/src/events/processors/Processors.ts +0 -52
  88. package/src/events/processors/async/DocumentUpdateProcessor.ts +0 -38
  89. package/src/events/processors/index.ts +0 -19
  90. package/src/events/processors/posthog/PosthogProcessor.ts +0 -118
  91. package/src/events/processors/posthog/index.ts +0 -3
  92. package/src/events/processors/posthog/rateLimiting.ts +0 -106
  93. package/src/events/processors/posthog/tests/PosthogProcessor.spec.ts +0 -164
  94. package/src/events/processors/types.ts +0 -1
  95. package/src/events/publishers/account.ts +0 -41
  96. package/src/events/publishers/ai.ts +0 -21
  97. package/src/events/publishers/app.ts +0 -168
  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 -25
  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 -89
  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/features/features.ts +0 -277
  122. package/src/features/index.ts +0 -2
  123. package/src/features/tests/features.spec.ts +0 -267
  124. package/src/features/tests/utils.ts +0 -64
  125. package/src/helpers.ts +0 -9
  126. package/src/index.ts +0 -59
  127. package/src/installation.ts +0 -115
  128. package/src/logging/alerts.ts +0 -26
  129. package/src/logging/correlation/correlation.ts +0 -15
  130. package/src/logging/correlation/index.ts +0 -1
  131. package/src/logging/correlation/middleware.ts +0 -18
  132. package/src/logging/index.ts +0 -4
  133. package/src/logging/pino/logger.ts +0 -239
  134. package/src/logging/pino/middleware.ts +0 -48
  135. package/src/logging/system.ts +0 -81
  136. package/src/logging/tests/system.spec.ts +0 -61
  137. package/src/middleware/adminOnly.ts +0 -9
  138. package/src/middleware/auditLog.ts +0 -6
  139. package/src/middleware/authenticated.ts +0 -247
  140. package/src/middleware/builderOnly.ts +0 -21
  141. package/src/middleware/builderOrAdmin.ts +0 -21
  142. package/src/middleware/contentSecurityPolicy.ts +0 -113
  143. package/src/middleware/csrf.ts +0 -81
  144. package/src/middleware/errorHandling.ts +0 -43
  145. package/src/middleware/index.ts +0 -24
  146. package/src/middleware/internalApi.ts +0 -23
  147. package/src/middleware/ip.ts +0 -12
  148. package/src/middleware/joi-validator.ts +0 -58
  149. package/src/middleware/matchers.ts +0 -39
  150. package/src/middleware/passport/datasource/google.ts +0 -102
  151. package/src/middleware/passport/local.ts +0 -54
  152. package/src/middleware/passport/sso/google.ts +0 -77
  153. package/src/middleware/passport/sso/oidc.ts +0 -152
  154. package/src/middleware/passport/sso/sso.ts +0 -138
  155. package/src/middleware/passport/sso/tests/google.spec.ts +0 -68
  156. package/src/middleware/passport/sso/tests/oidc.spec.ts +0 -144
  157. package/src/middleware/passport/sso/tests/sso.spec.ts +0 -197
  158. package/src/middleware/passport/utils.ts +0 -38
  159. package/src/middleware/querystringToBody.ts +0 -28
  160. package/src/middleware/tenancy.ts +0 -36
  161. package/src/middleware/tests/builder.spec.ts +0 -181
  162. package/src/middleware/tests/contentSecurityPolicy.spec.ts +0 -75
  163. package/src/middleware/tests/matchers.spec.ts +0 -100
  164. package/src/migrations/definitions.ts +0 -40
  165. package/src/migrations/index.ts +0 -2
  166. package/src/migrations/migrations.ts +0 -186
  167. package/src/migrations/tests/__snapshots__/migrations.spec.ts.snap +0 -11
  168. package/src/migrations/tests/migrations.spec.ts +0 -64
  169. package/src/objectStore/buckets/app.ts +0 -53
  170. package/src/objectStore/buckets/global.ts +0 -29
  171. package/src/objectStore/buckets/index.ts +0 -3
  172. package/src/objectStore/buckets/plugins.ts +0 -71
  173. package/src/objectStore/buckets/tests/app.spec.ts +0 -161
  174. package/src/objectStore/buckets/tests/global.spec.ts +0 -74
  175. package/src/objectStore/buckets/tests/plugins.spec.ts +0 -111
  176. package/src/objectStore/cloudfront.ts +0 -41
  177. package/src/objectStore/index.ts +0 -3
  178. package/src/objectStore/objectStore.ts +0 -585
  179. package/src/objectStore/utils.ts +0 -113
  180. package/src/platform/index.ts +0 -3
  181. package/src/platform/platformDb.ts +0 -6
  182. package/src/platform/tenants.ts +0 -101
  183. package/src/platform/tests/tenants.spec.ts +0 -26
  184. package/src/platform/users.ts +0 -129
  185. package/src/plugin/index.ts +0 -1
  186. package/src/plugin/tests/validation.spec.ts +0 -209
  187. package/src/plugin/utils.ts +0 -175
  188. package/src/queue/constants.ts +0 -8
  189. package/src/queue/inMemoryQueue.ts +0 -189
  190. package/src/queue/index.ts +0 -2
  191. package/src/queue/listeners.ts +0 -199
  192. package/src/queue/queue.ts +0 -84
  193. package/src/redis/index.ts +0 -6
  194. package/src/redis/init.ts +0 -118
  195. package/src/redis/redis.ts +0 -358
  196. package/src/redis/redlockImpl.ts +0 -155
  197. package/src/redis/tests/redis.spec.ts +0 -207
  198. package/src/redis/tests/redlockImpl.spec.ts +0 -105
  199. package/src/redis/utils.ts +0 -128
  200. package/src/security/auth.ts +0 -24
  201. package/src/security/encryption.ts +0 -185
  202. package/src/security/index.ts +0 -1
  203. package/src/security/permissions.ts +0 -166
  204. package/src/security/roles.ts +0 -655
  205. package/src/security/secrets.ts +0 -20
  206. package/src/security/sessions.ts +0 -123
  207. package/src/security/tests/auth.spec.ts +0 -45
  208. package/src/security/tests/encryption.spec.ts +0 -31
  209. package/src/security/tests/permissions.spec.ts +0 -146
  210. package/src/security/tests/secrets.spec.ts +0 -35
  211. package/src/security/tests/sessions.spec.ts +0 -12
  212. package/src/sql/designDoc.ts +0 -17
  213. package/src/sql/index.ts +0 -5
  214. package/src/sql/sql.ts +0 -1854
  215. package/src/sql/sqlTable.ts +0 -319
  216. package/src/sql/utils.ts +0 -193
  217. package/src/tenancy/db.ts +0 -6
  218. package/src/tenancy/index.ts +0 -2
  219. package/src/tenancy/tenancy.ts +0 -148
  220. package/src/tenancy/tests/tenancy.spec.ts +0 -184
  221. package/src/timers/index.ts +0 -1
  222. package/src/timers/timers.ts +0 -22
  223. package/src/users/db.ts +0 -582
  224. package/src/users/events.ts +0 -176
  225. package/src/users/index.ts +0 -4
  226. package/src/users/lookup.ts +0 -99
  227. package/src/users/test/db.spec.ts +0 -188
  228. package/src/users/test/utils.spec.ts +0 -67
  229. package/src/users/users.ts +0 -353
  230. package/src/users/utils.ts +0 -81
  231. package/src/utils/Duration.ts +0 -56
  232. package/src/utils/hashing.ts +0 -15
  233. package/src/utils/index.ts +0 -4
  234. package/src/utils/stringUtils.ts +0 -8
  235. package/src/utils/tests/Duration.spec.ts +0 -19
  236. package/src/utils/tests/utils.spec.ts +0 -204
  237. package/src/utils/utils.ts +0 -249
  238. package/tests/core/logging.ts +0 -34
  239. package/tests/core/users/users.spec.js +0 -53
  240. package/tests/core/utilities/index.ts +0 -7
  241. package/tests/core/utilities/jestUtils.ts +0 -33
  242. package/tests/core/utilities/mocks/alerts.ts +0 -4
  243. package/tests/core/utilities/mocks/date.ts +0 -3
  244. package/tests/core/utilities/mocks/events.ts +0 -132
  245. package/tests/core/utilities/mocks/index.ts +0 -9
  246. package/tests/core/utilities/mocks/licenses.ts +0 -119
  247. package/tests/core/utilities/queue.ts +0 -9
  248. package/tests/core/utilities/structures/Chance.ts +0 -20
  249. package/tests/core/utilities/structures/accounts.ts +0 -80
  250. package/tests/core/utilities/structures/apps.ts +0 -21
  251. package/tests/core/utilities/structures/common.ts +0 -7
  252. package/tests/core/utilities/structures/db.ts +0 -12
  253. package/tests/core/utilities/structures/documents/index.ts +0 -1
  254. package/tests/core/utilities/structures/documents/platform/index.ts +0 -1
  255. package/tests/core/utilities/structures/documents/platform/installation.ts +0 -12
  256. package/tests/core/utilities/structures/generator.ts +0 -3
  257. package/tests/core/utilities/structures/index.ts +0 -15
  258. package/tests/core/utilities/structures/koa.ts +0 -16
  259. package/tests/core/utilities/structures/licenses.ts +0 -190
  260. package/tests/core/utilities/structures/plugins.ts +0 -19
  261. package/tests/core/utilities/structures/quotas.ts +0 -72
  262. package/tests/core/utilities/structures/scim.ts +0 -80
  263. package/tests/core/utilities/structures/sso.ts +0 -118
  264. package/tests/core/utilities/structures/tenants.ts +0 -5
  265. package/tests/core/utilities/structures/userGroups.ts +0 -10
  266. package/tests/core/utilities/structures/users.ts +0 -89
  267. package/tests/core/utilities/testContainerUtils.ts +0 -165
  268. package/tests/core/utilities/utils/index.ts +0 -2
  269. package/tests/core/utilities/utils/queue.ts +0 -27
  270. package/tests/core/utilities/utils/time.ts +0 -3
  271. package/tests/extra/DBTestConfiguration.ts +0 -36
  272. package/tests/extra/index.ts +0 -2
  273. package/tests/extra/testEnv.ts +0 -95
  274. package/tests/index.ts +0 -2
  275. package/tests/jestEnv.ts +0 -10
  276. package/tests/jestSetup.ts +0 -36
@@ -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
- }
@@ -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
- }
@@ -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
- }
@@ -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
- }
@@ -1,4 +0,0 @@
1
- export * from "./hashing"
2
- export * from "./utils"
3
- export * from "./stringUtils"
4
- export * from "./Duration"
@@ -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,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
- })