@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.
Files changed (272) hide show
  1. package/dist/index.js.map +1 -1
  2. package/dist/index.js.meta.json +1 -1
  3. package/dist/package.json +11 -4
  4. package/dist/plugins.js.meta.json +1 -1
  5. package/package.json +11 -4
  6. package/src/accounts/accounts.ts +0 -82
  7. package/src/accounts/api.ts +0 -59
  8. package/src/accounts/index.ts +0 -1
  9. package/src/auth/auth.ts +0 -210
  10. package/src/auth/index.ts +0 -1
  11. package/src/auth/tests/auth.spec.ts +0 -14
  12. package/src/blacklist/blacklist.ts +0 -54
  13. package/src/blacklist/index.ts +0 -1
  14. package/src/blacklist/tests/blacklist.spec.ts +0 -46
  15. package/src/cache/appMetadata.ts +0 -88
  16. package/src/cache/base/index.ts +0 -150
  17. package/src/cache/docWritethrough.ts +0 -105
  18. package/src/cache/generic.ts +0 -33
  19. package/src/cache/index.ts +0 -8
  20. package/src/cache/invite.ts +0 -86
  21. package/src/cache/passwordReset.ts +0 -49
  22. package/src/cache/tests/docWritethrough.spec.ts +0 -296
  23. package/src/cache/tests/user.spec.ts +0 -145
  24. package/src/cache/tests/writethrough.spec.ts +0 -139
  25. package/src/cache/user.ts +0 -154
  26. package/src/cache/writethrough.ts +0 -133
  27. package/src/configs/configs.ts +0 -263
  28. package/src/configs/index.ts +0 -1
  29. package/src/configs/tests/configs.spec.ts +0 -184
  30. package/src/constants/db.ts +0 -75
  31. package/src/constants/index.ts +0 -2
  32. package/src/constants/misc.ts +0 -36
  33. package/src/context/Context.ts +0 -14
  34. package/src/context/identity.ts +0 -58
  35. package/src/context/index.ts +0 -3
  36. package/src/context/mainContext.ts +0 -422
  37. package/src/context/tests/index.spec.ts +0 -255
  38. package/src/context/types.ts +0 -26
  39. package/src/db/Replication.ts +0 -94
  40. package/src/db/couch/DatabaseImpl.ts +0 -511
  41. package/src/db/couch/connections.ts +0 -89
  42. package/src/db/couch/index.ts +0 -4
  43. package/src/db/couch/pouchDB.ts +0 -97
  44. package/src/db/couch/pouchDump.ts +0 -0
  45. package/src/db/couch/tests/DatabaseImpl.spec.ts +0 -118
  46. package/src/db/couch/utils.ts +0 -55
  47. package/src/db/db.ts +0 -34
  48. package/src/db/errors.ts +0 -14
  49. package/src/db/index.ts +0 -12
  50. package/src/db/instrumentation.ts +0 -199
  51. package/src/db/lucene.ts +0 -721
  52. package/src/db/searchIndexes/index.ts +0 -1
  53. package/src/db/searchIndexes/searchIndexes.ts +0 -62
  54. package/src/db/tests/DatabaseImpl.spec.ts +0 -55
  55. package/src/db/tests/connections.spec.ts +0 -22
  56. package/src/db/tests/index.spec.ts +0 -32
  57. package/src/db/tests/lucene.spec.ts +0 -400
  58. package/src/db/tests/pouch.spec.js +0 -62
  59. package/src/db/tests/utils.spec.ts +0 -63
  60. package/src/db/utils.ts +0 -208
  61. package/src/db/views.ts +0 -245
  62. package/src/docIds/conversions.ts +0 -60
  63. package/src/docIds/ids.ts +0 -126
  64. package/src/docIds/index.ts +0 -2
  65. package/src/docIds/newid.ts +0 -5
  66. package/src/docIds/params.ts +0 -189
  67. package/src/docUpdates/index.ts +0 -24
  68. package/src/environment.ts +0 -293
  69. package/src/errors/errors.ts +0 -119
  70. package/src/errors/index.ts +0 -1
  71. package/src/events/analytics.ts +0 -6
  72. package/src/events/asyncEvents/index.ts +0 -2
  73. package/src/events/asyncEvents/publisher.ts +0 -12
  74. package/src/events/asyncEvents/queue.ts +0 -22
  75. package/src/events/backfill.ts +0 -183
  76. package/src/events/documentId.ts +0 -56
  77. package/src/events/events.ts +0 -47
  78. package/src/events/identification.ts +0 -311
  79. package/src/events/index.ts +0 -15
  80. package/src/events/processors/AnalyticsProcessor.ts +0 -64
  81. package/src/events/processors/AuditLogsProcessor.ts +0 -92
  82. package/src/events/processors/LoggingProcessor.ts +0 -36
  83. package/src/events/processors/Processors.ts +0 -52
  84. package/src/events/processors/async/DocumentUpdateProcessor.ts +0 -38
  85. package/src/events/processors/index.ts +0 -19
  86. package/src/events/processors/posthog/PosthogProcessor.ts +0 -118
  87. package/src/events/processors/posthog/index.ts +0 -3
  88. package/src/events/processors/posthog/rateLimiting.ts +0 -106
  89. package/src/events/processors/posthog/tests/PosthogProcessor.spec.ts +0 -164
  90. package/src/events/processors/types.ts +0 -1
  91. package/src/events/publishers/account.ts +0 -41
  92. package/src/events/publishers/ai.ts +0 -21
  93. package/src/events/publishers/app.ts +0 -168
  94. package/src/events/publishers/auditLog.ts +0 -26
  95. package/src/events/publishers/auth.ts +0 -73
  96. package/src/events/publishers/automation.ts +0 -110
  97. package/src/events/publishers/backfill.ts +0 -74
  98. package/src/events/publishers/backup.ts +0 -42
  99. package/src/events/publishers/datasource.ts +0 -48
  100. package/src/events/publishers/email.ts +0 -17
  101. package/src/events/publishers/environmentVariable.ts +0 -38
  102. package/src/events/publishers/group.ts +0 -99
  103. package/src/events/publishers/index.ts +0 -25
  104. package/src/events/publishers/installation.ts +0 -38
  105. package/src/events/publishers/layout.ts +0 -26
  106. package/src/events/publishers/license.ts +0 -84
  107. package/src/events/publishers/org.ts +0 -37
  108. package/src/events/publishers/plugin.ts +0 -47
  109. package/src/events/publishers/query.ts +0 -89
  110. package/src/events/publishers/role.ts +0 -62
  111. package/src/events/publishers/rows.ts +0 -29
  112. package/src/events/publishers/screen.ts +0 -36
  113. package/src/events/publishers/serve.ts +0 -43
  114. package/src/events/publishers/table.ts +0 -70
  115. package/src/events/publishers/user.ts +0 -202
  116. package/src/events/publishers/view.ts +0 -107
  117. package/src/features/features.ts +0 -277
  118. package/src/features/index.ts +0 -2
  119. package/src/features/tests/features.spec.ts +0 -267
  120. package/src/features/tests/utils.ts +0 -64
  121. package/src/helpers.ts +0 -9
  122. package/src/index.ts +0 -59
  123. package/src/installation.ts +0 -115
  124. package/src/logging/alerts.ts +0 -26
  125. package/src/logging/correlation/correlation.ts +0 -15
  126. package/src/logging/correlation/index.ts +0 -1
  127. package/src/logging/correlation/middleware.ts +0 -18
  128. package/src/logging/index.ts +0 -4
  129. package/src/logging/pino/logger.ts +0 -239
  130. package/src/logging/pino/middleware.ts +0 -48
  131. package/src/logging/system.ts +0 -81
  132. package/src/logging/tests/system.spec.ts +0 -61
  133. package/src/middleware/adminOnly.ts +0 -9
  134. package/src/middleware/auditLog.ts +0 -6
  135. package/src/middleware/authenticated.ts +0 -247
  136. package/src/middleware/builderOnly.ts +0 -21
  137. package/src/middleware/builderOrAdmin.ts +0 -21
  138. package/src/middleware/contentSecurityPolicy.ts +0 -113
  139. package/src/middleware/csrf.ts +0 -81
  140. package/src/middleware/errorHandling.ts +0 -43
  141. package/src/middleware/index.ts +0 -24
  142. package/src/middleware/internalApi.ts +0 -23
  143. package/src/middleware/ip.ts +0 -12
  144. package/src/middleware/joi-validator.ts +0 -58
  145. package/src/middleware/matchers.ts +0 -39
  146. package/src/middleware/passport/datasource/google.ts +0 -102
  147. package/src/middleware/passport/local.ts +0 -54
  148. package/src/middleware/passport/sso/google.ts +0 -77
  149. package/src/middleware/passport/sso/oidc.ts +0 -152
  150. package/src/middleware/passport/sso/sso.ts +0 -138
  151. package/src/middleware/passport/sso/tests/google.spec.ts +0 -68
  152. package/src/middleware/passport/sso/tests/oidc.spec.ts +0 -144
  153. package/src/middleware/passport/sso/tests/sso.spec.ts +0 -197
  154. package/src/middleware/passport/utils.ts +0 -38
  155. package/src/middleware/querystringToBody.ts +0 -28
  156. package/src/middleware/tenancy.ts +0 -36
  157. package/src/middleware/tests/builder.spec.ts +0 -181
  158. package/src/middleware/tests/contentSecurityPolicy.spec.ts +0 -75
  159. package/src/middleware/tests/matchers.spec.ts +0 -100
  160. package/src/migrations/definitions.ts +0 -40
  161. package/src/migrations/index.ts +0 -2
  162. package/src/migrations/migrations.ts +0 -186
  163. package/src/migrations/tests/__snapshots__/migrations.spec.ts.snap +0 -11
  164. package/src/migrations/tests/migrations.spec.ts +0 -64
  165. package/src/objectStore/buckets/app.ts +0 -53
  166. package/src/objectStore/buckets/global.ts +0 -29
  167. package/src/objectStore/buckets/index.ts +0 -3
  168. package/src/objectStore/buckets/plugins.ts +0 -71
  169. package/src/objectStore/buckets/tests/app.spec.ts +0 -161
  170. package/src/objectStore/buckets/tests/global.spec.ts +0 -74
  171. package/src/objectStore/buckets/tests/plugins.spec.ts +0 -111
  172. package/src/objectStore/cloudfront.ts +0 -41
  173. package/src/objectStore/index.ts +0 -3
  174. package/src/objectStore/objectStore.ts +0 -585
  175. package/src/objectStore/utils.ts +0 -113
  176. package/src/platform/index.ts +0 -3
  177. package/src/platform/platformDb.ts +0 -6
  178. package/src/platform/tenants.ts +0 -101
  179. package/src/platform/tests/tenants.spec.ts +0 -26
  180. package/src/platform/users.ts +0 -129
  181. package/src/plugin/index.ts +0 -1
  182. package/src/plugin/tests/validation.spec.ts +0 -209
  183. package/src/plugin/utils.ts +0 -175
  184. package/src/queue/constants.ts +0 -8
  185. package/src/queue/inMemoryQueue.ts +0 -189
  186. package/src/queue/index.ts +0 -2
  187. package/src/queue/listeners.ts +0 -199
  188. package/src/queue/queue.ts +0 -84
  189. package/src/redis/index.ts +0 -6
  190. package/src/redis/init.ts +0 -118
  191. package/src/redis/redis.ts +0 -358
  192. package/src/redis/redlockImpl.ts +0 -155
  193. package/src/redis/tests/redis.spec.ts +0 -207
  194. package/src/redis/tests/redlockImpl.spec.ts +0 -105
  195. package/src/redis/utils.ts +0 -128
  196. package/src/security/auth.ts +0 -24
  197. package/src/security/encryption.ts +0 -185
  198. package/src/security/index.ts +0 -1
  199. package/src/security/permissions.ts +0 -166
  200. package/src/security/roles.ts +0 -655
  201. package/src/security/secrets.ts +0 -20
  202. package/src/security/sessions.ts +0 -123
  203. package/src/security/tests/auth.spec.ts +0 -45
  204. package/src/security/tests/encryption.spec.ts +0 -31
  205. package/src/security/tests/permissions.spec.ts +0 -146
  206. package/src/security/tests/secrets.spec.ts +0 -35
  207. package/src/security/tests/sessions.spec.ts +0 -12
  208. package/src/sql/designDoc.ts +0 -17
  209. package/src/sql/index.ts +0 -5
  210. package/src/sql/sql.ts +0 -1854
  211. package/src/sql/sqlTable.ts +0 -319
  212. package/src/sql/utils.ts +0 -193
  213. package/src/tenancy/db.ts +0 -6
  214. package/src/tenancy/index.ts +0 -2
  215. package/src/tenancy/tenancy.ts +0 -148
  216. package/src/tenancy/tests/tenancy.spec.ts +0 -184
  217. package/src/timers/index.ts +0 -1
  218. package/src/timers/timers.ts +0 -22
  219. package/src/users/db.ts +0 -582
  220. package/src/users/events.ts +0 -176
  221. package/src/users/index.ts +0 -4
  222. package/src/users/lookup.ts +0 -99
  223. package/src/users/test/db.spec.ts +0 -188
  224. package/src/users/test/utils.spec.ts +0 -67
  225. package/src/users/users.ts +0 -353
  226. package/src/users/utils.ts +0 -81
  227. package/src/utils/Duration.ts +0 -56
  228. package/src/utils/hashing.ts +0 -15
  229. package/src/utils/index.ts +0 -4
  230. package/src/utils/stringUtils.ts +0 -8
  231. package/src/utils/tests/Duration.spec.ts +0 -19
  232. package/src/utils/tests/utils.spec.ts +0 -204
  233. package/src/utils/utils.ts +0 -249
  234. package/tests/core/logging.ts +0 -34
  235. package/tests/core/users/users.spec.js +0 -53
  236. package/tests/core/utilities/index.ts +0 -7
  237. package/tests/core/utilities/jestUtils.ts +0 -33
  238. package/tests/core/utilities/mocks/alerts.ts +0 -4
  239. package/tests/core/utilities/mocks/date.ts +0 -3
  240. package/tests/core/utilities/mocks/events.ts +0 -132
  241. package/tests/core/utilities/mocks/index.ts +0 -9
  242. package/tests/core/utilities/mocks/licenses.ts +0 -119
  243. package/tests/core/utilities/queue.ts +0 -9
  244. package/tests/core/utilities/structures/Chance.ts +0 -20
  245. package/tests/core/utilities/structures/accounts.ts +0 -80
  246. package/tests/core/utilities/structures/apps.ts +0 -21
  247. package/tests/core/utilities/structures/common.ts +0 -7
  248. package/tests/core/utilities/structures/db.ts +0 -12
  249. package/tests/core/utilities/structures/documents/index.ts +0 -1
  250. package/tests/core/utilities/structures/documents/platform/index.ts +0 -1
  251. package/tests/core/utilities/structures/documents/platform/installation.ts +0 -12
  252. package/tests/core/utilities/structures/generator.ts +0 -3
  253. package/tests/core/utilities/structures/index.ts +0 -15
  254. package/tests/core/utilities/structures/koa.ts +0 -16
  255. package/tests/core/utilities/structures/licenses.ts +0 -190
  256. package/tests/core/utilities/structures/plugins.ts +0 -19
  257. package/tests/core/utilities/structures/quotas.ts +0 -72
  258. package/tests/core/utilities/structures/scim.ts +0 -80
  259. package/tests/core/utilities/structures/sso.ts +0 -118
  260. package/tests/core/utilities/structures/tenants.ts +0 -5
  261. package/tests/core/utilities/structures/userGroups.ts +0 -10
  262. package/tests/core/utilities/structures/users.ts +0 -89
  263. package/tests/core/utilities/testContainerUtils.ts +0 -165
  264. package/tests/core/utilities/utils/index.ts +0 -2
  265. package/tests/core/utilities/utils/queue.ts +0 -27
  266. package/tests/core/utilities/utils/time.ts +0 -3
  267. package/tests/extra/DBTestConfiguration.ts +0 -36
  268. package/tests/extra/index.ts +0 -2
  269. package/tests/extra/testEnv.ts +0 -95
  270. package/tests/index.ts +0 -2
  271. package/tests/jestEnv.ts +0 -10
  272. package/tests/jestSetup.ts +0 -36
