@budibase/backend-core 2.9.19 → 2.9.21-alpha.0

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 (250) hide show
  1. package/dist/index.js +266 -324
  2. package/dist/index.js.map +4 -4
  3. package/dist/index.js.meta.json +1 -1
  4. package/dist/package.json +19 -4
  5. package/dist/plugins.js +1 -1
  6. package/dist/plugins.js.map +1 -1
  7. package/dist/plugins.js.meta.json +1 -1
  8. package/dist/src/security/permissions.d.ts +1 -1
  9. package/dist/tests.js +222 -260
  10. package/dist/tests.js.map +4 -4
  11. package/dist/tests.js.meta.json +1 -1
  12. package/package.json +19 -4
  13. package/dist/tsconfig.build.tsbuildinfo +0 -1
  14. package/src/accounts/accounts.ts +0 -82
  15. package/src/accounts/api.ts +0 -59
  16. package/src/accounts/index.ts +0 -1
  17. package/src/auth/auth.ts +0 -208
  18. package/src/auth/index.ts +0 -1
  19. package/src/auth/tests/auth.spec.ts +0 -14
  20. package/src/blacklist/blacklist.ts +0 -54
  21. package/src/blacklist/index.ts +0 -1
  22. package/src/blacklist/tests/blacklist.spec.ts +0 -46
  23. package/src/cache/appMetadata.ts +0 -88
  24. package/src/cache/base/index.ts +0 -92
  25. package/src/cache/generic.ts +0 -30
  26. package/src/cache/index.ts +0 -5
  27. package/src/cache/tests/writethrough.spec.ts +0 -138
  28. package/src/cache/user.ts +0 -69
  29. package/src/cache/writethrough.ts +0 -133
  30. package/src/configs/configs.ts +0 -257
  31. package/src/configs/index.ts +0 -1
  32. package/src/configs/tests/configs.spec.ts +0 -184
  33. package/src/constants/db.ts +0 -63
  34. package/src/constants/index.ts +0 -2
  35. package/src/constants/misc.ts +0 -50
  36. package/src/context/Context.ts +0 -14
  37. package/src/context/identity.ts +0 -58
  38. package/src/context/index.ts +0 -3
  39. package/src/context/mainContext.ts +0 -310
  40. package/src/context/tests/index.spec.ts +0 -147
  41. package/src/context/types.ts +0 -11
  42. package/src/db/Replication.ts +0 -84
  43. package/src/db/constants.ts +0 -10
  44. package/src/db/couch/DatabaseImpl.ts +0 -238
  45. package/src/db/couch/connections.ts +0 -77
  46. package/src/db/couch/index.ts +0 -5
  47. package/src/db/couch/pouchDB.ts +0 -97
  48. package/src/db/couch/pouchDump.ts +0 -0
  49. package/src/db/couch/utils.ts +0 -50
  50. package/src/db/db.ts +0 -39
  51. package/src/db/errors.ts +0 -14
  52. package/src/db/index.ts +0 -12
  53. package/src/db/lucene.ts +0 -732
  54. package/src/db/searchIndexes/index.ts +0 -1
  55. package/src/db/searchIndexes/searchIndexes.ts +0 -62
  56. package/src/db/tests/index.spec.js +0 -25
  57. package/src/db/tests/lucene.spec.ts +0 -298
  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 -207
  61. package/src/db/views.ts +0 -241
  62. package/src/docIds/conversions.ts +0 -59
  63. package/src/docIds/ids.ts +0 -113
  64. package/src/docIds/index.ts +0 -2
  65. package/src/docIds/newid.ts +0 -5
  66. package/src/docIds/params.ts +0 -174
  67. package/src/docUpdates/index.ts +0 -29
  68. package/src/environment.ts +0 -201
  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 -40
  78. package/src/events/identification.ts +0 -310
  79. package/src/events/index.ts +0 -14
  80. package/src/events/processors/AnalyticsProcessor.ts +0 -64
  81. package/src/events/processors/AuditLogsProcessor.ts +0 -93
  82. package/src/events/processors/LoggingProcessor.ts +0 -37
  83. package/src/events/processors/Processors.ts +0 -52
  84. package/src/events/processors/async/DocumentUpdateProcessor.ts +0 -43
  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 -2
  88. package/src/events/processors/posthog/rateLimiting.ts +0 -106
  89. package/src/events/processors/posthog/tests/PosthogProcessor.spec.ts +0 -168
  90. package/src/events/processors/types.ts +0 -1
  91. package/src/events/publishers/account.ts +0 -35
  92. package/src/events/publishers/app.ts +0 -155
  93. package/src/events/publishers/auditLog.ts +0 -26
  94. package/src/events/publishers/auth.ts +0 -73
  95. package/src/events/publishers/automation.ts +0 -110
  96. package/src/events/publishers/backfill.ts +0 -74
  97. package/src/events/publishers/backup.ts +0 -42
  98. package/src/events/publishers/datasource.ts +0 -48
  99. package/src/events/publishers/email.ts +0 -17
  100. package/src/events/publishers/environmentVariable.ts +0 -38
  101. package/src/events/publishers/group.ts +0 -99
  102. package/src/events/publishers/index.ts +0 -24
  103. package/src/events/publishers/installation.ts +0 -38
  104. package/src/events/publishers/layout.ts +0 -26
  105. package/src/events/publishers/license.ts +0 -84
  106. package/src/events/publishers/org.ts +0 -37
  107. package/src/events/publishers/plugin.ts +0 -47
  108. package/src/events/publishers/query.ts +0 -88
  109. package/src/events/publishers/role.ts +0 -62
  110. package/src/events/publishers/rows.ts +0 -29
  111. package/src/events/publishers/screen.ts +0 -36
  112. package/src/events/publishers/serve.ts +0 -43
  113. package/src/events/publishers/table.ts +0 -70
  114. package/src/events/publishers/user.ts +0 -202
  115. package/src/events/publishers/view.ts +0 -107
  116. package/src/featureFlags/index.ts +0 -77
  117. package/src/featureFlags/tests/featureFlags.spec.ts +0 -85
  118. package/src/helpers.ts +0 -9
  119. package/src/index.ts +0 -53
  120. package/src/installation.ts +0 -107
  121. package/src/logging/alerts.ts +0 -26
  122. package/src/logging/correlation/correlation.ts +0 -13
  123. package/src/logging/correlation/index.ts +0 -1
  124. package/src/logging/correlation/middleware.ts +0 -17
  125. package/src/logging/index.ts +0 -4
  126. package/src/logging/pino/logger.ts +0 -232
  127. package/src/logging/pino/middleware.ts +0 -45
  128. package/src/logging/system.ts +0 -81
  129. package/src/logging/tests/system.spec.ts +0 -61
  130. package/src/middleware/adminOnly.ts +0 -9
  131. package/src/middleware/auditLog.ts +0 -6
  132. package/src/middleware/authenticated.ts +0 -193
  133. package/src/middleware/builderOnly.ts +0 -20
  134. package/src/middleware/builderOrAdmin.ts +0 -20
  135. package/src/middleware/csrf.ts +0 -81
  136. package/src/middleware/errorHandling.ts +0 -29
  137. package/src/middleware/index.ts +0 -21
  138. package/src/middleware/internalApi.ts +0 -23
  139. package/src/middleware/joi-validator.ts +0 -45
  140. package/src/middleware/matchers.ts +0 -47
  141. package/src/middleware/passport/datasource/google.ts +0 -95
  142. package/src/middleware/passport/local.ts +0 -54
  143. package/src/middleware/passport/sso/google.ts +0 -77
  144. package/src/middleware/passport/sso/oidc.ts +0 -154
  145. package/src/middleware/passport/sso/sso.ts +0 -165
  146. package/src/middleware/passport/sso/tests/google.spec.ts +0 -67
  147. package/src/middleware/passport/sso/tests/oidc.spec.ts +0 -152
  148. package/src/middleware/passport/sso/tests/sso.spec.ts +0 -197
  149. package/src/middleware/passport/utils.ts +0 -38
  150. package/src/middleware/querystringToBody.ts +0 -28
  151. package/src/middleware/tenancy.ts +0 -36
  152. package/src/middleware/tests/builder.spec.ts +0 -180
  153. package/src/middleware/tests/matchers.spec.ts +0 -134
  154. package/src/migrations/definitions.ts +0 -40
  155. package/src/migrations/index.ts +0 -2
  156. package/src/migrations/migrations.ts +0 -191
  157. package/src/migrations/tests/__snapshots__/migrations.spec.ts.snap +0 -11
  158. package/src/migrations/tests/migrations.spec.ts +0 -64
  159. package/src/objectStore/buckets/app.ts +0 -40
  160. package/src/objectStore/buckets/global.ts +0 -29
  161. package/src/objectStore/buckets/index.ts +0 -3
  162. package/src/objectStore/buckets/plugins.ts +0 -71
  163. package/src/objectStore/buckets/tests/app.spec.ts +0 -171
  164. package/src/objectStore/buckets/tests/global.spec.ts +0 -74
  165. package/src/objectStore/buckets/tests/plugins.spec.ts +0 -111
  166. package/src/objectStore/cloudfront.ts +0 -41
  167. package/src/objectStore/index.ts +0 -3
  168. package/src/objectStore/objectStore.ts +0 -440
  169. package/src/objectStore/utils.ts +0 -27
  170. package/src/platform/index.ts +0 -3
  171. package/src/platform/platformDb.ts +0 -6
  172. package/src/platform/tenants.ts +0 -101
  173. package/src/platform/tests/tenants.spec.ts +0 -26
  174. package/src/platform/users.ts +0 -90
  175. package/src/plugin/index.ts +0 -1
  176. package/src/plugin/tests/validation.spec.ts +0 -83
  177. package/src/plugin/utils.ts +0 -156
  178. package/src/queue/constants.ts +0 -6
  179. package/src/queue/inMemoryQueue.ts +0 -141
  180. package/src/queue/index.ts +0 -2
  181. package/src/queue/listeners.ts +0 -195
  182. package/src/queue/queue.ts +0 -54
  183. package/src/redis/index.ts +0 -6
  184. package/src/redis/init.ts +0 -86
  185. package/src/redis/redis.ts +0 -308
  186. package/src/redis/redlockImpl.ts +0 -139
  187. package/src/redis/utils.ts +0 -117
  188. package/src/security/encryption.ts +0 -179
  189. package/src/security/permissions.ts +0 -159
  190. package/src/security/roles.ts +0 -420
  191. package/src/security/sessions.ts +0 -120
  192. package/src/security/tests/encryption.spec.ts +0 -31
  193. package/src/security/tests/permissions.spec.ts +0 -145
  194. package/src/security/tests/sessions.spec.ts +0 -12
  195. package/src/tenancy/db.ts +0 -6
  196. package/src/tenancy/index.ts +0 -2
  197. package/src/tenancy/tenancy.ts +0 -140
  198. package/src/tenancy/tests/tenancy.spec.ts +0 -184
  199. package/src/timers/index.ts +0 -1
  200. package/src/timers/timers.ts +0 -22
  201. package/src/users/db.ts +0 -460
  202. package/src/users/events.ts +0 -176
  203. package/src/users/index.ts +0 -4
  204. package/src/users/lookup.ts +0 -102
  205. package/src/users/users.ts +0 -276
  206. package/src/users/utils.ts +0 -55
  207. package/src/utils/hashing.ts +0 -14
  208. package/src/utils/index.ts +0 -3
  209. package/src/utils/stringUtils.ts +0 -8
  210. package/src/utils/tests/utils.spec.ts +0 -191
  211. package/src/utils/utils.ts +0 -239
  212. package/tests/core/logging.ts +0 -34
  213. package/tests/core/utilities/index.ts +0 -6
  214. package/tests/core/utilities/jestUtils.ts +0 -30
  215. package/tests/core/utilities/mocks/alerts.ts +0 -3
  216. package/tests/core/utilities/mocks/date.ts +0 -2
  217. package/tests/core/utilities/mocks/events.ts +0 -131
  218. package/tests/core/utilities/mocks/fetch.ts +0 -17
  219. package/tests/core/utilities/mocks/index.ts +0 -10
  220. package/tests/core/utilities/mocks/licenses.ts +0 -107
  221. package/tests/core/utilities/mocks/posthog.ts +0 -7
  222. package/tests/core/utilities/structures/Chance.ts +0 -20
  223. package/tests/core/utilities/structures/accounts.ts +0 -115
  224. package/tests/core/utilities/structures/apps.ts +0 -21
  225. package/tests/core/utilities/structures/common.ts +0 -7
  226. package/tests/core/utilities/structures/db.ts +0 -12
  227. package/tests/core/utilities/structures/documents/index.ts +0 -1
  228. package/tests/core/utilities/structures/documents/platform/index.ts +0 -1
  229. package/tests/core/utilities/structures/documents/platform/installation.ts +0 -12
  230. package/tests/core/utilities/structures/generator.ts +0 -2
  231. package/tests/core/utilities/structures/index.ts +0 -15
  232. package/tests/core/utilities/structures/koa.ts +0 -16
  233. package/tests/core/utilities/structures/licenses.ts +0 -167
  234. package/tests/core/utilities/structures/plugins.ts +0 -19
  235. package/tests/core/utilities/structures/quotas.ts +0 -67
  236. package/tests/core/utilities/structures/scim.ts +0 -80
  237. package/tests/core/utilities/structures/shared.ts +0 -19
  238. package/tests/core/utilities/structures/sso.ts +0 -119
  239. package/tests/core/utilities/structures/tenants.ts +0 -5
  240. package/tests/core/utilities/structures/userGroups.ts +0 -10
  241. package/tests/core/utilities/structures/users.ts +0 -73
  242. package/tests/core/utilities/testContainerUtils.ts +0 -98
  243. package/tests/core/utilities/utils/index.ts +0 -1
  244. package/tests/core/utilities/utils/time.ts +0 -3
  245. package/tests/extra/DBTestConfiguration.ts +0 -36
  246. package/tests/extra/index.ts +0 -2
  247. package/tests/extra/testEnv.ts +0 -95
  248. package/tests/index.ts +0 -1
  249. package/tests/jestEnv.ts +0 -6
  250. package/tests/jestSetup.ts +0 -28
