@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,92 +0,0 @@
1
- import {
2
- Event,
3
- Identity,
4
- IdentityType,
5
- AuditLogQueueEvent,
6
- AuditLogFn,
7
- HostInfo,
8
- } from "@budibase/types"
9
- import { EventProcessor } from "./types"
10
- import { getAppId, doInTenant, getTenantId } from "../../context"
11
- import BullQueue from "bull"
12
- import { createQueue, JobQueue } from "../../queue"
13
- import { isAudited } from "../../utils"
14
- import env from "../../environment"
15
-
16
- export default class AuditLogsProcessor implements EventProcessor {
17
- static auditLogsEnabled = false
18
- static auditLogQueue: BullQueue.Queue<AuditLogQueueEvent>
19
-
20
- // can't use constructor as need to return promise
21
- static init(fn: AuditLogFn) {
22
- AuditLogsProcessor.auditLogsEnabled = true
23
- const writeAuditLogs = fn
24
- AuditLogsProcessor.auditLogQueue = createQueue<AuditLogQueueEvent>(
25
- JobQueue.AUDIT_LOG
26
- )
27
- return AuditLogsProcessor.auditLogQueue.process(async job => {
28
- return doInTenant(job.data.tenantId, async () => {
29
- let properties = job.data.properties
30
- if (properties.audited) {
31
- properties = {
32
- ...properties,
33
- ...properties.audited,
34
- }
35
- delete properties.audited
36
- }
37
-
38
- // this feature is disabled by default due to privacy requirements
39
- // in some countries - available as env var in-case it is desired
40
- // in self host deployments
41
- let hostInfo: HostInfo | undefined = {}
42
- if (env.ENABLE_AUDIT_LOG_IP_ADDR) {
43
- hostInfo = job.data.opts.hostInfo
44
- }
45
-
46
- await writeAuditLogs(job.data.event, properties, {
47
- userId: job.data.opts.userId,
48
- timestamp: job.data.opts.timestamp,
49
- appId: job.data.opts.appId,
50
- hostInfo,
51
- })
52
- })
53
- })
54
- }
55
-
56
- async processEvent(
57
- event: Event,
58
- identity: Identity,
59
- properties: any,
60
- timestamp?: string
61
- ): Promise<void> {
62
- if (AuditLogsProcessor.auditLogsEnabled && isAudited(event)) {
63
- // only audit log actual events, don't include backfills
64
- const userId =
65
- identity.type === IdentityType.USER ? identity.id : undefined
66
- // add to the event queue, rather than just writing immediately
67
- await AuditLogsProcessor.auditLogQueue.add({
68
- event,
69
- properties,
70
- opts: {
71
- userId,
72
- timestamp,
73
- appId: getAppId(),
74
- hostInfo: identity.hostInfo,
75
- },
76
- tenantId: getTenantId(),
77
- })
78
- }
79
- }
80
-
81
- async identify() {
82
- // no-op
83
- }
84
-
85
- async identifyGroup() {
86
- // no-op
87
- }
88
-
89
- shutdown(): void {
90
- AuditLogsProcessor.auditLogQueue?.close()
91
- }
92
- }
@@ -1,36 +0,0 @@
1
- import { Event, Identity, Group } from "@budibase/types"
2
- import { EventProcessor } from "./types"
3
- import env from "../../environment"
4
-
5
- const skipLogging = env.SELF_HOSTED && !env.isDev()
6
-
7
- export default class LoggingProcessor implements EventProcessor {
8
- async processEvent(
9
- event: Event,
10
- identity: Identity,
11
- properties: any
12
- ): Promise<void> {
13
- if (skipLogging) {
14
- return
15
- }
16
- console.log(`[audit] [identityType=${identity.type}] ${event}`, properties)
17
- }
18
-
19
- async identify(identity: Identity) {
20
- if (skipLogging) {
21
- return
22
- }
23
- console.log(`[audit] identified`, identity)
24
- }
25
-
26
- async identifyGroup(group: Group) {
27
- if (skipLogging) {
28
- return
29
- }
30
- console.log(`[audit] group identified`, group)
31
- }
32
-
33
- shutdown(): void {
34
- // no-op
35
- }
36
- }
@@ -1,52 +0,0 @@
1
- import { Event, Identity, Group } from "@budibase/types"
2
- import { EventProcessor } from "./types"
3
-
4
- export default class Processor implements EventProcessor {
5
- initialised: boolean = false
6
- processors: EventProcessor[] = []
7
-
8
- constructor(processors: EventProcessor[]) {
9
- this.processors = processors
10
- }
11
-
12
- async processEvent(
13
- event: Event,
14
- identity: Identity,
15
- properties: any,
16
- timestamp?: string | number
17
- ): Promise<void> {
18
- for (const eventProcessor of this.processors) {
19
- await eventProcessor.processEvent(event, identity, properties, timestamp)
20
- }
21
- }
22
-
23
- async identify(
24
- identity: Identity,
25
- timestamp?: string | number
26
- ): Promise<void> {
27
- for (const eventProcessor of this.processors) {
28
- if (eventProcessor.identify) {
29
- await eventProcessor.identify(identity, timestamp)
30
- }
31
- }
32
- }
33
-
34
- async identifyGroup(
35
- identity: Group,
36
- timestamp?: string | number
37
- ): Promise<void> {
38
- for (const eventProcessor of this.processors) {
39
- if (eventProcessor.identifyGroup) {
40
- await eventProcessor.identifyGroup(identity, timestamp)
41
- }
42
- }
43
- }
44
-
45
- shutdown() {
46
- for (const eventProcessor of this.processors) {
47
- if (eventProcessor.shutdown) {
48
- eventProcessor.shutdown()
49
- }
50
- }
51
- }
52
- }
@@ -1,38 +0,0 @@
1
- import { EventProcessor } from "../types"
2
- import { Event, Identity, DocUpdateEvent } from "@budibase/types"
3
- import { doInTenant } from "../../../context"
4
- import { getDocumentId } from "../../documentId"
5
- import { shutdown } from "../../asyncEvents"
6
-
7
- export type Processor = (update: DocUpdateEvent) => Promise<void>
8
- export type ProcessorMap = { events: Event[]; processor: Processor }[]
9
-
10
- export default class DocumentUpdateProcessor implements EventProcessor {
11
- processors: ProcessorMap = []
12
-
13
- constructor(processors: ProcessorMap) {
14
- this.processors = processors
15
- }
16
-
17
- async processEvent(event: Event, identity: Identity, properties: any) {
18
- const tenantId = identity.realTenantId
19
- const docId = getDocumentId(event, properties)
20
- if (!tenantId || !docId) {
21
- return
22
- }
23
- for (let { events, processor } of this.processors) {
24
- if (events.includes(event)) {
25
- await doInTenant(tenantId, async () => {
26
- await processor({
27
- id: docId,
28
- tenantId,
29
- })
30
- })
31
- }
32
- }
33
- }
34
-
35
- shutdown() {
36
- return shutdown()
37
- }
38
- }
@@ -1,19 +0,0 @@
1
- import AnalyticsProcessor from "./AnalyticsProcessor"
2
- import LoggingProcessor from "./LoggingProcessor"
3
- import AuditLogsProcessor from "./AuditLogsProcessor"
4
- import Processors from "./Processors"
5
- import { AuditLogFn } from "@budibase/types"
6
-
7
- export const analyticsProcessor = new AnalyticsProcessor()
8
- const loggingProcessor = new LoggingProcessor()
9
- const auditLogsProcessor = new AuditLogsProcessor()
10
-
11
- export function init(auditingFn: AuditLogFn) {
12
- return AuditLogsProcessor.init(auditingFn)
13
- }
14
-
15
- export const processors = new Processors([
16
- analyticsProcessor,
17
- loggingProcessor,
18
- auditLogsProcessor,
19
- ])
@@ -1,118 +0,0 @@
1
- import { PostHog } from "posthog-node"
2
- import { Event, Identity, Group, BaseEvent } from "@budibase/types"
3
- import { EventProcessor } from "../types"
4
- import env from "../../../environment"
5
- import * as context from "../../../context"
6
- import * as rateLimiting from "./rateLimiting"
7
-
8
- const EXCLUDED_EVENTS: Event[] = [
9
- Event.USER_UPDATED,
10
- Event.EMAIL_SMTP_UPDATED,
11
- Event.AUTH_SSO_UPDATED,
12
- Event.APP_UPDATED,
13
- Event.ROLE_UPDATED,
14
- Event.DATASOURCE_UPDATED,
15
- Event.QUERY_UPDATED,
16
- Event.TABLE_UPDATED,
17
- Event.VIEW_UPDATED,
18
- Event.VIEW_FILTER_UPDATED,
19
- Event.VIEW_CALCULATION_UPDATED,
20
- Event.AUTOMATION_TRIGGER_UPDATED,
21
- Event.USER_GROUP_UPDATED,
22
- ]
23
-
24
- export default class PosthogProcessor implements EventProcessor {
25
- posthog: PostHog
26
-
27
- constructor(token: string | undefined) {
28
- if (!token) {
29
- throw new Error("Posthog token is not defined")
30
- }
31
- this.posthog = new PostHog(token)
32
- }
33
-
34
- async processEvent(
35
- event: Event,
36
- identity: Identity,
37
- properties: BaseEvent,
38
- timestamp?: string | number
39
- ): Promise<void> {
40
- // don't send excluded events
41
- if (EXCLUDED_EVENTS.includes(event)) {
42
- return
43
- }
44
-
45
- if (await rateLimiting.limited(event)) {
46
- return
47
- }
48
-
49
- properties = this.clearPIIProperties(properties)
50
-
51
- properties.version = env.VERSION
52
- properties.service = env.SERVICE
53
- properties.environment = identity.environment
54
- properties.hosting = identity.hosting
55
-
56
- const appId = context.getAppId()
57
- if (appId) {
58
- properties.appId = appId
59
- }
60
-
61
- const payload: any = { distinctId: identity.id, event, properties }
62
-
63
- if (timestamp) {
64
- payload.timestamp = new Date(timestamp)
65
- }
66
-
67
- // add groups to the event
68
- if (identity.installationId || identity.tenantId) {
69
- payload.groups = {}
70
- if (identity.installationId) {
71
- payload.groups.installation = identity.installationId
72
- payload.properties.installationId = identity.installationId
73
- }
74
- if (identity.tenantId) {
75
- payload.groups.tenant = identity.tenantId
76
- payload.properties.tenantId = identity.tenantId
77
- }
78
- }
79
-
80
- this.posthog.capture(payload)
81
- }
82
-
83
- clearPIIProperties(properties: any) {
84
- if (properties.email) {
85
- delete properties.email
86
- }
87
- if (properties.audited) {
88
- delete properties.audited
89
- }
90
- return properties
91
- }
92
-
93
- async identify(identity: Identity, timestamp?: string | number) {
94
- const payload: any = { distinctId: identity.id, properties: identity }
95
- if (timestamp) {
96
- payload.timestamp = new Date(timestamp)
97
- }
98
- this.posthog.identify(payload)
99
- }
100
-
101
- async identifyGroup(group: Group, timestamp?: string | number) {
102
- const payload: any = {
103
- distinctId: group.id,
104
- groupType: group.type,
105
- groupKey: group.id,
106
- properties: group,
107
- }
108
-
109
- if (timestamp) {
110
- payload.timestamp = new Date(timestamp)
111
- }
112
- this.posthog.groupIdentify(payload)
113
- }
114
-
115
- shutdown() {
116
- this.posthog.shutdown()
117
- }
118
- }
@@ -1,3 +0,0 @@
1
- import PosthogProcessor from "./PosthogProcessor"
2
-
3
- export default PosthogProcessor
@@ -1,106 +0,0 @@
1
- import { Event } from "@budibase/types"
2
- import { CacheKey, TTL } from "../../../cache/generic"
3
- import * as cache from "../../../cache/generic"
4
- import * as context from "../../../context"
5
-
6
- type RateLimitedEvent =
7
- | Event.SERVED_BUILDER
8
- | Event.SERVED_APP_PREVIEW
9
- | Event.SERVED_APP
10
-
11
- const isRateLimited = (event: Event): event is RateLimitedEvent => {
12
- return (
13
- event === Event.SERVED_BUILDER ||
14
- event === Event.SERVED_APP_PREVIEW ||
15
- event === Event.SERVED_APP
16
- )
17
- }
18
-
19
- const isPerApp = (event: RateLimitedEvent) => {
20
- return event === Event.SERVED_APP_PREVIEW || event === Event.SERVED_APP
21
- }
22
-
23
- interface EventProperties {
24
- timestamp: number
25
- }
26
-
27
- enum RateLimit {
28
- CALENDAR_DAY = "calendarDay",
29
- }
30
-
31
- const RATE_LIMITS = {
32
- [Event.SERVED_APP]: RateLimit.CALENDAR_DAY,
33
- [Event.SERVED_APP_PREVIEW]: RateLimit.CALENDAR_DAY,
34
- [Event.SERVED_BUILDER]: RateLimit.CALENDAR_DAY,
35
- }
36
-
37
- /**
38
- * Check if this event should be sent right now
39
- * Return false to signal the event SHOULD be sent
40
- * Return true to signal the event should NOT be sent
41
- */
42
- export const limited = async (event: Event): Promise<boolean> => {
43
- // not a rate limited event -- send
44
- if (!isRateLimited(event)) {
45
- return false
46
- }
47
-
48
- const cachedEvent = await readEvent(event)
49
- if (cachedEvent) {
50
- const timestamp = new Date(cachedEvent.timestamp)
51
- const limit = RATE_LIMITS[event]
52
- switch (limit) {
53
- case RateLimit.CALENDAR_DAY: {
54
- // get midnight at the start of the next day for the timestamp
55
- timestamp.setDate(timestamp.getDate() + 1)
56
- timestamp.setHours(0, 0, 0, 0)
57
-
58
- // if we have passed the threshold into the next day
59
- if (Date.now() > timestamp.getTime()) {
60
- // update the timestamp in the event -- send
61
- await recordEvent(event, { timestamp: Date.now() })
62
- return false
63
- } else {
64
- // still within the limited period -- don't send
65
- return true
66
- }
67
- }
68
- }
69
- } else {
70
- // no event present i.e. expired -- send
71
- await recordEvent(event, { timestamp: Date.now() })
72
- return false
73
- }
74
- }
75
-
76
- const eventKey = (event: RateLimitedEvent) => {
77
- let key = `${CacheKey.EVENTS_RATE_LIMIT}:${event}`
78
- if (isPerApp(event)) {
79
- key = key + ":" + context.getAppId()
80
- }
81
- return key
82
- }
83
-
84
- const readEvent = async (
85
- event: RateLimitedEvent
86
- ): Promise<EventProperties | undefined> => {
87
- const key = eventKey(event)
88
- const result = await cache.get(key)
89
- return result as EventProperties
90
- }
91
-
92
- const recordEvent = async (
93
- event: RateLimitedEvent,
94
- properties: EventProperties
95
- ) => {
96
- const key = eventKey(event)
97
- const limit = RATE_LIMITS[event]
98
- let ttl
99
- switch (limit) {
100
- case RateLimit.CALENDAR_DAY: {
101
- ttl = TTL.ONE_DAY
102
- }
103
- }
104
-
105
- await cache.store(key, properties, ttl)
106
- }
@@ -1,164 +0,0 @@
1
- import { testEnv } from "../../../../../tests/extra"
2
- import PosthogProcessor from "../PosthogProcessor"
3
- import { Event, IdentityType, Hosting } from "@budibase/types"
4
- import tk from "timekeeper"
5
- import * as cache from "../../../../cache/generic"
6
- import { CacheKey } from "../../../../cache/generic"
7
- import * as context from "../../../../context"
8
-
9
- const newIdentity = () => {
10
- return {
11
- id: "test",
12
- type: IdentityType.USER,
13
- hosting: Hosting.SELF,
14
- environment: "test",
15
- }
16
- }
17
-
18
- describe("PosthogProcessor", () => {
19
- let processor: PosthogProcessor
20
- let spy: jest.SpyInstance
21
-
22
- beforeAll(() => {
23
- testEnv.singleTenant()
24
- })
25
-
26
- beforeEach(async () => {
27
- jest.clearAllMocks()
28
- await cache.bustCache(
29
- `${CacheKey.EVENTS_RATE_LIMIT}:${Event.SERVED_BUILDER}`
30
- )
31
-
32
- processor = new PosthogProcessor("test")
33
- spy = jest.spyOn(processor.posthog, "capture")
34
- })
35
-
36
- describe("processEvent", () => {
37
- it("processes event", async () => {
38
- const identity = newIdentity()
39
- const properties = {}
40
-
41
- await processor.processEvent(Event.APP_CREATED, identity, properties)
42
- expect(spy).toHaveBeenCalledTimes(1)
43
- })
44
-
45
- it("honours exclusions", async () => {
46
- const identity = newIdentity()
47
- const properties = {}
48
-
49
- await processor.processEvent(Event.AUTH_SSO_UPDATED, identity, properties)
50
- expect(spy).toHaveBeenCalledTimes(0)
51
- })
52
-
53
- it("removes audited information", async () => {
54
- const identity = newIdentity()
55
- const properties = {
56
- email: "test",
57
- audited: {
58
- name: "test",
59
- },
60
- }
61
-
62
- await processor.processEvent(Event.USER_CREATED, identity, properties)
63
- expect(spy).toHaveBeenCalled()
64
-
65
- // @ts-ignore
66
- const call = processor.posthog.capture.mock.calls[0][0]
67
- expect(call.properties.audited).toBeUndefined()
68
- expect(call.properties.email).toBeUndefined()
69
- })
70
-
71
- describe("rate limiting", () => {
72
- it("sends daily event once in same day", async () => {
73
- const identity = newIdentity()
74
- const properties = {}
75
-
76
- tk.freeze(new Date(2022, 0, 1, 14, 0))
77
- await processor.processEvent(Event.SERVED_BUILDER, identity, properties)
78
- // go forward one hour
79
- tk.freeze(new Date(2022, 0, 1, 15, 0))
80
- await processor.processEvent(Event.SERVED_BUILDER, identity, properties)
81
-
82
- expect(spy).toHaveBeenCalledTimes(1)
83
- })
84
-
85
- it("sends daily event once per unique day", async () => {
86
- const identity = newIdentity()
87
- const properties = {}
88
-
89
- tk.freeze(new Date(2022, 0, 1, 14, 0))
90
- await processor.processEvent(Event.SERVED_BUILDER, identity, properties)
91
- // go forward into next day
92
- tk.freeze(new Date(2022, 0, 2, 9, 0))
93
- await processor.processEvent(Event.SERVED_BUILDER, identity, properties)
94
- // go forward into next day
95
- tk.freeze(new Date(2022, 0, 3, 5, 0))
96
- await processor.processEvent(Event.SERVED_BUILDER, identity, properties)
97
- // go forward one hour
98
- tk.freeze(new Date(2022, 0, 3, 6, 0))
99
- await processor.processEvent(Event.SERVED_BUILDER, identity, properties)
100
-
101
- expect(spy).toHaveBeenCalledTimes(3)
102
- })
103
-
104
- it("sends event again after cache expires", async () => {
105
- const identity = newIdentity()
106
- const properties = {}
107
-
108
- tk.freeze(new Date(2022, 0, 1, 14, 0))
109
- await processor.processEvent(Event.SERVED_BUILDER, identity, properties)
110
-
111
- await cache.bustCache(
112
- `${CacheKey.EVENTS_RATE_LIMIT}:${Event.SERVED_BUILDER}`
113
- )
114
-
115
- tk.freeze(new Date(2022, 0, 1, 14, 0))
116
- await processor.processEvent(Event.SERVED_BUILDER, identity, properties)
117
-
118
- expect(spy).toHaveBeenCalledTimes(2)
119
- })
120
-
121
- it("sends per app events once per day per app", async () => {
122
- const identity = newIdentity()
123
- const properties = {}
124
-
125
- const runAppEvents = async (appId: string) => {
126
- await context.doInAppContext(appId, async () => {
127
- tk.freeze(new Date(2022, 0, 1, 14, 0))
128
- await processor.processEvent(Event.SERVED_APP, identity, properties)
129
- await processor.processEvent(
130
- Event.SERVED_APP_PREVIEW,
131
- identity,
132
- properties
133
- )
134
-
135
- // go forward one hour - should be ignored
136
- tk.freeze(new Date(2022, 0, 1, 15, 0))
137
- await processor.processEvent(Event.SERVED_APP, identity, properties)
138
- await processor.processEvent(
139
- Event.SERVED_APP_PREVIEW,
140
- identity,
141
- properties
142
- )
143
-
144
- // go forward into next day
145
- tk.freeze(new Date(2022, 0, 2, 9, 0))
146
-
147
- await processor.processEvent(Event.SERVED_APP, identity, properties)
148
- await processor.processEvent(
149
- Event.SERVED_APP_PREVIEW,
150
- identity,
151
- properties
152
- )
153
- })
154
- }
155
-
156
- await runAppEvents("app_1")
157
- expect(spy).toHaveBeenCalledTimes(4)
158
-
159
- await runAppEvents("app_2")
160
- expect(spy).toHaveBeenCalledTimes(8)
161
- })
162
- })
163
- })
164
- })
@@ -1 +0,0 @@
1
- export { EventProcessor } from "@budibase/types"
@@ -1,41 +0,0 @@
1
- import { publishEvent } from "../events"
2
- import {
3
- Event,
4
- Account,
5
- AccountCreatedEvent,
6
- AccountDeletedEvent,
7
- AccountVerifiedEvent,
8
- Identity,
9
- } from "@budibase/types"
10
-
11
- async function created(account: Account, identityOverride?: Identity) {
12
- const properties: AccountCreatedEvent = {
13
- tenantId: account.tenantId,
14
- }
15
- await publishEvent(
16
- Event.ACCOUNT_CREATED,
17
- properties,
18
- undefined,
19
- identityOverride
20
- )
21
- }
22
-
23
- async function deleted(account: Account) {
24
- const properties: AccountDeletedEvent = {
25
- tenantId: account.tenantId,
26
- }
27
- await publishEvent(Event.ACCOUNT_DELETED, properties)
28
- }
29
-
30
- async function verified(account: Account) {
31
- const properties: AccountVerifiedEvent = {
32
- tenantId: account.tenantId,
33
- }
34
- await publishEvent(Event.ACCOUNT_VERIFIED, properties)
35
- }
36
-
37
- export default {
38
- created,
39
- deleted,
40
- verified,
41
- }
@@ -1,21 +0,0 @@
1
- import { publishEvent } from "../events"
2
- import {
3
- Event,
4
- AIConfigCreatedEvent,
5
- AIConfigUpdatedEvent,
6
- } from "@budibase/types"
7
-
8
- async function AIConfigCreated(timestamp?: string | number) {
9
- const properties: AIConfigCreatedEvent = {}
10
- await publishEvent(Event.AI_CONFIG_CREATED, properties, timestamp)
11
- }
12
-
13
- async function AIConfigUpdated() {
14
- const properties: AIConfigUpdatedEvent = {}
15
- await publishEvent(Event.AI_CONFIG_UPDATED, properties)
16
- }
17
-
18
- export default {
19
- AIConfigCreated,
20
- AIConfigUpdated,
21
- }