@@ -1,38 +0,0 @@
1
- import { getTenantId, isMultiTenant } from "../../context"
2
- import * as configs from "../../configs"
3
- import { ConfigType, GoogleInnerConfig } from "@budibase/types"
4
-
5
- /**
6
- * Utility to handle authentication errors.
7
- *
8
- * @param done The passport callback.
9
- * @param message Message that will be returned in the response body
10
- * @param err (Optional) error that will be logged
11
- */
12
-
13
- export function authError(done: Function, message: string, err?: any) {
14
- return done(
15
- err,
16
- null, // never return a user
17
- { message: message }
18
- )
19
- }
20
-
21
- export async function ssoCallbackUrl(
22
- type: ConfigType,
23
- config?: GoogleInnerConfig
24
- ) {
25
- // incase there is a callback URL from before
26
- if (config && (config as GoogleInnerConfig).callbackURL) {
27
- return (config as GoogleInnerConfig).callbackURL as string
28
- }
29
- const settingsConfig = await configs.getSettingsConfig()
30
-
31
- let callbackUrl = `/api/global/auth`
32
- if (isMultiTenant()) {
33
- callbackUrl += `/${getTenantId()}`
34
- }
35
- callbackUrl += `/${type}/callback`
36
-
37
- return `${settingsConfig.platformUrl}${callbackUrl}`
38
- }
@@ -1,28 +0,0 @@
1
- import { Ctx } from "@budibase/types"
2
-
3
- /**
4
- * Expects a standard "query" query string property which is the JSON body
5
- * of the request, which has to be sent via query string due to the requirement
6
- * of making an endpoint a GET request e.g. downloading a file stream.
7
- */
8
- export default function (ctx: Ctx, next: any) {
9
- const queryString = ctx.request.query?.query as string | undefined
10
- if (ctx.request.method.toLowerCase() !== "get") {
11
- ctx.throw(
12
- 500,
13
- "Query to download middleware can only be used for get requests."
14
- )
15
- }
16
- if (!queryString) {
17
- return next()
18
- }
19
- const decoded = decodeURIComponent(queryString)
20
- let json
21
- try {
22
- json = JSON.parse(decoded)
23
- } catch (err) {
24
- return next()
25
- }
26
- ctx.request.body = json
27
- return next()
28
- }
@@ -1,36 +0,0 @@
1
- import { doInTenant } from "../context"
2
- import { getTenantIDFromCtx } from "../tenancy"
3
- import { buildMatcherRegex, matches } from "./matchers"
4
- import { Header } from "../constants"
5
- import {
6
- BBContext,
7
- EndpointMatcher,
8
- GetTenantIdOptions,
9
- TenantResolutionStrategy,
10
- } from "@budibase/types"
11
-
12
- export default function (
13
- allowQueryStringPatterns: EndpointMatcher[],
14
- noTenancyPatterns: EndpointMatcher[],
15
- opts: { noTenancyRequired?: boolean } = { noTenancyRequired: false }
16
- ) {
17
- const allowQsOptions = buildMatcherRegex(allowQueryStringPatterns)
18
- const noTenancyOptions = buildMatcherRegex(noTenancyPatterns)
19
-
20
- return async function (ctx: BBContext | any, next: any) {
21
- const allowNoTenant =
22
- opts.noTenancyRequired || !!matches(ctx, noTenancyOptions)
23
- const tenantOpts: GetTenantIdOptions = {
24
- allowNoTenant,
25
- }
26
-
27
- const allowQs = !!matches(ctx, allowQsOptions)
28
- if (!allowQs) {
29
- tenantOpts.excludeStrategies = [TenantResolutionStrategy.QUERY]
30
- }
31
-
32
- const tenantId = getTenantIDFromCtx(ctx, tenantOpts)
33
- ctx.set(Header.TENANT_ID, tenantId as string)
34
- return doInTenant(tenantId, next)
35
- }
36
- }
@@ -1,181 +0,0 @@
1
- import adminOnly from "../adminOnly"
2
- import builderOnly from "../builderOnly"
3
- import builderOrAdmin from "../builderOrAdmin"
4
- import { structures } from "../../../tests"
5
- import { ContextUser, ServiceType } from "@budibase/types"
6
- import { doInAppContext } from "../../context"
7
- import env from "../../environment"
8
-
9
- env._set("SERVICE_TYPE", ServiceType.APPS)
10
-
11
- const appId = "app_aaa"
12
- const basicUser = structures.users.user()
13
- const adminUser = structures.users.adminUser()
14
- const adminOnlyUser = structures.users.adminOnlyUser()
15
- const builderUser = structures.users.builderUser()
16
- const appBuilderUser = structures.users.appBuilderUser(appId)
17
-
18
- function buildUserCtx(user: ContextUser) {
19
- return {
20
- internal: false,
21
- user,
22
- throw: jest.fn(),
23
- } as any
24
- }
25
-
26
- function passed(throwFn: jest.Func, nextFn: jest.Func) {
27
- expect(throwFn).not.toHaveBeenCalled()
28
- expect(nextFn).toHaveBeenCalled()
29
- }
30
-
31
- function threw(throwFn: jest.Func) {
32
- // cant check next, the throw function doesn't actually throw - so it still continues
33
- expect(throwFn).toHaveBeenCalled()
34
- }
35
-
36
- describe("adminOnly middleware", () => {
37
- it("should allow admin user", () => {
38
- const ctx = buildUserCtx(adminUser),
39
- next = jest.fn()
40
- adminOnly(ctx, next)
41
- passed(ctx.throw, next)
42
- })
43
-
44
- it("should not allow basic user", () => {
45
- const ctx = buildUserCtx(basicUser),
46
- next = jest.fn()
47
- adminOnly(ctx, next)
48
- threw(ctx.throw)
49
- })
50
-
51
- it("should not allow builder user", () => {
52
- const ctx = buildUserCtx(builderUser),
53
- next = jest.fn()
54
- adminOnly(ctx, next)
55
- threw(ctx.throw)
56
- })
57
- })
58
-
59
- describe("builderOnly middleware", () => {
60
- it("should allow builder user", () => {
61
- const ctx = buildUserCtx(builderUser),
62
- next = jest.fn()
63
- builderOnly(ctx, next)
64
- passed(ctx.throw, next)
65
- })
66
-
67
- it("should allow app builder user", () => {
68
- const ctx = buildUserCtx(appBuilderUser),
69
- next = jest.fn()
70
- doInAppContext(appId, () => {
71
- builderOnly(ctx, next)
72
- })
73
- passed(ctx.throw, next)
74
- })
75
-
76
- it("should allow admin and builder user", () => {
77
- const ctx = buildUserCtx(adminUser),
78
- next = jest.fn()
79
- builderOnly(ctx, next)
80
- passed(ctx.throw, next)
81
- })
82
-
83
- it("should not allow admin user", () => {
84
- const ctx = buildUserCtx(adminOnlyUser),
85
- next = jest.fn()
86
- builderOnly(ctx, next)
87
- threw(ctx.throw)
88
- })
89
-
90
- it("should not allow app builder user to different app", () => {
91
- const ctx = buildUserCtx(appBuilderUser),
92
- next = jest.fn()
93
- doInAppContext("app_bbb", () => {
94
- builderOnly(ctx, next)
95
- })
96
- threw(ctx.throw)
97
- })
98
-
99
- it("should not allow basic user", () => {
100
- const ctx = buildUserCtx(basicUser),
101
- next = jest.fn()
102
- builderOnly(ctx, next)
103
- threw(ctx.throw)
104
- })
105
- })
106
-
107
- describe("builderOrAdmin middleware", () => {
108
- it("should allow builder user", () => {
109
- const ctx = buildUserCtx(builderUser),
110
- next = jest.fn()
111
- builderOrAdmin(ctx, next)
112
- passed(ctx.throw, next)
113
- })
114
-
115
- it("should allow builder and admin user", () => {
116
- const ctx = buildUserCtx(adminUser),
117
- next = jest.fn()
118
- builderOrAdmin(ctx, next)
119
- passed(ctx.throw, next)
120
- })
121
-
122
- it("should allow admin user", () => {
123
- const ctx = buildUserCtx(adminOnlyUser),
124
- next = jest.fn()
125
- builderOrAdmin(ctx, next)
126
- passed(ctx.throw, next)
127
- })
128
-
129
- it("should allow app builder user", () => {
130
- const ctx = buildUserCtx(appBuilderUser),
131
- next = jest.fn()
132
- doInAppContext(appId, () => {
133
- builderOrAdmin(ctx, next)
134
- })
135
- passed(ctx.throw, next)
136
- })
137
-
138
- it("should not allow basic user", () => {
139
- const ctx = buildUserCtx(basicUser),
140
- next = jest.fn()
141
- builderOrAdmin(ctx, next)
142
- threw(ctx.throw)
143
- })
144
- })
145
-
146
- describe("check service difference", () => {
147
- it("should not allow without app ID in apps", () => {
148
- env._set("SERVICE_TYPE", ServiceType.APPS)
149
- const appId = "app_a"
150
- const ctx = buildUserCtx({
151
- ...basicUser,
152
- builder: {
153
- apps: [appId],
154
- },
155
- })
156
- const next = jest.fn()
157
- doInAppContext(appId, () => {
158
- builderOnly(ctx, next)
159
- })
160
- passed(ctx.throw, next)
161
- doInAppContext("app_b", () => {
162
- builderOnly(ctx, next)
163
- })
164
- threw(ctx.throw)
165
- })
166
-
167
- it("should allow without app ID in worker", () => {
168
- env._set("SERVICE_TYPE", ServiceType.WORKER)
169
- const ctx = buildUserCtx({
170
- ...basicUser,
171
- builder: {
172
- apps: ["app_a"],
173
- },
174
- })
175
- const next = jest.fn()
176
- doInAppContext("app_b", () => {
177
- builderOnly(ctx, next)
178
- })
179
- passed(ctx.throw, next)
180
- })
181
- })
@@ -1,75 +0,0 @@
1
- import crypto from "crypto"
2
- import contentSecurityPolicy from "../contentSecurityPolicy"
3
-
4
- jest.mock("crypto", () => ({
5
- randomBytes: jest.fn(),
6
- randomUUID: jest.fn(),
7
- }))
8
-
9
- describe("contentSecurityPolicy middleware", () => {
10
- let ctx: any
11
- let next: any
12
- const mockNonce = "mocked/nonce"
13
-
14
- beforeEach(() => {
15
- ctx = {
16
- state: {},
17
- set: jest.fn(),
18
- }
19
- next = jest.fn()
20
- // @ts-ignore
21
- crypto.randomBytes.mockReturnValue(Buffer.from(mockNonce, "base64"))
22
- })
23
-
24
- afterEach(() => {
25
- jest.clearAllMocks()
26
- })
27
-
28
- it("should generate a nonce and set it in the script-src directive", async () => {
29
- await contentSecurityPolicy(ctx, next)
30
-
31
- expect(ctx.state.nonce).toBe(mockNonce)
32
- expect(ctx.set).toHaveBeenCalledWith(
33
- "Content-Security-Policy",
34
- expect.stringContaining(
35
- `script-src 'self' 'unsafe-eval' https://*.budibase.net https://cdn.budi.live https://js.intercomcdn.com https://widget.intercom.io https://d2l5prqdbvm3op.cloudfront.net https://us-assets.i.posthog.com 'nonce-${mockNonce}'`
36
- )
37
- )
38
- expect(next).toHaveBeenCalled()
39
- })
40
-
41
- it("should include all CSP directives in the header", async () => {
42
- await contentSecurityPolicy(ctx, next)
43
-
44
- const cspHeader = ctx.set.mock.calls[0][1]
45
- expect(cspHeader).toContain("default-src 'self'")
46
- expect(cspHeader).toContain("script-src 'self' 'unsafe-eval'")
47
- expect(cspHeader).toContain("style-src 'self' 'unsafe-inline'")
48
- expect(cspHeader).toContain("object-src 'none'")
49
- expect(cspHeader).toContain("base-uri 'self'")
50
- expect(cspHeader).toContain("connect-src 'self'")
51
- expect(cspHeader).toContain("font-src 'self'")
52
- expect(cspHeader).toContain("frame-src 'self'")
53
- expect(cspHeader).toContain("img-src http: https: data: blob:")
54
- expect(cspHeader).toContain("manifest-src 'self'")
55
- expect(cspHeader).toContain("media-src 'self'")
56
- expect(cspHeader).toContain("worker-src blob:")
57
- })
58
-
59
- it("should handle errors and log an error message", async () => {
60
- const consoleSpy = jest.spyOn(console, "error").mockImplementation()
61
- const error = new Error("Test error")
62
- // @ts-ignore
63
- crypto.randomBytes.mockImplementation(() => {
64
- throw error
65
- })
66
-
67
- await contentSecurityPolicy(ctx, next)
68
-
69
- expect(consoleSpy).toHaveBeenCalledWith(
70
- `Error occurred in Content-Security-Policy middleware: ${error}`
71
- )
72
- expect(next).not.toHaveBeenCalled()
73
- consoleSpy.mockRestore()
74
- })
75
- })
@@ -1,100 +0,0 @@
1
- import * as matchers from "../matchers"
2
- import { structures } from "../../../tests"
3
-
4
- describe("matchers", () => {
5
- it("matches by path and method", () => {
6
- const pattern = [
7
- {
8
- route: "/api/tests",
9
- method: "POST",
10
- },
11
- ]
12
- const ctx = structures.koa.newContext()
13
- ctx.request.url = "/api/tests"
14
- ctx.request.method = "POST"
15
-
16
- const built = matchers.buildMatcherRegex(pattern)
17
-
18
- expect(!!matchers.matches(ctx, built)).toBe(true)
19
- })
20
-
21
- it("wildcards path", () => {
22
- const pattern = [
23
- {
24
- route: "/api/tests",
25
- method: "POST",
26
- },
27
- ]
28
- const ctx = structures.koa.newContext()
29
- ctx.request.url = "/api/tests/id/something/else"
30
- ctx.request.method = "POST"
31
-
32
- const built = matchers.buildMatcherRegex(pattern)
33
-
34
- expect(!!matchers.matches(ctx, built)).toBe(true)
35
- })
36
-
37
- it("matches with param", () => {
38
- const pattern = [
39
- {
40
- route: "/api/tests/:testId",
41
- method: "GET",
42
- },
43
- ]
44
- const ctx = structures.koa.newContext()
45
- ctx.request.url = "/api/tests/id"
46
- ctx.request.method = "GET"
47
-
48
- const built = matchers.buildMatcherRegex(pattern)
49
-
50
- expect(!!matchers.matches(ctx, built)).toBe(true)
51
- })
52
-
53
- it("doesn't match by path", () => {
54
- const pattern = [
55
- {
56
- route: "/api/tests",
57
- method: "POST",
58
- },
59
- ]
60
- const ctx = structures.koa.newContext()
61
- ctx.request.url = "/api/unknown"
62
- ctx.request.method = "POST"
63
-
64
- const built = matchers.buildMatcherRegex(pattern)
65
-
66
- expect(!!matchers.matches(ctx, built)).toBe(false)
67
- })
68
-
69
- it("doesn't match by method", () => {
70
- const pattern = [
71
- {
72
- route: "/api/tests",
73
- method: "POST",
74
- },
75
- ]
76
- const ctx = structures.koa.newContext()
77
- ctx.request.url = "/api/tests"
78
- ctx.request.method = "GET"
79
-
80
- const built = matchers.buildMatcherRegex(pattern)
81
-
82
- expect(!!matchers.matches(ctx, built)).toBe(false)
83
- })
84
-
85
- it("matches by path and wildcard method", () => {
86
- const pattern = [
87
- {
88
- route: "/api/tests",
89
- method: "ALL",
90
- },
91
- ]
92
- const ctx = structures.koa.newContext()
93
- ctx.request.url = "/api/tests"
94
- ctx.request.method = "GET"
95
-
96
- const built = matchers.buildMatcherRegex(pattern)
97
-
98
- expect(!!matchers.matches(ctx, built)).toBe(true)
99
- })
100
- })
@@ -1,40 +0,0 @@
1
- import {
2
- MigrationType,
3
- MigrationName,
4
- MigrationDefinition,
5
- } from "@budibase/types"
6
-
7
- export const DEFINITIONS: MigrationDefinition[] = [
8
- {
9
- type: MigrationType.GLOBAL,
10
- name: MigrationName.USER_EMAIL_VIEW_CASING,
11
- },
12
- {
13
- type: MigrationType.GLOBAL,
14
- name: MigrationName.SYNC_QUOTAS,
15
- },
16
- {
17
- type: MigrationType.APP,
18
- name: MigrationName.APP_URLS,
19
- },
20
- {
21
- type: MigrationType.APP,
22
- name: MigrationName.EVENT_APP_BACKFILL,
23
- },
24
- {
25
- type: MigrationType.APP,
26
- name: MigrationName.TABLE_SETTINGS_LINKS_TO_ACTIONS,
27
- },
28
- {
29
- type: MigrationType.GLOBAL,
30
- name: MigrationName.EVENT_GLOBAL_BACKFILL,
31
- },
32
- {
33
- type: MigrationType.INSTALLATION,
34
- name: MigrationName.EVENT_INSTALLATION_BACKFILL,
35
- },
36
- {
37
- type: MigrationType.GLOBAL,
38
- name: MigrationName.GLOBAL_INFO_SYNC_USERS,
39
- },
40
- ]
@@ -1,2 +0,0 @@
1
- export * from "./migrations"
2
- export * from "./definitions"
@@ -1,186 +0,0 @@
1
- import { DEFAULT_TENANT_ID } from "../constants"
2
- import {
3
- DocumentType,
4
- StaticDatabases,
5
- getAllApps,
6
- getGlobalDBName,
7
- getDB,
8
- } from "../db"
9
- import environment from "../environment"
10
- import * as platform from "../platform"
11
- import * as context from "../context"
12
- import { DEFINITIONS } from "."
13
- import {
14
- Migration,
15
- MigrationOptions,
16
- MigrationType,
17
- MigrationNoOpOptions,
18
- App,
19
- } from "@budibase/types"
20
-
21
- export const getMigrationsDoc = async (db: any) => {
22
- // get the migrations doc
23
- try {
24
- return await db.get(DocumentType.MIGRATIONS)
25
- } catch (err: any) {
26
- if (err.status && err.status === 404) {
27
- return { _id: DocumentType.MIGRATIONS }
28
- } else {
29
- throw err
30
- }
31
- }
32
- }
33
-
34
- export const backPopulateMigrations = async (opts: MigrationNoOpOptions) => {
35
- // filter migrations to the type and populate a no-op migration
36
- const migrations: Migration[] = DEFINITIONS.filter(
37
- def => def.type === opts.type
38
- ).map(d => ({ ...d, fn: () => {} }))
39
- await runMigrations(migrations, { noOp: opts })
40
- }
41
-
42
- export const runMigration = async (
43
- migration: Migration,
44
- options: MigrationOptions = {}
45
- ) => {
46
- const migrationType = migration.type
47
- const migrationName = migration.name
48
- const silent = migration.silent
49
-
50
- const log = (message: string) => {
51
- if (!silent) {
52
- console.log(message)
53
- }
54
- }
55
-
56
- // get the db to store the migration in
57
- let dbNames: string[]
58
- if (migrationType === MigrationType.GLOBAL) {
59
- dbNames = [getGlobalDBName()]
60
- } else if (migrationType === MigrationType.APP) {
61
- if (options.noOp) {
62
- if (!options.noOp.appId) {
63
- throw new Error("appId is required for noOp app migration")
64
- }
65
- dbNames = [options.noOp.appId]
66
- } else {
67
- const apps = (await getAllApps(migration.appOpts)) as App[]
68
- dbNames = apps.map(app => app.appId)
69
- }
70
- } else if (migrationType === MigrationType.INSTALLATION) {
71
- dbNames = [StaticDatabases.PLATFORM_INFO.name]
72
- } else {
73
- throw new Error(`Unrecognised migration type [${migrationType}]`)
74
- }
75
-
76
- const length = dbNames.length
77
- let count = 0
78
-
79
- // run the migration against each db
80
- for (const dbName of dbNames) {
81
- count++
82
- const lengthStatement = length > 1 ? `[${count}/${length}]` : ""
83
-
84
- const db = getDB(dbName)
85
-
86
- try {
87
- const doc = await getMigrationsDoc(db)
88
-
89
- // the migration has already been run
90
- if (doc[migrationName]) {
91
- // check for force
92
- if (
93
- options.force &&
94
- options.force[migrationType] &&
95
- options.force[migrationType].includes(migrationName)
96
- ) {
97
- log(`[Migration: ${migrationName}] [DB: ${dbName}] Forcing`)
98
- } else {
99
- // no force, exit
100
- return
101
- }
102
- }
103
-
104
- // check if the migration is not a no-op
105
- if (!options.noOp) {
106
- log(
107
- `[Migration: ${migrationName}] [DB: ${dbName}] Running ${lengthStatement}`
108
- )
109
-
110
- if (migration.preventRetry) {
111
- // eagerly set the completion date
112
- // so that we never run this migration twice even upon failure
113
- doc[migrationName] = Date.now()
114
- const response = await db.put(doc)
115
- doc._rev = response.rev
116
- }
117
-
118
- // run the migration
119
- if (migrationType === MigrationType.APP) {
120
- await context.doInAppContext(db.name, async () => {
121
- await migration.fn(db)
122
- })
123
- } else {
124
- await migration.fn(db)
125
- }
126
-
127
- log(`[Migration: ${migrationName}] [DB: ${dbName}] Complete`)
128
- }
129
-
130
- // mark as complete
131
- doc[migrationName] = Date.now()
132
- await db.put(doc)
133
- } catch (err) {
134
- console.error(
135
- `[Migration: ${migrationName}] [DB: ${dbName}] Error: `,
136
- err
137
- )
138
- throw err
139
- }
140
- }
141
- }
142
-
143
- export const runMigrations = async (
144
- migrations: Migration[],
145
- options: MigrationOptions = {}
146
- ) => {
147
- let tenantIds
148
-
149
- if (environment.MULTI_TENANCY) {
150
- if (options.noOp) {
151
- tenantIds = [options.noOp.tenantId]
152
- } else if (!options.tenantIds || !options.tenantIds.length) {
153
- // run for all tenants
154
- tenantIds = await platform.tenants.getTenantIds()
155
- } else {
156
- tenantIds = options.tenantIds
157
- }
158
- } else {
159
- // single tenancy
160
- tenantIds = [DEFAULT_TENANT_ID]
161
- }
162
-
163
- if (tenantIds.length > 1) {
164
- console.log(`Checking migrations for ${tenantIds.length} tenants`)
165
- } else {
166
- console.log("Checking migrations")
167
- }
168
-
169
- let count = 0
170
- // for all tenants
171
- for (const tenantId of tenantIds) {
172
- count++
173
- if (tenantIds.length > 1) {
174
- console.log(`Progress [${count}/${tenantIds.length}]`)
175
- }
176
- // for all migrations
177
- for (const migration of migrations) {
178
- // run the migration
179
- await context.doInTenant(
180
- tenantId,
181
- async () => await runMigration(migration, options)
182
- )
183
- }
184
- }
185
- console.log("Migrations complete")
186
- }
@@ -1,11 +0,0 @@
1
- // Jest Snapshot v1, https://goo.gl/fbAQLP
2
-
3
- exports[`migrations should match snapshot 1`] = `
4
- {
5
- "_id": "migrations",
6
- "_rev": "1-2f64479842a0513aa8b97f356b0b9127",
7
- "createdAt": "2020-01-01T00:00:00.000Z",
8
- "test": 1577836800000,
9
- "updatedAt": "2020-01-01T00:00:00.000Z",
10
- }
11
- `;