@budibase/backend-core 2.9.19 → 2.9.20

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 (241) hide show
  1. package/dist/package.json +19 -4
  2. package/dist/src/security/permissions.d.ts +1 -1
  3. package/package.json +19 -4
  4. package/dist/tsconfig.build.tsbuildinfo +0 -1
  5. package/src/accounts/accounts.ts +0 -82
  6. package/src/accounts/api.ts +0 -59
  7. package/src/accounts/index.ts +0 -1
  8. package/src/auth/auth.ts +0 -208
  9. package/src/auth/index.ts +0 -1
  10. package/src/auth/tests/auth.spec.ts +0 -14
  11. package/src/blacklist/blacklist.ts +0 -54
  12. package/src/blacklist/index.ts +0 -1
  13. package/src/blacklist/tests/blacklist.spec.ts +0 -46
  14. package/src/cache/appMetadata.ts +0 -88
  15. package/src/cache/base/index.ts +0 -92
  16. package/src/cache/generic.ts +0 -30
  17. package/src/cache/index.ts +0 -5
  18. package/src/cache/tests/writethrough.spec.ts +0 -138
  19. package/src/cache/user.ts +0 -69
  20. package/src/cache/writethrough.ts +0 -133
  21. package/src/configs/configs.ts +0 -257
  22. package/src/configs/index.ts +0 -1
  23. package/src/configs/tests/configs.spec.ts +0 -184
  24. package/src/constants/db.ts +0 -63
  25. package/src/constants/index.ts +0 -2
  26. package/src/constants/misc.ts +0 -50
  27. package/src/context/Context.ts +0 -14
  28. package/src/context/identity.ts +0 -58
  29. package/src/context/index.ts +0 -3
  30. package/src/context/mainContext.ts +0 -310
  31. package/src/context/tests/index.spec.ts +0 -147
  32. package/src/context/types.ts +0 -11
  33. package/src/db/Replication.ts +0 -84
  34. package/src/db/constants.ts +0 -10
  35. package/src/db/couch/DatabaseImpl.ts +0 -238
  36. package/src/db/couch/connections.ts +0 -77
  37. package/src/db/couch/index.ts +0 -5
  38. package/src/db/couch/pouchDB.ts +0 -97
  39. package/src/db/couch/pouchDump.ts +0 -0
  40. package/src/db/couch/utils.ts +0 -50
  41. package/src/db/db.ts +0 -39
  42. package/src/db/errors.ts +0 -14
  43. package/src/db/index.ts +0 -12
  44. package/src/db/lucene.ts +0 -732
  45. package/src/db/searchIndexes/index.ts +0 -1
  46. package/src/db/searchIndexes/searchIndexes.ts +0 -62
  47. package/src/db/tests/index.spec.js +0 -25
  48. package/src/db/tests/lucene.spec.ts +0 -298
  49. package/src/db/tests/pouch.spec.js +0 -62
  50. package/src/db/tests/utils.spec.ts +0 -63
  51. package/src/db/utils.ts +0 -207
  52. package/src/db/views.ts +0 -241
  53. package/src/docIds/conversions.ts +0 -59
  54. package/src/docIds/ids.ts +0 -113
  55. package/src/docIds/index.ts +0 -2
  56. package/src/docIds/newid.ts +0 -5
  57. package/src/docIds/params.ts +0 -174
  58. package/src/docUpdates/index.ts +0 -29
  59. package/src/environment.ts +0 -201
  60. package/src/errors/errors.ts +0 -119
  61. package/src/errors/index.ts +0 -1
  62. package/src/events/analytics.ts +0 -6
  63. package/src/events/asyncEvents/index.ts +0 -2
  64. package/src/events/asyncEvents/publisher.ts +0 -12
  65. package/src/events/asyncEvents/queue.ts +0 -22
  66. package/src/events/backfill.ts +0 -183
  67. package/src/events/documentId.ts +0 -56
  68. package/src/events/events.ts +0 -40
  69. package/src/events/identification.ts +0 -310
  70. package/src/events/index.ts +0 -14
  71. package/src/events/processors/AnalyticsProcessor.ts +0 -64
  72. package/src/events/processors/AuditLogsProcessor.ts +0 -93
  73. package/src/events/processors/LoggingProcessor.ts +0 -37
  74. package/src/events/processors/Processors.ts +0 -52
  75. package/src/events/processors/async/DocumentUpdateProcessor.ts +0 -43
  76. package/src/events/processors/index.ts +0 -19
  77. package/src/events/processors/posthog/PosthogProcessor.ts +0 -118
  78. package/src/events/processors/posthog/index.ts +0 -2
  79. package/src/events/processors/posthog/rateLimiting.ts +0 -106
  80. package/src/events/processors/posthog/tests/PosthogProcessor.spec.ts +0 -168
  81. package/src/events/processors/types.ts +0 -1
  82. package/src/events/publishers/account.ts +0 -35
  83. package/src/events/publishers/app.ts +0 -155
  84. package/src/events/publishers/auditLog.ts +0 -26
  85. package/src/events/publishers/auth.ts +0 -73
  86. package/src/events/publishers/automation.ts +0 -110
  87. package/src/events/publishers/backfill.ts +0 -74
  88. package/src/events/publishers/backup.ts +0 -42
  89. package/src/events/publishers/datasource.ts +0 -48
  90. package/src/events/publishers/email.ts +0 -17
  91. package/src/events/publishers/environmentVariable.ts +0 -38
  92. package/src/events/publishers/group.ts +0 -99
  93. package/src/events/publishers/index.ts +0 -24
  94. package/src/events/publishers/installation.ts +0 -38
  95. package/src/events/publishers/layout.ts +0 -26
  96. package/src/events/publishers/license.ts +0 -84
  97. package/src/events/publishers/org.ts +0 -37
  98. package/src/events/publishers/plugin.ts +0 -47
  99. package/src/events/publishers/query.ts +0 -88
  100. package/src/events/publishers/role.ts +0 -62
  101. package/src/events/publishers/rows.ts +0 -29
  102. package/src/events/publishers/screen.ts +0 -36
  103. package/src/events/publishers/serve.ts +0 -43
  104. package/src/events/publishers/table.ts +0 -70
  105. package/src/events/publishers/user.ts +0 -202
  106. package/src/events/publishers/view.ts +0 -107
  107. package/src/featureFlags/index.ts +0 -77
  108. package/src/featureFlags/tests/featureFlags.spec.ts +0 -85
  109. package/src/helpers.ts +0 -9
  110. package/src/index.ts +0 -53
  111. package/src/installation.ts +0 -107
  112. package/src/logging/alerts.ts +0 -26
  113. package/src/logging/correlation/correlation.ts +0 -13
  114. package/src/logging/correlation/index.ts +0 -1
  115. package/src/logging/correlation/middleware.ts +0 -17
  116. package/src/logging/index.ts +0 -4
  117. package/src/logging/pino/logger.ts +0 -232
  118. package/src/logging/pino/middleware.ts +0 -45
  119. package/src/logging/system.ts +0 -81
  120. package/src/logging/tests/system.spec.ts +0 -61
  121. package/src/middleware/adminOnly.ts +0 -9
  122. package/src/middleware/auditLog.ts +0 -6
  123. package/src/middleware/authenticated.ts +0 -193
  124. package/src/middleware/builderOnly.ts +0 -20
  125. package/src/middleware/builderOrAdmin.ts +0 -20
  126. package/src/middleware/csrf.ts +0 -81
  127. package/src/middleware/errorHandling.ts +0 -29
  128. package/src/middleware/index.ts +0 -21
  129. package/src/middleware/internalApi.ts +0 -23
  130. package/src/middleware/joi-validator.ts +0 -45
  131. package/src/middleware/matchers.ts +0 -47
  132. package/src/middleware/passport/datasource/google.ts +0 -95
  133. package/src/middleware/passport/local.ts +0 -54
  134. package/src/middleware/passport/sso/google.ts +0 -77
  135. package/src/middleware/passport/sso/oidc.ts +0 -154
  136. package/src/middleware/passport/sso/sso.ts +0 -165
  137. package/src/middleware/passport/sso/tests/google.spec.ts +0 -67
  138. package/src/middleware/passport/sso/tests/oidc.spec.ts +0 -152
  139. package/src/middleware/passport/sso/tests/sso.spec.ts +0 -197
  140. package/src/middleware/passport/utils.ts +0 -38
  141. package/src/middleware/querystringToBody.ts +0 -28
  142. package/src/middleware/tenancy.ts +0 -36
  143. package/src/middleware/tests/builder.spec.ts +0 -180
  144. package/src/middleware/tests/matchers.spec.ts +0 -134
  145. package/src/migrations/definitions.ts +0 -40
  146. package/src/migrations/index.ts +0 -2
  147. package/src/migrations/migrations.ts +0 -191
  148. package/src/migrations/tests/__snapshots__/migrations.spec.ts.snap +0 -11
  149. package/src/migrations/tests/migrations.spec.ts +0 -64
  150. package/src/objectStore/buckets/app.ts +0 -40
  151. package/src/objectStore/buckets/global.ts +0 -29
  152. package/src/objectStore/buckets/index.ts +0 -3
  153. package/src/objectStore/buckets/plugins.ts +0 -71
  154. package/src/objectStore/buckets/tests/app.spec.ts +0 -171
  155. package/src/objectStore/buckets/tests/global.spec.ts +0 -74
  156. package/src/objectStore/buckets/tests/plugins.spec.ts +0 -111
  157. package/src/objectStore/cloudfront.ts +0 -41
  158. package/src/objectStore/index.ts +0 -3
  159. package/src/objectStore/objectStore.ts +0 -440
  160. package/src/objectStore/utils.ts +0 -27
  161. package/src/platform/index.ts +0 -3
  162. package/src/platform/platformDb.ts +0 -6
  163. package/src/platform/tenants.ts +0 -101
  164. package/src/platform/tests/tenants.spec.ts +0 -26
  165. package/src/platform/users.ts +0 -90
  166. package/src/plugin/index.ts +0 -1
  167. package/src/plugin/tests/validation.spec.ts +0 -83
  168. package/src/plugin/utils.ts +0 -156
  169. package/src/queue/constants.ts +0 -6
  170. package/src/queue/inMemoryQueue.ts +0 -141
  171. package/src/queue/index.ts +0 -2
  172. package/src/queue/listeners.ts +0 -195
  173. package/src/queue/queue.ts +0 -54
  174. package/src/redis/index.ts +0 -6
  175. package/src/redis/init.ts +0 -86
  176. package/src/redis/redis.ts +0 -308
  177. package/src/redis/redlockImpl.ts +0 -139
  178. package/src/redis/utils.ts +0 -117
  179. package/src/security/encryption.ts +0 -179
  180. package/src/security/permissions.ts +0 -159
  181. package/src/security/roles.ts +0 -420
  182. package/src/security/sessions.ts +0 -120
  183. package/src/security/tests/encryption.spec.ts +0 -31
  184. package/src/security/tests/permissions.spec.ts +0 -145
  185. package/src/security/tests/sessions.spec.ts +0 -12
  186. package/src/tenancy/db.ts +0 -6
  187. package/src/tenancy/index.ts +0 -2
  188. package/src/tenancy/tenancy.ts +0 -140
  189. package/src/tenancy/tests/tenancy.spec.ts +0 -184
  190. package/src/timers/index.ts +0 -1
  191. package/src/timers/timers.ts +0 -22
  192. package/src/users/db.ts +0 -460
  193. package/src/users/events.ts +0 -176
  194. package/src/users/index.ts +0 -4
  195. package/src/users/lookup.ts +0 -102
  196. package/src/users/users.ts +0 -276
  197. package/src/users/utils.ts +0 -55
  198. package/src/utils/hashing.ts +0 -14
  199. package/src/utils/index.ts +0 -3
  200. package/src/utils/stringUtils.ts +0 -8
  201. package/src/utils/tests/utils.spec.ts +0 -191
  202. package/src/utils/utils.ts +0 -239
  203. package/tests/core/logging.ts +0 -34
  204. package/tests/core/utilities/index.ts +0 -6
  205. package/tests/core/utilities/jestUtils.ts +0 -30
  206. package/tests/core/utilities/mocks/alerts.ts +0 -3
  207. package/tests/core/utilities/mocks/date.ts +0 -2
  208. package/tests/core/utilities/mocks/events.ts +0 -131
  209. package/tests/core/utilities/mocks/fetch.ts +0 -17
  210. package/tests/core/utilities/mocks/index.ts +0 -10
  211. package/tests/core/utilities/mocks/licenses.ts +0 -107
  212. package/tests/core/utilities/mocks/posthog.ts +0 -7
  213. package/tests/core/utilities/structures/Chance.ts +0 -20
  214. package/tests/core/utilities/structures/accounts.ts +0 -115
  215. package/tests/core/utilities/structures/apps.ts +0 -21
  216. package/tests/core/utilities/structures/common.ts +0 -7
  217. package/tests/core/utilities/structures/db.ts +0 -12
  218. package/tests/core/utilities/structures/documents/index.ts +0 -1
  219. package/tests/core/utilities/structures/documents/platform/index.ts +0 -1
  220. package/tests/core/utilities/structures/documents/platform/installation.ts +0 -12
  221. package/tests/core/utilities/structures/generator.ts +0 -2
  222. package/tests/core/utilities/structures/index.ts +0 -15
  223. package/tests/core/utilities/structures/koa.ts +0 -16
  224. package/tests/core/utilities/structures/licenses.ts +0 -167
  225. package/tests/core/utilities/structures/plugins.ts +0 -19
  226. package/tests/core/utilities/structures/quotas.ts +0 -67
  227. package/tests/core/utilities/structures/scim.ts +0 -80
  228. package/tests/core/utilities/structures/shared.ts +0 -19
  229. package/tests/core/utilities/structures/sso.ts +0 -119
  230. package/tests/core/utilities/structures/tenants.ts +0 -5
  231. package/tests/core/utilities/structures/userGroups.ts +0 -10
  232. package/tests/core/utilities/structures/users.ts +0 -73
  233. package/tests/core/utilities/testContainerUtils.ts +0 -98
  234. package/tests/core/utilities/utils/index.ts +0 -1
  235. package/tests/core/utilities/utils/time.ts +0 -3
  236. package/tests/extra/DBTestConfiguration.ts +0 -36
  237. package/tests/extra/index.ts +0 -2
  238. package/tests/extra/testEnv.ts +0 -95
  239. package/tests/index.ts +0 -1
  240. package/tests/jestEnv.ts +0 -6
  241. package/tests/jestSetup.ts +0 -28
