@budibase/backend-core 3.2.4 → 3.2.6
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.
- package/dist/index.js.map +1 -1
- package/dist/index.js.meta.json +1 -1
- package/dist/package.json +11 -4
- package/dist/plugins.js.meta.json +1 -1
- package/package.json +11 -4
- package/src/accounts/accounts.ts +0 -82
- package/src/accounts/api.ts +0 -59
- package/src/accounts/index.ts +0 -1
- package/src/auth/auth.ts +0 -210
- package/src/auth/index.ts +0 -1
- package/src/auth/tests/auth.spec.ts +0 -14
- package/src/blacklist/blacklist.ts +0 -54
- package/src/blacklist/index.ts +0 -1
- package/src/blacklist/tests/blacklist.spec.ts +0 -46
- package/src/cache/appMetadata.ts +0 -88
- package/src/cache/base/index.ts +0 -150
- package/src/cache/docWritethrough.ts +0 -105
- package/src/cache/generic.ts +0 -33
- package/src/cache/index.ts +0 -8
- package/src/cache/invite.ts +0 -86
- package/src/cache/passwordReset.ts +0 -49
- package/src/cache/tests/docWritethrough.spec.ts +0 -296
- package/src/cache/tests/user.spec.ts +0 -145
- package/src/cache/tests/writethrough.spec.ts +0 -139
- package/src/cache/user.ts +0 -154
- package/src/cache/writethrough.ts +0 -133
- package/src/configs/configs.ts +0 -263
- package/src/configs/index.ts +0 -1
- package/src/configs/tests/configs.spec.ts +0 -184
- package/src/constants/db.ts +0 -75
- package/src/constants/index.ts +0 -2
- package/src/constants/misc.ts +0 -36
- package/src/context/Context.ts +0 -14
- package/src/context/identity.ts +0 -58
- package/src/context/index.ts +0 -3
- package/src/context/mainContext.ts +0 -422
- package/src/context/tests/index.spec.ts +0 -255
- package/src/context/types.ts +0 -26
- package/src/db/Replication.ts +0 -94
- package/src/db/couch/DatabaseImpl.ts +0 -511
- package/src/db/couch/connections.ts +0 -89
- package/src/db/couch/index.ts +0 -4
- package/src/db/couch/pouchDB.ts +0 -97
- package/src/db/couch/pouchDump.ts +0 -0
- package/src/db/couch/tests/DatabaseImpl.spec.ts +0 -118
- package/src/db/couch/utils.ts +0 -55
- package/src/db/db.ts +0 -34
- package/src/db/errors.ts +0 -14
- package/src/db/index.ts +0 -12
- package/src/db/instrumentation.ts +0 -199
- package/src/db/lucene.ts +0 -721
- package/src/db/searchIndexes/index.ts +0 -1
- package/src/db/searchIndexes/searchIndexes.ts +0 -62
- package/src/db/tests/DatabaseImpl.spec.ts +0 -55
- package/src/db/tests/connections.spec.ts +0 -22
- package/src/db/tests/index.spec.ts +0 -32
- package/src/db/tests/lucene.spec.ts +0 -400
- package/src/db/tests/pouch.spec.js +0 -62
- package/src/db/tests/utils.spec.ts +0 -63
- package/src/db/utils.ts +0 -208
- package/src/db/views.ts +0 -245
- package/src/docIds/conversions.ts +0 -60
- package/src/docIds/ids.ts +0 -126
- package/src/docIds/index.ts +0 -2
- package/src/docIds/newid.ts +0 -5
- package/src/docIds/params.ts +0 -189
- package/src/docUpdates/index.ts +0 -24
- package/src/environment.ts +0 -293
- package/src/errors/errors.ts +0 -119
- package/src/errors/index.ts +0 -1
- package/src/events/analytics.ts +0 -6
- package/src/events/asyncEvents/index.ts +0 -2
- package/src/events/asyncEvents/publisher.ts +0 -12
- package/src/events/asyncEvents/queue.ts +0 -22
- package/src/events/backfill.ts +0 -183
- package/src/events/documentId.ts +0 -56
- package/src/events/events.ts +0 -47
- package/src/events/identification.ts +0 -311
- package/src/events/index.ts +0 -15
- package/src/events/processors/AnalyticsProcessor.ts +0 -64
- package/src/events/processors/AuditLogsProcessor.ts +0 -92
- package/src/events/processors/LoggingProcessor.ts +0 -36
- package/src/events/processors/Processors.ts +0 -52
- package/src/events/processors/async/DocumentUpdateProcessor.ts +0 -38
- package/src/events/processors/index.ts +0 -19
- package/src/events/processors/posthog/PosthogProcessor.ts +0 -118
- package/src/events/processors/posthog/index.ts +0 -3
- package/src/events/processors/posthog/rateLimiting.ts +0 -106
- package/src/events/processors/posthog/tests/PosthogProcessor.spec.ts +0 -164
- package/src/events/processors/types.ts +0 -1
- package/src/events/publishers/account.ts +0 -41
- package/src/events/publishers/ai.ts +0 -21
- package/src/events/publishers/app.ts +0 -168
- package/src/events/publishers/auditLog.ts +0 -26
- package/src/events/publishers/auth.ts +0 -73
- package/src/events/publishers/automation.ts +0 -110
- package/src/events/publishers/backfill.ts +0 -74
- package/src/events/publishers/backup.ts +0 -42
- package/src/events/publishers/datasource.ts +0 -48
- package/src/events/publishers/email.ts +0 -17
- package/src/events/publishers/environmentVariable.ts +0 -38
- package/src/events/publishers/group.ts +0 -99
- package/src/events/publishers/index.ts +0 -25
- package/src/events/publishers/installation.ts +0 -38
- package/src/events/publishers/layout.ts +0 -26
- package/src/events/publishers/license.ts +0 -84
- package/src/events/publishers/org.ts +0 -37
- package/src/events/publishers/plugin.ts +0 -47
- package/src/events/publishers/query.ts +0 -89
- package/src/events/publishers/role.ts +0 -62
- package/src/events/publishers/rows.ts +0 -29
- package/src/events/publishers/screen.ts +0 -36
- package/src/events/publishers/serve.ts +0 -43
- package/src/events/publishers/table.ts +0 -70
- package/src/events/publishers/user.ts +0 -202
- package/src/events/publishers/view.ts +0 -107
- package/src/features/features.ts +0 -277
- package/src/features/index.ts +0 -2
- package/src/features/tests/features.spec.ts +0 -267
- package/src/features/tests/utils.ts +0 -64
- package/src/helpers.ts +0 -9
- package/src/index.ts +0 -59
- package/src/installation.ts +0 -115
- package/src/logging/alerts.ts +0 -26
- package/src/logging/correlation/correlation.ts +0 -15
- package/src/logging/correlation/index.ts +0 -1
- package/src/logging/correlation/middleware.ts +0 -18
- package/src/logging/index.ts +0 -4
- package/src/logging/pino/logger.ts +0 -239
- package/src/logging/pino/middleware.ts +0 -48
- package/src/logging/system.ts +0 -81
- package/src/logging/tests/system.spec.ts +0 -61
- package/src/middleware/adminOnly.ts +0 -9
- package/src/middleware/auditLog.ts +0 -6
- package/src/middleware/authenticated.ts +0 -247
- package/src/middleware/builderOnly.ts +0 -21
- package/src/middleware/builderOrAdmin.ts +0 -21
- package/src/middleware/contentSecurityPolicy.ts +0 -113
- package/src/middleware/csrf.ts +0 -81
- package/src/middleware/errorHandling.ts +0 -43
- package/src/middleware/index.ts +0 -24
- package/src/middleware/internalApi.ts +0 -23
- package/src/middleware/ip.ts +0 -12
- package/src/middleware/joi-validator.ts +0 -58
- package/src/middleware/matchers.ts +0 -39
- package/src/middleware/passport/datasource/google.ts +0 -102
- package/src/middleware/passport/local.ts +0 -54
- package/src/middleware/passport/sso/google.ts +0 -77
- package/src/middleware/passport/sso/oidc.ts +0 -152
- package/src/middleware/passport/sso/sso.ts +0 -138
- package/src/middleware/passport/sso/tests/google.spec.ts +0 -68
- package/src/middleware/passport/sso/tests/oidc.spec.ts +0 -144
- package/src/middleware/passport/sso/tests/sso.spec.ts +0 -197
- package/src/middleware/passport/utils.ts +0 -38
- package/src/middleware/querystringToBody.ts +0 -28
- package/src/middleware/tenancy.ts +0 -36
- package/src/middleware/tests/builder.spec.ts +0 -181
- package/src/middleware/tests/contentSecurityPolicy.spec.ts +0 -75
- package/src/middleware/tests/matchers.spec.ts +0 -100
- package/src/migrations/definitions.ts +0 -40
- package/src/migrations/index.ts +0 -2
- package/src/migrations/migrations.ts +0 -186
- package/src/migrations/tests/__snapshots__/migrations.spec.ts.snap +0 -11
- package/src/migrations/tests/migrations.spec.ts +0 -64
- package/src/objectStore/buckets/app.ts +0 -53
- package/src/objectStore/buckets/global.ts +0 -29
- package/src/objectStore/buckets/index.ts +0 -3
- package/src/objectStore/buckets/plugins.ts +0 -71
- package/src/objectStore/buckets/tests/app.spec.ts +0 -161
- package/src/objectStore/buckets/tests/global.spec.ts +0 -74
- package/src/objectStore/buckets/tests/plugins.spec.ts +0 -111
- package/src/objectStore/cloudfront.ts +0 -41
- package/src/objectStore/index.ts +0 -3
- package/src/objectStore/objectStore.ts +0 -585
- package/src/objectStore/utils.ts +0 -113
- package/src/platform/index.ts +0 -3
- package/src/platform/platformDb.ts +0 -6
- package/src/platform/tenants.ts +0 -101
- package/src/platform/tests/tenants.spec.ts +0 -26
- package/src/platform/users.ts +0 -129
- package/src/plugin/index.ts +0 -1
- package/src/plugin/tests/validation.spec.ts +0 -209
- package/src/plugin/utils.ts +0 -175
- package/src/queue/constants.ts +0 -8
- package/src/queue/inMemoryQueue.ts +0 -189
- package/src/queue/index.ts +0 -2
- package/src/queue/listeners.ts +0 -199
- package/src/queue/queue.ts +0 -84
- package/src/redis/index.ts +0 -6
- package/src/redis/init.ts +0 -118
- package/src/redis/redis.ts +0 -358
- package/src/redis/redlockImpl.ts +0 -155
- package/src/redis/tests/redis.spec.ts +0 -207
- package/src/redis/tests/redlockImpl.spec.ts +0 -105
- package/src/redis/utils.ts +0 -128
- package/src/security/auth.ts +0 -24
- package/src/security/encryption.ts +0 -185
- package/src/security/index.ts +0 -1
- package/src/security/permissions.ts +0 -166
- package/src/security/roles.ts +0 -655
- package/src/security/secrets.ts +0 -20
- package/src/security/sessions.ts +0 -123
- package/src/security/tests/auth.spec.ts +0 -45
- package/src/security/tests/encryption.spec.ts +0 -31
- package/src/security/tests/permissions.spec.ts +0 -146
- package/src/security/tests/secrets.spec.ts +0 -35
- package/src/security/tests/sessions.spec.ts +0 -12
- package/src/sql/designDoc.ts +0 -17
- package/src/sql/index.ts +0 -5
- package/src/sql/sql.ts +0 -1854
- package/src/sql/sqlTable.ts +0 -319
- package/src/sql/utils.ts +0 -193
- package/src/tenancy/db.ts +0 -6
- package/src/tenancy/index.ts +0 -2
- package/src/tenancy/tenancy.ts +0 -148
- package/src/tenancy/tests/tenancy.spec.ts +0 -184
- package/src/timers/index.ts +0 -1
- package/src/timers/timers.ts +0 -22
- package/src/users/db.ts +0 -582
- package/src/users/events.ts +0 -176
- package/src/users/index.ts +0 -4
- package/src/users/lookup.ts +0 -99
- package/src/users/test/db.spec.ts +0 -188
- package/src/users/test/utils.spec.ts +0 -67
- package/src/users/users.ts +0 -353
- package/src/users/utils.ts +0 -81
- package/src/utils/Duration.ts +0 -56
- package/src/utils/hashing.ts +0 -15
- package/src/utils/index.ts +0 -4
- package/src/utils/stringUtils.ts +0 -8
- package/src/utils/tests/Duration.spec.ts +0 -19
- package/src/utils/tests/utils.spec.ts +0 -204
- package/src/utils/utils.ts +0 -249
- package/tests/core/logging.ts +0 -34
- package/tests/core/users/users.spec.js +0 -53
- package/tests/core/utilities/index.ts +0 -7
- package/tests/core/utilities/jestUtils.ts +0 -33
- package/tests/core/utilities/mocks/alerts.ts +0 -4
- package/tests/core/utilities/mocks/date.ts +0 -3
- package/tests/core/utilities/mocks/events.ts +0 -132
- package/tests/core/utilities/mocks/index.ts +0 -9
- package/tests/core/utilities/mocks/licenses.ts +0 -119
- package/tests/core/utilities/queue.ts +0 -9
- package/tests/core/utilities/structures/Chance.ts +0 -20
- package/tests/core/utilities/structures/accounts.ts +0 -80
- package/tests/core/utilities/structures/apps.ts +0 -21
- package/tests/core/utilities/structures/common.ts +0 -7
- package/tests/core/utilities/structures/db.ts +0 -12
- package/tests/core/utilities/structures/documents/index.ts +0 -1
- package/tests/core/utilities/structures/documents/platform/index.ts +0 -1
- package/tests/core/utilities/structures/documents/platform/installation.ts +0 -12
- package/tests/core/utilities/structures/generator.ts +0 -3
- package/tests/core/utilities/structures/index.ts +0 -15
- package/tests/core/utilities/structures/koa.ts +0 -16
- package/tests/core/utilities/structures/licenses.ts +0 -190
- package/tests/core/utilities/structures/plugins.ts +0 -19
- package/tests/core/utilities/structures/quotas.ts +0 -72
- package/tests/core/utilities/structures/scim.ts +0 -80
- package/tests/core/utilities/structures/sso.ts +0 -118
- package/tests/core/utilities/structures/tenants.ts +0 -5
- package/tests/core/utilities/structures/userGroups.ts +0 -10
- package/tests/core/utilities/structures/users.ts +0 -89
- package/tests/core/utilities/testContainerUtils.ts +0 -165
- package/tests/core/utilities/utils/index.ts +0 -2
- package/tests/core/utilities/utils/queue.ts +0 -27
- package/tests/core/utilities/utils/time.ts +0 -3
- package/tests/extra/DBTestConfiguration.ts +0 -36
- package/tests/extra/index.ts +0 -2
- package/tests/extra/testEnv.ts +0 -95
- package/tests/index.ts +0 -2
- package/tests/jestEnv.ts +0 -10
- package/tests/jestSetup.ts +0 -36
package/src/cache/index.ts
DELETED
|
@@ -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"
|
package/src/cache/invite.ts
DELETED
|
@@ -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
|
-
})
|
|
@@ -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
|
-
})
|