@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,239 +0,0 @@
1
- import pino, { LoggerOptions } from "pino"
2
- import pinoPretty from "pino-pretty"
3
-
4
- import { IdentityType } from "@budibase/types"
5
- import env from "../../environment"
6
- import * as context from "../../context"
7
- import * as correlation from "../correlation"
8
- import tracer from "dd-trace"
9
- import { formats } from "dd-trace/ext"
10
-
11
- import { localFileDestination } from "../system"
12
-
13
- function isPlainObject(obj: any) {
14
- return typeof obj === "object" && obj !== null && !(obj instanceof Error)
15
- }
16
-
17
- function isError(obj: any) {
18
- return obj instanceof Error
19
- }
20
-
21
- function isMessage(obj: any) {
22
- return typeof obj === "string"
23
- }
24
-
25
- // LOGGER
26
-
27
- let pinoInstance: pino.Logger | undefined
28
- if (!env.DISABLE_PINO_LOGGER) {
29
- const level = env.LOG_LEVEL
30
- const pinoOptions: LoggerOptions = {
31
- level,
32
- formatters: {
33
- level: level => {
34
- return { level: level.toUpperCase() }
35
- },
36
- bindings: () => {
37
- if (env.SELF_HOSTED) {
38
- // "service" is being injected in datadog using the pod names,
39
- // so we should leave it blank to allow the default behaviour if it's not running self-hosted
40
- return {
41
- service: env.SERVICE_NAME,
42
- }
43
- } else {
44
- return {}
45
- }
46
- },
47
- },
48
- timestamp: () => `,"timestamp":"${new Date(Date.now()).toISOString()}"`,
49
- }
50
-
51
- const destinations: pino.StreamEntry[] = []
52
-
53
- destinations.push(
54
- env.isDev()
55
- ? {
56
- stream: pinoPretty({ singleLine: true }),
57
- level: level as pino.Level,
58
- }
59
- : { stream: process.stdout, level: level as pino.Level }
60
- )
61
-
62
- if (env.SELF_HOSTED) {
63
- destinations.push({
64
- stream: localFileDestination(),
65
- level: level as pino.Level,
66
- })
67
- }
68
-
69
- pinoInstance = destinations.length
70
- ? pino(pinoOptions, pino.multistream(destinations))
71
- : pino(pinoOptions)
72
-
73
- // CONSOLE OVERRIDES
74
-
75
- interface MergingObject {
76
- objects?: any[]
77
- tenantId?: string
78
- appId?: string
79
- automationId?: string
80
- identityId?: string
81
- identityType?: IdentityType
82
- correlationId?: string
83
- err?: Error
84
- }
85
-
86
- /**
87
- * Backwards compatibility between console logging statements
88
- * and pino logging requirements.
89
- */
90
- const getLogParams = (args: any[]): [MergingObject, string] => {
91
- let error = undefined
92
- let objects: any[] = []
93
- let message = ""
94
-
95
- args.forEach(arg => {
96
- if (isMessage(arg)) {
97
- message = `${message} ${arg}`.trimStart()
98
- }
99
- if (isPlainObject(arg)) {
100
- objects.push(arg)
101
- }
102
- if (isError(arg)) {
103
- error = arg
104
- }
105
- })
106
-
107
- const identity = getIdentity()
108
-
109
- let contextObject = {}
110
-
111
- contextObject = {
112
- tenantId: getTenantId(),
113
- appId: getAppId(),
114
- automationId: getAutomationId(),
115
- identityId: identity?._id,
116
- identityType: identity?.type,
117
- correlationId: correlation.getId(),
118
- }
119
-
120
- const span = tracer.scope().active()
121
- if (span) {
122
- tracer.inject(span.context(), formats.LOG, contextObject)
123
- }
124
-
125
- const mergingObject: any = {
126
- err: error,
127
- pid: process.pid,
128
- ...contextObject,
129
- }
130
-
131
- if (objects.length) {
132
- // init generic data object for params supplied that don't have a
133
- // '_logKey' field. This prints an object using argument index as the key
134
- // e.g. { 0: {}, 1: {} }
135
- const data: any = {}
136
- let dataIndex = 0
137
-
138
- for (let i = 0; i < objects.length; i++) {
139
- const object = objects[i]
140
- // the object has specified a log key
141
- // use this instead of generic key
142
- const logKey = object._logKey
143
- if (logKey) {
144
- delete object._logKey
145
- mergingObject[logKey] = object
146
- } else {
147
- data[dataIndex] = object
148
- dataIndex++
149
- }
150
- }
151
-
152
- if (Object.keys(data).length) {
153
- mergingObject.data = data
154
- }
155
- }
156
-
157
- return [mergingObject, message]
158
- }
159
-
160
- console.log = (...arg: any[]) => {
161
- const [obj, msg] = getLogParams(arg)
162
- pinoInstance?.info(obj, msg)
163
- }
164
- console.info = (...arg: any[]) => {
165
- const [obj, msg] = getLogParams(arg)
166
- pinoInstance?.info(obj, msg)
167
- }
168
- console.warn = (...arg: any[]) => {
169
- const [obj, msg] = getLogParams(arg)
170
- pinoInstance?.warn(obj, msg)
171
- }
172
- console.error = (...arg: any[]) => {
173
- const [obj, msg] = getLogParams(arg)
174
- pinoInstance?.error(obj, msg)
175
- }
176
-
177
- /**
178
- * custom trace impl - this resembles the node trace behaviour rather
179
- * than traditional trace logging
180
- * @param arg
181
- */
182
- console.trace = (...arg: any[]) => {
183
- const [obj, msg] = getLogParams(arg)
184
- if (!obj.err) {
185
- // to get stack trace
186
- obj.err = new Error()
187
- }
188
- pinoInstance?.trace(obj, msg)
189
- }
190
-
191
- console.debug = (...arg: any) => {
192
- const [obj, msg] = getLogParams(arg)
193
- pinoInstance?.debug(obj, msg)
194
- }
195
-
196
- // CONTEXT
197
-
198
- const getTenantId = () => {
199
- let tenantId
200
- try {
201
- tenantId = context.getTenantId()
202
- } catch (e: any) {
203
- // do nothing
204
- }
205
- return tenantId
206
- }
207
-
208
- const getAppId = () => {
209
- let appId
210
- try {
211
- appId = context.getAppId()
212
- } catch (e) {
213
- // do nothing
214
- }
215
- return appId
216
- }
217
-
218
- const getAutomationId = () => {
219
- let appId
220
- try {
221
- appId = context.getAutomationId()
222
- } catch (e) {
223
- // do nothing
224
- }
225
- return appId
226
- }
227
-
228
- const getIdentity = () => {
229
- let identity
230
- try {
231
- identity = context.getIdentity()
232
- } catch (e) {
233
- // do nothing
234
- }
235
- return identity
236
- }
237
- }
238
-
239
- export const logger = pinoInstance
@@ -1,48 +0,0 @@
1
- import env from "../../environment"
2
- import { logger } from "./logger"
3
- import { IncomingMessage } from "http"
4
-
5
- const pino = require("koa-pino-logger")
6
-
7
- import { Options } from "pino-http"
8
- import { Ctx } from "@budibase/types"
9
-
10
- const correlator = require("correlation-id")
11
-
12
- export function pinoSettings(): Options {
13
- return {
14
- logger,
15
- genReqId: correlator.getId,
16
- autoLogging: {
17
- ignore: (req: IncomingMessage) => !!req.url?.includes("/health"),
18
- },
19
- serializers: {
20
- req: req => {
21
- return {
22
- method: req.method,
23
- url: req.url,
24
- correlationId: req.id,
25
- }
26
- },
27
- res: res => {
28
- return {
29
- status: res.statusCode,
30
- }
31
- },
32
- },
33
- }
34
- }
35
-
36
- function getMiddleware() {
37
- if (env.HTTP_LOGGING) {
38
- return pino(pinoSettings())
39
- } else {
40
- return (ctx: Ctx, next: any) => {
41
- return next()
42
- }
43
- }
44
- }
45
-
46
- const pinoMiddleware = getMiddleware()
47
-
48
- export default pinoMiddleware
@@ -1,81 +0,0 @@
1
- import fs from "fs"
2
- import path from "path"
3
- import * as rfs from "rotating-file-stream"
4
-
5
- import env from "../environment"
6
- import { budibaseTempDir } from "../objectStore"
7
-
8
- const logsFileName = `budibase.log`
9
- const budibaseLogsHistoryFileName = "budibase-logs-history.txt"
10
-
11
- const logsPath = path.join(budibaseTempDir(), "systemlogs")
12
-
13
- function getFullPath(fileName: string) {
14
- return path.join(logsPath, fileName)
15
- }
16
-
17
- export function getSingleFileMaxSizeInfo(totalMaxSize: string) {
18
- const regex = /(\d+)([A-Za-z])/
19
- const match = totalMaxSize?.match(regex)
20
- if (!match) {
21
- console.warn(`totalMaxSize does not have a valid value`, {
22
- totalMaxSize,
23
- })
24
- return undefined
25
- }
26
-
27
- const size = +match[1]
28
- const unit = match[2]
29
- if (size === 1) {
30
- switch (unit) {
31
- case "B":
32
- return { size: `${size}B`, totalHistoryFiles: 1 }
33
- case "K":
34
- return { size: `${(size * 1000) / 2}B`, totalHistoryFiles: 1 }
35
- case "M":
36
- return { size: `${(size * 1000) / 2}K`, totalHistoryFiles: 1 }
37
- case "G":
38
- return { size: `${(size * 1000) / 2}M`, totalHistoryFiles: 1 }
39
- default:
40
- return undefined
41
- }
42
- }
43
-
44
- if (size % 2 === 0) {
45
- return { size: `${size / 2}${unit}`, totalHistoryFiles: 1 }
46
- }
47
-
48
- return { size: `1${unit}`, totalHistoryFiles: size - 1 }
49
- }
50
-
51
- export function localFileDestination() {
52
- const fileInfo = getSingleFileMaxSizeInfo(env.ROLLING_LOG_MAX_SIZE)
53
- const outFile = rfs.createStream(logsFileName, {
54
- // As we have a rolling size, we want to half the max size
55
- size: fileInfo?.size,
56
- path: logsPath,
57
- maxFiles: fileInfo?.totalHistoryFiles || 1,
58
- immutable: true,
59
- history: budibaseLogsHistoryFileName,
60
- initialRotation: false,
61
- })
62
-
63
- return outFile
64
- }
65
-
66
- export function getLogReadStream() {
67
- const streams = []
68
- const historyFile = getFullPath(budibaseLogsHistoryFileName)
69
- if (fs.existsSync(historyFile)) {
70
- const fileContent = fs.readFileSync(historyFile, "utf-8")
71
- const historyFiles = fileContent.split("\n")
72
- for (const historyFile of historyFiles.filter(x => x)) {
73
- streams.push(fs.readFileSync(historyFile))
74
- }
75
- }
76
-
77
- streams.push(fs.readFileSync(getFullPath(logsFileName)))
78
-
79
- const combinedContent = Buffer.concat(streams)
80
- return combinedContent
81
- }
@@ -1,61 +0,0 @@
1
- import { getSingleFileMaxSizeInfo } from "../system"
2
-
3
- describe("system", () => {
4
- describe("getSingleFileMaxSizeInfo", () => {
5
- it.each([
6
- ["100B", "50B"],
7
- ["200K", "100K"],
8
- ["20M", "10M"],
9
- ["4G", "2G"],
10
- ])(
11
- "Halving even number (%s) returns halved size and 1 history file (%s)",
12
- (totalValue, expectedMaxSize) => {
13
- const result = getSingleFileMaxSizeInfo(totalValue)
14
- expect(result).toEqual({
15
- size: expectedMaxSize,
16
- totalHistoryFiles: 1,
17
- })
18
- }
19
- )
20
-
21
- it.each([
22
- ["5B", "1B", 4],
23
- ["17K", "1K", 16],
24
- ["21M", "1M", 20],
25
- ["3G", "1G", 2],
26
- ])(
27
- "Halving an odd number (%s) returns as many files as size (-1) (%s)",
28
- (totalValue, expectedMaxSize, totalHistoryFiles) => {
29
- const result = getSingleFileMaxSizeInfo(totalValue)
30
- expect(result).toEqual({
31
- size: expectedMaxSize,
32
- totalHistoryFiles,
33
- })
34
- }
35
- )
36
-
37
- it.each([
38
- ["1B", "1B"],
39
- ["1K", "500B"],
40
- ["1M", "500K"],
41
- ["1G", "500M"],
42
- ])(
43
- "Halving '%s' returns halved unit (%s)",
44
- (totalValue, expectedMaxSize) => {
45
- const result = getSingleFileMaxSizeInfo(totalValue)
46
- expect(result).toEqual({
47
- size: expectedMaxSize,
48
- totalHistoryFiles: 1,
49
- })
50
- }
51
- )
52
-
53
- it.each([[undefined], [""], ["50"], ["wrongvalue"]])(
54
- "Halving wrongly formatted value ('%s') returns undefined",
55
- totalValue => {
56
- const result = getSingleFileMaxSizeInfo(totalValue!)
57
- expect(result).toBeUndefined()
58
- }
59
- )
60
- })
61
- })
@@ -1,9 +0,0 @@
1
- import { UserCtx } from "@budibase/types"
2
- import { isAdmin } from "../users"
3
-
4
- export default async (ctx: UserCtx, next: any) => {
5
- if (!ctx.internal && !isAdmin(ctx.user)) {
6
- ctx.throw(403, "Admin user only endpoint.")
7
- }
8
- return next()
9
- }
@@ -1,6 +0,0 @@
1
- import { BBContext } from "@budibase/types"
2
-
3
- export default async (ctx: BBContext | any, next: any) => {
4
- // Placeholder for audit log middleware
5
- return next()
6
- }
@@ -1,247 +0,0 @@
1
- import { Cookie, Header } from "../constants"
2
- import {
3
- clearCookie,
4
- getCookie,
5
- isValidInternalAPIKey,
6
- openJwt,
7
- } from "../utils"
8
- import { getUser } from "../cache/user"
9
- import { getSession, updateSessionTTL } from "../security/sessions"
10
- import { buildMatcherRegex, matches } from "./matchers"
11
- import { queryGlobalView, SEPARATOR, ViewName } from "../db"
12
- import { doInTenant, getGlobalDB } from "../context"
13
- import { decrypt } from "../security/encryption"
14
- import * as identity from "../context/identity"
15
- import env from "../environment"
16
- import {
17
- Ctx,
18
- EndpointMatcher,
19
- LoginMethod,
20
- SessionCookie,
21
- User,
22
- } from "@budibase/types"
23
- import { ErrorCode, InvalidAPIKeyError } from "../errors"
24
- import tracer from "dd-trace"
25
-
26
- const ONE_MINUTE = env.SESSION_UPDATE_PERIOD
27
- ? parseInt(env.SESSION_UPDATE_PERIOD)
28
- : 60 * 1000
29
-
30
- interface FinaliseOpts {
31
- authenticated?: boolean
32
- internal?: boolean
33
- publicEndpoint?: boolean
34
- version?: string
35
- user?: User | { tenantId: string }
36
- loginMethod?: LoginMethod
37
- }
38
-
39
- function timeMinusOneMinute() {
40
- return new Date(Date.now() - ONE_MINUTE).toISOString()
41
- }
42
-
43
- function finalise(ctx: Ctx, opts: FinaliseOpts = {}) {
44
- ctx.publicEndpoint = opts.publicEndpoint || false
45
- ctx.isAuthenticated = opts.authenticated || false
46
- ctx.loginMethod = opts.loginMethod
47
- ctx.user = opts.user
48
- ctx.internal = opts.internal || false
49
- ctx.version = opts.version
50
- }
51
-
52
- async function checkApiKey(
53
- apiKey: string,
54
- populateUser?: (
55
- userId: string,
56
- tenantId: string,
57
- email?: string
58
- ) => Promise<User>
59
- ) {
60
- // check both the primary and the fallback internal api keys
61
- // this allows for rotation
62
- if (isValidInternalAPIKey(apiKey)) {
63
- return { valid: true, user: undefined }
64
- }
65
- const decrypted = decrypt(apiKey)
66
- const tenantId = decrypted.split(SEPARATOR)[0]
67
- return doInTenant(tenantId, async () => {
68
- let userId
69
- try {
70
- const db = getGlobalDB()
71
- // api key is encrypted in the database
72
- userId = (await queryGlobalView(
73
- ViewName.BY_API_KEY,
74
- {
75
- key: apiKey,
76
- },
77
- db
78
- )) as string
79
- } catch (err) {
80
- userId = undefined
81
- }
82
- if (userId) {
83
- return {
84
- valid: true,
85
- user: await getUser({
86
- userId,
87
- tenantId,
88
- populateUser,
89
- }),
90
- }
91
- } else {
92
- throw new InvalidAPIKeyError()
93
- }
94
- })
95
- }
96
-
97
- /**
98
- * This middleware is tenancy aware, so that it does not depend on other middlewares being used.
99
- * The tenancy modules should not be used here and it should be assumed that the tenancy context
100
- * has not yet been populated.
101
- */
102
- export default function (
103
- noAuthPatterns: EndpointMatcher[] = [],
104
- opts: { publicAllowed?: boolean; populateUser?: Function } = {
105
- publicAllowed: false,
106
- }
107
- ) {
108
- const noAuthOptions = noAuthPatterns ? buildMatcherRegex(noAuthPatterns) : []
109
- return async (ctx: Ctx | any, next: any) => {
110
- let publicEndpoint = false
111
- const version = ctx.request.headers[Header.API_VER]
112
- // the path is not authenticated
113
- const found = matches(ctx, noAuthOptions)
114
- if (found) {
115
- publicEndpoint = true
116
- }
117
- try {
118
- // check the actual user is authenticated first, try header or cookie
119
- let headerToken = ctx.request.headers[Header.TOKEN]
120
-
121
- const authCookie =
122
- getCookie<SessionCookie>(ctx, Cookie.Auth) ||
123
- openJwt<SessionCookie>(headerToken)
124
- let apiKey = ctx.request.headers[Header.API_KEY]
125
-
126
- if (!apiKey && ctx.request.headers[Header.AUTHORIZATION]) {
127
- apiKey = ctx.request.headers[Header.AUTHORIZATION].split(" ")[1]
128
- }
129
-
130
- const tenantId = ctx.request.headers[Header.TENANT_ID]
131
- let authenticated: boolean = false,
132
- user: User | { tenantId: string } | undefined = undefined,
133
- internal: boolean = false,
134
- loginMethod: LoginMethod | undefined = undefined
135
- if (authCookie && !apiKey) {
136
- const sessionId = authCookie.sessionId
137
- const userId = authCookie.userId
138
- let session
139
- try {
140
- // getting session handles error checking (if session exists etc)
141
- session = await getSession(userId, sessionId)
142
- if (opts && opts.populateUser) {
143
- user = await getUser({
144
- userId,
145
- tenantId: session.tenantId,
146
- email: session.email,
147
- populateUser: opts.populateUser(ctx),
148
- })
149
- } else {
150
- user = await getUser({
151
- userId,
152
- tenantId: session.tenantId,
153
- email: session.email,
154
- })
155
- }
156
- // @ts-ignore
157
- user.csrfToken = session.csrfToken
158
- loginMethod = LoginMethod.COOKIE
159
-
160
- if (session?.lastAccessedAt < timeMinusOneMinute()) {
161
- // make sure we denote that the session is still in use
162
- await updateSessionTTL(session)
163
- }
164
- authenticated = true
165
- } catch (err: any) {
166
- authenticated = false
167
- console.error(`Auth Error: ${err.message}`)
168
- // remove the cookie as the user does not exist anymore
169
- clearCookie(ctx, Cookie.Auth)
170
- }
171
- }
172
- // this is an internal request, no user made it
173
- if (!authenticated && apiKey) {
174
- const populateUser: (
175
- userId: string,
176
- tenantId: string,
177
- email?: string
178
- ) => Promise<User> = opts.populateUser ? opts.populateUser(ctx) : null
179
- const { valid, user: foundUser } = await checkApiKey(
180
- apiKey,
181
- populateUser
182
- )
183
- if (valid) {
184
- authenticated = true
185
- loginMethod = LoginMethod.API_KEY
186
- user = foundUser
187
- internal = !foundUser
188
- }
189
- }
190
- if (!user && tenantId) {
191
- user = { tenantId }
192
- } else if (user && "password" in user) {
193
- delete user.password
194
- }
195
- // be explicit
196
- if (!authenticated) {
197
- authenticated = false
198
- }
199
-
200
- const isUser = (
201
- user: any
202
- ): user is User & { budibaseAccess?: string } => {
203
- return user && user.email
204
- }
205
-
206
- if (isUser(user)) {
207
- tracer.setUser({
208
- id: user._id!,
209
- tenantId: user.tenantId,
210
- budibaseAccess: user.budibaseAccess,
211
- status: user.status,
212
- })
213
- }
214
-
215
- // isAuthenticated is a function, so use a variable to be able to check authed state
216
- finalise(ctx, {
217
- authenticated,
218
- user,
219
- internal,
220
- version,
221
- publicEndpoint,
222
- loginMethod,
223
- })
224
-
225
- if (isUser(user)) {
226
- return identity.doInUserContext(user, ctx, next)
227
- } else {
228
- return next()
229
- }
230
- } catch (err: any) {
231
- console.error(`Auth Error: ${err.message}`)
232
- // invalid token, clear the cookie
233
- if (err?.name === "JsonWebTokenError") {
234
- clearCookie(ctx, Cookie.Auth)
235
- } else if (err?.code === ErrorCode.INVALID_API_KEY) {
236
- ctx.throw(403, err.message)
237
- }
238
- // allow configuring for public access
239
- if ((opts && opts.publicAllowed) || publicEndpoint) {
240
- finalise(ctx, { authenticated: false, version, publicEndpoint })
241
- return next()
242
- } else {
243
- ctx.throw(err.status || 403, err)
244
- }
245
- }
246
- }
247
- }