@@ -1,82 +0,0 @@
1
- import API from "./api"
2
- import env from "../environment"
3
- import { Header } from "../constants"
4
- import { CloudAccount, HealthStatusResponse } from "@budibase/types"
5
-
6
- const api = new API(env.ACCOUNT_PORTAL_URL)
7
-
8
- /**
9
- * This client is intended to be used in a cloud hosted deploy only.
10
- * Rather than relying on each consumer to perform the necessary environmental checks
11
- * we use the following check to exit early with a undefined response which should be
12
- * handled by the caller.
13
- */
14
- const EXIT_EARLY = env.SELF_HOSTED || env.DISABLE_ACCOUNT_PORTAL
15
-
16
- export const getAccount = async (
17
- email: string
18
- ): Promise<CloudAccount | undefined> => {
19
- if (EXIT_EARLY) {
20
- return
21
- }
22
- const payload = {
23
- email,
24
- }
25
- const response = await api.post(`/api/accounts/search`, {
26
- body: payload,
27
- headers: {
28
- [Header.API_KEY]: env.ACCOUNT_PORTAL_API_KEY,
29
- },
30
- })
31
-
32
- if (response.status !== 200) {
33
- throw new Error(`Error getting account by email ${email}`)
34
- }
35
-
36
- const json: CloudAccount[] = await response.json()
37
- return json[0]
38
- }
39
-
40
- export const getAccountByTenantId = async (
41
- tenantId: string
42
- ): Promise<CloudAccount | undefined> => {
43
- if (EXIT_EARLY) {
44
- return
45
- }
46
- const payload = {
47
- tenantId,
48
- }
49
- const response = await api.post(`/api/accounts/search`, {
50
- body: payload,
51
- headers: {
52
- [Header.API_KEY]: env.ACCOUNT_PORTAL_API_KEY,
53
- },
54
- })
55
-
56
- if (response.status !== 200) {
57
- throw new Error(`Error getting account by tenantId ${tenantId}`)
58
- }
59
-
60
- const json: CloudAccount[] = await response.json()
61
- return json[0]
62
- }
63
-
64
- export const getStatus = async (): Promise<
65
- HealthStatusResponse | undefined
66
- > => {
67
- if (EXIT_EARLY) {
68
- return
69
- }
70
- const response = await api.get(`/api/status`, {
71
- headers: {
72
- [Header.API_KEY]: env.ACCOUNT_PORTAL_API_KEY,
73
- },
74
- })
75
- const json = await response.json()
76
-
77
- if (response.status !== 200) {
78
- throw new Error(`Error getting status`)
79
- }
80
-
81
- return json
82
- }
@@ -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"