@@ -1,59 +0,0 @@
1
- import fetch from "node-fetch"
2
- import * as logging from "../logging"
3
-
4
- export default class API {
5
- host: string
6
-
7
- constructor(host: string) {
8
- this.host = host
9
- }
10
-
11
- async apiCall(method: string, url: string, options?: any) {
12
- if (!options.headers) {
13
- options.headers = {}
14
- }
15
-
16
- if (!options.headers["Content-Type"]) {
17
- options.headers = {
18
- "Content-Type": "application/json",
19
- Accept: "application/json",
20
- ...options.headers,
21
- }
22
- }
23
-
24
- let json = options.headers["Content-Type"] === "application/json"
25
-
26
- // add x-budibase-correlation-id header
27
- logging.correlation.setHeader(options.headers)
28
-
29
- const requestOptions = {
30
- method: method,
31
- body: json ? JSON.stringify(options.body) : options.body,
32
- headers: options.headers,
33
- // TODO: See if this is necessary
34
- credentials: "include",
35
- }
36
-
37
- return await fetch(`${this.host}${url}`, requestOptions)
38
- }
39
-
40
- async post(url: string, options?: any) {
41
- return this.apiCall("POST", url, options)
42
- }
43
-
44
- async get(url: string, options?: any) {
45
- return this.apiCall("GET", url, options)
46
- }
47
-
48
- async patch(url: string, options?: any) {
49
- return this.apiCall("PATCH", url, options)
50
- }
51
-
52
- async del(url: string, options?: any) {
53
- return this.apiCall("DELETE", url, options)
54
- }
55
-
56
- async put(url: string, options?: any) {
57
- return this.apiCall("PUT", url, options)
58
- }
59
- }
@@ -1 +0,0 @@
1
- export * from "./accounts"
package/src/auth/auth.ts DELETED
@@ -1,208 +0,0 @@
1
- const _passport = require("koa-passport")
2
- const LocalStrategy = require("passport-local").Strategy
3
- import { getGlobalDB } from "../context"
4
- import { Cookie } from "../constants"
5
- import { getSessionsForUser, invalidateSessions } from "../security/sessions"
6
- import {
7
- authenticated,
8
- csrf,
9
- google,
10
- local,
11
- oidc,
12
- tenancy,
13
- } from "../middleware"
14
- import * as userCache from "../cache/user"
15
- import { invalidateUser } from "../cache/user"
16
- import {
17
- ConfigType,
18
- GoogleInnerConfig,
19
- OIDCInnerConfig,
20
- PlatformLogoutOpts,
21
- SSOProviderType,
22
- } from "@budibase/types"
23
- import * as events from "../events"
24
- import * as configs from "../configs"
25
- import { clearCookie, getCookie } from "../utils"
26
- import { ssoSaveUserNoOp } from "../middleware/passport/sso/sso"
27
-
28
- const refresh = require("passport-oauth2-refresh")
29
- export {
30
- auditLog,
31
- authError,
32
- internalApi,
33
- ssoCallbackUrl,
34
- adminOnly,
35
- builderOnly,
36
- builderOrAdmin,
37
- joiValidator,
38
- google,
39
- oidc,
40
- } from "../middleware"
41
- export const buildAuthMiddleware = authenticated
42
- export const buildTenancyMiddleware = tenancy
43
- export const buildCsrfMiddleware = csrf
44
- export const passport = _passport
45
- export const jwt = require("jsonwebtoken")
46
-
47
- // Strategies
48
- _passport.use(new LocalStrategy(local.options, local.authenticate))
49
-
50
- async function refreshOIDCAccessToken(
51
- chosenConfig: OIDCInnerConfig,
52
- refreshToken: string
53
- ): Promise<RefreshResponse> {
54
- const callbackUrl = await oidc.getCallbackUrl()
55
- let enrichedConfig: any
56
- let strategy: any
57
-
58
- try {
59
- enrichedConfig = await oidc.fetchStrategyConfig(chosenConfig, callbackUrl)
60
- if (!enrichedConfig) {
61
- throw new Error("OIDC Config contents invalid")
62
- }
63
- strategy = await oidc.strategyFactory(enrichedConfig, ssoSaveUserNoOp)
64
- } catch (err) {
65
- console.error(err)
66
- throw new Error("Could not refresh OAuth Token")
67
- }
68
-
69
- refresh.use(strategy, {
70
- setRefreshOAuth2() {
71
- return strategy._getOAuth2Client(enrichedConfig)
72
- },
73
- })
74
-
75
- return new Promise(resolve => {
76
- refresh.requestNewAccessToken(
77
- ConfigType.OIDC,
78
- refreshToken,
79
- (err: any, accessToken: string, refreshToken: any, params: any) => {
80
- resolve({ err, accessToken, refreshToken, params })
81
- }
82
- )
83
- })
84
- }
85
-
86
- async function refreshGoogleAccessToken(
87
- config: GoogleInnerConfig,
88
- refreshToken: any
89
- ): Promise<RefreshResponse> {
90
- let callbackUrl = await google.getCallbackUrl(config)
91
-
92
- let strategy
93
- try {
94
- strategy = await google.strategyFactory(
95
- config,
96
- callbackUrl,
97
- ssoSaveUserNoOp
98
- )
99
- } catch (err: any) {
100
- console.error(err)
101
- throw new Error(
102
- `Error constructing OIDC refresh strategy: message=${err.message}`
103
- )
104
- }
105
-
106
- refresh.use(strategy)
107
-
108
- return new Promise(resolve => {
109
- refresh.requestNewAccessToken(
110
- ConfigType.GOOGLE,
111
- refreshToken,
112
- (err: any, accessToken: string, refreshToken: string, params: any) => {
113
- resolve({ err, accessToken, refreshToken, params })
114
- }
115
- )
116
- })
117
- }
118
-
119
- interface RefreshResponse {
120
- err?: {
121
- data?: string
122
- }
123
- accessToken?: string
124
- refreshToken?: string
125
- params?: any
126
- }
127
-
128
- export async function refreshOAuthToken(
129
- refreshToken: string,
130
- providerType: SSOProviderType,
131
- configId?: string
132
- ): Promise<RefreshResponse> {
133
- switch (providerType) {
134
- case SSOProviderType.OIDC:
135
- if (!configId) {
136
- return { err: { data: "OIDC config id not provided" } }
137
- }
138
- const oidcConfig = await configs.getOIDCConfigById(configId)
139
- if (!oidcConfig) {
140
- return { err: { data: "OIDC configuration not found" } }
141
- }
142
- return refreshOIDCAccessToken(oidcConfig, refreshToken)
143
- case SSOProviderType.GOOGLE:
144
- let googleConfig = await configs.getGoogleConfig()
145
- if (!googleConfig) {
146
- return { err: { data: "Google configuration not found" } }
147
- }
148
- return refreshGoogleAccessToken(googleConfig, refreshToken)
149
- }
150
- }
151
-
152
- // TODO: Refactor to use user save function instead to prevent the need for
153
- // manually saving and invalidating on callback
154
- export async function updateUserOAuth(userId: string, oAuthConfig: any) {
155
- const details = {
156
- accessToken: oAuthConfig.accessToken,
157
- refreshToken: oAuthConfig.refreshToken,
158
- }
159
-
160
- try {
161
- const db = getGlobalDB()
162
- const dbUser = await db.get<any>(userId)
163
-
164
- //Do not overwrite the refresh token if a valid one is not provided.
165
- if (typeof details.refreshToken !== "string") {
166
- delete details.refreshToken
167
- }
168
-
169
- dbUser.oauth2 = {
170
- ...dbUser.oauth2,
171
- ...details,
172
- }
173
-
174
- await db.put(dbUser)
175
-
176
- await invalidateUser(userId)
177
- } catch (e) {
178
- console.error("Could not update OAuth details for current user", e)
179
- }
180
- }
181
-
182
- /**
183
- * Logs a user out from budibase. Re-used across account portal and builder.
184
- */
185
- export async function platformLogout(opts: PlatformLogoutOpts) {
186
- const ctx = opts.ctx
187
- const userId = opts.userId
188
- const keepActiveSession = opts.keepActiveSession
189
-
190
- if (!ctx) throw new Error("Koa context must be supplied to logout.")
191
-
192
- const currentSession = getCookie(ctx, Cookie.Auth)
193
- let sessions = await getSessionsForUser(userId)
194
-
195
- if (keepActiveSession) {
196
- sessions = sessions.filter(
197
- session => session.sessionId !== currentSession.sessionId
198
- )
199
- } else {
200
- // clear cookies
201
- clearCookie(ctx, Cookie.Auth)
202
- }
203
-
204
- const sessionIds = sessions.map(({ sessionId }) => sessionId)
205
- await invalidateSessions(userId, { sessionIds, reason: "logout" })
206
- await events.auth.logout(ctx.user?.email)
207
- await userCache.invalidateUser(userId)
208
- }
package/src/auth/index.ts DELETED
@@ -1 +0,0 @@
1
- export * from "./auth"
@@ -1,14 +0,0 @@
1
- import { structures } from "../../../tests"
2
- import { testEnv } from "../../../tests/extra"
3
- import * as auth from "../auth"
4
- import * as events from "../../events"
5
-
6
- describe("platformLogout", () => {
7
- it("should call platform logout", async () => {
8
- await testEnv.withTenant(async () => {
9
- const ctx = structures.koa.newContext()
10
- await auth.platformLogout({ ctx, userId: "test" })
11
- expect(events.auth.logout).toBeCalledTimes(1)
12
- })
13
- })
14
- })
@@ -1,54 +0,0 @@
1
- import dns from "dns"
2
- import net from "net"
3
- import env from "../environment"
4
- import { promisify } from "util"
5
-
6
- let blackListArray: string[] | undefined
7
- const performLookup = promisify(dns.lookup)
8
-
9
- async function lookup(address: string): Promise<string[]> {
10
- if (!net.isIP(address)) {
11
- // need this for URL parsing simply
12
- if (!address.startsWith("http")) {
13
- address = `https://${address}`
14
- }
15
- address = new URL(address).hostname
16
- }
17
- const addresses = await performLookup(address, {
18
- all: true,
19
- })
20
- return addresses.map(addr => addr.address)
21
- }
22
-
23
- export async function refreshBlacklist() {
24
- const blacklist = env.BLACKLIST_IPS
25
- const list = blacklist?.split(",") || []
26
- let final: string[] = []
27
- for (let addr of list) {
28
- const trimmed = addr.trim()
29
- if (!net.isIP(trimmed)) {
30
- const addresses = await lookup(trimmed)
31
- final = final.concat(addresses)
32
- } else {
33
- final.push(trimmed)
34
- }
35
- }
36
- blackListArray = final
37
- }
38
-
39
- export async function isBlacklisted(address: string): Promise<boolean> {
40
- if (!blackListArray) {
41
- await refreshBlacklist()
42
- }
43
- if (blackListArray?.length === 0) {
44
- return false
45
- }
46
- // no need for DNS
47
- let ips: string[]
48
- if (!net.isIP(address)) {
49
- ips = await lookup(address)
50
- } else {
51
- ips = [address]
52
- }
53
- return !!blackListArray?.find(addr => ips.includes(addr))
54
- }
@@ -1 +0,0 @@
1
- export * from "./blacklist"
@@ -1,46 +0,0 @@
1
- import { refreshBlacklist, isBlacklisted } from ".."
2
- import env from "../../environment"
3
-
4
- describe("blacklist", () => {
5
- beforeAll(async () => {
6
- env._set(
7
- "BLACKLIST_IPS",
8
- "www.google.com,192.168.1.1, 1.1.1.1,2.2.2.2/something"
9
- )
10
- await refreshBlacklist()
11
- })
12
-
13
- it("should blacklist 192.168.1.1", async () => {
14
- expect(await isBlacklisted("192.168.1.1")).toBe(true)
15
- })
16
-
17
- it("should allow 192.168.1.2", async () => {
18
- expect(await isBlacklisted("192.168.1.2")).toBe(false)
19
- })
20
-
21
- it("should blacklist www.google.com", async () => {
22
- expect(await isBlacklisted("www.google.com")).toBe(true)
23
- })
24
-
25
- it("should handle a complex domain", async () => {
26
- expect(
27
- await isBlacklisted("https://www.google.com/derp/?something=1")
28
- ).toBe(true)
29
- })
30
-
31
- it("should allow www.microsoft.com", async () => {
32
- expect(await isBlacklisted("www.microsoft.com")).toBe(false)
33
- })
34
-
35
- it("should blacklist an IP that needed trimming", async () => {
36
- expect(await isBlacklisted("1.1.1.1")).toBe(true)
37
- })
38
-
39
- it("should blacklist 1.1.1.1/something", async () => {
40
- expect(await isBlacklisted("1.1.1.1/something")).toBe(true)
41
- })
42
-
43
- it("should blacklist 2.2.2.2", async () => {
44
- expect(await isBlacklisted("2.2.2.2")).toBe(true)
45
- })
46
- })
@@ -1,88 +0,0 @@
1
- import { getAppClient } from "../redis/init"
2
- import { doWithDB, DocumentType } from "../db"
3
- import { Database, App } from "@budibase/types"
4
-
5
- export enum AppState {
6
- INVALID = "invalid",
7
- }
8
-
9
- export interface DeletedApp {
10
- state: AppState
11
- }
12
-
13
- const EXPIRY_SECONDS = 3600
14
-
15
- /**
16
- * The default populate app metadata function
17
- */
18
- async function populateFromDB(appId: string) {
19
- return doWithDB(
20
- appId,
21
- (db: Database) => {
22
- return db.get(DocumentType.APP_METADATA)
23
- },
24
- { skip_setup: true }
25
- )
26
- }
27
-
28
- function isInvalid(metadata?: { state: string }) {
29
- return !metadata || metadata.state === AppState.INVALID
30
- }
31
-
32
- /**
33
- * Get the requested app metadata by id.
34
- * Use redis cache to first read the app metadata.
35
- * If not present fallback to loading the app metadata directly and re-caching.
36
- * @param {string} appId the id of the app to get metadata from.
37
- * @returns {object} the app metadata.
38
- */
39
- export async function getAppMetadata(appId: string): Promise<App | DeletedApp> {
40
- const client = await getAppClient()
41
- // try cache
42
- let metadata = await client.get(appId)
43
- if (!metadata) {
44
- let expiry: number | undefined = EXPIRY_SECONDS
45
- try {
46
- metadata = await populateFromDB(appId)
47
- } catch (err: any) {
48
- // app DB left around, but no metadata, it is invalid
49
- if (err && err.status === 404) {
50
- metadata = { state: AppState.INVALID }
51
- // don't expire the reference to an invalid app, it'll only be
52
- // updated if a metadata doc actually gets stored (app is remade/reverted)
53
- expiry = undefined
54
- } else {
55
- throw err
56
- }
57
- }
58
- // needed for cypress/some scenarios where the caching happens
59
- // so quickly the requests can get slightly out of sync
60
- // might store its invalid just before it stores its valid
61
- if (isInvalid(metadata)) {
62
- const temp = await client.get(appId)
63
- if (temp) {
64
- metadata = temp
65
- }
66
- }
67
- await client.store(appId, metadata, expiry)
68
- }
69
-
70
- return metadata
71
- }
72
-
73
- /**
74
- * Invalidate/reset the cached metadata when a change occurs in the db.
75
- * @param appId {string} the cache key to bust/update.
76
- * @param newMetadata {object|undefined} optional - can simply provide the new metadata to update with.
77
- * @return {Promise<void>} will respond with success when cache is updated.
78
- */
79
- export async function invalidateAppMetadata(appId: string, newMetadata?: any) {
80
- if (!appId) {
81
- throw "Cannot invalidate if no app ID provided."
82
- }
83
- const client = await getAppClient()
84
- await client.delete(appId)
85
- if (newMetadata) {
86
- await client.store(appId, newMetadata, EXPIRY_SECONDS)
87
- }
88
- }
@@ -1,92 +0,0 @@
1
- import { getTenantId } from "../../context"
2
- import * as redis from "../../redis/init"
3
- import { Client } from "../../redis"
4
-
5
- function generateTenantKey(key: string) {
6
- const tenantId = getTenantId()
7
- return `${key}:${tenantId}`
8
- }
9
-
10
- export default class BaseCache {
11
- client: Client | undefined
12
-
13
- constructor(client: Client | undefined = undefined) {
14
- this.client = client
15
- }
16
-
17
- async getClient() {
18
- return !this.client ? await redis.getCacheClient() : this.client
19
- }
20
-
21
- async keys(pattern: string) {
22
- const client = await this.getClient()
23
- return client.keys(pattern)
24
- }
25
-
26
- /**
27
- * Read only from the cache.
28
- */
29
- async get(key: string, opts = { useTenancy: true }) {
30
- key = opts.useTenancy ? generateTenantKey(key) : key
31
- const client = await this.getClient()
32
- return client.get(key)
33
- }
34
-
35
- /**
36
- * Write to the cache.
37
- */
38
- async store(
39
- key: string,
40
- value: any,
41
- ttl: number | null = null,
42
- opts = { useTenancy: true }
43
- ) {
44
- key = opts.useTenancy ? generateTenantKey(key) : key
45
- const client = await this.getClient()
46
- await client.store(key, value, ttl)
47
- }
48
-
49
- /**
50
- * Remove from cache.
51
- */
52
- async delete(key: string, opts = { useTenancy: true }) {
53
- key = opts.useTenancy ? generateTenantKey(key) : key
54
- const client = await this.getClient()
55
- return client.delete(key)
56
- }
57
-
58
- /**
59
- * Read from the cache. Write to the cache if not exists.
60
- */
61
- async withCache(
62
- key: string,
63
- ttl: number,
64
- fetchFn: any,
65
- opts = { useTenancy: true }
66
- ) {
67
- const cachedValue = await this.get(key, opts)
68
- if (cachedValue) {
69
- return cachedValue
70
- }
71
-
72
- try {
73
- const fetchedValue = await fetchFn()
74
-
75
- await this.store(key, fetchedValue, ttl, opts)
76
- return fetchedValue
77
- } catch (err) {
78
- console.error("Error fetching before cache - ", err)
79
- throw err
80
- }
81
- }
82
-
83
- async bustCache(key: string, opts = { client: null }) {
84
- const client = await this.getClient()
85
- try {
86
- await client.delete(generateTenantKey(key))
87
- } catch (err) {
88
- console.error("Error busting cache - ", err)
89
- throw err
90
- }
91
- }
92
- }
@@ -1,30 +0,0 @@
1
- const BaseCache = require("./base")
2
-
3
- const GENERIC = new BaseCache.default()
4
-
5
- export enum CacheKey {
6
- CHECKLIST = "checklist",
7
- INSTALLATION = "installation",
8
- ANALYTICS_ENABLED = "analyticsEnabled",
9
- UNIQUE_TENANT_ID = "uniqueTenantId",
10
- EVENTS = "events",
11
- BACKFILL_METADATA = "backfillMetadata",
12
- EVENTS_RATE_LIMIT = "eventsRateLimit",
13
- }
14
-
15
- export enum TTL {
16
- ONE_MINUTE = 600,
17
- ONE_HOUR = 3600,
18
- ONE_DAY = 86400,
19
- }
20
-
21
- function performExport(funcName: string) {
22
- return (...args: any) => GENERIC[funcName](...args)
23
- }
24
-
25
- export const keys = performExport("keys")
26
- export const get = performExport("get")
27
- export const store = performExport("store")
28
- export const destroy = performExport("delete")
29
- export const withCache = performExport("withCache")
30
- export const bustCache = performExport("bustCache")
@@ -1,5 +0,0 @@
1
- export * as generic from "./generic"
2
- export * as user from "./user"
3
- export * as app from "./appMetadata"
4
- export * as writethrough from "./writethrough"
5
- export * from "./generic"