@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
|
@@ -1,204 +0,0 @@
|
|
|
1
|
-
import { structures } from "../../../tests"
|
|
2
|
-
import { DBTestConfiguration } from "../../../tests/extra"
|
|
3
|
-
import * as utils from "../../utils"
|
|
4
|
-
import * as db from "../../db"
|
|
5
|
-
import { Header } from "../../constants"
|
|
6
|
-
import { newid } from "../../utils"
|
|
7
|
-
import env from "../../environment"
|
|
8
|
-
import { BBContext } from "@budibase/types"
|
|
9
|
-
|
|
10
|
-
describe("utils", () => {
|
|
11
|
-
const config = new DBTestConfiguration()
|
|
12
|
-
|
|
13
|
-
describe("getAppIdFromCtx", () => {
|
|
14
|
-
it("gets appId from header", async () => {
|
|
15
|
-
const ctx = structures.koa.newContext()
|
|
16
|
-
const expected = db.generateAppID()
|
|
17
|
-
ctx.request.headers = {
|
|
18
|
-
[Header.APP_ID]: expected,
|
|
19
|
-
}
|
|
20
|
-
|
|
21
|
-
const actual = await utils.getAppIdFromCtx(ctx)
|
|
22
|
-
expect(actual).toBe(expected)
|
|
23
|
-
})
|
|
24
|
-
|
|
25
|
-
it("gets appId from body", async () => {
|
|
26
|
-
const ctx = structures.koa.newContext()
|
|
27
|
-
const expected = db.generateAppID()
|
|
28
|
-
ctx.request.body = {
|
|
29
|
-
appId: expected,
|
|
30
|
-
}
|
|
31
|
-
|
|
32
|
-
const actual = await utils.getAppIdFromCtx(ctx)
|
|
33
|
-
expect(actual).toBe(expected)
|
|
34
|
-
})
|
|
35
|
-
|
|
36
|
-
it("gets appId from path", async () => {
|
|
37
|
-
const ctx = structures.koa.newContext()
|
|
38
|
-
const expected = db.generateAppID()
|
|
39
|
-
ctx.path = `/apps/${expected}`
|
|
40
|
-
|
|
41
|
-
const actual = await utils.getAppIdFromCtx(ctx)
|
|
42
|
-
expect(actual).toBe(expected)
|
|
43
|
-
})
|
|
44
|
-
|
|
45
|
-
it("gets appId from url", async () => {
|
|
46
|
-
await config.doInTenant(async () => {
|
|
47
|
-
const url = "http://example.com"
|
|
48
|
-
env._set("PLATFORM_URL", url)
|
|
49
|
-
|
|
50
|
-
const ctx = structures.koa.newContext()
|
|
51
|
-
ctx.host = `${config.tenantId}.example.com`
|
|
52
|
-
|
|
53
|
-
const expected = db.generateAppID(config.tenantId)
|
|
54
|
-
const app = structures.apps.app(expected)
|
|
55
|
-
|
|
56
|
-
// set custom url
|
|
57
|
-
const appUrl = newid()
|
|
58
|
-
app.url = `/${appUrl}`
|
|
59
|
-
ctx.path = `/app/${appUrl}`
|
|
60
|
-
|
|
61
|
-
// save the app
|
|
62
|
-
const database = db.getDB(expected)
|
|
63
|
-
await database.put(app)
|
|
64
|
-
|
|
65
|
-
const actual = await utils.getAppIdFromCtx(ctx)
|
|
66
|
-
expect(actual).toBe(expected)
|
|
67
|
-
})
|
|
68
|
-
})
|
|
69
|
-
|
|
70
|
-
it("doesn't get appId from url when previewing", async () => {
|
|
71
|
-
const ctx = structures.koa.newContext()
|
|
72
|
-
const appId = db.generateAppID()
|
|
73
|
-
const app = structures.apps.app(appId)
|
|
74
|
-
|
|
75
|
-
// set custom url
|
|
76
|
-
const appUrl = "preview"
|
|
77
|
-
app.url = `/${appUrl}`
|
|
78
|
-
ctx.path = `/app/${appUrl}`
|
|
79
|
-
|
|
80
|
-
// save the app
|
|
81
|
-
const database = db.getDB(appId)
|
|
82
|
-
await database.put(app)
|
|
83
|
-
|
|
84
|
-
const actual = await utils.getAppIdFromCtx(ctx)
|
|
85
|
-
expect(actual).toBe(undefined)
|
|
86
|
-
})
|
|
87
|
-
|
|
88
|
-
it("gets appId from referer", async () => {
|
|
89
|
-
const ctx = structures.koa.newContext()
|
|
90
|
-
const expected = db.generateAppID()
|
|
91
|
-
ctx.request.headers = {
|
|
92
|
-
referer: `http://example.com/builder/app/${expected}/design/screen_123/screens`,
|
|
93
|
-
}
|
|
94
|
-
|
|
95
|
-
const actual = await utils.getAppIdFromCtx(ctx)
|
|
96
|
-
expect(actual).toBe(expected)
|
|
97
|
-
})
|
|
98
|
-
|
|
99
|
-
it("doesn't get appId from referer when not builder", async () => {
|
|
100
|
-
const ctx = structures.koa.newContext()
|
|
101
|
-
const appId = db.generateAppID()
|
|
102
|
-
ctx.request.headers = {
|
|
103
|
-
referer: `http://example.com/foo/app/${appId}/bar`,
|
|
104
|
-
}
|
|
105
|
-
|
|
106
|
-
const actual = await utils.getAppIdFromCtx(ctx)
|
|
107
|
-
expect(actual).toBe(undefined)
|
|
108
|
-
})
|
|
109
|
-
})
|
|
110
|
-
|
|
111
|
-
describe("isServingBuilder", () => {
|
|
112
|
-
let ctx: BBContext
|
|
113
|
-
|
|
114
|
-
const expectResult = (result: boolean) =>
|
|
115
|
-
expect(utils.isServingBuilder(ctx)).toBe(result)
|
|
116
|
-
|
|
117
|
-
beforeEach(() => {
|
|
118
|
-
ctx = structures.koa.newContext()
|
|
119
|
-
})
|
|
120
|
-
|
|
121
|
-
it("returns true if current path is in builder", async () => {
|
|
122
|
-
ctx.path = "/builder/app/app_"
|
|
123
|
-
expectResult(true)
|
|
124
|
-
})
|
|
125
|
-
|
|
126
|
-
it("returns false if current path doesn't have '/' suffix", async () => {
|
|
127
|
-
ctx.path = "/builder/app"
|
|
128
|
-
expectResult(false)
|
|
129
|
-
|
|
130
|
-
ctx.path = "/xx"
|
|
131
|
-
expectResult(false)
|
|
132
|
-
})
|
|
133
|
-
})
|
|
134
|
-
|
|
135
|
-
describe("isServingBuilderPreview", () => {
|
|
136
|
-
let ctx: BBContext
|
|
137
|
-
|
|
138
|
-
const expectResult = (result: boolean) =>
|
|
139
|
-
expect(utils.isServingBuilderPreview(ctx)).toBe(result)
|
|
140
|
-
|
|
141
|
-
beforeEach(() => {
|
|
142
|
-
ctx = structures.koa.newContext()
|
|
143
|
-
})
|
|
144
|
-
|
|
145
|
-
it("returns true if current path is in builder preview", async () => {
|
|
146
|
-
ctx.path = "/app/preview/xx"
|
|
147
|
-
expectResult(true)
|
|
148
|
-
})
|
|
149
|
-
|
|
150
|
-
it("returns false if current path is not in builder preview", async () => {
|
|
151
|
-
ctx.path = "/builder"
|
|
152
|
-
expectResult(false)
|
|
153
|
-
|
|
154
|
-
ctx.path = "/xx"
|
|
155
|
-
expectResult(false)
|
|
156
|
-
})
|
|
157
|
-
})
|
|
158
|
-
|
|
159
|
-
describe("isPublicAPIRequest", () => {
|
|
160
|
-
let ctx: BBContext
|
|
161
|
-
|
|
162
|
-
const expectResult = (result: boolean) =>
|
|
163
|
-
expect(utils.isPublicApiRequest(ctx)).toBe(result)
|
|
164
|
-
|
|
165
|
-
beforeEach(() => {
|
|
166
|
-
ctx = structures.koa.newContext()
|
|
167
|
-
})
|
|
168
|
-
|
|
169
|
-
it("returns true if current path remains to public API", async () => {
|
|
170
|
-
ctx.path = "/api/public/v1/invoices"
|
|
171
|
-
expectResult(true)
|
|
172
|
-
|
|
173
|
-
ctx.path = "/api/public/v1"
|
|
174
|
-
expectResult(true)
|
|
175
|
-
|
|
176
|
-
ctx.path = "/api/public/v2"
|
|
177
|
-
expectResult(true)
|
|
178
|
-
|
|
179
|
-
ctx.path = "/api/public/v21"
|
|
180
|
-
expectResult(true)
|
|
181
|
-
})
|
|
182
|
-
|
|
183
|
-
it("returns false if current path doesn't remain to public API", async () => {
|
|
184
|
-
ctx.path = "/api/public"
|
|
185
|
-
expectResult(false)
|
|
186
|
-
|
|
187
|
-
ctx.path = "/xx"
|
|
188
|
-
expectResult(false)
|
|
189
|
-
})
|
|
190
|
-
})
|
|
191
|
-
|
|
192
|
-
describe("hasCircularStructure", () => {
|
|
193
|
-
it("should detect a circular structure", () => {
|
|
194
|
-
const a: any = { b: "b" }
|
|
195
|
-
const b = { a }
|
|
196
|
-
a.b = b
|
|
197
|
-
expect(utils.hasCircularStructure(b)).toBe(true)
|
|
198
|
-
})
|
|
199
|
-
|
|
200
|
-
it("should allow none circular structures", () => {
|
|
201
|
-
expect(utils.hasCircularStructure({ a: "b" })).toBe(false)
|
|
202
|
-
})
|
|
203
|
-
})
|
|
204
|
-
})
|
package/src/utils/utils.ts
DELETED
|
@@ -1,249 +0,0 @@
|
|
|
1
|
-
import { getAllApps } from "../db"
|
|
2
|
-
import { Header, MAX_VALID_DATE, DocumentType, SEPARATOR } from "../constants"
|
|
3
|
-
import env from "../environment"
|
|
4
|
-
import * as tenancy from "../tenancy"
|
|
5
|
-
import * as context from "../context"
|
|
6
|
-
import {
|
|
7
|
-
App,
|
|
8
|
-
AuditedEventFriendlyName,
|
|
9
|
-
Ctx,
|
|
10
|
-
Event,
|
|
11
|
-
TenantResolutionStrategy,
|
|
12
|
-
} from "@budibase/types"
|
|
13
|
-
import type { SetOption } from "cookies"
|
|
14
|
-
import jwt, { Secret } from "jsonwebtoken"
|
|
15
|
-
|
|
16
|
-
const APP_PREFIX = DocumentType.APP + SEPARATOR
|
|
17
|
-
const PROD_APP_PREFIX = "/app/"
|
|
18
|
-
|
|
19
|
-
const BUILDER_PREVIEW_PATH = "/app/preview"
|
|
20
|
-
const BUILDER_PREFIX = "/builder"
|
|
21
|
-
const BUILDER_APP_PREFIX = `${BUILDER_PREFIX}/app/`
|
|
22
|
-
const PUBLIC_API_PREFIX = "/api/public/v"
|
|
23
|
-
|
|
24
|
-
function confirmAppId(possibleAppId: string | undefined) {
|
|
25
|
-
return possibleAppId && possibleAppId.startsWith(APP_PREFIX)
|
|
26
|
-
? possibleAppId
|
|
27
|
-
: undefined
|
|
28
|
-
}
|
|
29
|
-
|
|
30
|
-
export async function resolveAppUrl(ctx: Ctx) {
|
|
31
|
-
const appUrl = ctx.path.split("/")[2]
|
|
32
|
-
let possibleAppUrl = `/${appUrl.toLowerCase()}`
|
|
33
|
-
|
|
34
|
-
let tenantId: string | undefined = context.getTenantId()
|
|
35
|
-
if (!env.isDev() && env.MULTI_TENANCY) {
|
|
36
|
-
// always use the tenant id from the subdomain in multi tenancy
|
|
37
|
-
// this ensures the logged-in user tenant id doesn't overwrite
|
|
38
|
-
// e.g. in the case of viewing a public app while already logged-in to another tenant
|
|
39
|
-
tenantId = tenancy.getTenantIDFromCtx(ctx, {
|
|
40
|
-
includeStrategies: [TenantResolutionStrategy.SUBDOMAIN],
|
|
41
|
-
})
|
|
42
|
-
}
|
|
43
|
-
|
|
44
|
-
// search prod apps for an url that matches
|
|
45
|
-
const apps: App[] = await context.doInTenant(
|
|
46
|
-
tenantId,
|
|
47
|
-
() => getAllApps({ dev: false }) as Promise<App[]>
|
|
48
|
-
)
|
|
49
|
-
const app = apps.filter(
|
|
50
|
-
a => a.url && a.url.toLowerCase() === possibleAppUrl
|
|
51
|
-
)[0]
|
|
52
|
-
|
|
53
|
-
return app && app.appId ? app.appId : undefined
|
|
54
|
-
}
|
|
55
|
-
|
|
56
|
-
export function isServingApp(ctx: Ctx) {
|
|
57
|
-
// dev app
|
|
58
|
-
if (ctx.path.startsWith(`/${APP_PREFIX}`)) {
|
|
59
|
-
return true
|
|
60
|
-
}
|
|
61
|
-
// prod app
|
|
62
|
-
return ctx.path.startsWith(PROD_APP_PREFIX)
|
|
63
|
-
}
|
|
64
|
-
|
|
65
|
-
export function isServingBuilder(ctx: Ctx): boolean {
|
|
66
|
-
return ctx.path.startsWith(BUILDER_APP_PREFIX)
|
|
67
|
-
}
|
|
68
|
-
|
|
69
|
-
export function isServingBuilderPreview(ctx: Ctx): boolean {
|
|
70
|
-
return ctx.path.startsWith(BUILDER_PREVIEW_PATH)
|
|
71
|
-
}
|
|
72
|
-
|
|
73
|
-
export function isPublicApiRequest(ctx: Ctx): boolean {
|
|
74
|
-
return ctx.path.startsWith(PUBLIC_API_PREFIX)
|
|
75
|
-
}
|
|
76
|
-
|
|
77
|
-
/**
|
|
78
|
-
* Given a request tries to find the appId, which can be located in various places
|
|
79
|
-
* @param ctx The main request body to look through.
|
|
80
|
-
* @returns If an appId was found it will be returned.
|
|
81
|
-
*/
|
|
82
|
-
export async function getAppIdFromCtx(ctx: Ctx) {
|
|
83
|
-
// look in headers
|
|
84
|
-
const options = [ctx.request.headers[Header.APP_ID]]
|
|
85
|
-
let appId
|
|
86
|
-
for (let option of options) {
|
|
87
|
-
appId = confirmAppId(option as string)
|
|
88
|
-
if (appId) {
|
|
89
|
-
break
|
|
90
|
-
}
|
|
91
|
-
}
|
|
92
|
-
|
|
93
|
-
// look in body
|
|
94
|
-
if (!appId && ctx.request.body && ctx.request.body.appId) {
|
|
95
|
-
appId = confirmAppId(ctx.request.body.appId)
|
|
96
|
-
}
|
|
97
|
-
|
|
98
|
-
// look in the path
|
|
99
|
-
const pathId = parseAppIdFromUrlPath(ctx.path)
|
|
100
|
-
if (!appId && pathId) {
|
|
101
|
-
appId = confirmAppId(pathId)
|
|
102
|
-
}
|
|
103
|
-
|
|
104
|
-
// lookup using custom url - prod apps only
|
|
105
|
-
// filter out the builder preview path which collides with the prod app path
|
|
106
|
-
// to ensure we don't load all apps excessively
|
|
107
|
-
const isBuilderPreview = ctx.path.startsWith(BUILDER_PREVIEW_PATH)
|
|
108
|
-
const isViewingProdApp =
|
|
109
|
-
ctx.path.startsWith(PROD_APP_PREFIX) && !isBuilderPreview
|
|
110
|
-
if (!appId && isViewingProdApp) {
|
|
111
|
-
appId = confirmAppId(await resolveAppUrl(ctx))
|
|
112
|
-
}
|
|
113
|
-
|
|
114
|
-
// look in the referer - builder only
|
|
115
|
-
// make sure this is performed after prod app url resolution, in case the
|
|
116
|
-
// referer header is present from a builder redirect
|
|
117
|
-
const referer = ctx.request.headers.referer
|
|
118
|
-
if (!appId && referer?.includes(BUILDER_APP_PREFIX)) {
|
|
119
|
-
const refererId = parseAppIdFromUrlPath(ctx.request.headers.referer)
|
|
120
|
-
appId = confirmAppId(refererId)
|
|
121
|
-
}
|
|
122
|
-
|
|
123
|
-
return appId
|
|
124
|
-
}
|
|
125
|
-
|
|
126
|
-
function parseAppIdFromUrlPath(url?: string) {
|
|
127
|
-
if (!url) {
|
|
128
|
-
return
|
|
129
|
-
}
|
|
130
|
-
return url
|
|
131
|
-
.split("?")[0] // Remove any possible query string
|
|
132
|
-
.split("/")
|
|
133
|
-
.find(subPath => subPath.startsWith(APP_PREFIX))
|
|
134
|
-
}
|
|
135
|
-
|
|
136
|
-
/**
|
|
137
|
-
* opens the contents of the specified encrypted JWT.
|
|
138
|
-
* @return the contents of the token.
|
|
139
|
-
*/
|
|
140
|
-
export function openJwt<T>(token?: string): T | undefined {
|
|
141
|
-
if (!token) {
|
|
142
|
-
return undefined
|
|
143
|
-
}
|
|
144
|
-
try {
|
|
145
|
-
return jwt.verify(token, env.JWT_SECRET as Secret) as T
|
|
146
|
-
} catch (e) {
|
|
147
|
-
if (env.JWT_SECRET_FALLBACK) {
|
|
148
|
-
// fallback to enable rotation
|
|
149
|
-
return jwt.verify(token, env.JWT_SECRET_FALLBACK) as T
|
|
150
|
-
} else {
|
|
151
|
-
throw e
|
|
152
|
-
}
|
|
153
|
-
}
|
|
154
|
-
}
|
|
155
|
-
|
|
156
|
-
export function isValidInternalAPIKey(apiKey: string) {
|
|
157
|
-
if (env.INTERNAL_API_KEY && env.INTERNAL_API_KEY === apiKey) {
|
|
158
|
-
return true
|
|
159
|
-
}
|
|
160
|
-
// fallback to enable rotation
|
|
161
|
-
return !!(
|
|
162
|
-
env.INTERNAL_API_KEY_FALLBACK && env.INTERNAL_API_KEY_FALLBACK === apiKey
|
|
163
|
-
)
|
|
164
|
-
}
|
|
165
|
-
|
|
166
|
-
/**
|
|
167
|
-
* Get a cookie from context, and decrypt if necessary.
|
|
168
|
-
* @param ctx The request which is to be manipulated.
|
|
169
|
-
* @param name The name of the cookie to get.
|
|
170
|
-
*/
|
|
171
|
-
export function getCookie<T>(ctx: Ctx, name: string) {
|
|
172
|
-
const cookie = ctx.cookies.get(name)
|
|
173
|
-
|
|
174
|
-
if (!cookie) {
|
|
175
|
-
return undefined
|
|
176
|
-
}
|
|
177
|
-
|
|
178
|
-
return openJwt<T>(cookie)
|
|
179
|
-
}
|
|
180
|
-
|
|
181
|
-
/**
|
|
182
|
-
* Store a cookie for the request - it will not expire.
|
|
183
|
-
* @param ctx The request which is to be manipulated.
|
|
184
|
-
* @param name The name of the cookie to set.
|
|
185
|
-
* @param value The value of cookie which will be set.
|
|
186
|
-
* @param opts options like whether to sign.
|
|
187
|
-
*/
|
|
188
|
-
export function setCookie(
|
|
189
|
-
ctx: Ctx,
|
|
190
|
-
value: any,
|
|
191
|
-
name = "builder",
|
|
192
|
-
opts = { sign: true }
|
|
193
|
-
) {
|
|
194
|
-
if (value && opts && opts.sign) {
|
|
195
|
-
value = jwt.sign(value, env.JWT_SECRET as Secret)
|
|
196
|
-
}
|
|
197
|
-
|
|
198
|
-
const config: SetOption = {
|
|
199
|
-
expires: MAX_VALID_DATE,
|
|
200
|
-
path: "/",
|
|
201
|
-
httpOnly: false,
|
|
202
|
-
overwrite: true,
|
|
203
|
-
}
|
|
204
|
-
|
|
205
|
-
if (env.COOKIE_DOMAIN) {
|
|
206
|
-
config.domain = env.COOKIE_DOMAIN
|
|
207
|
-
}
|
|
208
|
-
|
|
209
|
-
ctx.cookies.set(name, value, config)
|
|
210
|
-
}
|
|
211
|
-
|
|
212
|
-
/**
|
|
213
|
-
* Utility function, simply calls setCookie with an empty string for value
|
|
214
|
-
*/
|
|
215
|
-
export function clearCookie(ctx: Ctx, name: string) {
|
|
216
|
-
setCookie(ctx, null, name)
|
|
217
|
-
}
|
|
218
|
-
|
|
219
|
-
/**
|
|
220
|
-
* Checks if the API call being made (based on the provided ctx object) is from the client. If
|
|
221
|
-
* the call is not from a client app then it is from the builder.
|
|
222
|
-
* @param ctx The koa context object to be tested.
|
|
223
|
-
* @return returns true if the call is from the client lib (a built app rather than the builder).
|
|
224
|
-
*/
|
|
225
|
-
export function isClient(ctx: Ctx) {
|
|
226
|
-
return ctx.headers[Header.TYPE] === "client"
|
|
227
|
-
}
|
|
228
|
-
|
|
229
|
-
export function timeout(timeMs: number) {
|
|
230
|
-
return new Promise(resolve => setTimeout(resolve, timeMs))
|
|
231
|
-
}
|
|
232
|
-
|
|
233
|
-
export function isAudited(event: Event) {
|
|
234
|
-
return !!AuditedEventFriendlyName[event]
|
|
235
|
-
}
|
|
236
|
-
|
|
237
|
-
export function hasCircularStructure(json: any) {
|
|
238
|
-
if (typeof json !== "object") {
|
|
239
|
-
return false
|
|
240
|
-
}
|
|
241
|
-
try {
|
|
242
|
-
JSON.stringify(json)
|
|
243
|
-
} catch (err) {
|
|
244
|
-
if (err instanceof Error && err?.message.includes("circular structure")) {
|
|
245
|
-
return true
|
|
246
|
-
}
|
|
247
|
-
}
|
|
248
|
-
return false
|
|
249
|
-
}
|
package/tests/core/logging.ts
DELETED
|
@@ -1,34 +0,0 @@
|
|
|
1
|
-
export enum LogLevel {
|
|
2
|
-
TRACE = "trace",
|
|
3
|
-
DEBUG = "debug",
|
|
4
|
-
INFO = "info",
|
|
5
|
-
WARN = "warn",
|
|
6
|
-
ERROR = "error",
|
|
7
|
-
}
|
|
8
|
-
|
|
9
|
-
const LOG_INDEX: { [key in LogLevel]: number } = {
|
|
10
|
-
[LogLevel.TRACE]: 1,
|
|
11
|
-
[LogLevel.DEBUG]: 2,
|
|
12
|
-
[LogLevel.INFO]: 3,
|
|
13
|
-
[LogLevel.WARN]: 4,
|
|
14
|
-
[LogLevel.ERROR]: 5,
|
|
15
|
-
}
|
|
16
|
-
|
|
17
|
-
const setIndex = LOG_INDEX[process.env.LOG_LEVEL as LogLevel]
|
|
18
|
-
|
|
19
|
-
if (setIndex > LOG_INDEX.trace) {
|
|
20
|
-
global.console.trace = jest.fn()
|
|
21
|
-
}
|
|
22
|
-
|
|
23
|
-
if (setIndex > LOG_INDEX.debug) {
|
|
24
|
-
global.console.debug = jest.fn()
|
|
25
|
-
}
|
|
26
|
-
|
|
27
|
-
if (setIndex > LOG_INDEX.info) {
|
|
28
|
-
global.console.info = jest.fn()
|
|
29
|
-
global.console.log = jest.fn()
|
|
30
|
-
}
|
|
31
|
-
|
|
32
|
-
if (setIndex > LOG_INDEX.warn) {
|
|
33
|
-
global.console.warn = jest.fn()
|
|
34
|
-
}
|
|
@@ -1,53 +0,0 @@
|
|
|
1
|
-
const _ = require("lodash/fp")
|
|
2
|
-
const { structures } = require("../../../tests")
|
|
3
|
-
|
|
4
|
-
jest.mock("../../../src/context")
|
|
5
|
-
jest.mock("../../../src/db")
|
|
6
|
-
|
|
7
|
-
const context = require("../../../src/context")
|
|
8
|
-
const db = require("../../../src/db")
|
|
9
|
-
|
|
10
|
-
const { getCreatorCount } = require("../../../src/users/users")
|
|
11
|
-
|
|
12
|
-
describe("Users", () => {
|
|
13
|
-
let getGlobalDBMock
|
|
14
|
-
let getGlobalUserParamsMock
|
|
15
|
-
let paginationMock
|
|
16
|
-
|
|
17
|
-
beforeEach(() => {
|
|
18
|
-
jest.resetAllMocks()
|
|
19
|
-
|
|
20
|
-
getGlobalDBMock = jest.spyOn(context, "getGlobalDB")
|
|
21
|
-
getGlobalUserParamsMock = jest.spyOn(db, "getGlobalUserParams")
|
|
22
|
-
paginationMock = jest.spyOn(db, "pagination")
|
|
23
|
-
})
|
|
24
|
-
|
|
25
|
-
it("Retrieves the number of creators", async () => {
|
|
26
|
-
const getUsers = (offset, limit, creators = false) => {
|
|
27
|
-
const range = _.range(offset, limit)
|
|
28
|
-
const opts = creators ? { builder: { global: true } } : undefined
|
|
29
|
-
return range.map(() => structures.users.user(opts))
|
|
30
|
-
}
|
|
31
|
-
const page1Data = getUsers(0, 8)
|
|
32
|
-
const page2Data = getUsers(8, 12, true)
|
|
33
|
-
getGlobalDBMock.mockImplementation(() => ({
|
|
34
|
-
name: "fake-db",
|
|
35
|
-
allDocs: () => ({
|
|
36
|
-
rows: [...page1Data, ...page2Data],
|
|
37
|
-
}),
|
|
38
|
-
}))
|
|
39
|
-
paginationMock.mockImplementationOnce(() => ({
|
|
40
|
-
data: page1Data,
|
|
41
|
-
hasNextPage: true,
|
|
42
|
-
nextPage: "1",
|
|
43
|
-
}))
|
|
44
|
-
paginationMock.mockImplementation(() => ({
|
|
45
|
-
data: page2Data,
|
|
46
|
-
hasNextPage: false,
|
|
47
|
-
nextPage: undefined,
|
|
48
|
-
}))
|
|
49
|
-
const creatorsCount = await getCreatorCount()
|
|
50
|
-
expect(creatorsCount).toBe(4)
|
|
51
|
-
expect(paginationMock).toHaveBeenCalledTimes(2)
|
|
52
|
-
})
|
|
53
|
-
})
|
|
@@ -1,7 +0,0 @@
|
|
|
1
|
-
export * as mocks from "./mocks"
|
|
2
|
-
export * as structures from "./structures"
|
|
3
|
-
export { generator } from "./structures"
|
|
4
|
-
export * as testContainerUtils from "./testContainerUtils"
|
|
5
|
-
export * as utils from "./utils"
|
|
6
|
-
export * from "./jestUtils"
|
|
7
|
-
export * as queue from "./queue"
|
|
@@ -1,33 +0,0 @@
|
|
|
1
|
-
import {
|
|
2
|
-
PROTECTED_EXTERNAL_COLUMNS,
|
|
3
|
-
PROTECTED_INTERNAL_COLUMNS,
|
|
4
|
-
} from "@budibase/shared-core"
|
|
5
|
-
|
|
6
|
-
export function expectFunctionWasCalledTimesWith(
|
|
7
|
-
jestFunction: any,
|
|
8
|
-
times: number,
|
|
9
|
-
argument: any
|
|
10
|
-
) {
|
|
11
|
-
expect(
|
|
12
|
-
jestFunction.mock.calls.filter((call: any) => call[0] === argument).length
|
|
13
|
-
).toBe(times)
|
|
14
|
-
}
|
|
15
|
-
|
|
16
|
-
export const expectAnyInternalColsAttributes: {
|
|
17
|
-
[K in (typeof PROTECTED_INTERNAL_COLUMNS)[number]]: any
|
|
18
|
-
} = {
|
|
19
|
-
tableId: expect.anything(),
|
|
20
|
-
type: expect.anything(),
|
|
21
|
-
_id: expect.anything(),
|
|
22
|
-
_rev: expect.anything(),
|
|
23
|
-
createdAt: expect.anything(),
|
|
24
|
-
updatedAt: expect.anything(),
|
|
25
|
-
}
|
|
26
|
-
|
|
27
|
-
export const expectAnyExternalColsAttributes: {
|
|
28
|
-
[K in (typeof PROTECTED_EXTERNAL_COLUMNS)[number]]: any
|
|
29
|
-
} = {
|
|
30
|
-
tableId: expect.anything(),
|
|
31
|
-
_id: expect.anything(),
|
|
32
|
-
_rev: expect.anything(),
|
|
33
|
-
}
|