@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,105 +0,0 @@
1
- import { AnyDocument, Database } from "@budibase/types"
2
-
3
- import { JobQueue, Queue, createQueue } from "../queue"
4
- import * as dbUtils from "../db"
5
-
6
- interface ProcessDocMessage {
7
- dbName: string
8
- docId: string
9
- data: Record<string, any>
10
- }
11
-
12
- const PERSIST_MAX_ATTEMPTS = 100
13
- let processor: DocWritethroughProcessor | undefined
14
-
15
- export class DocWritethroughProcessor {
16
- private static _queue: Queue
17
-
18
- public static get queue() {
19
- if (!DocWritethroughProcessor._queue) {
20
- DocWritethroughProcessor._queue = createQueue<ProcessDocMessage>(
21
- JobQueue.DOC_WRITETHROUGH_QUEUE,
22
- {
23
- jobOptions: {
24
- attempts: PERSIST_MAX_ATTEMPTS,
25
- },
26
- }
27
- )
28
- }
29
-
30
- return DocWritethroughProcessor._queue
31
- }
32
-
33
- init() {
34
- DocWritethroughProcessor.queue.process(async message => {
35
- try {
36
- await this.persistToDb(message.data)
37
- } catch (err: any) {
38
- if (err.status === 409) {
39
- // If we get a 409, it means that another job updated it meanwhile. We want to retry it to persist it again.
40
- throw new Error(
41
- `Conflict persisting message ${message.id}. Attempt ${message.attemptsMade}`
42
- )
43
- }
44
-
45
- throw err
46
- }
47
- })
48
- return this
49
- }
50
-
51
- private async persistToDb({
52
- dbName,
53
- docId,
54
- data,
55
- }: {
56
- dbName: string
57
- docId: string
58
- data: Record<string, any>
59
- }) {
60
- const db = dbUtils.getDB(dbName)
61
- let doc: AnyDocument | undefined
62
- try {
63
- doc = await db.get(docId)
64
- } catch {
65
- doc = { _id: docId }
66
- }
67
-
68
- doc = { ...doc, ...data }
69
- await db.put(doc)
70
- }
71
- }
72
-
73
- export class DocWritethrough {
74
- private db: Database
75
- private _docId: string
76
-
77
- constructor(db: Database, docId: string) {
78
- this.db = db
79
- this._docId = docId
80
- }
81
-
82
- get docId() {
83
- return this._docId
84
- }
85
-
86
- async patch(data: Record<string, any>) {
87
- await DocWritethroughProcessor.queue.add({
88
- dbName: this.db.name,
89
- docId: this.docId,
90
- data,
91
- })
92
- }
93
- }
94
-
95
- export function init(): DocWritethroughProcessor {
96
- processor = new DocWritethroughProcessor().init()
97
- return processor
98
- }
99
-
100
- export function getProcessor(): DocWritethroughProcessor {
101
- if (!processor) {
102
- return init()
103
- }
104
- return processor
105
- }
@@ -1,33 +0,0 @@
1
- import BaseCache from "./base"
2
-
3
- const GENERIC = new BaseCache()
4
-
5
- export enum CacheKey {
6
- CHECKLIST = "checklist",
7
- INSTALLATION = "installation",
8
- ANALYTICS_ENABLED = "analyticsEnabled",
9
- UNIQUE_TENANT_ID = "uniqueTenantId",
10
- EVENTS = "events",
11
- BACKFILL_METADATA = "backfillMetadata",
12
- EVENTS_RATE_LIMIT = "eventsRateLimit",
13
- }
14
-
15
- export enum TTL {
16
- ONE_MINUTE = 600,
17
- ONE_HOUR = 3600,
18
- ONE_DAY = 86400,
19
- }
20
-
21
- export const keys = (...args: Parameters<typeof GENERIC.keys>) =>
22
- GENERIC.keys(...args)
23
- export const get = (...args: Parameters<typeof GENERIC.get>) =>
24
- GENERIC.get(...args)
25
- export const store = (...args: Parameters<typeof GENERIC.store>) =>
26
- GENERIC.store(...args)
27
- export const destroy = (...args: Parameters<typeof GENERIC.delete>) =>
28
- GENERIC.delete(...args)
29
- export const withCache = <T>(
30
- ...args: Parameters<typeof GENERIC.withCache<T>>
31
- ) => GENERIC.withCache(...args)
32
- export const bustCache = (...args: Parameters<typeof GENERIC.bustCache>) =>
33
- GENERIC.bustCache(...args)
@@ -1,8 +0,0 @@
1
- export * as generic from "./generic"
2
- export * as user from "./user"
3
- export * as app from "./appMetadata"
4
- export * as writethrough from "./writethrough"
5
- export * as invite from "./invite"
6
- export * as passwordReset from "./passwordReset"
7
- export * from "./generic"
8
- export * as docWritethrough from "./docWritethrough"
@@ -1,86 +0,0 @@
1
- import * as utils from "../utils"
2
- import { Duration } from "../utils"
3
- import env from "../environment"
4
- import { getTenantId } from "../context"
5
- import * as redis from "../redis/init"
6
-
7
- const TTL_SECONDS = Duration.fromDays(7).toSeconds()
8
-
9
- interface Invite {
10
- email: string
11
- info: any
12
- }
13
-
14
- interface InviteWithCode extends Invite {
15
- code: string
16
- }
17
-
18
- /**
19
- * Given an invite code and invite body, allow the update an existing/valid invite in redis
20
- * @param code The invite code for an invite in redis
21
- * @param value The body of the updated user invitation
22
- */
23
- export async function updateCode(code: string, value: Invite) {
24
- const client = await redis.getInviteClient()
25
- await client.store(code, value, TTL_SECONDS)
26
- }
27
-
28
- /**
29
- * Generates an invitation code and writes it to redis - which can later be checked for user creation.
30
- * @param email the email address which the code is being sent to (for use later).
31
- * @param info Information to be carried along with the invitation.
32
- * @return returns the code that was stored to redis.
33
- */
34
- export async function createCode(email: string, info: any): Promise<string> {
35
- const code = utils.newid()
36
- const client = await redis.getInviteClient()
37
- await client.store(code, { email, info }, TTL_SECONDS)
38
- return code
39
- }
40
-
41
- /**
42
- * Checks that the provided invite code is valid - will return the email address of user that was invited.
43
- * @param code the invite code that was provided as part of the link.
44
- * @return If the code is valid then an email address will be returned.
45
- */
46
- export async function getCode(code: string): Promise<Invite> {
47
- const client = await redis.getInviteClient()
48
- const value = (await client.get(code)) as Invite | undefined
49
- if (!value) {
50
- throw "Invitation is not valid or has expired, please request a new one."
51
- }
52
- return value
53
- }
54
-
55
- export async function deleteCode(code: string) {
56
- const client = await redis.getInviteClient()
57
- await client.delete(code)
58
- }
59
-
60
- /**
61
- Get all currently available user invitations for the current tenant.
62
- **/
63
- export async function getInviteCodes(): Promise<InviteWithCode[]> {
64
- const client = await redis.getInviteClient()
65
- const invites: { key: string; value: Invite }[] = await client.scan()
66
-
67
- const results: InviteWithCode[] = invites.map(invite => {
68
- return {
69
- ...invite.value,
70
- code: invite.key,
71
- }
72
- })
73
- if (!env.MULTI_TENANCY) {
74
- return results
75
- }
76
- const tenantId = getTenantId()
77
- return results.filter(invite => tenantId === invite.info.tenantId)
78
- }
79
-
80
- export async function getExistingInvites(
81
- emails: string[]
82
- ): Promise<InviteWithCode[]> {
83
- return (await getInviteCodes()).filter(invite =>
84
- emails.includes(invite.email)
85
- )
86
- }
@@ -1,49 +0,0 @@
1
- import * as redis from "../redis/init"
2
- import * as utils from "../utils"
3
- import { Duration } from "../utils"
4
-
5
- const TTL_SECONDS = Duration.fromHours(1).toSeconds()
6
-
7
- interface PasswordReset {
8
- userId: string
9
- info: any
10
- }
11
-
12
- /**
13
- * Given a user ID this will store a code (that is returned) for an hour in redis.
14
- * The user can then return this code for resetting their password (through their reset link).
15
- * @param userId the ID of the user which is to be reset.
16
- * @param info Info about the user/the reset process.
17
- * @return returns the code that was stored to redis.
18
- */
19
- export async function createCode(userId: string, info: any): Promise<string> {
20
- const code = utils.newid()
21
- const client = await redis.getPasswordResetClient()
22
- await client.store(code, { userId, info }, TTL_SECONDS)
23
- return code
24
- }
25
-
26
- /**
27
- * Given a reset code this will lookup to redis, check if the code is valid.
28
- * @param code The code provided via the email link.
29
- * @return returns the user ID if it is found
30
- */
31
- export async function getCode(code: string): Promise<PasswordReset> {
32
- const client = await redis.getPasswordResetClient()
33
- const value = (await client.get(code)) as PasswordReset | undefined
34
- if (!value) {
35
- throw new Error(
36
- "Provided information is not valid, cannot reset password - please try again."
37
- )
38
- }
39
- return value
40
- }
41
-
42
- /**
43
- * Given a reset code this will invalidate it.
44
- * @param code The code provided via the email link.
45
- */
46
- export async function invalidateCode(code: string): Promise<void> {
47
- const client = await redis.getPasswordResetClient()
48
- await client.delete(code)
49
- }
@@ -1,296 +0,0 @@
1
- import tk from "timekeeper"
2
-
3
- import _ from "lodash"
4
- import {
5
- DBTestConfiguration,
6
- generator,
7
- structures,
8
- utils,
9
- } from "../../../tests"
10
- import { getDB } from "../../db"
11
-
12
- import {
13
- DocWritethrough,
14
- DocWritethroughProcessor,
15
- init,
16
- } from "../docWritethrough"
17
-
18
- const initialTime = Date.now()
19
-
20
- async function waitForQueueCompletion() {
21
- await utils.queue.processMessages(DocWritethroughProcessor.queue)
22
- }
23
-
24
- beforeAll(() => utils.queue.useRealQueues())
25
-
26
- describe("docWritethrough", () => {
27
- beforeAll(() => {
28
- init()
29
- })
30
-
31
- const config = new DBTestConfiguration()
32
-
33
- const db = getDB(structures.db.id())
34
- let documentId: string
35
- let docWritethrough: DocWritethrough
36
-
37
- describe("patch", () => {
38
- function generatePatchObject(fieldCount: number) {
39
- const keys = generator.unique(() => generator.guid(), fieldCount)
40
- return keys.reduce((acc, c) => {
41
- acc[c] = generator.word()
42
- return acc
43
- }, {} as Record<string, any>)
44
- }
45
-
46
- beforeEach(async () => {
47
- jest.clearAllMocks()
48
- documentId = structures.uuid()
49
- docWritethrough = new DocWritethrough(db, documentId)
50
- })
51
-
52
- it("patching will not persist until the messages are persisted", async () => {
53
- await config.doInTenant(async () => {
54
- await docWritethrough.patch(generatePatchObject(2))
55
- await docWritethrough.patch(generatePatchObject(2))
56
-
57
- expect(await db.exists(documentId)).toBe(false)
58
- })
59
- })
60
-
61
- it("patching will persist when the messages are persisted", async () => {
62
- await config.doInTenant(async () => {
63
- const patch1 = generatePatchObject(2)
64
- const patch2 = generatePatchObject(2)
65
- await docWritethrough.patch(patch1)
66
- await docWritethrough.patch(patch2)
67
-
68
- await waitForQueueCompletion()
69
-
70
- // This will not be persisted
71
- const patch3 = generatePatchObject(3)
72
- await docWritethrough.patch(patch3)
73
-
74
- expect(await db.tryGet(documentId)).toEqual({
75
- _id: documentId,
76
- ...patch1,
77
- ...patch2,
78
- _rev: expect.stringMatching(/2-.+/),
79
- createdAt: new Date(initialTime).toISOString(),
80
- updatedAt: new Date(initialTime).toISOString(),
81
- })
82
- })
83
- })
84
-
85
- it("patching will persist keeping the previous data", async () => {
86
- await config.doInTenant(async () => {
87
- const patch1 = generatePatchObject(2)
88
- const patch2 = generatePatchObject(2)
89
- await docWritethrough.patch(patch1)
90
- await docWritethrough.patch(patch2)
91
-
92
- await waitForQueueCompletion()
93
-
94
- const patch3 = generatePatchObject(3)
95
- await docWritethrough.patch(patch3)
96
-
97
- await waitForQueueCompletion()
98
-
99
- expect(await db.tryGet(documentId)).toEqual(
100
- expect.objectContaining({
101
- _id: documentId,
102
- ...patch1,
103
- ...patch2,
104
- ...patch3,
105
- })
106
- )
107
- })
108
- })
109
-
110
- it("date audit fields are set correctly when persisting", async () => {
111
- await config.doInTenant(async () => {
112
- const patch1 = generatePatchObject(2)
113
- const patch2 = generatePatchObject(2)
114
- await docWritethrough.patch(patch1)
115
- const date1 = new Date()
116
- await waitForQueueCompletion()
117
- await docWritethrough.patch(patch2)
118
-
119
- tk.travel(Date.now() + 100)
120
- const date2 = new Date()
121
- await waitForQueueCompletion()
122
-
123
- expect(date1).not.toEqual(date2)
124
- expect(await db.tryGet(documentId)).toEqual(
125
- expect.objectContaining({
126
- createdAt: date1.toISOString(),
127
- updatedAt: date2.toISOString(),
128
- })
129
- )
130
- })
131
- })
132
-
133
- it("concurrent patches will override keys", async () => {
134
- await config.doInTenant(async () => {
135
- const patch1 = generatePatchObject(2)
136
- await docWritethrough.patch(patch1)
137
- await waitForQueueCompletion()
138
- const patch2 = generatePatchObject(1)
139
- await docWritethrough.patch(patch2)
140
-
141
- const keyToOverride = _.sample(Object.keys(patch1))!
142
- expect(await db.tryGet(documentId)).toEqual(
143
- expect.objectContaining({
144
- [keyToOverride]: patch1[keyToOverride],
145
- })
146
- )
147
-
148
- await waitForQueueCompletion()
149
-
150
- const patch3 = {
151
- ...generatePatchObject(3),
152
- [keyToOverride]: generator.word(),
153
- }
154
- await docWritethrough.patch(patch3)
155
- await waitForQueueCompletion()
156
-
157
- expect(await db.tryGet(documentId)).toEqual(
158
- expect.objectContaining({
159
- ...patch1,
160
- ...patch2,
161
- ...patch3,
162
- })
163
- )
164
- })
165
- })
166
-
167
- it("concurrent patches to different docWritethrough will not pollute each other", async () => {
168
- await config.doInTenant(async () => {
169
- const secondDocWritethrough = new DocWritethrough(
170
- db,
171
- structures.db.id()
172
- )
173
-
174
- const doc1Patch = generatePatchObject(2)
175
- await docWritethrough.patch(doc1Patch)
176
- const doc2Patch = generatePatchObject(1)
177
- await secondDocWritethrough.patch(doc2Patch)
178
-
179
- await waitForQueueCompletion()
180
-
181
- const doc1Patch2 = generatePatchObject(3)
182
- await docWritethrough.patch(doc1Patch2)
183
- const doc2Patch2 = generatePatchObject(3)
184
- await secondDocWritethrough.patch(doc2Patch2)
185
- await waitForQueueCompletion()
186
-
187
- expect(await db.tryGet(docWritethrough.docId)).toEqual(
188
- expect.objectContaining({
189
- ...doc1Patch,
190
- ...doc1Patch2,
191
- })
192
- )
193
-
194
- expect(await db.tryGet(secondDocWritethrough.docId)).toEqual(
195
- expect.objectContaining({
196
- ...doc2Patch,
197
- ...doc2Patch2,
198
- })
199
- )
200
- })
201
- })
202
-
203
- it("cached values are persisted only once", async () => {
204
- await config.doInTenant(async () => {
205
- const initialPatch = generatePatchObject(5)
206
-
207
- await docWritethrough.patch(initialPatch)
208
- await waitForQueueCompletion()
209
-
210
- expect(await db.tryGet(documentId)).toEqual(
211
- expect.objectContaining(initialPatch)
212
- )
213
-
214
- await db.remove(await db.get(documentId))
215
-
216
- await waitForQueueCompletion()
217
- const extraPatch = generatePatchObject(5)
218
- await docWritethrough.patch(extraPatch)
219
- await waitForQueueCompletion()
220
-
221
- expect(await db.tryGet(documentId)).toEqual(
222
- expect.objectContaining(extraPatch)
223
- )
224
- expect(await db.tryGet(documentId)).not.toEqual(
225
- expect.objectContaining(initialPatch)
226
- )
227
- })
228
- })
229
-
230
- it("concurrent calls will not cause conflicts", async () => {
231
- async function parallelPatch(count: number) {
232
- const patches = Array.from({ length: count }).map(() =>
233
- generatePatchObject(1)
234
- )
235
- await Promise.all(patches.map(p => docWritethrough.patch(p)))
236
-
237
- return patches.reduce((acc, c) => {
238
- acc = { ...acc, ...c }
239
- return acc
240
- }, {})
241
- }
242
- const queueMessageSpy = jest.spyOn(DocWritethroughProcessor.queue, "add")
243
-
244
- await config.doInTenant(async () => {
245
- let patches = await parallelPatch(5)
246
- expect(queueMessageSpy).toHaveBeenCalledTimes(5)
247
-
248
- await waitForQueueCompletion()
249
- expect(await db.tryGet(documentId)).toEqual(
250
- expect.objectContaining(patches)
251
- )
252
-
253
- patches = { ...patches, ...(await parallelPatch(40)) }
254
- expect(queueMessageSpy).toHaveBeenCalledTimes(45)
255
-
256
- await waitForQueueCompletion()
257
- expect(await db.tryGet(documentId)).toEqual(
258
- expect.objectContaining(patches)
259
- )
260
-
261
- patches = { ...patches, ...(await parallelPatch(10)) }
262
- expect(queueMessageSpy).toHaveBeenCalledTimes(55)
263
-
264
- await waitForQueueCompletion()
265
- expect(await db.tryGet(documentId)).toEqual(
266
- expect.objectContaining(patches)
267
- )
268
- })
269
- })
270
-
271
- it("patches will execute in order", async () => {
272
- let incrementalValue = 0
273
- const keyToOverride = generator.word()
274
- async function incrementalPatches(count: number) {
275
- for (let i = 0; i < count; i++) {
276
- await docWritethrough.patch({ [keyToOverride]: ++incrementalValue })
277
- }
278
- }
279
-
280
- await config.doInTenant(async () => {
281
- await incrementalPatches(5)
282
-
283
- await waitForQueueCompletion()
284
- expect(await db.tryGet(documentId)).toEqual(
285
- expect.objectContaining({ [keyToOverride]: 5 })
286
- )
287
-
288
- await incrementalPatches(40)
289
- await waitForQueueCompletion()
290
- expect(await db.tryGet(documentId)).toEqual(
291
- expect.objectContaining({ [keyToOverride]: 45 })
292
- )
293
- })
294
- })
295
- })
296
- })