@budibase/backend-core 3.2.5 → 3.2.7

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (276) hide show
  1. package/dist/index.js +7 -1
  2. package/dist/index.js.map +2 -2
  3. package/dist/index.js.meta.json +1 -1
  4. package/dist/package.json +11 -4
  5. package/dist/plugins.js.meta.json +1 -1
  6. package/dist/src/environment.d.ts +1 -0
  7. package/dist/src/environment.js +6 -1
  8. package/dist/src/environment.js.map +1 -1
  9. package/package.json +11 -4
  10. package/src/accounts/accounts.ts +0 -82
  11. package/src/accounts/api.ts +0 -59
  12. package/src/accounts/index.ts +0 -1
  13. package/src/auth/auth.ts +0 -210
  14. package/src/auth/index.ts +0 -1
  15. package/src/auth/tests/auth.spec.ts +0 -14
  16. package/src/blacklist/blacklist.ts +0 -54
  17. package/src/blacklist/index.ts +0 -1
  18. package/src/blacklist/tests/blacklist.spec.ts +0 -46
  19. package/src/cache/appMetadata.ts +0 -88
  20. package/src/cache/base/index.ts +0 -150
  21. package/src/cache/docWritethrough.ts +0 -105
  22. package/src/cache/generic.ts +0 -33
  23. package/src/cache/index.ts +0 -8
  24. package/src/cache/invite.ts +0 -86
  25. package/src/cache/passwordReset.ts +0 -49
  26. package/src/cache/tests/docWritethrough.spec.ts +0 -296
  27. package/src/cache/tests/user.spec.ts +0 -145
  28. package/src/cache/tests/writethrough.spec.ts +0 -139
  29. package/src/cache/user.ts +0 -154
  30. package/src/cache/writethrough.ts +0 -133
  31. package/src/configs/configs.ts +0 -263
  32. package/src/configs/index.ts +0 -1
  33. package/src/configs/tests/configs.spec.ts +0 -184
  34. package/src/constants/db.ts +0 -75
  35. package/src/constants/index.ts +0 -2
  36. package/src/constants/misc.ts +0 -36
  37. package/src/context/Context.ts +0 -14
  38. package/src/context/identity.ts +0 -58
  39. package/src/context/index.ts +0 -3
  40. package/src/context/mainContext.ts +0 -422
  41. package/src/context/tests/index.spec.ts +0 -255
  42. package/src/context/types.ts +0 -26
  43. package/src/db/Replication.ts +0 -94
  44. package/src/db/couch/DatabaseImpl.ts +0 -511
  45. package/src/db/couch/connections.ts +0 -89
  46. package/src/db/couch/index.ts +0 -4
  47. package/src/db/couch/pouchDB.ts +0 -97
  48. package/src/db/couch/pouchDump.ts +0 -0
  49. package/src/db/couch/tests/DatabaseImpl.spec.ts +0 -118
  50. package/src/db/couch/utils.ts +0 -55
  51. package/src/db/db.ts +0 -34
  52. package/src/db/errors.ts +0 -14
  53. package/src/db/index.ts +0 -12
  54. package/src/db/instrumentation.ts +0 -199
  55. package/src/db/lucene.ts +0 -721
  56. package/src/db/searchIndexes/index.ts +0 -1
  57. package/src/db/searchIndexes/searchIndexes.ts +0 -62
  58. package/src/db/tests/DatabaseImpl.spec.ts +0 -55
  59. package/src/db/tests/connections.spec.ts +0 -22
  60. package/src/db/tests/index.spec.ts +0 -32
  61. package/src/db/tests/lucene.spec.ts +0 -400
  62. package/src/db/tests/pouch.spec.js +0 -62
  63. package/src/db/tests/utils.spec.ts +0 -63
  64. package/src/db/utils.ts +0 -208
  65. package/src/db/views.ts +0 -245
  66. package/src/docIds/conversions.ts +0 -60
  67. package/src/docIds/ids.ts +0 -126
  68. package/src/docIds/index.ts +0 -2
  69. package/src/docIds/newid.ts +0 -5
  70. package/src/docIds/params.ts +0 -189
  71. package/src/docUpdates/index.ts +0 -24
  72. package/src/environment.ts +0 -293
  73. package/src/errors/errors.ts +0 -119
  74. package/src/errors/index.ts +0 -1
  75. package/src/events/analytics.ts +0 -6
  76. package/src/events/asyncEvents/index.ts +0 -2
  77. package/src/events/asyncEvents/publisher.ts +0 -12
  78. package/src/events/asyncEvents/queue.ts +0 -22
  79. package/src/events/backfill.ts +0 -183
  80. package/src/events/documentId.ts +0 -56
  81. package/src/events/events.ts +0 -47
  82. package/src/events/identification.ts +0 -311
  83. package/src/events/index.ts +0 -15
  84. package/src/events/processors/AnalyticsProcessor.ts +0 -64
  85. package/src/events/processors/AuditLogsProcessor.ts +0 -92
  86. package/src/events/processors/LoggingProcessor.ts +0 -36
  87. package/src/events/processors/Processors.ts +0 -52
  88. package/src/events/processors/async/DocumentUpdateProcessor.ts +0 -38
  89. package/src/events/processors/index.ts +0 -19
  90. package/src/events/processors/posthog/PosthogProcessor.ts +0 -118
  91. package/src/events/processors/posthog/index.ts +0 -3
  92. package/src/events/processors/posthog/rateLimiting.ts +0 -106
  93. package/src/events/processors/posthog/tests/PosthogProcessor.spec.ts +0 -164
  94. package/src/events/processors/types.ts +0 -1
  95. package/src/events/publishers/account.ts +0 -41
  96. package/src/events/publishers/ai.ts +0 -21
  97. package/src/events/publishers/app.ts +0 -168
  98. package/src/events/publishers/auditLog.ts +0 -26
  99. package/src/events/publishers/auth.ts +0 -73
  100. package/src/events/publishers/automation.ts +0 -110
  101. package/src/events/publishers/backfill.ts +0 -74
  102. package/src/events/publishers/backup.ts +0 -42
  103. package/src/events/publishers/datasource.ts +0 -48
  104. package/src/events/publishers/email.ts +0 -17
  105. package/src/events/publishers/environmentVariable.ts +0 -38
  106. package/src/events/publishers/group.ts +0 -99
  107. package/src/events/publishers/index.ts +0 -25
  108. package/src/events/publishers/installation.ts +0 -38
  109. package/src/events/publishers/layout.ts +0 -26
  110. package/src/events/publishers/license.ts +0 -84
  111. package/src/events/publishers/org.ts +0 -37
  112. package/src/events/publishers/plugin.ts +0 -47
  113. package/src/events/publishers/query.ts +0 -89
  114. package/src/events/publishers/role.ts +0 -62
  115. package/src/events/publishers/rows.ts +0 -29
  116. package/src/events/publishers/screen.ts +0 -36
  117. package/src/events/publishers/serve.ts +0 -43
  118. package/src/events/publishers/table.ts +0 -70
  119. package/src/events/publishers/user.ts +0 -202
  120. package/src/events/publishers/view.ts +0 -107
  121. package/src/features/features.ts +0 -277
  122. package/src/features/index.ts +0 -2
  123. package/src/features/tests/features.spec.ts +0 -267
  124. package/src/features/tests/utils.ts +0 -64
  125. package/src/helpers.ts +0 -9
  126. package/src/index.ts +0 -59
  127. package/src/installation.ts +0 -115
  128. package/src/logging/alerts.ts +0 -26
  129. package/src/logging/correlation/correlation.ts +0 -15
  130. package/src/logging/correlation/index.ts +0 -1
  131. package/src/logging/correlation/middleware.ts +0 -18
  132. package/src/logging/index.ts +0 -4
  133. package/src/logging/pino/logger.ts +0 -239
  134. package/src/logging/pino/middleware.ts +0 -48
  135. package/src/logging/system.ts +0 -81
  136. package/src/logging/tests/system.spec.ts +0 -61
  137. package/src/middleware/adminOnly.ts +0 -9
  138. package/src/middleware/auditLog.ts +0 -6
  139. package/src/middleware/authenticated.ts +0 -247
  140. package/src/middleware/builderOnly.ts +0 -21
  141. package/src/middleware/builderOrAdmin.ts +0 -21
  142. package/src/middleware/contentSecurityPolicy.ts +0 -113
  143. package/src/middleware/csrf.ts +0 -81
  144. package/src/middleware/errorHandling.ts +0 -43
  145. package/src/middleware/index.ts +0 -24
  146. package/src/middleware/internalApi.ts +0 -23
  147. package/src/middleware/ip.ts +0 -12
  148. package/src/middleware/joi-validator.ts +0 -58
  149. package/src/middleware/matchers.ts +0 -39
  150. package/src/middleware/passport/datasource/google.ts +0 -102
  151. package/src/middleware/passport/local.ts +0 -54
  152. package/src/middleware/passport/sso/google.ts +0 -77
  153. package/src/middleware/passport/sso/oidc.ts +0 -152
  154. package/src/middleware/passport/sso/sso.ts +0 -138
  155. package/src/middleware/passport/sso/tests/google.spec.ts +0 -68
  156. package/src/middleware/passport/sso/tests/oidc.spec.ts +0 -144
  157. package/src/middleware/passport/sso/tests/sso.spec.ts +0 -197
  158. package/src/middleware/passport/utils.ts +0 -38
  159. package/src/middleware/querystringToBody.ts +0 -28
  160. package/src/middleware/tenancy.ts +0 -36
  161. package/src/middleware/tests/builder.spec.ts +0 -181
  162. package/src/middleware/tests/contentSecurityPolicy.spec.ts +0 -75
  163. package/src/middleware/tests/matchers.spec.ts +0 -100
  164. package/src/migrations/definitions.ts +0 -40
  165. package/src/migrations/index.ts +0 -2
  166. package/src/migrations/migrations.ts +0 -186
  167. package/src/migrations/tests/__snapshots__/migrations.spec.ts.snap +0 -11
  168. package/src/migrations/tests/migrations.spec.ts +0 -64
  169. package/src/objectStore/buckets/app.ts +0 -53
  170. package/src/objectStore/buckets/global.ts +0 -29
  171. package/src/objectStore/buckets/index.ts +0 -3
  172. package/src/objectStore/buckets/plugins.ts +0 -71
  173. package/src/objectStore/buckets/tests/app.spec.ts +0 -161
  174. package/src/objectStore/buckets/tests/global.spec.ts +0 -74
  175. package/src/objectStore/buckets/tests/plugins.spec.ts +0 -111
  176. package/src/objectStore/cloudfront.ts +0 -41
  177. package/src/objectStore/index.ts +0 -3
  178. package/src/objectStore/objectStore.ts +0 -585
  179. package/src/objectStore/utils.ts +0 -113
  180. package/src/platform/index.ts +0 -3
  181. package/src/platform/platformDb.ts +0 -6
  182. package/src/platform/tenants.ts +0 -101
  183. package/src/platform/tests/tenants.spec.ts +0 -26
  184. package/src/platform/users.ts +0 -129
  185. package/src/plugin/index.ts +0 -1
  186. package/src/plugin/tests/validation.spec.ts +0 -209
  187. package/src/plugin/utils.ts +0 -175
  188. package/src/queue/constants.ts +0 -8
  189. package/src/queue/inMemoryQueue.ts +0 -189
  190. package/src/queue/index.ts +0 -2
  191. package/src/queue/listeners.ts +0 -199
  192. package/src/queue/queue.ts +0 -84
  193. package/src/redis/index.ts +0 -6
  194. package/src/redis/init.ts +0 -118
  195. package/src/redis/redis.ts +0 -358
  196. package/src/redis/redlockImpl.ts +0 -155
  197. package/src/redis/tests/redis.spec.ts +0 -207
  198. package/src/redis/tests/redlockImpl.spec.ts +0 -105
  199. package/src/redis/utils.ts +0 -128
  200. package/src/security/auth.ts +0 -24
  201. package/src/security/encryption.ts +0 -185
  202. package/src/security/index.ts +0 -1
  203. package/src/security/permissions.ts +0 -166
  204. package/src/security/roles.ts +0 -655
  205. package/src/security/secrets.ts +0 -20
  206. package/src/security/sessions.ts +0 -123
  207. package/src/security/tests/auth.spec.ts +0 -45
  208. package/src/security/tests/encryption.spec.ts +0 -31
  209. package/src/security/tests/permissions.spec.ts +0 -146
  210. package/src/security/tests/secrets.spec.ts +0 -35
  211. package/src/security/tests/sessions.spec.ts +0 -12
  212. package/src/sql/designDoc.ts +0 -17
  213. package/src/sql/index.ts +0 -5
  214. package/src/sql/sql.ts +0 -1854
  215. package/src/sql/sqlTable.ts +0 -319
  216. package/src/sql/utils.ts +0 -193
  217. package/src/tenancy/db.ts +0 -6
  218. package/src/tenancy/index.ts +0 -2
  219. package/src/tenancy/tenancy.ts +0 -148
  220. package/src/tenancy/tests/tenancy.spec.ts +0 -184
  221. package/src/timers/index.ts +0 -1
  222. package/src/timers/timers.ts +0 -22
  223. package/src/users/db.ts +0 -582
  224. package/src/users/events.ts +0 -176
  225. package/src/users/index.ts +0 -4
  226. package/src/users/lookup.ts +0 -99
  227. package/src/users/test/db.spec.ts +0 -188
  228. package/src/users/test/utils.spec.ts +0 -67
  229. package/src/users/users.ts +0 -353
  230. package/src/users/utils.ts +0 -81
  231. package/src/utils/Duration.ts +0 -56
  232. package/src/utils/hashing.ts +0 -15
  233. package/src/utils/index.ts +0 -4
  234. package/src/utils/stringUtils.ts +0 -8
  235. package/src/utils/tests/Duration.spec.ts +0 -19
  236. package/src/utils/tests/utils.spec.ts +0 -204
  237. package/src/utils/utils.ts +0 -249
  238. package/tests/core/logging.ts +0 -34
  239. package/tests/core/users/users.spec.js +0 -53
  240. package/tests/core/utilities/index.ts +0 -7
  241. package/tests/core/utilities/jestUtils.ts +0 -33
  242. package/tests/core/utilities/mocks/alerts.ts +0 -4
  243. package/tests/core/utilities/mocks/date.ts +0 -3
  244. package/tests/core/utilities/mocks/events.ts +0 -132
  245. package/tests/core/utilities/mocks/index.ts +0 -9
  246. package/tests/core/utilities/mocks/licenses.ts +0 -119
  247. package/tests/core/utilities/queue.ts +0 -9
  248. package/tests/core/utilities/structures/Chance.ts +0 -20
  249. package/tests/core/utilities/structures/accounts.ts +0 -80
  250. package/tests/core/utilities/structures/apps.ts +0 -21
  251. package/tests/core/utilities/structures/common.ts +0 -7
  252. package/tests/core/utilities/structures/db.ts +0 -12
  253. package/tests/core/utilities/structures/documents/index.ts +0 -1
  254. package/tests/core/utilities/structures/documents/platform/index.ts +0 -1
  255. package/tests/core/utilities/structures/documents/platform/installation.ts +0 -12
  256. package/tests/core/utilities/structures/generator.ts +0 -3
  257. package/tests/core/utilities/structures/index.ts +0 -15
  258. package/tests/core/utilities/structures/koa.ts +0 -16
  259. package/tests/core/utilities/structures/licenses.ts +0 -190
  260. package/tests/core/utilities/structures/plugins.ts +0 -19
  261. package/tests/core/utilities/structures/quotas.ts +0 -72
  262. package/tests/core/utilities/structures/scim.ts +0 -80
  263. package/tests/core/utilities/structures/sso.ts +0 -118
  264. package/tests/core/utilities/structures/tenants.ts +0 -5
  265. package/tests/core/utilities/structures/userGroups.ts +0 -10
  266. package/tests/core/utilities/structures/users.ts +0 -89
  267. package/tests/core/utilities/testContainerUtils.ts +0 -165
  268. package/tests/core/utilities/utils/index.ts +0 -2
  269. package/tests/core/utilities/utils/queue.ts +0 -27
  270. package/tests/core/utilities/utils/time.ts +0 -3
  271. package/tests/extra/DBTestConfiguration.ts +0 -36
  272. package/tests/extra/index.ts +0 -2
  273. package/tests/extra/testEnv.ts +0 -95
  274. package/tests/index.ts +0 -2
  275. package/tests/jestEnv.ts +0 -10
  276. package/tests/jestSetup.ts +0 -36
@@ -1,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
- `;