@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,145 +0,0 @@
1
- import { User } from "@budibase/types"
2
- import { generator, structures } from "../../../tests"
3
- import { DBTestConfiguration } from "../../../tests/extra"
4
- import { getUsers } from "../user"
5
- import { getGlobalDB } from "../../context"
6
- import _ from "lodash"
7
-
8
- import * as redis from "../../redis/init"
9
- import { UserDB } from "../../users"
10
-
11
- const config = new DBTestConfiguration()
12
-
13
- describe("user cache", () => {
14
- describe("getUsers", () => {
15
- const users: User[] = []
16
- beforeAll(async () => {
17
- const userCount = 10
18
- const userIds = generator.arrayOf(() => generator.guid(), {
19
- min: userCount,
20
- max: userCount,
21
- })
22
-
23
- await config.doInTenant(async () => {
24
- const db = getGlobalDB()
25
- for (const userId of userIds) {
26
- const user = structures.users.user({ _id: userId })
27
- await db.put(user)
28
- users.push(user)
29
- }
30
- })
31
- })
32
-
33
- beforeEach(async () => {
34
- jest.clearAllMocks()
35
-
36
- const redisClient = await redis.getUserClient()
37
- await redisClient.clear()
38
- })
39
-
40
- it("when no user is in cache, all of them are retrieved from db", async () => {
41
- const usersToRequest = _.sampleSize(users, 5)
42
-
43
- const userIdsToRequest = usersToRequest.map(x => x._id!)
44
-
45
- jest.spyOn(UserDB, "bulkGet")
46
-
47
- const results = await config.doInTenant(() => getUsers(userIdsToRequest))
48
-
49
- expect(results.users).toHaveLength(5)
50
- expect(results).toEqual({
51
- users: usersToRequest.map(u => ({
52
- ...u,
53
- budibaseAccess: true,
54
- _rev: expect.any(String),
55
- })),
56
- })
57
-
58
- expect(UserDB.bulkGet).toHaveBeenCalledTimes(1)
59
- expect(UserDB.bulkGet).toHaveBeenCalledWith(userIdsToRequest)
60
- })
61
-
62
- it("on a second all, all of them are retrieved from cache", async () => {
63
- const usersToRequest = _.sampleSize(users, 5)
64
-
65
- const userIdsToRequest = usersToRequest.map(x => x._id!)
66
-
67
- jest.spyOn(UserDB, "bulkGet")
68
-
69
- await config.doInTenant(() => getUsers(userIdsToRequest))
70
- const resultsFromCache = await config.doInTenant(() =>
71
- getUsers(userIdsToRequest)
72
- )
73
-
74
- expect(resultsFromCache.users).toHaveLength(5)
75
- expect(resultsFromCache).toEqual({
76
- users: expect.arrayContaining(
77
- usersToRequest.map(u => ({
78
- ...u,
79
- budibaseAccess: true,
80
- _rev: expect.any(String),
81
- }))
82
- ),
83
- })
84
-
85
- expect(UserDB.bulkGet).toHaveBeenCalledTimes(1)
86
- })
87
-
88
- it("when some users are cached, only the missing ones are retrieved from db", async () => {
89
- const usersToRequest = _.sampleSize(users, 5)
90
-
91
- const userIdsToRequest = usersToRequest.map(x => x._id!)
92
-
93
- jest.spyOn(UserDB, "bulkGet")
94
-
95
- await config.doInTenant(() =>
96
- getUsers([userIdsToRequest[0], userIdsToRequest[3]])
97
- )
98
- ;(UserDB.bulkGet as jest.Mock).mockClear()
99
-
100
- const results = await config.doInTenant(() => getUsers(userIdsToRequest))
101
-
102
- expect(results.users).toHaveLength(5)
103
- expect(results).toEqual({
104
- users: expect.arrayContaining(
105
- usersToRequest.map(u => ({
106
- ...u,
107
- budibaseAccess: true,
108
- _rev: expect.any(String),
109
- }))
110
- ),
111
- })
112
-
113
- expect(UserDB.bulkGet).toHaveBeenCalledTimes(1)
114
- expect(UserDB.bulkGet).toHaveBeenCalledWith([
115
- userIdsToRequest[1],
116
- userIdsToRequest[2],
117
- userIdsToRequest[4],
118
- ])
119
- })
120
-
121
- it("requesting existing and unexisting ids will return found ones", async () => {
122
- const usersToRequest = _.sampleSize(users, 3)
123
- const missingIds = [generator.guid(), generator.guid()]
124
-
125
- const userIdsToRequest = _.shuffle([
126
- ...missingIds,
127
- ...usersToRequest.map(x => x._id!),
128
- ])
129
-
130
- const results = await config.doInTenant(() => getUsers(userIdsToRequest))
131
-
132
- expect(results.users).toHaveLength(3)
133
- expect(results).toEqual({
134
- users: expect.arrayContaining(
135
- usersToRequest.map(u => ({
136
- ...u,
137
- budibaseAccess: true,
138
- _rev: expect.any(String),
139
- }))
140
- ),
141
- notFoundIds: expect.arrayContaining(missingIds),
142
- })
143
- })
144
- })
145
- })
@@ -1,139 +0,0 @@
1
- import { DBTestConfiguration } from "../../../tests/extra"
2
- import { structures } from "../../../tests"
3
- import { Writethrough } from "../writethrough"
4
- import { getDB } from "../../db"
5
- import { Document } from "@budibase/types"
6
- import tk from "timekeeper"
7
-
8
- tk.freeze(Date.now())
9
-
10
- interface ValueDoc extends Document {
11
- value: any
12
- }
13
-
14
- const DELAY = 5000
15
-
16
- describe("writethrough", () => {
17
- const config = new DBTestConfiguration()
18
-
19
- const db = getDB(structures.db.id())
20
- const db2 = getDB(structures.db.id())
21
-
22
- const writethrough = new Writethrough(db, DELAY)
23
- const writethrough2 = new Writethrough(db2, DELAY)
24
-
25
- const docId = structures.uuid()
26
-
27
- beforeEach(() => {
28
- jest.clearAllMocks()
29
- })
30
-
31
- describe("put", () => {
32
- let current: any
33
-
34
- it("should be able to store, will go to DB", async () => {
35
- await config.doInTenant(async () => {
36
- const response = await writethrough.put({
37
- _id: docId,
38
- value: 1,
39
- })
40
- const output = await db.get<any>(response.id)
41
- current = output
42
- expect(output.value).toBe(1)
43
- })
44
- })
45
-
46
- it("second put shouldn't update DB", async () => {
47
- await config.doInTenant(async () => {
48
- const response = await writethrough.put({ ...current, value: 2 })
49
- const output = await db.get<any>(response.id)
50
- expect(current._rev).toBe(output._rev)
51
- expect(output.value).toBe(1)
52
- })
53
- })
54
-
55
- it("should put it again after delay period", async () => {
56
- await config.doInTenant(async () => {
57
- tk.freeze(Date.now() + DELAY + 1)
58
- const response = await writethrough.put({ ...current, value: 3 })
59
- const output = await db.get<any>(response.id)
60
- expect(response.rev).not.toBe(current._rev)
61
- expect(output.value).toBe(3)
62
-
63
- current = output
64
- })
65
- })
66
-
67
- it("should handle parallel DB updates ignoring conflicts", async () => {
68
- await config.doInTenant(async () => {
69
- tk.freeze(Date.now() + DELAY + 1)
70
- const responses = await Promise.all([
71
- writethrough.put({ ...current, value: 4 }),
72
- writethrough.put({ ...current, value: 4 }),
73
- writethrough.put({ ...current, value: 4 }),
74
- ])
75
-
76
- // with a lock, this will work
77
- const newRev = responses.map(x => x.rev).find(x => x !== current._rev)
78
- expect(newRev).toBeDefined()
79
- expect(responses.map(x => x.rev)).toEqual(
80
- expect.arrayContaining([current._rev, current._rev, newRev])
81
- )
82
-
83
- const output = await db.get<any>(current._id)
84
- expect(output.value).toBe(4)
85
- expect(output._rev).toBe(newRev)
86
-
87
- current = output
88
- })
89
- })
90
-
91
- it("should handle updates with documents falling behind", async () => {
92
- await config.doInTenant(async () => {
93
- tk.freeze(Date.now() + DELAY + 1)
94
-
95
- const id = structures.uuid()
96
- await writethrough.put({ _id: id, value: 1 })
97
- const doc = await writethrough.get(id)
98
-
99
- // Updating document
100
- tk.freeze(Date.now() + DELAY + 1)
101
- await writethrough.put({ ...doc, value: 2 })
102
-
103
- // Update with the old rev value
104
- tk.freeze(Date.now() + DELAY + 1)
105
- const res = await writethrough.put({
106
- ...doc,
107
- value: 3,
108
- })
109
- expect(res.ok).toBe(true)
110
-
111
- const output = await db.get<any>(id)
112
- expect(output.value).toBe(3)
113
- expect(output._rev).toBe(res.rev)
114
- })
115
- })
116
- })
117
-
118
- describe("get", () => {
119
- it("should be able to retrieve", async () => {
120
- await config.doInTenant(async () => {
121
- const response = await writethrough.get<ValueDoc>(docId)
122
- expect(response.value).toBe(4)
123
- })
124
- })
125
- })
126
-
127
- describe("same doc, different databases (tenancy)", () => {
128
- it("should be able to two different databases", async () => {
129
- await config.doInTenant(async () => {
130
- const resp1 = await writethrough.put({ _id: "db1", value: "first" })
131
- const resp2 = await writethrough2.put({ _id: "db1", value: "second" })
132
- expect(resp1.rev).toBeDefined()
133
- expect(resp2.rev).toBeDefined()
134
- expect((await db.get<any>("db1")).value).toBe("first")
135
- expect((await db2.get<any>("db1")).value).toBe("second")
136
- })
137
- })
138
- })
139
- })
package/src/cache/user.ts DELETED
@@ -1,154 +0,0 @@
1
- import * as redis from "../redis/init"
2
- import * as tenancy from "../tenancy"
3
- import * as context from "../context"
4
- import * as platform from "../platform"
5
- import env from "../environment"
6
- import * as accounts from "../accounts"
7
- import { UserDB } from "../users"
8
- import { sdk } from "@budibase/shared-core"
9
- import { User, UserMetadata } from "@budibase/types"
10
-
11
- const EXPIRY_SECONDS = 3600
12
-
13
- /**
14
- * The default populate user function
15
- */
16
- async function populateFromDB(userId: string, tenantId: string) {
17
- const db = tenancy.getTenantDB(tenantId)
18
- const user = await db.get<UserMetadata>(userId)
19
- user.budibaseAccess = true
20
- if (!env.SELF_HOSTED && !env.DISABLE_ACCOUNT_PORTAL) {
21
- const account = await accounts.getAccount(user.email)
22
- if (account) {
23
- user.account = account
24
- user.accountPortalAccess = true
25
- }
26
- }
27
-
28
- return user
29
- }
30
-
31
- async function populateUsersFromDB(
32
- userIds: string[]
33
- ): Promise<{ users: User[]; notFoundIds?: string[] }> {
34
- const getUsersResponse = await UserDB.bulkGet(userIds)
35
-
36
- // Handle missed user ids
37
- const notFoundIds = userIds.filter((uid, i) => !getUsersResponse[i])
38
-
39
- const users = getUsersResponse.filter(x => x)
40
-
41
- await Promise.all(
42
- users.map(async (user: any) => {
43
- user.budibaseAccess = true
44
- if (!env.SELF_HOSTED && !env.DISABLE_ACCOUNT_PORTAL) {
45
- const account = await accounts.getAccount(user.email)
46
- if (account) {
47
- user.account = account
48
- user.accountPortalAccess = true
49
- }
50
- }
51
- })
52
- )
53
-
54
- if (notFoundIds.length) {
55
- return { users, notFoundIds }
56
- }
57
- return { users }
58
- }
59
-
60
- /**
61
- * Get the requested user by id.
62
- * Use redis cache to first read the user.
63
- * If not present fallback to loading the user directly and re-caching.
64
- * @param userId the id of the user to get
65
- * @param tenantId the tenant of the user to get
66
- * @param email the email of the user to populate from account if needed
67
- * @param populateUser function to provide the user for re-caching. default to couch db
68
- * @returns
69
- */
70
- export async function getUser({
71
- userId,
72
- tenantId,
73
- email,
74
- populateUser,
75
- }: {
76
- userId: string
77
- email?: string
78
- tenantId?: string
79
- populateUser?: (
80
- userId: string,
81
- tenantId: string,
82
- email?: string
83
- ) => Promise<User>
84
- }) {
85
- if (!populateUser) {
86
- populateUser = populateFromDB
87
- }
88
- if (!tenantId) {
89
- try {
90
- tenantId = context.getTenantId()
91
- } catch (err) {
92
- tenantId = await platform.users.lookupTenantId(userId)
93
- }
94
- }
95
- const client = await redis.getUserClient()
96
- // try cache
97
- let user: User = await client.get(userId)
98
- if (!user) {
99
- user = await populateUser(userId, tenantId, email)
100
- await client.store(userId, user, EXPIRY_SECONDS)
101
- }
102
- if (user && !user.tenantId && tenantId) {
103
- // make sure the tenant ID is always correct/set
104
- user.tenantId = tenantId
105
- }
106
- // if has groups, could have builder permissions granted by a group
107
- if (user.userGroups && !sdk.users.isGlobalBuilder(user)) {
108
- await context.doInTenant(tenantId, async () => {
109
- const appIds = await UserDB.getGroupBuilderAppIds(user)
110
- if (appIds.length) {
111
- const existing = user.builder?.apps || []
112
- user.builder = {
113
- apps: [...new Set(existing.concat(appIds))],
114
- }
115
- }
116
- })
117
- }
118
- return user
119
- }
120
-
121
- /**
122
- * Get the requested users by id.
123
- * Use redis cache to first read the users.
124
- * If not present fallback to loading the users directly and re-caching.
125
- * @param userIds the ids of the user to get
126
- * @param tenantId the tenant of the users to get
127
- * @returns
128
- */
129
- export async function getUsers(
130
- userIds: string[]
131
- ): Promise<{ users: User[]; notFoundIds?: string[] }> {
132
- const client = await redis.getUserClient()
133
- // try cache
134
- let usersFromCache = await client.bulkGet<User>(userIds)
135
- const missingUsersFromCache = userIds.filter(uid => !usersFromCache[uid])
136
- const users = Object.values(usersFromCache)
137
- let notFoundIds
138
-
139
- if (missingUsersFromCache.length) {
140
- const usersFromDb = await populateUsersFromDB(missingUsersFromCache)
141
-
142
- notFoundIds = usersFromDb.notFoundIds
143
- for (const userToCache of usersFromDb.users) {
144
- await client.store(userToCache._id!, userToCache, EXPIRY_SECONDS)
145
- }
146
- users.push(...usersFromDb.users)
147
- }
148
- return { users, notFoundIds: notFoundIds }
149
- }
150
-
151
- export async function invalidateUser(userId: string) {
152
- const client = await redis.getUserClient()
153
- await client.delete(userId)
154
- }
@@ -1,133 +0,0 @@
1
- import BaseCache from "./base"
2
- import { getWritethroughClient } from "../redis/init"
3
- import { logWarn } from "../logging"
4
- import { Database, Document, LockName, LockType } from "@budibase/types"
5
- import * as locks from "../redis/redlockImpl"
6
-
7
- const DEFAULT_WRITE_RATE_MS = 10000
8
- let CACHE: BaseCache | null = null
9
-
10
- interface CacheItem<T extends Document> {
11
- doc: T
12
- lastWrite: number
13
- }
14
-
15
- async function getCache() {
16
- if (!CACHE) {
17
- const client = await getWritethroughClient()
18
- CACHE = new BaseCache(client)
19
- }
20
- return CACHE
21
- }
22
-
23
- function makeCacheKey(db: Database, key: string) {
24
- return db.name + key
25
- }
26
-
27
- function makeCacheItem<T extends Document>(
28
- doc: T,
29
- lastWrite: number | null = null
30
- ): CacheItem<T> {
31
- return { doc, lastWrite: lastWrite || Date.now() }
32
- }
33
-
34
- async function put(
35
- db: Database,
36
- doc: Document,
37
- writeRateMs: number = DEFAULT_WRITE_RATE_MS
38
- ) {
39
- const cache = await getCache()
40
- const key = doc._id
41
- let cacheItem: CacheItem<any> | undefined
42
- if (key) {
43
- cacheItem = await cache.get(makeCacheKey(db, key))
44
- }
45
- const updateDb = !cacheItem || cacheItem.lastWrite < Date.now() - writeRateMs
46
- let output = doc
47
- if (updateDb) {
48
- const lockResponse = await locks.doWithLock(
49
- {
50
- type: LockType.TRY_ONCE,
51
- name: LockName.PERSIST_WRITETHROUGH,
52
- resource: key,
53
- ttl: 15000,
54
- },
55
- async () => {
56
- const writeDb = async (toWrite: any) => {
57
- // doc should contain the _id and _rev
58
- const response = await db.put(toWrite, { force: true })
59
- output._id = response.id
60
- output._rev = response.rev
61
- }
62
- try {
63
- await writeDb(doc)
64
- } catch (err: any) {
65
- if (err.status !== 409) {
66
- throw err
67
- } else {
68
- // Swallow 409s but log them
69
- logWarn(`Ignoring conflict in write-through cache`)
70
- }
71
- }
72
- }
73
- )
74
-
75
- if (!lockResponse.executed) {
76
- logWarn(`Ignoring redlock conflict in write-through cache`)
77
- }
78
- }
79
- // if we are updating the DB then need to set the lastWrite to now
80
- cacheItem = makeCacheItem(output, updateDb ? null : cacheItem?.lastWrite)
81
- if (output._id) {
82
- await cache.store(makeCacheKey(db, output._id), cacheItem)
83
- }
84
- return { ok: true, id: output._id, rev: output._rev }
85
- }
86
-
87
- async function get<T extends Document>(db: Database, id: string): Promise<T> {
88
- const cache = await getCache()
89
- const cacheKey = makeCacheKey(db, id)
90
- let cacheItem: CacheItem<T> = await cache.get(cacheKey)
91
- if (!cacheItem) {
92
- const doc = await db.get<T>(id)
93
- cacheItem = makeCacheItem(doc)
94
- await cache.store(cacheKey, cacheItem)
95
- }
96
- return cacheItem.doc
97
- }
98
-
99
- async function remove(db: Database, docOrId: any, rev?: any): Promise<void> {
100
- const cache = await getCache()
101
- if (!docOrId) {
102
- throw new Error("No ID/Rev provided.")
103
- }
104
- const id = typeof docOrId === "string" ? docOrId : docOrId._id
105
- rev = typeof docOrId === "string" ? rev : docOrId._rev
106
- try {
107
- await cache.delete(makeCacheKey(db, id))
108
- } finally {
109
- await db.remove(id, rev)
110
- }
111
- }
112
-
113
- export class Writethrough {
114
- db: Database
115
- writeRateMs: number
116
-
117
- constructor(db: Database, writeRateMs: number = DEFAULT_WRITE_RATE_MS) {
118
- this.db = db
119
- this.writeRateMs = writeRateMs
120
- }
121
-
122
- async put(doc: any, writeRateMs: number = this.writeRateMs) {
123
- return put(this.db, doc, writeRateMs)
124
- }
125
-
126
- async get<T extends Document>(id: string) {
127
- return get<T>(this.db, id)
128
- }
129
-
130
- async remove(docOrId: any, rev?: any) {
131
- return remove(this.db, docOrId, rev)
132
- }
133
- }