@budibase/backend-core 2.9.40-alpha.6 → 2.10.1

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 (252) hide show
  1. package/dist/index.js +5 -4
  2. package/dist/index.js.map +2 -2
  3. package/dist/index.js.meta.json +1 -1
  4. package/dist/package.json +6 -6
  5. package/dist/src/cache/appMetadata.js +1 -1
  6. package/dist/src/cache/appMetadata.js.map +1 -1
  7. package/dist/src/constants/misc.d.ts +0 -2
  8. package/dist/src/constants/misc.js +0 -2
  9. package/dist/src/constants/misc.js.map +1 -1
  10. package/dist/src/environment.js +5 -4
  11. package/dist/src/environment.js.map +1 -1
  12. package/dist/src/logging/system.d.ts +1 -1
  13. package/dist/src/timers/timers.d.ts +1 -1
  14. package/package.json +6 -6
  15. package/src/accounts/accounts.ts +82 -0
  16. package/src/accounts/api.ts +59 -0
  17. package/src/accounts/index.ts +1 -0
  18. package/src/auth/auth.ts +208 -0
  19. package/src/auth/index.ts +1 -0
  20. package/src/auth/tests/auth.spec.ts +14 -0
  21. package/src/blacklist/blacklist.ts +54 -0
  22. package/src/blacklist/index.ts +1 -0
  23. package/src/blacklist/tests/blacklist.spec.ts +46 -0
  24. package/src/cache/appMetadata.ts +88 -0
  25. package/src/cache/base/index.ts +92 -0
  26. package/src/cache/generic.ts +30 -0
  27. package/src/cache/index.ts +5 -0
  28. package/src/cache/tests/writethrough.spec.ts +138 -0
  29. package/src/cache/user.ts +83 -0
  30. package/src/cache/writethrough.ts +133 -0
  31. package/src/configs/configs.ts +257 -0
  32. package/src/configs/index.ts +1 -0
  33. package/src/configs/tests/configs.spec.ts +184 -0
  34. package/src/constants/db.ts +63 -0
  35. package/src/constants/index.ts +2 -0
  36. package/src/constants/misc.ts +50 -0
  37. package/src/context/Context.ts +14 -0
  38. package/src/context/identity.ts +58 -0
  39. package/src/context/index.ts +3 -0
  40. package/src/context/mainContext.ts +310 -0
  41. package/src/context/tests/index.spec.ts +147 -0
  42. package/src/context/types.ts +11 -0
  43. package/src/db/Replication.ts +84 -0
  44. package/src/db/constants.ts +10 -0
  45. package/src/db/couch/DatabaseImpl.ts +238 -0
  46. package/src/db/couch/connections.ts +77 -0
  47. package/src/db/couch/index.ts +5 -0
  48. package/src/db/couch/pouchDB.ts +97 -0
  49. package/src/db/couch/pouchDump.ts +0 -0
  50. package/src/db/couch/utils.ts +50 -0
  51. package/src/db/db.ts +43 -0
  52. package/src/db/errors.ts +14 -0
  53. package/src/db/index.ts +12 -0
  54. package/src/db/lucene.ts +750 -0
  55. package/src/db/searchIndexes/index.ts +1 -0
  56. package/src/db/searchIndexes/searchIndexes.ts +62 -0
  57. package/src/db/tests/index.spec.js +25 -0
  58. package/src/db/tests/lucene.spec.ts +368 -0
  59. package/src/db/tests/pouch.spec.js +62 -0
  60. package/src/db/tests/utils.spec.ts +63 -0
  61. package/src/db/utils.ts +207 -0
  62. package/src/db/views.ts +241 -0
  63. package/src/docIds/conversions.ts +59 -0
  64. package/src/docIds/ids.ts +113 -0
  65. package/src/docIds/index.ts +2 -0
  66. package/src/docIds/newid.ts +5 -0
  67. package/src/docIds/params.ts +174 -0
  68. package/src/docUpdates/index.ts +29 -0
  69. package/src/environment.ts +201 -0
  70. package/src/errors/errors.ts +119 -0
  71. package/src/errors/index.ts +1 -0
  72. package/src/events/analytics.ts +6 -0
  73. package/src/events/asyncEvents/index.ts +2 -0
  74. package/src/events/asyncEvents/publisher.ts +12 -0
  75. package/src/events/asyncEvents/queue.ts +22 -0
  76. package/src/events/backfill.ts +183 -0
  77. package/src/events/documentId.ts +56 -0
  78. package/src/events/events.ts +40 -0
  79. package/src/events/identification.ts +310 -0
  80. package/src/events/index.ts +14 -0
  81. package/src/events/processors/AnalyticsProcessor.ts +64 -0
  82. package/src/events/processors/AuditLogsProcessor.ts +93 -0
  83. package/src/events/processors/LoggingProcessor.ts +37 -0
  84. package/src/events/processors/Processors.ts +52 -0
  85. package/src/events/processors/async/DocumentUpdateProcessor.ts +43 -0
  86. package/src/events/processors/index.ts +19 -0
  87. package/src/events/processors/posthog/PosthogProcessor.ts +118 -0
  88. package/src/events/processors/posthog/index.ts +2 -0
  89. package/src/events/processors/posthog/rateLimiting.ts +106 -0
  90. package/src/events/processors/posthog/tests/PosthogProcessor.spec.ts +168 -0
  91. package/src/events/processors/types.ts +1 -0
  92. package/src/events/publishers/account.ts +35 -0
  93. package/src/events/publishers/app.ts +155 -0
  94. package/src/events/publishers/auditLog.ts +26 -0
  95. package/src/events/publishers/auth.ts +73 -0
  96. package/src/events/publishers/automation.ts +110 -0
  97. package/src/events/publishers/backfill.ts +74 -0
  98. package/src/events/publishers/backup.ts +42 -0
  99. package/src/events/publishers/datasource.ts +48 -0
  100. package/src/events/publishers/email.ts +17 -0
  101. package/src/events/publishers/environmentVariable.ts +38 -0
  102. package/src/events/publishers/group.ts +99 -0
  103. package/src/events/publishers/index.ts +24 -0
  104. package/src/events/publishers/installation.ts +38 -0
  105. package/src/events/publishers/layout.ts +26 -0
  106. package/src/events/publishers/license.ts +84 -0
  107. package/src/events/publishers/org.ts +37 -0
  108. package/src/events/publishers/plugin.ts +47 -0
  109. package/src/events/publishers/query.ts +88 -0
  110. package/src/events/publishers/role.ts +62 -0
  111. package/src/events/publishers/rows.ts +29 -0
  112. package/src/events/publishers/screen.ts +36 -0
  113. package/src/events/publishers/serve.ts +43 -0
  114. package/src/events/publishers/table.ts +70 -0
  115. package/src/events/publishers/user.ts +202 -0
  116. package/src/events/publishers/view.ts +107 -0
  117. package/src/features/index.ts +78 -0
  118. package/src/features/installation.ts +17 -0
  119. package/src/features/tests/featureFlags.spec.ts +85 -0
  120. package/src/helpers.ts +9 -0
  121. package/src/index.ts +54 -0
  122. package/src/installation.ts +107 -0
  123. package/src/logging/alerts.ts +26 -0
  124. package/src/logging/correlation/correlation.ts +13 -0
  125. package/src/logging/correlation/index.ts +1 -0
  126. package/src/logging/correlation/middleware.ts +17 -0
  127. package/src/logging/index.ts +4 -0
  128. package/src/logging/pino/logger.ts +232 -0
  129. package/src/logging/pino/middleware.ts +45 -0
  130. package/src/logging/system.ts +81 -0
  131. package/src/logging/tests/system.spec.ts +61 -0
  132. package/src/middleware/adminOnly.ts +9 -0
  133. package/src/middleware/auditLog.ts +6 -0
  134. package/src/middleware/authenticated.ts +193 -0
  135. package/src/middleware/builderOnly.ts +21 -0
  136. package/src/middleware/builderOrAdmin.ts +21 -0
  137. package/src/middleware/csrf.ts +81 -0
  138. package/src/middleware/errorHandling.ts +29 -0
  139. package/src/middleware/index.ts +21 -0
  140. package/src/middleware/internalApi.ts +23 -0
  141. package/src/middleware/joi-validator.ts +45 -0
  142. package/src/middleware/matchers.ts +47 -0
  143. package/src/middleware/passport/datasource/google.ts +95 -0
  144. package/src/middleware/passport/local.ts +54 -0
  145. package/src/middleware/passport/sso/google.ts +77 -0
  146. package/src/middleware/passport/sso/oidc.ts +154 -0
  147. package/src/middleware/passport/sso/sso.ts +165 -0
  148. package/src/middleware/passport/sso/tests/google.spec.ts +67 -0
  149. package/src/middleware/passport/sso/tests/oidc.spec.ts +152 -0
  150. package/src/middleware/passport/sso/tests/sso.spec.ts +197 -0
  151. package/src/middleware/passport/utils.ts +38 -0
  152. package/src/middleware/querystringToBody.ts +28 -0
  153. package/src/middleware/tenancy.ts +36 -0
  154. package/src/middleware/tests/builder.spec.ts +180 -0
  155. package/src/middleware/tests/matchers.spec.ts +134 -0
  156. package/src/migrations/definitions.ts +40 -0
  157. package/src/migrations/index.ts +2 -0
  158. package/src/migrations/migrations.ts +191 -0
  159. package/src/migrations/tests/__snapshots__/migrations.spec.ts.snap +11 -0
  160. package/src/migrations/tests/migrations.spec.ts +64 -0
  161. package/src/objectStore/buckets/app.ts +40 -0
  162. package/src/objectStore/buckets/global.ts +29 -0
  163. package/src/objectStore/buckets/index.ts +3 -0
  164. package/src/objectStore/buckets/plugins.ts +71 -0
  165. package/src/objectStore/buckets/tests/app.spec.ts +171 -0
  166. package/src/objectStore/buckets/tests/global.spec.ts +74 -0
  167. package/src/objectStore/buckets/tests/plugins.spec.ts +111 -0
  168. package/src/objectStore/cloudfront.ts +41 -0
  169. package/src/objectStore/index.ts +3 -0
  170. package/src/objectStore/objectStore.ts +440 -0
  171. package/src/objectStore/utils.ts +27 -0
  172. package/src/platform/index.ts +3 -0
  173. package/src/platform/platformDb.ts +6 -0
  174. package/src/platform/tenants.ts +101 -0
  175. package/src/platform/tests/tenants.spec.ts +26 -0
  176. package/src/platform/users.ts +90 -0
  177. package/src/plugin/index.ts +1 -0
  178. package/src/plugin/tests/validation.spec.ts +83 -0
  179. package/src/plugin/utils.ts +156 -0
  180. package/src/queue/constants.ts +6 -0
  181. package/src/queue/inMemoryQueue.ts +141 -0
  182. package/src/queue/index.ts +2 -0
  183. package/src/queue/listeners.ts +195 -0
  184. package/src/queue/queue.ts +54 -0
  185. package/src/redis/index.ts +6 -0
  186. package/src/redis/init.ts +86 -0
  187. package/src/redis/redis.ts +308 -0
  188. package/src/redis/redlockImpl.ts +139 -0
  189. package/src/redis/utils.ts +117 -0
  190. package/src/security/encryption.ts +179 -0
  191. package/src/security/permissions.ts +158 -0
  192. package/src/security/roles.ts +389 -0
  193. package/src/security/sessions.ts +120 -0
  194. package/src/security/tests/encryption.spec.ts +31 -0
  195. package/src/security/tests/permissions.spec.ts +145 -0
  196. package/src/security/tests/sessions.spec.ts +12 -0
  197. package/src/tenancy/db.ts +6 -0
  198. package/src/tenancy/index.ts +2 -0
  199. package/src/tenancy/tenancy.ts +140 -0
  200. package/src/tenancy/tests/tenancy.spec.ts +184 -0
  201. package/src/timers/index.ts +1 -0
  202. package/src/timers/timers.ts +22 -0
  203. package/src/users/db.ts +484 -0
  204. package/src/users/events.ts +176 -0
  205. package/src/users/index.ts +4 -0
  206. package/src/users/lookup.ts +102 -0
  207. package/src/users/users.ts +276 -0
  208. package/src/users/utils.ts +55 -0
  209. package/src/utils/hashing.ts +14 -0
  210. package/src/utils/index.ts +3 -0
  211. package/src/utils/stringUtils.ts +8 -0
  212. package/src/utils/tests/utils.spec.ts +191 -0
  213. package/src/utils/utils.ts +239 -0
  214. package/tests/core/logging.ts +34 -0
  215. package/tests/core/utilities/index.ts +6 -0
  216. package/tests/core/utilities/jestUtils.ts +30 -0
  217. package/tests/core/utilities/mocks/alerts.ts +3 -0
  218. package/tests/core/utilities/mocks/date.ts +2 -0
  219. package/tests/core/utilities/mocks/events.ts +131 -0
  220. package/tests/core/utilities/mocks/fetch.ts +17 -0
  221. package/tests/core/utilities/mocks/index.ts +10 -0
  222. package/tests/core/utilities/mocks/licenses.ts +115 -0
  223. package/tests/core/utilities/mocks/posthog.ts +7 -0
  224. package/tests/core/utilities/structures/Chance.ts +20 -0
  225. package/tests/core/utilities/structures/accounts.ts +115 -0
  226. package/tests/core/utilities/structures/apps.ts +21 -0
  227. package/tests/core/utilities/structures/common.ts +7 -0
  228. package/tests/core/utilities/structures/db.ts +12 -0
  229. package/tests/core/utilities/structures/documents/index.ts +1 -0
  230. package/tests/core/utilities/structures/documents/platform/index.ts +1 -0
  231. package/tests/core/utilities/structures/documents/platform/installation.ts +12 -0
  232. package/tests/core/utilities/structures/generator.ts +2 -0
  233. package/tests/core/utilities/structures/index.ts +15 -0
  234. package/tests/core/utilities/structures/koa.ts +16 -0
  235. package/tests/core/utilities/structures/licenses.ts +167 -0
  236. package/tests/core/utilities/structures/plugins.ts +19 -0
  237. package/tests/core/utilities/structures/quotas.ts +67 -0
  238. package/tests/core/utilities/structures/scim.ts +80 -0
  239. package/tests/core/utilities/structures/shared.ts +19 -0
  240. package/tests/core/utilities/structures/sso.ts +119 -0
  241. package/tests/core/utilities/structures/tenants.ts +5 -0
  242. package/tests/core/utilities/structures/userGroups.ts +10 -0
  243. package/tests/core/utilities/structures/users.ts +73 -0
  244. package/tests/core/utilities/testContainerUtils.ts +85 -0
  245. package/tests/core/utilities/utils/index.ts +1 -0
  246. package/tests/core/utilities/utils/time.ts +3 -0
  247. package/tests/extra/DBTestConfiguration.ts +36 -0
  248. package/tests/extra/index.ts +2 -0
  249. package/tests/extra/testEnv.ts +95 -0
  250. package/tests/index.ts +1 -0
  251. package/tests/jestEnv.ts +6 -0
  252. package/tests/jestSetup.ts +28 -0
