@budibase/backend-core 3.2.4 → 3.2.6

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 (272) hide show
  1. package/dist/index.js.map +1 -1
  2. package/dist/index.js.meta.json +1 -1
  3. package/dist/package.json +11 -4
  4. package/dist/plugins.js.meta.json +1 -1
  5. package/package.json +11 -4
  6. package/src/accounts/accounts.ts +0 -82
  7. package/src/accounts/api.ts +0 -59
  8. package/src/accounts/index.ts +0 -1
  9. package/src/auth/auth.ts +0 -210
  10. package/src/auth/index.ts +0 -1
  11. package/src/auth/tests/auth.spec.ts +0 -14
  12. package/src/blacklist/blacklist.ts +0 -54
  13. package/src/blacklist/index.ts +0 -1
  14. package/src/blacklist/tests/blacklist.spec.ts +0 -46
  15. package/src/cache/appMetadata.ts +0 -88
  16. package/src/cache/base/index.ts +0 -150
  17. package/src/cache/docWritethrough.ts +0 -105
  18. package/src/cache/generic.ts +0 -33
  19. package/src/cache/index.ts +0 -8
  20. package/src/cache/invite.ts +0 -86
  21. package/src/cache/passwordReset.ts +0 -49
  22. package/src/cache/tests/docWritethrough.spec.ts +0 -296
  23. package/src/cache/tests/user.spec.ts +0 -145
  24. package/src/cache/tests/writethrough.spec.ts +0 -139
  25. package/src/cache/user.ts +0 -154
  26. package/src/cache/writethrough.ts +0 -133
  27. package/src/configs/configs.ts +0 -263
  28. package/src/configs/index.ts +0 -1
  29. package/src/configs/tests/configs.spec.ts +0 -184
  30. package/src/constants/db.ts +0 -75
  31. package/src/constants/index.ts +0 -2
  32. package/src/constants/misc.ts +0 -36
  33. package/src/context/Context.ts +0 -14
  34. package/src/context/identity.ts +0 -58
  35. package/src/context/index.ts +0 -3
  36. package/src/context/mainContext.ts +0 -422
  37. package/src/context/tests/index.spec.ts +0 -255
  38. package/src/context/types.ts +0 -26
  39. package/src/db/Replication.ts +0 -94
  40. package/src/db/couch/DatabaseImpl.ts +0 -511
  41. package/src/db/couch/connections.ts +0 -89
  42. package/src/db/couch/index.ts +0 -4
  43. package/src/db/couch/pouchDB.ts +0 -97
  44. package/src/db/couch/pouchDump.ts +0 -0
  45. package/src/db/couch/tests/DatabaseImpl.spec.ts +0 -118
  46. package/src/db/couch/utils.ts +0 -55
  47. package/src/db/db.ts +0 -34
  48. package/src/db/errors.ts +0 -14
  49. package/src/db/index.ts +0 -12
  50. package/src/db/instrumentation.ts +0 -199
  51. package/src/db/lucene.ts +0 -721
  52. package/src/db/searchIndexes/index.ts +0 -1
  53. package/src/db/searchIndexes/searchIndexes.ts +0 -62
  54. package/src/db/tests/DatabaseImpl.spec.ts +0 -55
  55. package/src/db/tests/connections.spec.ts +0 -22
  56. package/src/db/tests/index.spec.ts +0 -32
  57. package/src/db/tests/lucene.spec.ts +0 -400
  58. package/src/db/tests/pouch.spec.js +0 -62
  59. package/src/db/tests/utils.spec.ts +0 -63
  60. package/src/db/utils.ts +0 -208
  61. package/src/db/views.ts +0 -245
  62. package/src/docIds/conversions.ts +0 -60
  63. package/src/docIds/ids.ts +0 -126
  64. package/src/docIds/index.ts +0 -2
  65. package/src/docIds/newid.ts +0 -5
  66. package/src/docIds/params.ts +0 -189
  67. package/src/docUpdates/index.ts +0 -24
  68. package/src/environment.ts +0 -293
  69. package/src/errors/errors.ts +0 -119
  70. package/src/errors/index.ts +0 -1
  71. package/src/events/analytics.ts +0 -6
  72. package/src/events/asyncEvents/index.ts +0 -2
  73. package/src/events/asyncEvents/publisher.ts +0 -12
  74. package/src/events/asyncEvents/queue.ts +0 -22
  75. package/src/events/backfill.ts +0 -183
  76. package/src/events/documentId.ts +0 -56
  77. package/src/events/events.ts +0 -47
  78. package/src/events/identification.ts +0 -311
  79. package/src/events/index.ts +0 -15
  80. package/src/events/processors/AnalyticsProcessor.ts +0 -64
  81. package/src/events/processors/AuditLogsProcessor.ts +0 -92
  82. package/src/events/processors/LoggingProcessor.ts +0 -36
  83. package/src/events/processors/Processors.ts +0 -52
  84. package/src/events/processors/async/DocumentUpdateProcessor.ts +0 -38
  85. package/src/events/processors/index.ts +0 -19
  86. package/src/events/processors/posthog/PosthogProcessor.ts +0 -118
  87. package/src/events/processors/posthog/index.ts +0 -3
  88. package/src/events/processors/posthog/rateLimiting.ts +0 -106
  89. package/src/events/processors/posthog/tests/PosthogProcessor.spec.ts +0 -164
  90. package/src/events/processors/types.ts +0 -1
  91. package/src/events/publishers/account.ts +0 -41
  92. package/src/events/publishers/ai.ts +0 -21
  93. package/src/events/publishers/app.ts +0 -168
  94. package/src/events/publishers/auditLog.ts +0 -26
  95. package/src/events/publishers/auth.ts +0 -73
  96. package/src/events/publishers/automation.ts +0 -110
  97. package/src/events/publishers/backfill.ts +0 -74
  98. package/src/events/publishers/backup.ts +0 -42
  99. package/src/events/publishers/datasource.ts +0 -48
  100. package/src/events/publishers/email.ts +0 -17
  101. package/src/events/publishers/environmentVariable.ts +0 -38
  102. package/src/events/publishers/group.ts +0 -99
  103. package/src/events/publishers/index.ts +0 -25
  104. package/src/events/publishers/installation.ts +0 -38
  105. package/src/events/publishers/layout.ts +0 -26
  106. package/src/events/publishers/license.ts +0 -84
  107. package/src/events/publishers/org.ts +0 -37
  108. package/src/events/publishers/plugin.ts +0 -47
  109. package/src/events/publishers/query.ts +0 -89
  110. package/src/events/publishers/role.ts +0 -62
  111. package/src/events/publishers/rows.ts +0 -29
  112. package/src/events/publishers/screen.ts +0 -36
  113. package/src/events/publishers/serve.ts +0 -43
  114. package/src/events/publishers/table.ts +0 -70
  115. package/src/events/publishers/user.ts +0 -202
  116. package/src/events/publishers/view.ts +0 -107
  117. package/src/features/features.ts +0 -277
  118. package/src/features/index.ts +0 -2
  119. package/src/features/tests/features.spec.ts +0 -267
  120. package/src/features/tests/utils.ts +0 -64
  121. package/src/helpers.ts +0 -9
  122. package/src/index.ts +0 -59
  123. package/src/installation.ts +0 -115
  124. package/src/logging/alerts.ts +0 -26
  125. package/src/logging/correlation/correlation.ts +0 -15
  126. package/src/logging/correlation/index.ts +0 -1
  127. package/src/logging/correlation/middleware.ts +0 -18
  128. package/src/logging/index.ts +0 -4
  129. package/src/logging/pino/logger.ts +0 -239
  130. package/src/logging/pino/middleware.ts +0 -48
  131. package/src/logging/system.ts +0 -81
  132. package/src/logging/tests/system.spec.ts +0 -61
  133. package/src/middleware/adminOnly.ts +0 -9
  134. package/src/middleware/auditLog.ts +0 -6
  135. package/src/middleware/authenticated.ts +0 -247
  136. package/src/middleware/builderOnly.ts +0 -21
  137. package/src/middleware/builderOrAdmin.ts +0 -21
  138. package/src/middleware/contentSecurityPolicy.ts +0 -113
  139. package/src/middleware/csrf.ts +0 -81
  140. package/src/middleware/errorHandling.ts +0 -43
  141. package/src/middleware/index.ts +0 -24
  142. package/src/middleware/internalApi.ts +0 -23
  143. package/src/middleware/ip.ts +0 -12
  144. package/src/middleware/joi-validator.ts +0 -58
  145. package/src/middleware/matchers.ts +0 -39
  146. package/src/middleware/passport/datasource/google.ts +0 -102
  147. package/src/middleware/passport/local.ts +0 -54
  148. package/src/middleware/passport/sso/google.ts +0 -77
  149. package/src/middleware/passport/sso/oidc.ts +0 -152
  150. package/src/middleware/passport/sso/sso.ts +0 -138
  151. package/src/middleware/passport/sso/tests/google.spec.ts +0 -68
  152. package/src/middleware/passport/sso/tests/oidc.spec.ts +0 -144
  153. package/src/middleware/passport/sso/tests/sso.spec.ts +0 -197
  154. package/src/middleware/passport/utils.ts +0 -38
  155. package/src/middleware/querystringToBody.ts +0 -28
  156. package/src/middleware/tenancy.ts +0 -36
  157. package/src/middleware/tests/builder.spec.ts +0 -181
  158. package/src/middleware/tests/contentSecurityPolicy.spec.ts +0 -75
  159. package/src/middleware/tests/matchers.spec.ts +0 -100
  160. package/src/migrations/definitions.ts +0 -40
  161. package/src/migrations/index.ts +0 -2
  162. package/src/migrations/migrations.ts +0 -186
  163. package/src/migrations/tests/__snapshots__/migrations.spec.ts.snap +0 -11
  164. package/src/migrations/tests/migrations.spec.ts +0 -64
  165. package/src/objectStore/buckets/app.ts +0 -53
  166. package/src/objectStore/buckets/global.ts +0 -29
  167. package/src/objectStore/buckets/index.ts +0 -3
  168. package/src/objectStore/buckets/plugins.ts +0 -71
  169. package/src/objectStore/buckets/tests/app.spec.ts +0 -161
  170. package/src/objectStore/buckets/tests/global.spec.ts +0 -74
  171. package/src/objectStore/buckets/tests/plugins.spec.ts +0 -111
  172. package/src/objectStore/cloudfront.ts +0 -41
  173. package/src/objectStore/index.ts +0 -3
  174. package/src/objectStore/objectStore.ts +0 -585
  175. package/src/objectStore/utils.ts +0 -113
  176. package/src/platform/index.ts +0 -3
  177. package/src/platform/platformDb.ts +0 -6
  178. package/src/platform/tenants.ts +0 -101
  179. package/src/platform/tests/tenants.spec.ts +0 -26
  180. package/src/platform/users.ts +0 -129
  181. package/src/plugin/index.ts +0 -1
  182. package/src/plugin/tests/validation.spec.ts +0 -209
  183. package/src/plugin/utils.ts +0 -175
  184. package/src/queue/constants.ts +0 -8
  185. package/src/queue/inMemoryQueue.ts +0 -189
  186. package/src/queue/index.ts +0 -2
  187. package/src/queue/listeners.ts +0 -199
  188. package/src/queue/queue.ts +0 -84
  189. package/src/redis/index.ts +0 -6
  190. package/src/redis/init.ts +0 -118
  191. package/src/redis/redis.ts +0 -358
  192. package/src/redis/redlockImpl.ts +0 -155
  193. package/src/redis/tests/redis.spec.ts +0 -207
  194. package/src/redis/tests/redlockImpl.spec.ts +0 -105
  195. package/src/redis/utils.ts +0 -128
  196. package/src/security/auth.ts +0 -24
  197. package/src/security/encryption.ts +0 -185
  198. package/src/security/index.ts +0 -1
  199. package/src/security/permissions.ts +0 -166
  200. package/src/security/roles.ts +0 -655
  201. package/src/security/secrets.ts +0 -20
  202. package/src/security/sessions.ts +0 -123
  203. package/src/security/tests/auth.spec.ts +0 -45
  204. package/src/security/tests/encryption.spec.ts +0 -31
  205. package/src/security/tests/permissions.spec.ts +0 -146
  206. package/src/security/tests/secrets.spec.ts +0 -35
  207. package/src/security/tests/sessions.spec.ts +0 -12
  208. package/src/sql/designDoc.ts +0 -17
  209. package/src/sql/index.ts +0 -5
  210. package/src/sql/sql.ts +0 -1854
  211. package/src/sql/sqlTable.ts +0 -319
  212. package/src/sql/utils.ts +0 -193
  213. package/src/tenancy/db.ts +0 -6
  214. package/src/tenancy/index.ts +0 -2
  215. package/src/tenancy/tenancy.ts +0 -148
  216. package/src/tenancy/tests/tenancy.spec.ts +0 -184
  217. package/src/timers/index.ts +0 -1
  218. package/src/timers/timers.ts +0 -22
  219. package/src/users/db.ts +0 -582
  220. package/src/users/events.ts +0 -176
  221. package/src/users/index.ts +0 -4
  222. package/src/users/lookup.ts +0 -99
  223. package/src/users/test/db.spec.ts +0 -188
  224. package/src/users/test/utils.spec.ts +0 -67
  225. package/src/users/users.ts +0 -353
  226. package/src/users/utils.ts +0 -81
  227. package/src/utils/Duration.ts +0 -56
  228. package/src/utils/hashing.ts +0 -15
  229. package/src/utils/index.ts +0 -4
  230. package/src/utils/stringUtils.ts +0 -8
  231. package/src/utils/tests/Duration.spec.ts +0 -19
  232. package/src/utils/tests/utils.spec.ts +0 -204
  233. package/src/utils/utils.ts +0 -249
  234. package/tests/core/logging.ts +0 -34
  235. package/tests/core/users/users.spec.js +0 -53
  236. package/tests/core/utilities/index.ts +0 -7
  237. package/tests/core/utilities/jestUtils.ts +0 -33
  238. package/tests/core/utilities/mocks/alerts.ts +0 -4
  239. package/tests/core/utilities/mocks/date.ts +0 -3
  240. package/tests/core/utilities/mocks/events.ts +0 -132
  241. package/tests/core/utilities/mocks/index.ts +0 -9
  242. package/tests/core/utilities/mocks/licenses.ts +0 -119
  243. package/tests/core/utilities/queue.ts +0 -9
  244. package/tests/core/utilities/structures/Chance.ts +0 -20
  245. package/tests/core/utilities/structures/accounts.ts +0 -80
  246. package/tests/core/utilities/structures/apps.ts +0 -21
  247. package/tests/core/utilities/structures/common.ts +0 -7
  248. package/tests/core/utilities/structures/db.ts +0 -12
  249. package/tests/core/utilities/structures/documents/index.ts +0 -1
  250. package/tests/core/utilities/structures/documents/platform/index.ts +0 -1
  251. package/tests/core/utilities/structures/documents/platform/installation.ts +0 -12
  252. package/tests/core/utilities/structures/generator.ts +0 -3
  253. package/tests/core/utilities/structures/index.ts +0 -15
  254. package/tests/core/utilities/structures/koa.ts +0 -16
  255. package/tests/core/utilities/structures/licenses.ts +0 -190
  256. package/tests/core/utilities/structures/plugins.ts +0 -19
  257. package/tests/core/utilities/structures/quotas.ts +0 -72
  258. package/tests/core/utilities/structures/scim.ts +0 -80
  259. package/tests/core/utilities/structures/sso.ts +0 -118
  260. package/tests/core/utilities/structures/tenants.ts +0 -5
  261. package/tests/core/utilities/structures/userGroups.ts +0 -10
  262. package/tests/core/utilities/structures/users.ts +0 -89
  263. package/tests/core/utilities/testContainerUtils.ts +0 -165
  264. package/tests/core/utilities/utils/index.ts +0 -2
  265. package/tests/core/utilities/utils/queue.ts +0 -27
  266. package/tests/core/utilities/utils/time.ts +0 -3
  267. package/tests/extra/DBTestConfiguration.ts +0 -36
  268. package/tests/extra/index.ts +0 -2
  269. package/tests/extra/testEnv.ts +0 -95
  270. package/tests/index.ts +0 -2
  271. package/tests/jestEnv.ts +0 -10
  272. 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
- }