@@ -0,0 +1,71 @@
1
+ import env from "../../environment"
2
+ import * as objectStore from "../objectStore"
3
+ import * as context from "../../context"
4
+ import * as cloudfront from "../cloudfront"
5
+ import { Plugin } from "@budibase/types"
6
+
7
+ // URLS
8
+
9
+ export const enrichPluginURLs = (plugins: Plugin[]) => {
10
+ if (!plugins || !plugins.length) {
11
+ return []
12
+ }
13
+ return plugins.map(plugin => {
14
+ const jsUrl = getPluginJSUrl(plugin)
15
+ const iconUrl = getPluginIconUrl(plugin)
16
+ return { ...plugin, jsUrl, iconUrl }
17
+ })
18
+ }
19
+
20
+ const getPluginJSUrl = (plugin: Plugin) => {
21
+ const s3Key = getPluginJSKey(plugin)
22
+ return getPluginUrl(s3Key)
23
+ }
24
+
25
+ const getPluginIconUrl = (plugin: Plugin): string | undefined => {
26
+ const s3Key = getPluginIconKey(plugin)
27
+ if (!s3Key) {
28
+ return
29
+ }
30
+ return getPluginUrl(s3Key)
31
+ }
32
+
33
+ const getPluginUrl = (s3Key: string) => {
34
+ if (env.CLOUDFRONT_CDN) {
35
+ return cloudfront.getPresignedUrl(s3Key)
36
+ } else {
37
+ return objectStore.getPresignedUrl(env.PLUGIN_BUCKET_NAME, s3Key)
38
+ }
39
+ }
40
+
41
+ // S3 KEYS
42
+
43
+ export const getPluginJSKey = (plugin: Plugin) => {
44
+ return getPluginS3Key(plugin, "plugin.min.js")
45
+ }
46
+
47
+ export const getPluginIconKey = (plugin: Plugin) => {
48
+ // stored iconUrl is deprecated - hardcode to icon.svg in this case
49
+ const iconFileName = plugin.iconUrl ? "icon.svg" : plugin.iconFileName
50
+ if (!iconFileName) {
51
+ return
52
+ }
53
+ return getPluginS3Key(plugin, iconFileName)
54
+ }
55
+
56
+ const getPluginS3Key = (plugin: Plugin, fileName: string) => {
57
+ const s3Key = getPluginS3Dir(plugin.name)
58
+ return `${s3Key}/${fileName}`
59
+ }
60
+
61
+ export const getPluginS3Dir = (pluginName: string) => {
62
+ let s3Key = `${pluginName}`
63
+ if (env.MULTI_TENANCY) {
64
+ const tenantId = context.getTenantId()
65
+ s3Key = `${tenantId}/${s3Key}`
66
+ }
67
+ if (env.CLOUDFRONT_CDN) {
68
+ s3Key = `plugins/${s3Key}`
69
+ }
70
+ return s3Key
71
+ }
@@ -0,0 +1,171 @@
1
+ import * as app from "../app"
2
+ import { getAppFileUrl } from "../app"
3
+ import { testEnv } from "../../../../tests/extra"
4
+
5
+ describe("app", () => {
6
+ beforeEach(() => {
7
+ testEnv.nodeJest()
8
+ })
9
+
10
+ describe("clientLibraryUrl", () => {
11
+ function getClientUrl() {
12
+ return app.clientLibraryUrl("app_123/budibase-client.js", "2.0.0")
13
+ }
14
+
15
+ describe("single tenant", () => {
16
+ beforeAll(() => {
17
+ testEnv.singleTenant()
18
+ })
19
+
20
+ it("gets url in dev", () => {
21
+ testEnv.nodeDev()
22
+ const url = getClientUrl()
23
+ expect(url).toBe("/api/assets/client")
24
+ })
25
+
26
+ it("gets url with embedded minio", () => {
27
+ testEnv.withMinio()
28
+ const url = getClientUrl()
29
+ expect(url).toBe(
30
+ "/files/signed/prod-budi-app-assets/app_123/budibase-client.js/budibase-client.js"
31
+ )
32
+ })
33
+
34
+ it("gets url with custom S3", () => {
35
+ testEnv.withS3()
36
+ const url = getClientUrl()
37
+ expect(url).toBe(
38
+ "http://s3.example.com/prod-budi-app-assets/app_123/budibase-client.js/budibase-client.js"
39
+ )
40
+ })
41
+
42
+ it("gets url with cloudfront + s3", () => {
43
+ testEnv.withCloudfront()
44
+ const url = getClientUrl()
45
+ expect(url).toBe(
46
+ "http://cf.example.com/app_123/budibase-client.js/budibase-client.js?v=2.0.0"
47
+ )
48
+ })
49
+ })
50
+
51
+ describe("multi tenant", () => {
52
+ beforeAll(() => {
53
+ testEnv.multiTenant()
54
+ })
55
+
56
+ it("gets url in dev", async () => {
57
+ testEnv.nodeDev()
58
+ await testEnv.withTenant(tenantId => {
59
+ const url = getClientUrl()
60
+ expect(url).toBe("/api/assets/client")
61
+ })
62
+ })
63
+
64
+ it("gets url with embedded minio", async () => {
65
+ await testEnv.withTenant(tenantId => {
66
+ testEnv.withMinio()
67
+ const url = getClientUrl()
68
+ expect(url).toBe(
69
+ "/files/signed/prod-budi-app-assets/app_123/budibase-client.js/budibase-client.js"
70
+ )
71
+ })
72
+ })
73
+
74
+ it("gets url with custom S3", async () => {
75
+ await testEnv.withTenant(tenantId => {
76
+ testEnv.withS3()
77
+ const url = getClientUrl()
78
+ expect(url).toBe(
79
+ "http://s3.example.com/prod-budi-app-assets/app_123/budibase-client.js/budibase-client.js"
80
+ )
81
+ })
82
+ })
83
+
84
+ it("gets url with cloudfront + s3", async () => {
85
+ await testEnv.withTenant(tenantId => {
86
+ testEnv.withCloudfront()
87
+ const url = getClientUrl()
88
+ expect(url).toBe(
89
+ "http://cf.example.com/app_123/budibase-client.js/budibase-client.js?v=2.0.0"
90
+ )
91
+ })
92
+ })
93
+ })
94
+ })
95
+
96
+ describe("getAppFileUrl", () => {
97
+ function getAppFileUrl() {
98
+ return app.getAppFileUrl("app_123/attachments/image.jpeg")
99
+ }
100
+
101
+ describe("single tenant", () => {
102
+ beforeAll(() => {
103
+ testEnv.multiTenant()
104
+ })
105
+
106
+ it("gets url with embedded minio", () => {
107
+ testEnv.withMinio()
108
+ const url = getAppFileUrl()
109
+ expect(url).toBe(
110
+ "/files/signed/prod-budi-app-assets/app_123/attachments/image.jpeg"
111
+ )
112
+ })
113
+
114
+ it("gets url with custom S3", () => {
115
+ testEnv.withS3()
116
+ const url = getAppFileUrl()
117
+ expect(url).toBe(
118
+ "http://s3.example.com/prod-budi-app-assets/app_123/attachments/image.jpeg"
119
+ )
120
+ })
121
+
122
+ it("gets url with cloudfront + s3", () => {
123
+ testEnv.withCloudfront()
124
+ const url = getAppFileUrl()
125
+ // omit rest of signed params
126
+ expect(
127
+ url.includes("http://cf.example.com/app_123/attachments/image.jpeg?")
128
+ ).toBe(true)
129
+ })
130
+ })
131
+
132
+ describe("multi tenant", () => {
133
+ beforeAll(() => {
134
+ testEnv.multiTenant()
135
+ })
136
+
137
+ it("gets url with embedded minio", async () => {
138
+ testEnv.withMinio()
139
+ await testEnv.withTenant(tenantId => {
140
+ const url = getAppFileUrl()
141
+ expect(url).toBe(
142
+ "/files/signed/prod-budi-app-assets/app_123/attachments/image.jpeg"
143
+ )
144
+ })
145
+ })
146
+
147
+ it("gets url with custom S3", async () => {
148
+ testEnv.withS3()
149
+ await testEnv.withTenant(tenantId => {
150
+ const url = getAppFileUrl()
151
+ expect(url).toBe(
152
+ "http://s3.example.com/prod-budi-app-assets/app_123/attachments/image.jpeg"
153
+ )
154
+ })
155
+ })
156
+
157
+ it("gets url with cloudfront + s3", async () => {
158
+ testEnv.withCloudfront()
159
+ await testEnv.withTenant(tenantId => {
160
+ const url = getAppFileUrl()
161
+ // omit rest of signed params
162
+ expect(
163
+ url.includes(
164
+ "http://cf.example.com/app_123/attachments/image.jpeg?"
165
+ )
166
+ ).toBe(true)
167
+ })
168
+ })
169
+ })
170
+ })
171
+ })
@@ -0,0 +1,74 @@
1
+ import * as global from "../global"
2
+ import { testEnv } from "../../../../tests/extra"
3
+
4
+ describe("global", () => {
5
+ describe("getGlobalFileUrl", () => {
6
+ function getGlobalFileUrl() {
7
+ return global.getGlobalFileUrl("settings", "logoUrl", "etag")
8
+ }
9
+
10
+ describe("single tenant", () => {
11
+ beforeAll(() => {
12
+ testEnv.singleTenant()
13
+ })
14
+
15
+ it("gets url with embedded minio", () => {
16
+ testEnv.withMinio()
17
+ const url = getGlobalFileUrl()
18
+ expect(url).toBe("/files/signed/global/settings/logoUrl")
19
+ })
20
+
21
+ it("gets url with custom S3", () => {
22
+ testEnv.withS3()
23
+ const url = getGlobalFileUrl()
24
+ expect(url).toBe("http://s3.example.com/global/settings/logoUrl")
25
+ })
26
+
27
+ it("gets url with cloudfront + s3", () => {
28
+ testEnv.withCloudfront()
29
+ const url = getGlobalFileUrl()
30
+ // omit rest of signed params
31
+ expect(
32
+ url.includes("http://cf.example.com/settings/logoUrl?etag=etag&")
33
+ ).toBe(true)
34
+ })
35
+ })
36
+
37
+ describe("multi tenant", () => {
38
+ beforeAll(() => {
39
+ testEnv.multiTenant()
40
+ })
41
+
42
+ it("gets url with embedded minio", async () => {
43
+ testEnv.withMinio()
44
+ await testEnv.withTenant(tenantId => {
45
+ const url = getGlobalFileUrl()
46
+ expect(url).toBe(`/files/signed/global/${tenantId}/settings/logoUrl`)
47
+ })
48
+ })
49
+
50
+ it("gets url with custom S3", async () => {
51
+ testEnv.withS3()
52
+ await testEnv.withTenant(tenantId => {
53
+ const url = getGlobalFileUrl()
54
+ expect(url).toBe(
55
+ `http://s3.example.com/global/${tenantId}/settings/logoUrl`
56
+ )
57
+ })
58
+ })
59
+
60
+ it("gets url with cloudfront + s3", async () => {
61
+ testEnv.withCloudfront()
62
+ await testEnv.withTenant(tenantId => {
63
+ const url = getGlobalFileUrl()
64
+ // omit rest of signed params
65
+ expect(
66
+ url.includes(
67
+ `http://cf.example.com/${tenantId}/settings/logoUrl?etag=etag&`
68
+ )
69
+ ).toBe(true)
70
+ })
71
+ })
72
+ })
73
+ })
74
+ })
@@ -0,0 +1,111 @@
1
+ import * as plugins from "../plugins"
2
+ import { structures } from "../../../../tests"
3
+ import { testEnv } from "../../../../tests/extra"
4
+
5
+ describe("plugins", () => {
6
+ describe("enrichPluginURLs", () => {
7
+ const plugin = structures.plugins.plugin()
8
+
9
+ function getEnrichedPluginUrls() {
10
+ const enriched = plugins.enrichPluginURLs([plugin])[0]
11
+ return {
12
+ jsUrl: enriched.jsUrl!,
13
+ iconUrl: enriched.iconUrl!,
14
+ }
15
+ }
16
+
17
+ describe("single tenant", () => {
18
+ beforeAll(() => {
19
+ testEnv.singleTenant()
20
+ })
21
+
22
+ it("gets url with embedded minio", () => {
23
+ testEnv.withMinio()
24
+ const urls = getEnrichedPluginUrls()
25
+ expect(urls.jsUrl).toBe(
26
+ `/files/signed/plugins/${plugin.name}/plugin.min.js`
27
+ )
28
+ expect(urls.iconUrl).toBe(
29
+ `/files/signed/plugins/${plugin.name}/icon.svg`
30
+ )
31
+ })
32
+
33
+ it("gets url with custom S3", () => {
34
+ testEnv.withS3()
35
+ const urls = getEnrichedPluginUrls()
36
+ expect(urls.jsUrl).toBe(
37
+ `http://s3.example.com/plugins/${plugin.name}/plugin.min.js`
38
+ )
39
+ expect(urls.iconUrl).toBe(
40
+ `http://s3.example.com/plugins/${plugin.name}/icon.svg`
41
+ )
42
+ })
43
+
44
+ it("gets url with cloudfront + s3", () => {
45
+ testEnv.withCloudfront()
46
+ const urls = getEnrichedPluginUrls()
47
+ // omit rest of signed params
48
+ expect(
49
+ urls.jsUrl.includes(
50
+ `http://cf.example.com/plugins/${plugin.name}/plugin.min.js?`
51
+ )
52
+ ).toBe(true)
53
+ expect(
54
+ urls.iconUrl.includes(
55
+ `http://cf.example.com/plugins/${plugin.name}/icon.svg?`
56
+ )
57
+ ).toBe(true)
58
+ })
59
+ })
60
+
61
+ describe("multi tenant", () => {
62
+ beforeAll(() => {
63
+ testEnv.multiTenant()
64
+ })
65
+
66
+ it("gets url with embedded minio", async () => {
67
+ testEnv.withMinio()
68
+ await testEnv.withTenant(tenantId => {
69
+ const urls = getEnrichedPluginUrls()
70
+ expect(urls.jsUrl).toBe(
71
+ `/files/signed/plugins/${tenantId}/${plugin.name}/plugin.min.js`
72
+ )
73
+ expect(urls.iconUrl).toBe(
74
+ `/files/signed/plugins/${tenantId}/${plugin.name}/icon.svg`
75
+ )
76
+ })
77
+ })
78
+
79
+ it("gets url with custom S3", async () => {
80
+ testEnv.withS3()
81
+ await testEnv.withTenant(tenantId => {
82
+ const urls = getEnrichedPluginUrls()
83
+ expect(urls.jsUrl).toBe(
84
+ `http://s3.example.com/plugins/${tenantId}/${plugin.name}/plugin.min.js`
85
+ )
86
+ expect(urls.iconUrl).toBe(
87
+ `http://s3.example.com/plugins/${tenantId}/${plugin.name}/icon.svg`
88
+ )
89
+ })
90
+ })
91
+
92
+ it("gets url with cloudfront + s3", async () => {
93
+ testEnv.withCloudfront()
94
+ await testEnv.withTenant(tenantId => {
95
+ const urls = getEnrichedPluginUrls()
96
+ // omit rest of signed params
97
+ expect(
98
+ urls.jsUrl.includes(
99
+ `http://cf.example.com/plugins/${tenantId}/${plugin.name}/plugin.min.js?`
100
+ )
101
+ ).toBe(true)
102
+ expect(
103
+ urls.iconUrl.includes(
104
+ `http://cf.example.com/plugins/${tenantId}/${plugin.name}/icon.svg?`
105
+ )
106
+ ).toBe(true)
107
+ })
108
+ })
109
+ })
110
+ })
111
+ })
@@ -0,0 +1,41 @@
1
+ import env from "../environment"
2
+ const cfsign = require("aws-cloudfront-sign")
3
+
4
+ let PRIVATE_KEY: string | undefined
5
+
6
+ function getPrivateKey() {
7
+ if (!env.CLOUDFRONT_PRIVATE_KEY_64) {
8
+ throw new Error("CLOUDFRONT_PRIVATE_KEY_64 is not set")
9
+ }
10
+
11
+ if (PRIVATE_KEY) {
12
+ return PRIVATE_KEY
13
+ }
14
+
15
+ PRIVATE_KEY = Buffer.from(env.CLOUDFRONT_PRIVATE_KEY_64, "base64").toString(
16
+ "utf-8"
17
+ )
18
+
19
+ return PRIVATE_KEY
20
+ }
21
+
22
+ const getCloudfrontSignParams = () => {
23
+ return {
24
+ keypairId: env.CLOUDFRONT_PUBLIC_KEY_ID,
25
+ privateKeyString: getPrivateKey(),
26
+ expireTime: new Date().getTime() + 1000 * 60 * 60, // 1 hour
27
+ }
28
+ }
29
+
30
+ export const getPresignedUrl = (s3Key: string) => {
31
+ const url = getUrl(s3Key)
32
+ return cfsign.getSignedUrl(url, getCloudfrontSignParams())
33
+ }
34
+
35
+ export const getUrl = (s3Key: string) => {
36
+ let prefix = "/"
37
+ if (s3Key.startsWith("/")) {
38
+ prefix = ""
39
+ }
40
+ return `${env.CLOUDFRONT_CDN}${prefix}${s3Key}`
41
+ }
@@ -0,0 +1,3 @@
1
+ export * from "./objectStore"
2
+ export * from "./utils"
3
+ export * from "./buckets"