@budibase/backend-core 2.5.9 → 2.5.10-alpha.1

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 (438) hide show
  1. package/dist/package.json +13 -10
  2. package/dist/src/configs/configs.d.ts +2 -1
  3. package/dist/src/configs/configs.js +9 -1
  4. package/dist/src/configs/configs.js.map +1 -1
  5. package/dist/src/constants/db.d.ts +1 -0
  6. package/dist/src/constants/db.js +1 -0
  7. package/dist/src/constants/db.js.map +1 -1
  8. package/dist/src/constants/misc.d.ts +4 -2
  9. package/dist/src/constants/misc.js +2 -0
  10. package/dist/src/constants/misc.js.map +1 -1
  11. package/dist/src/context/mainContext.d.ts +5 -2
  12. package/dist/src/context/mainContext.js +20 -3
  13. package/dist/src/context/mainContext.js.map +1 -1
  14. package/dist/src/context/types.d.ts +1 -0
  15. package/dist/src/db/couch/DatabaseImpl.js +1 -1
  16. package/dist/src/db/couch/DatabaseImpl.js.map +1 -1
  17. package/dist/src/db/index.d.ts +2 -1
  18. package/dist/src/db/index.js +15 -2
  19. package/dist/src/db/index.js.map +1 -1
  20. package/dist/src/db/lucene.d.ts +8 -14
  21. package/dist/src/db/lucene.js +164 -97
  22. package/dist/src/db/lucene.js.map +1 -1
  23. package/dist/src/db/searchIndexes/index.d.ts +1 -0
  24. package/dist/src/db/searchIndexes/index.js +18 -0
  25. package/dist/src/db/searchIndexes/index.js.map +1 -0
  26. package/dist/src/db/searchIndexes/searchIndexes.d.ts +1 -0
  27. package/dist/src/db/searchIndexes/searchIndexes.js +77 -0
  28. package/dist/src/db/searchIndexes/searchIndexes.js.map +1 -0
  29. package/dist/src/db/utils.d.ts +5 -126
  30. package/dist/src/db/utils.js +20 -232
  31. package/dist/src/db/utils.js.map +1 -1
  32. package/dist/src/db/views.d.ts +3 -1
  33. package/dist/src/db/views.js +61 -30
  34. package/dist/src/db/views.js.map +1 -1
  35. package/dist/src/docIds/conversions.js.map +1 -0
  36. package/dist/src/docIds/ids.d.ts +53 -0
  37. package/dist/src/docIds/ids.js +101 -0
  38. package/dist/src/docIds/ids.js.map +1 -0
  39. package/dist/src/docIds/index.d.ts +2 -0
  40. package/dist/src/docIds/index.js +19 -0
  41. package/dist/src/docIds/index.js.map +1 -0
  42. package/dist/src/docIds/newid.js.map +1 -0
  43. package/dist/src/docIds/params.d.ts +69 -0
  44. package/dist/src/docIds/params.js +138 -0
  45. package/dist/src/docIds/params.js.map +1 -0
  46. package/dist/src/docUpdates/index.d.ts +2 -0
  47. package/dist/src/docUpdates/index.js +36 -0
  48. package/dist/src/docUpdates/index.js.map +1 -0
  49. package/dist/src/environment.d.ts +4 -2
  50. package/dist/src/environment.js +35 -2
  51. package/dist/src/environment.js.map +1 -1
  52. package/dist/src/errors/errors.d.ts +3 -0
  53. package/dist/src/errors/errors.js +8 -1
  54. package/dist/src/errors/errors.js.map +1 -1
  55. package/dist/src/events/asyncEvents/index.d.ts +2 -0
  56. package/dist/src/events/asyncEvents/index.js +19 -0
  57. package/dist/src/events/asyncEvents/index.js.map +1 -0
  58. package/dist/src/events/asyncEvents/publisher.d.ts +2 -0
  59. package/dist/src/events/asyncEvents/publisher.js +27 -0
  60. package/dist/src/events/asyncEvents/publisher.js.map +1 -0
  61. package/dist/src/events/asyncEvents/queue.d.ts +11 -0
  62. package/dist/src/events/asyncEvents/queue.js +26 -0
  63. package/dist/src/events/asyncEvents/queue.js.map +1 -0
  64. package/dist/src/events/documentId.d.ts +2 -0
  65. package/dist/src/events/documentId.js +28 -0
  66. package/dist/src/events/documentId.js.map +1 -0
  67. package/dist/src/events/events.js +9 -0
  68. package/dist/src/events/events.js.map +1 -1
  69. package/dist/src/events/identification.d.ts +1 -0
  70. package/dist/src/events/identification.js +3 -2
  71. package/dist/src/events/identification.js.map +1 -1
  72. package/dist/src/events/index.d.ts +1 -0
  73. package/dist/src/events/index.js +3 -1
  74. package/dist/src/events/index.js.map +1 -1
  75. package/dist/src/events/processors/LoggingProcessor.js +3 -17
  76. package/dist/src/events/processors/LoggingProcessor.js.map +1 -1
  77. package/dist/src/events/processors/Processors.js +9 -3
  78. package/dist/src/events/processors/Processors.js.map +1 -1
  79. package/dist/src/events/processors/async/DocumentUpdateProcessor.d.ts +13 -0
  80. package/dist/src/events/processors/async/DocumentUpdateProcessor.js +44 -0
  81. package/dist/src/events/processors/async/DocumentUpdateProcessor.js.map +1 -0
  82. package/dist/src/events/processors/posthog/PosthogProcessor.js +1 -2
  83. package/dist/src/events/processors/posthog/PosthogProcessor.js.map +1 -1
  84. package/dist/src/events/processors/types.d.ts +1 -11
  85. package/dist/src/events/processors/types.js +0 -6
  86. package/dist/src/events/processors/types.js.map +1 -1
  87. package/dist/src/events/publishers/group.js +6 -0
  88. package/dist/src/events/publishers/group.js.map +1 -1
  89. package/dist/src/events/publishers/license.d.ts +9 -4
  90. package/dist/src/events/publishers/license.js +2 -17
  91. package/dist/src/events/publishers/license.js.map +1 -1
  92. package/dist/src/events/publishers/user.js +4 -0
  93. package/dist/src/events/publishers/user.js.map +1 -1
  94. package/dist/src/index.d.ts +6 -2
  95. package/dist/src/index.js +2 -1
  96. package/dist/src/index.js.map +1 -1
  97. package/dist/src/installation.d.ts +1 -0
  98. package/dist/src/installation.js +7 -6
  99. package/dist/src/installation.js.map +1 -1
  100. package/dist/src/{logging.d.ts → logging/alerts.d.ts} +0 -5
  101. package/dist/src/logging/alerts.js +24 -0
  102. package/dist/src/logging/alerts.js.map +1 -0
  103. package/dist/src/logging/correlation/correlation.d.ts +2 -0
  104. package/dist/src/logging/correlation/correlation.js +17 -0
  105. package/dist/src/logging/correlation/correlation.js.map +1 -0
  106. package/dist/src/logging/correlation/index.d.ts +1 -0
  107. package/dist/src/logging/correlation/index.js +18 -0
  108. package/dist/src/logging/correlation/index.js.map +1 -0
  109. package/dist/src/logging/correlation/middleware.d.ts +2 -0
  110. package/dist/src/logging/correlation/middleware.js +17 -0
  111. package/dist/src/logging/correlation/middleware.js.map +1 -0
  112. package/dist/src/logging/index.d.ts +4 -0
  113. package/dist/src/logging/index.js +36 -0
  114. package/dist/src/logging/index.js.map +1 -0
  115. package/dist/src/logging/pino/logger.d.ts +2 -0
  116. package/dist/src/logging/pino/logger.js +167 -0
  117. package/dist/src/logging/pino/logger.js.map +1 -0
  118. package/dist/src/logging/pino/middleware.d.ts +4 -0
  119. package/dist/src/logging/pino/middleware.js +47 -0
  120. package/dist/src/logging/pino/middleware.js.map +1 -0
  121. package/dist/src/middleware/authenticated.js +6 -3
  122. package/dist/src/middleware/authenticated.js.map +1 -1
  123. package/dist/src/middleware/errorHandling.js +5 -7
  124. package/dist/src/middleware/errorHandling.js.map +1 -1
  125. package/dist/src/middleware/index.d.ts +2 -1
  126. package/dist/src/middleware/index.js +5 -3
  127. package/dist/src/middleware/index.js.map +1 -1
  128. package/dist/src/middleware/passport/sso/oidc.js +2 -5
  129. package/dist/src/middleware/passport/sso/oidc.js.map +1 -1
  130. package/dist/src/middleware/tenancy.d.ts +1 -1
  131. package/dist/src/migrations/migrations.js +4 -4
  132. package/dist/src/migrations/migrations.js.map +1 -1
  133. package/dist/src/objectStore/objectStore.js +3 -3
  134. package/dist/src/objectStore/objectStore.js.map +1 -1
  135. package/dist/src/plugin/utils.js +53 -2
  136. package/dist/src/plugin/utils.js.map +1 -1
  137. package/dist/src/queue/constants.d.ts +2 -1
  138. package/dist/src/queue/constants.js +1 -0
  139. package/dist/src/queue/constants.js.map +1 -1
  140. package/dist/src/redis/redlockImpl.js +4 -1
  141. package/dist/src/redis/redlockImpl.js.map +1 -1
  142. package/dist/src/security/encryption.d.ts +1 -0
  143. package/dist/src/security/encryption.js +2 -1
  144. package/dist/src/security/encryption.js.map +1 -1
  145. package/dist/src/security/permissions.d.ts +35 -2
  146. package/dist/src/security/permissions.js +9 -6
  147. package/dist/src/security/permissions.js.map +1 -1
  148. package/dist/src/tenancy/tenancy.js +1 -5
  149. package/dist/src/tenancy/tenancy.js.map +1 -1
  150. package/dist/src/users.d.ts +11 -1
  151. package/dist/src/users.js +45 -1
  152. package/dist/src/users.js.map +1 -1
  153. package/dist/src/utils/hashing.d.ts +1 -1
  154. package/dist/src/utils/hashing.js +1 -1
  155. package/dist/src/utils/hashing.js.map +1 -1
  156. package/dist/src/utils/index.d.ts +1 -0
  157. package/dist/src/utils/index.js +1 -0
  158. package/dist/src/utils/index.js.map +1 -1
  159. package/dist/src/utils/stringUtils.d.ts +1 -0
  160. package/dist/src/utils/stringUtils.js +9 -0
  161. package/dist/src/utils/stringUtils.js.map +1 -0
  162. package/dist/src/utils/utils.d.ts +0 -1
  163. package/dist/src/utils/utils.js +1 -24
  164. package/dist/src/utils/utils.js.map +1 -1
  165. package/dist/tests/core/logging.js.map +1 -0
  166. package/dist/tests/{utilities → core/utilities}/index.d.ts +1 -2
  167. package/dist/tests/{utilities → core/utilities}/index.js +2 -7
  168. package/dist/tests/core/utilities/index.js.map +1 -0
  169. package/dist/tests/core/utilities/jestUtils.js.map +1 -0
  170. package/dist/tests/core/utilities/mocks/alerts.d.ts +3 -0
  171. package/dist/tests/core/utilities/mocks/alerts.js +30 -0
  172. package/dist/tests/core/utilities/mocks/alerts.js.map +1 -0
  173. package/dist/tests/core/utilities/mocks/date.js.map +1 -0
  174. package/dist/tests/core/utilities/mocks/events.js +144 -0
  175. package/dist/tests/core/utilities/mocks/events.js.map +1 -0
  176. package/dist/tests/core/utilities/mocks/fetch.d.ts +33 -0
  177. package/dist/tests/core/utilities/mocks/fetch.js +15 -0
  178. package/dist/tests/core/utilities/mocks/fetch.js.map +1 -0
  179. package/dist/tests/{utilities → core/utilities}/mocks/index.d.ts +4 -3
  180. package/dist/tests/{utilities → core/utilities}/mocks/index.js +7 -3
  181. package/dist/tests/core/utilities/mocks/index.js.map +1 -0
  182. package/dist/tests/{utilities → core/utilities}/mocks/licenses.d.ts +1 -0
  183. package/dist/tests/{utilities → core/utilities}/mocks/licenses.js +5 -1
  184. package/dist/tests/core/utilities/mocks/licenses.js.map +1 -0
  185. package/dist/tests/core/utilities/mocks/posthog.js.map +1 -0
  186. package/dist/tests/core/utilities/structures/Chance.d.ts +7 -0
  187. package/dist/tests/core/utilities/structures/Chance.js +21 -0
  188. package/dist/tests/core/utilities/structures/Chance.js.map +1 -0
  189. package/dist/tests/{utilities → core/utilities}/structures/accounts.js +3 -25
  190. package/dist/tests/core/utilities/structures/accounts.js.map +1 -0
  191. package/dist/tests/{utilities → core/utilities}/structures/apps.js +1 -1
  192. package/dist/tests/core/utilities/structures/apps.js.map +1 -0
  193. package/dist/tests/core/utilities/structures/common.js.map +1 -0
  194. package/dist/tests/{utilities → core/utilities}/structures/db.js +1 -1
  195. package/dist/tests/core/utilities/structures/db.js.map +1 -0
  196. package/dist/tests/core/utilities/structures/generator.d.ts +2 -0
  197. package/dist/tests/{utilities → core/utilities}/structures/generator.js +2 -2
  198. package/dist/tests/core/utilities/structures/generator.js.map +1 -0
  199. package/dist/tests/{utilities → core/utilities}/structures/index.d.ts +2 -0
  200. package/dist/tests/{utilities → core/utilities}/structures/index.js +3 -1
  201. package/dist/tests/core/utilities/structures/index.js.map +1 -0
  202. package/dist/tests/core/utilities/structures/koa.js.map +1 -0
  203. package/dist/tests/core/utilities/structures/licenses.d.ts +17 -0
  204. package/dist/tests/core/utilities/structures/licenses.js +127 -0
  205. package/dist/tests/core/utilities/structures/licenses.js.map +1 -0
  206. package/dist/tests/core/utilities/structures/plugins.js.map +1 -0
  207. package/dist/tests/core/utilities/structures/quotas.d.ts +2 -0
  208. package/dist/tests/core/utilities/structures/quotas.js +71 -0
  209. package/dist/tests/core/utilities/structures/quotas.js.map +1 -0
  210. package/dist/tests/core/utilities/structures/scim.d.ts +14 -0
  211. package/dist/tests/core/utilities/structures/scim.js +67 -0
  212. package/dist/tests/core/utilities/structures/scim.js.map +1 -0
  213. package/dist/tests/core/utilities/structures/shared.js.map +1 -0
  214. package/dist/tests/core/utilities/structures/sso.js.map +1 -0
  215. package/dist/tests/{utilities → core/utilities}/structures/tenants.js +1 -1
  216. package/dist/tests/core/utilities/structures/tenants.js.map +1 -0
  217. package/dist/tests/core/utilities/structures/userGroups.js.map +1 -0
  218. package/dist/tests/core/utilities/structures/users.js.map +1 -0
  219. package/dist/tests/core/utilities/testContainerUtils.js.map +1 -0
  220. package/dist/tests/core/utilities/utils/index.d.ts +1 -0
  221. package/dist/tests/core/utilities/utils/index.js +28 -0
  222. package/dist/tests/core/utilities/utils/index.js.map +1 -0
  223. package/dist/tests/core/utilities/utils/time.d.ts +1 -0
  224. package/dist/tests/core/utilities/utils/time.js +8 -0
  225. package/dist/tests/core/utilities/utils/time.js.map +1 -0
  226. package/dist/tests/{utilities → extra}/DBTestConfiguration.d.ts +1 -1
  227. package/dist/tests/{utilities → extra}/DBTestConfiguration.js +2 -2
  228. package/dist/tests/extra/DBTestConfiguration.js.map +1 -0
  229. package/dist/tests/extra/index.d.ts +2 -0
  230. package/dist/tests/extra/index.js +33 -0
  231. package/dist/tests/extra/index.js.map +1 -0
  232. package/dist/tests/{utilities → extra}/testEnv.d.ts +1 -1
  233. package/dist/tests/{utilities → extra}/testEnv.js +1 -1
  234. package/dist/tests/extra/testEnv.js.map +1 -0
  235. package/dist/tests/index.d.ts +1 -1
  236. package/dist/tests/index.js +1 -1
  237. package/dist/tests/index.js.map +1 -1
  238. package/dist/tests/jestEnv.js +0 -1
  239. package/dist/tests/jestEnv.js.map +1 -1
  240. package/dist/tests/jestSetup.d.ts +1 -1
  241. package/dist/tests/jestSetup.js +2 -2
  242. package/dist/tests/jestSetup.js.map +1 -1
  243. package/dist/tsconfig.build.tsbuildinfo +1 -1
  244. package/package.json +13 -10
  245. package/src/auth/tests/auth.spec.ts +2 -1
  246. package/src/cache/tests/writethrough.spec.ts +4 -3
  247. package/src/configs/configs.ts +9 -0
  248. package/src/configs/tests/configs.spec.ts +2 -6
  249. package/src/constants/db.ts +1 -0
  250. package/src/constants/misc.ts +2 -0
  251. package/src/context/mainContext.ts +22 -5
  252. package/src/context/tests/index.spec.ts +16 -3
  253. package/src/context/types.ts +1 -0
  254. package/src/db/couch/DatabaseImpl.ts +1 -1
  255. package/src/db/index.ts +2 -1
  256. package/src/db/lucene.ts +156 -99
  257. package/src/db/searchIndexes/index.ts +1 -0
  258. package/src/db/searchIndexes/searchIndexes.ts +62 -0
  259. package/src/db/tests/lucene.spec.ts +101 -1
  260. package/src/db/tests/utils.spec.ts +1 -1
  261. package/src/db/utils.ts +7 -275
  262. package/src/db/views.ts +64 -25
  263. package/src/docIds/ids.ts +102 -0
  264. package/src/docIds/index.ts +2 -0
  265. package/src/docIds/params.ts +174 -0
  266. package/src/docUpdates/index.ts +29 -0
  267. package/src/environment.ts +44 -2
  268. package/src/errors/errors.ts +8 -0
  269. package/src/events/asyncEvents/index.ts +2 -0
  270. package/src/events/asyncEvents/publisher.ts +12 -0
  271. package/src/events/asyncEvents/queue.ts +22 -0
  272. package/src/events/documentId.ts +56 -0
  273. package/src/events/events.ts +10 -1
  274. package/src/events/identification.ts +3 -3
  275. package/src/events/index.ts +2 -0
  276. package/src/events/processors/LoggingProcessor.ts +3 -22
  277. package/src/events/processors/Processors.ts +9 -3
  278. package/src/events/processors/async/DocumentUpdateProcessor.ts +43 -0
  279. package/src/events/processors/posthog/PosthogProcessor.ts +1 -2
  280. package/src/events/processors/posthog/tests/PosthogProcessor.spec.ts +1 -1
  281. package/src/events/processors/types.ts +1 -18
  282. package/src/events/publishers/group.ts +6 -1
  283. package/src/events/publishers/license.ts +12 -13
  284. package/src/events/publishers/user.ts +4 -0
  285. package/src/index.ts +1 -0
  286. package/src/installation.ts +4 -5
  287. package/src/logging/alerts.ts +26 -0
  288. package/src/logging/correlation/correlation.ts +13 -0
  289. package/src/logging/correlation/index.ts +1 -0
  290. package/src/logging/correlation/middleware.ts +17 -0
  291. package/src/logging/index.ts +6 -0
  292. package/src/logging/pino/logger.ts +173 -0
  293. package/src/logging/pino/middleware.ts +45 -0
  294. package/src/middleware/authenticated.ts +9 -3
  295. package/src/middleware/errorHandling.ts +4 -4
  296. package/src/middleware/index.ts +2 -1
  297. package/src/middleware/passport/sso/oidc.ts +2 -9
  298. package/src/middleware/passport/sso/tests/sso.spec.ts +2 -1
  299. package/src/migrations/migrations.ts +4 -8
  300. package/src/migrations/tests/__snapshots__/migrations.spec.ts.snap +1 -1
  301. package/src/migrations/tests/migrations.spec.ts +1 -1
  302. package/src/objectStore/buckets/tests/app.spec.ts +1 -1
  303. package/src/objectStore/buckets/tests/global.spec.ts +1 -1
  304. package/src/objectStore/buckets/tests/plugins.spec.ts +2 -1
  305. package/src/objectStore/objectStore.ts +3 -3
  306. package/src/platform/tests/tenants.spec.ts +2 -1
  307. package/src/plugin/tests/validation.spec.ts +83 -0
  308. package/src/plugin/utils.ts +63 -3
  309. package/src/queue/constants.ts +1 -0
  310. package/src/redis/redlockImpl.ts +9 -3
  311. package/src/security/encryption.ts +1 -1
  312. package/src/security/permissions.ts +5 -5
  313. package/src/security/tests/encryption.spec.ts +31 -0
  314. package/src/security/tests/permissions.spec.ts +145 -0
  315. package/src/tenancy/tenancy.ts +2 -2
  316. package/src/tenancy/tests/tenancy.spec.ts +184 -0
  317. package/src/users.ts +56 -7
  318. package/src/utils/hashing.ts +1 -1
  319. package/src/utils/index.ts +1 -0
  320. package/src/utils/stringUtils.ts +8 -0
  321. package/src/utils/tests/utils.spec.ts +2 -1
  322. package/src/utils/utils.ts +3 -23
  323. package/tests/{utilities → core/utilities}/index.ts +1 -4
  324. package/tests/core/utilities/mocks/alerts.ts +3 -0
  325. package/tests/core/utilities/mocks/events.ts +133 -0
  326. package/tests/core/utilities/mocks/fetch.ts +17 -0
  327. package/tests/{utilities → core/utilities}/mocks/index.ts +4 -3
  328. package/tests/{utilities → core/utilities}/mocks/licenses.ts +4 -0
  329. package/tests/core/utilities/structures/Chance.ts +20 -0
  330. package/tests/{utilities → core/utilities}/structures/accounts.ts +4 -3
  331. package/tests/{utilities → core/utilities}/structures/apps.ts +1 -1
  332. package/tests/{utilities → core/utilities}/structures/db.ts +1 -1
  333. package/tests/{utilities → core/utilities}/structures/generator.ts +1 -1
  334. package/tests/{utilities → core/utilities}/structures/index.ts +2 -0
  335. package/tests/core/utilities/structures/licenses.ts +145 -0
  336. package/tests/core/utilities/structures/quotas.ts +67 -0
  337. package/tests/core/utilities/structures/scim.ts +81 -0
  338. package/tests/{utilities → core/utilities}/structures/tenants.ts +1 -1
  339. package/tests/core/utilities/utils/index.ts +1 -0
  340. package/tests/core/utilities/utils/time.ts +3 -0
  341. package/tests/{utilities → extra}/DBTestConfiguration.ts +2 -2
  342. package/tests/extra/index.ts +2 -0
  343. package/tests/{utilities → extra}/testEnv.ts +1 -1
  344. package/tests/index.ts +1 -1
  345. package/tests/jestEnv.ts +0 -1
  346. package/tests/jestSetup.ts +2 -2
  347. package/tsconfig.build.json +3 -7
  348. package/dist/src/db/conversions.js.map +0 -1
  349. package/dist/src/logging.js +0 -56
  350. package/dist/src/logging.js.map +0 -1
  351. package/dist/src/middleware/logging.d.ts +0 -2
  352. package/dist/src/middleware/logging.js +0 -106
  353. package/dist/src/middleware/logging.js.map +0 -1
  354. package/dist/src/newid.js.map +0 -1
  355. package/dist/tests/logging.js.map +0 -1
  356. package/dist/tests/utilities/DBTestConfiguration.js.map +0 -1
  357. package/dist/tests/utilities/index.js.map +0 -1
  358. package/dist/tests/utilities/jestUtils.js.map +0 -1
  359. package/dist/tests/utilities/mocks/date.js.map +0 -1
  360. package/dist/tests/utilities/mocks/events.js +0 -126
  361. package/dist/tests/utilities/mocks/events.js.map +0 -1
  362. package/dist/tests/utilities/mocks/fetch.d.ts +0 -31
  363. package/dist/tests/utilities/mocks/fetch.js +0 -8
  364. package/dist/tests/utilities/mocks/fetch.js.map +0 -1
  365. package/dist/tests/utilities/mocks/index.js.map +0 -1
  366. package/dist/tests/utilities/mocks/licenses.js.map +0 -1
  367. package/dist/tests/utilities/mocks/posthog.js.map +0 -1
  368. package/dist/tests/utilities/structures/accounts.js.map +0 -1
  369. package/dist/tests/utilities/structures/apps.js.map +0 -1
  370. package/dist/tests/utilities/structures/common.js.map +0 -1
  371. package/dist/tests/utilities/structures/db.js.map +0 -1
  372. package/dist/tests/utilities/structures/generator.d.ts +0 -1
  373. package/dist/tests/utilities/structures/generator.js.map +0 -1
  374. package/dist/tests/utilities/structures/index.js.map +0 -1
  375. package/dist/tests/utilities/structures/koa.js.map +0 -1
  376. package/dist/tests/utilities/structures/licenses.d.ts +0 -5
  377. package/dist/tests/utilities/structures/licenses.js +0 -18
  378. package/dist/tests/utilities/structures/licenses.js.map +0 -1
  379. package/dist/tests/utilities/structures/plugins.js.map +0 -1
  380. package/dist/tests/utilities/structures/shared.js.map +0 -1
  381. package/dist/tests/utilities/structures/sso.js.map +0 -1
  382. package/dist/tests/utilities/structures/tenants.js.map +0 -1
  383. package/dist/tests/utilities/structures/userGroups.js.map +0 -1
  384. package/dist/tests/utilities/structures/users.js.map +0 -1
  385. package/dist/tests/utilities/testContainerUtils.js.map +0 -1
  386. package/dist/tests/utilities/testEnv.js.map +0 -1
  387. package/src/logging.ts +0 -60
  388. package/src/middleware/logging.ts +0 -90
  389. package/tests/utilities/mocks/events.ts +0 -122
  390. package/tests/utilities/mocks/fetch.ts +0 -10
  391. package/tests/utilities/structures/licenses.ts +0 -18
  392. /package/dist/src/{db → docIds}/conversions.d.ts +0 -0
  393. /package/dist/src/{db → docIds}/conversions.js +0 -0
  394. /package/dist/src/{newid.d.ts → docIds/newid.d.ts} +0 -0
  395. /package/dist/src/{newid.js → docIds/newid.js} +0 -0
  396. /package/dist/tests/{logging.d.ts → core/logging.d.ts} +0 -0
  397. /package/dist/tests/{logging.js → core/logging.js} +0 -0
  398. /package/dist/tests/{utilities → core/utilities}/jestUtils.d.ts +0 -0
  399. /package/dist/tests/{utilities → core/utilities}/jestUtils.js +0 -0
  400. /package/dist/tests/{utilities → core/utilities}/mocks/date.d.ts +0 -0
  401. /package/dist/tests/{utilities → core/utilities}/mocks/date.js +0 -0
  402. /package/dist/tests/{utilities → core/utilities}/mocks/events.d.ts +0 -0
  403. /package/dist/tests/{utilities → core/utilities}/mocks/posthog.d.ts +0 -0
  404. /package/dist/tests/{utilities → core/utilities}/mocks/posthog.js +0 -0
  405. /package/dist/tests/{utilities → core/utilities}/structures/accounts.d.ts +0 -0
  406. /package/dist/tests/{utilities → core/utilities}/structures/apps.d.ts +0 -0
  407. /package/dist/tests/{utilities → core/utilities}/structures/common.d.ts +0 -0
  408. /package/dist/tests/{utilities → core/utilities}/structures/common.js +0 -0
  409. /package/dist/tests/{utilities → core/utilities}/structures/db.d.ts +0 -0
  410. /package/dist/tests/{utilities → core/utilities}/structures/koa.d.ts +0 -0
  411. /package/dist/tests/{utilities → core/utilities}/structures/koa.js +0 -0
  412. /package/dist/tests/{utilities → core/utilities}/structures/plugins.d.ts +0 -0
  413. /package/dist/tests/{utilities → core/utilities}/structures/plugins.js +0 -0
  414. /package/dist/tests/{utilities → core/utilities}/structures/shared.d.ts +0 -0
  415. /package/dist/tests/{utilities → core/utilities}/structures/shared.js +0 -0
  416. /package/dist/tests/{utilities → core/utilities}/structures/sso.d.ts +0 -0
  417. /package/dist/tests/{utilities → core/utilities}/structures/sso.js +0 -0
  418. /package/dist/tests/{utilities → core/utilities}/structures/tenants.d.ts +0 -0
  419. /package/dist/tests/{utilities → core/utilities}/structures/userGroups.d.ts +0 -0
  420. /package/dist/tests/{utilities → core/utilities}/structures/userGroups.js +0 -0
  421. /package/dist/tests/{utilities → core/utilities}/structures/users.d.ts +0 -0
  422. /package/dist/tests/{utilities → core/utilities}/structures/users.js +0 -0
  423. /package/dist/tests/{utilities → core/utilities}/testContainerUtils.d.ts +0 -0
  424. /package/dist/tests/{utilities → core/utilities}/testContainerUtils.js +0 -0
  425. /package/src/{db → docIds}/conversions.ts +0 -0
  426. /package/src/{newid.ts → docIds/newid.ts} +0 -0
  427. /package/tests/{logging.ts → core/logging.ts} +0 -0
  428. /package/tests/{utilities → core/utilities}/jestUtils.ts +0 -0
  429. /package/tests/{utilities → core/utilities}/mocks/date.ts +0 -0
  430. /package/tests/{utilities → core/utilities}/mocks/posthog.ts +0 -0
  431. /package/tests/{utilities → core/utilities}/structures/common.ts +0 -0
  432. /package/tests/{utilities → core/utilities}/structures/koa.ts +0 -0
  433. /package/tests/{utilities → core/utilities}/structures/plugins.ts +0 -0
  434. /package/tests/{utilities → core/utilities}/structures/shared.ts +0 -0
  435. /package/tests/{utilities → core/utilities}/structures/sso.ts +0 -0
  436. /package/tests/{utilities → core/utilities}/structures/userGroups.ts +0 -0
  437. /package/tests/{utilities → core/utilities}/structures/users.ts +0 -0
  438. /package/tests/{utilities → core/utilities}/testContainerUtils.ts +0 -0
@@ -0,0 +1,83 @@
1
+ import { validate } from "../utils"
2
+ import fetch from "node-fetch"
3
+ import { PluginType } from "@budibase/types"
4
+
5
+ const repoUrl =
6
+ "https://raw.githubusercontent.com/Budibase/budibase-skeleton/master"
7
+ const automationLink = `${repoUrl}/automation/schema.json.hbs`
8
+ const componentLink = `${repoUrl}/component/schema.json.hbs`
9
+ const datasourceLink = `${repoUrl}/datasource/schema.json.hbs`
10
+
11
+ async function getSchema(link: string) {
12
+ const response = await fetch(link)
13
+ if (response.status > 300) {
14
+ return
15
+ }
16
+ const text = await response.text()
17
+ return JSON.parse(text)
18
+ }
19
+
20
+ async function runTest(opts: { link?: string; schema?: any }) {
21
+ let error
22
+ try {
23
+ let schema = opts.schema
24
+ if (opts.link) {
25
+ schema = await getSchema(opts.link)
26
+ }
27
+ validate(schema)
28
+ } catch (err) {
29
+ error = err
30
+ }
31
+ return error
32
+ }
33
+
34
+ describe("it should be able to validate an automation schema", () => {
35
+ it("should return automation skeleton schema is valid", async () => {
36
+ const error = await runTest({ link: automationLink })
37
+ expect(error).toBeUndefined()
38
+ })
39
+
40
+ it("should fail given invalid automation schema", async () => {
41
+ const error = await runTest({
42
+ schema: {
43
+ type: PluginType.AUTOMATION,
44
+ schema: {},
45
+ },
46
+ })
47
+ expect(error).toBeDefined()
48
+ })
49
+ })
50
+
51
+ describe("it should be able to validate a component schema", () => {
52
+ it("should return component skeleton schema is valid", async () => {
53
+ const error = await runTest({ link: componentLink })
54
+ expect(error).toBeUndefined()
55
+ })
56
+
57
+ it("should fail given invalid component schema", async () => {
58
+ const error = await runTest({
59
+ schema: {
60
+ type: PluginType.COMPONENT,
61
+ schema: {},
62
+ },
63
+ })
64
+ expect(error).toBeDefined()
65
+ })
66
+ })
67
+
68
+ describe("it should be able to validate a datasource schema", () => {
69
+ it("should return datasource skeleton schema is valid", async () => {
70
+ const error = await runTest({ link: datasourceLink })
71
+ expect(error).toBeUndefined()
72
+ })
73
+
74
+ it("should fail given invalid datasource schema", async () => {
75
+ const error = await runTest({
76
+ schema: {
77
+ type: PluginType.DATASOURCE,
78
+ schema: {},
79
+ },
80
+ })
81
+ expect(error).toBeDefined()
82
+ })
83
+ })
@@ -1,4 +1,12 @@
1
- import { DatasourceFieldType, QueryType, PluginType } from "@budibase/types"
1
+ import {
2
+ DatasourceFieldType,
3
+ QueryType,
4
+ PluginType,
5
+ AutomationStepType,
6
+ AutomationStepIdArray,
7
+ AutomationIOType,
8
+ AutomationCustomIOType,
9
+ } from "@budibase/types"
2
10
  import joi from "joi"
3
11
 
4
12
  const DATASOURCE_TYPES = [
@@ -19,7 +27,7 @@ function runJoi(validator: joi.Schema, schema: any) {
19
27
 
20
28
  function validateComponent(schema: any) {
21
29
  const validator = joi.object({
22
- type: joi.string().allow("component").required(),
30
+ type: joi.string().allow(PluginType.COMPONENT).required(),
23
31
  metadata: joi.object().unknown(true).required(),
24
32
  hash: joi.string().optional(),
25
33
  version: joi.string().optional(),
@@ -53,7 +61,7 @@ function validateDatasource(schema: any) {
53
61
  .required()
54
62
 
55
63
  const validator = joi.object({
56
- type: joi.string().allow("datasource").required(),
64
+ type: joi.string().allow(PluginType.DATASOURCE).required(),
57
65
  metadata: joi.object().unknown(true).required(),
58
66
  hash: joi.string().optional(),
59
67
  version: joi.string().optional(),
@@ -82,6 +90,55 @@ function validateDatasource(schema: any) {
82
90
  runJoi(validator, schema)
83
91
  }
84
92
 
93
+ function validateAutomation(schema: any) {
94
+ const basePropsValidator = joi.object().pattern(joi.string(), {
95
+ type: joi
96
+ .string()
97
+ .allow(...Object.values(AutomationIOType))
98
+ .required(),
99
+ customType: joi.string().allow(...Object.values(AutomationCustomIOType)),
100
+ title: joi.string(),
101
+ description: joi.string(),
102
+ enum: joi.array().items(joi.string()),
103
+ pretty: joi.array().items(joi.string()),
104
+ })
105
+ const stepSchemaValidator = joi
106
+ .object({
107
+ properties: basePropsValidator,
108
+ required: joi.array().items(joi.string()),
109
+ })
110
+ .concat(basePropsValidator)
111
+ .required()
112
+ const validator = joi.object({
113
+ type: joi.string().allow(PluginType.AUTOMATION).required(),
114
+ metadata: joi.object().unknown(true).required(),
115
+ hash: joi.string().optional(),
116
+ version: joi.string().optional(),
117
+ schema: joi.object({
118
+ name: joi.string().required(),
119
+ tagline: joi.string().required(),
120
+ icon: joi.string().required(),
121
+ description: joi.string().required(),
122
+ type: joi
123
+ .string()
124
+ .allow(AutomationStepType.ACTION, AutomationStepType.LOGIC)
125
+ .required(),
126
+ stepId: joi
127
+ .string()
128
+ .disallow(...AutomationStepIdArray)
129
+ .required(),
130
+ inputs: joi.object().optional(),
131
+ schema: joi
132
+ .object({
133
+ inputs: stepSchemaValidator,
134
+ outputs: stepSchemaValidator,
135
+ })
136
+ .required(),
137
+ }),
138
+ })
139
+ runJoi(validator, schema)
140
+ }
141
+
85
142
  export function validate(schema: any) {
86
143
  switch (schema?.type) {
87
144
  case PluginType.COMPONENT:
@@ -90,6 +147,9 @@ export function validate(schema: any) {
90
147
  case PluginType.DATASOURCE:
91
148
  validateDatasource(schema)
92
149
  break
150
+ case PluginType.AUTOMATION:
151
+ validateAutomation(schema)
152
+ break
93
153
  default:
94
154
  throw new Error(`Unknown plugin type - check schema.json: ${schema.type}`)
95
155
  }
@@ -2,4 +2,5 @@ export enum JobQueue {
2
2
  AUTOMATION = "automationQueue",
3
3
  APP_BACKUP = "appBackupQueue",
4
4
  AUDIT_LOG = "auditLogQueue",
5
+ SYSTEM_EVENT_QUEUE = "systemEventQueue",
5
6
  }
@@ -1,10 +1,16 @@
1
- import Redlock, { Options } from "redlock"
1
+ import Redlock from "redlock"
2
2
  import { getLockClient } from "./init"
3
3
  import { LockOptions, LockType } from "@budibase/types"
4
4
  import * as context from "../context"
5
5
  import env from "../environment"
6
6
 
7
- const getClient = async (type: LockType): Promise<Redlock> => {
7
+ const getClient = async (
8
+ type: LockType,
9
+ opts?: Redlock.Options
10
+ ): Promise<Redlock> => {
11
+ if (type === LockType.CUSTOM) {
12
+ return newRedlock(opts)
13
+ }
8
14
  if (env.isTest() && type !== LockType.TRY_ONCE) {
9
15
  return newRedlock(OPTIONS.TEST)
10
16
  }
@@ -56,7 +62,7 @@ const OPTIONS = {
56
62
  },
57
63
  }
58
64
 
59
- const newRedlock = async (opts: Options = {}) => {
65
+ const newRedlock = async (opts: Redlock.Options = {}) => {
60
66
  let options = { ...OPTIONS.DEFAULT, ...opts }
61
67
  const redisWrapper = await getLockClient()
62
68
  const client = redisWrapper.getClient()
@@ -12,7 +12,7 @@ export enum SecretOption {
12
12
  ENCRYPTION = "encryption",
13
13
  }
14
14
 
15
- function getSecret(secretOption: SecretOption): string {
15
+ export function getSecret(secretOption: SecretOption): string {
16
16
  let secret, secretName
17
17
  switch (secretOption) {
18
18
  case SecretOption.ENCRYPTION:
@@ -24,7 +24,7 @@ export enum PermissionType {
24
24
  QUERY = "query",
25
25
  }
26
26
 
27
- class Permission {
27
+ export class Permission {
28
28
  type: PermissionType
29
29
  level: PermissionLevel
30
30
 
@@ -34,7 +34,7 @@ class Permission {
34
34
  }
35
35
  }
36
36
 
37
- function levelToNumber(perm: PermissionLevel) {
37
+ export function levelToNumber(perm: PermissionLevel) {
38
38
  switch (perm) {
39
39
  // not everything has execute privileges
40
40
  case PermissionLevel.EXECUTE:
@@ -55,7 +55,7 @@ function levelToNumber(perm: PermissionLevel) {
55
55
  * @param {string} userPermLevel The permission level of the user.
56
56
  * @return {string[]} All the permission levels this user is allowed to carry out.
57
57
  */
58
- function getAllowedLevels(userPermLevel: PermissionLevel) {
58
+ export function getAllowedLevels(userPermLevel: PermissionLevel): string[] {
59
59
  switch (userPermLevel) {
60
60
  case PermissionLevel.EXECUTE:
61
61
  return [PermissionLevel.EXECUTE]
@@ -64,9 +64,9 @@ function getAllowedLevels(userPermLevel: PermissionLevel) {
64
64
  case PermissionLevel.WRITE:
65
65
  case PermissionLevel.ADMIN:
66
66
  return [
67
+ PermissionLevel.EXECUTE,
67
68
  PermissionLevel.READ,
68
69
  PermissionLevel.WRITE,
69
- PermissionLevel.EXECUTE,
70
70
  ]
71
71
  default:
72
72
  return []
@@ -81,7 +81,7 @@ export enum BuiltinPermissionID {
81
81
  POWER = "power",
82
82
  }
83
83
 
84
- const BUILTIN_PERMISSIONS = {
84
+ export const BUILTIN_PERMISSIONS = {
85
85
  PUBLIC: {
86
86
  _id: BuiltinPermissionID.PUBLIC,
87
87
  name: "Public",
@@ -0,0 +1,31 @@
1
+ import { encrypt, decrypt, SecretOption, getSecret } from "../encryption"
2
+ import env from "../../environment"
3
+
4
+ describe("encryption", () => {
5
+ it("should throw an error if API encryption key is not set", () => {
6
+ const jwt = getSecret(SecretOption.API)
7
+ expect(jwt).toBe(env.JWT_SECRET)
8
+ })
9
+
10
+ it("should throw an error if encryption key is not set", () => {
11
+ expect(() => getSecret(SecretOption.ENCRYPTION)).toThrow(
12
+ 'Secret "ENCRYPTION_KEY" has not been set in environment.'
13
+ )
14
+ })
15
+
16
+ it("should encrypt and decrypt a string using API encryption key", () => {
17
+ env._set("API_ENCRYPTION_KEY", "api_secret")
18
+ const plaintext = "budibase"
19
+ const apiEncrypted = encrypt(plaintext, SecretOption.API)
20
+ const decrypted = decrypt(apiEncrypted, SecretOption.API)
21
+ expect(decrypted).toEqual(plaintext)
22
+ })
23
+
24
+ it("should encrypt and decrypt a string using encryption key", () => {
25
+ env._set("ENCRYPTION_KEY", "normal_secret")
26
+ const plaintext = "budibase"
27
+ const encryptionEncrypted = encrypt(plaintext, SecretOption.ENCRYPTION)
28
+ const decrypted = decrypt(encryptionEncrypted, SecretOption.ENCRYPTION)
29
+ expect(decrypted).toEqual(plaintext)
30
+ })
31
+ })
@@ -0,0 +1,145 @@
1
+ import { cloneDeep } from "lodash"
2
+ import * as permissions from "../permissions"
3
+ import { BUILTIN_ROLE_IDS } from "../roles"
4
+
5
+ describe("levelToNumber", () => {
6
+ it("should return 0 for EXECUTE", () => {
7
+ expect(permissions.levelToNumber(permissions.PermissionLevel.EXECUTE)).toBe(
8
+ 0
9
+ )
10
+ })
11
+
12
+ it("should return 1 for READ", () => {
13
+ expect(permissions.levelToNumber(permissions.PermissionLevel.READ)).toBe(1)
14
+ })
15
+
16
+ it("should return 2 for WRITE", () => {
17
+ expect(permissions.levelToNumber(permissions.PermissionLevel.WRITE)).toBe(2)
18
+ })
19
+
20
+ it("should return 3 for ADMIN", () => {
21
+ expect(permissions.levelToNumber(permissions.PermissionLevel.ADMIN)).toBe(3)
22
+ })
23
+
24
+ it("should return -1 for an unknown permission level", () => {
25
+ expect(
26
+ permissions.levelToNumber("unknown" as permissions.PermissionLevel)
27
+ ).toBe(-1)
28
+ })
29
+ })
30
+ describe("getAllowedLevels", () => {
31
+ it('should return ["execute"] for EXECUTE', () => {
32
+ expect(
33
+ permissions.getAllowedLevels(permissions.PermissionLevel.EXECUTE)
34
+ ).toEqual([permissions.PermissionLevel.EXECUTE])
35
+ })
36
+
37
+ it('should return ["execute", "read"] for READ', () => {
38
+ expect(
39
+ permissions.getAllowedLevels(permissions.PermissionLevel.READ)
40
+ ).toEqual([
41
+ permissions.PermissionLevel.EXECUTE,
42
+ permissions.PermissionLevel.READ,
43
+ ])
44
+ })
45
+
46
+ it('should return ["execute", "read", "write"] for WRITE', () => {
47
+ expect(
48
+ permissions.getAllowedLevels(permissions.PermissionLevel.WRITE)
49
+ ).toEqual([
50
+ permissions.PermissionLevel.EXECUTE,
51
+ permissions.PermissionLevel.READ,
52
+ permissions.PermissionLevel.WRITE,
53
+ ])
54
+ })
55
+
56
+ it('should return ["execute", "read", "write"] for ADMIN', () => {
57
+ expect(
58
+ permissions.getAllowedLevels(permissions.PermissionLevel.ADMIN)
59
+ ).toEqual([
60
+ permissions.PermissionLevel.EXECUTE,
61
+ permissions.PermissionLevel.READ,
62
+ permissions.PermissionLevel.WRITE,
63
+ ])
64
+ })
65
+
66
+ it("should return [] for an unknown permission level", () => {
67
+ expect(
68
+ permissions.getAllowedLevels("unknown" as permissions.PermissionLevel)
69
+ ).toEqual([])
70
+ })
71
+ })
72
+
73
+ describe("doesHaveBasePermission", () => {
74
+ it("should return true if base permission has the required level", () => {
75
+ const permType = permissions.PermissionType.USER
76
+ const permLevel = permissions.PermissionLevel.READ
77
+ const rolesHierarchy = [
78
+ {
79
+ roleId: BUILTIN_ROLE_IDS.ADMIN,
80
+ permissionId: permissions.BuiltinPermissionID.ADMIN,
81
+ },
82
+ ]
83
+ expect(
84
+ permissions.doesHaveBasePermission(permType, permLevel, rolesHierarchy)
85
+ ).toBe(true)
86
+ })
87
+
88
+ it("should return false if base permission does not have the required level", () => {
89
+ const permType = permissions.PermissionType.APP
90
+ const permLevel = permissions.PermissionLevel.READ
91
+ const rolesHierarchy = [
92
+ {
93
+ roleId: BUILTIN_ROLE_IDS.PUBLIC,
94
+ permissionId: permissions.BuiltinPermissionID.PUBLIC,
95
+ },
96
+ ]
97
+ expect(
98
+ permissions.doesHaveBasePermission(permType, permLevel, rolesHierarchy)
99
+ ).toBe(false)
100
+ })
101
+ })
102
+
103
+ describe("isPermissionLevelHigherThanRead", () => {
104
+ it("should return true if level is higher than read", () => {
105
+ expect(
106
+ permissions.isPermissionLevelHigherThanRead(
107
+ permissions.PermissionLevel.WRITE
108
+ )
109
+ ).toBe(true)
110
+ })
111
+
112
+ it("should return false if level is read or lower", () => {
113
+ expect(
114
+ permissions.isPermissionLevelHigherThanRead(
115
+ permissions.PermissionLevel.READ
116
+ )
117
+ ).toBe(false)
118
+ })
119
+ })
120
+
121
+ describe("getBuiltinPermissions", () => {
122
+ it("returns a clone of the builtin permissions", () => {
123
+ const builtins = permissions.getBuiltinPermissions()
124
+ expect(builtins).toEqual(cloneDeep(permissions.BUILTIN_PERMISSIONS))
125
+ expect(builtins).not.toBe(permissions.BUILTIN_PERMISSIONS)
126
+ })
127
+ })
128
+
129
+ describe("getBuiltinPermissionByID", () => {
130
+ it("returns correct permission object for valid ID", () => {
131
+ const expectedPermission = {
132
+ _id: permissions.BuiltinPermissionID.PUBLIC,
133
+ name: "Public",
134
+ permissions: [
135
+ new permissions.Permission(
136
+ permissions.PermissionType.WEBHOOK,
137
+ permissions.PermissionLevel.EXECUTE
138
+ ),
139
+ ],
140
+ }
141
+ expect(permissions.getBuiltinPermissionByID("public")).toEqual(
142
+ expectedPermission
143
+ )
144
+ })
145
+ })
@@ -3,8 +3,8 @@ import {
3
3
  getTenantId,
4
4
  getTenantIDFromAppID,
5
5
  isMultiTenant,
6
+ getPlatformURL,
6
7
  } from "../context"
7
- import env from "../environment"
8
8
  import {
9
9
  BBContext,
10
10
  TenantResolutionStrategy,
@@ -93,7 +93,7 @@ export const getTenantIDFromCtx = (
93
93
  // subdomain
94
94
  if (isAllowed(TenantResolutionStrategy.SUBDOMAIN)) {
95
95
  // e.g. budibase.app or local.com:10000
96
- const platformHost = new URL(env.PLATFORM_URL).host.split(":")[0]
96
+ const platformHost = new URL(getPlatformURL()).host.split(":")[0]
97
97
  // e.g. tenant.budibase.app or tenant.local.com
98
98
  const requestHost = ctx.host
99
99
  // parse the tenant id from the difference
@@ -0,0 +1,184 @@
1
+ import { TenantResolutionStrategy } from "@budibase/types"
2
+ import { addTenantToUrl, isUserInAppTenant, getTenantIDFromCtx } from "../"
3
+ import { isMultiTenant, getTenantIDFromAppID } from "../../context"
4
+
5
+ jest.mock("../../context", () => ({
6
+ getTenantId: jest.fn(() => "budibase"),
7
+ isMultiTenant: jest.fn(() => true),
8
+ getTenantIDFromAppID: jest.fn(),
9
+ getPlatformURL: jest.fn(() => "https://app.com"),
10
+ DEFAULT_TENANT_ID: "default",
11
+ }))
12
+
13
+ const mockedIsMultiTenant = isMultiTenant as jest.MockedFunction<
14
+ typeof isMultiTenant
15
+ >
16
+ const mockedGetTenantIDFromAppID = getTenantIDFromAppID as jest.MockedFunction<
17
+ typeof getTenantIDFromAppID
18
+ >
19
+
20
+ describe("addTenantToUrl", () => {
21
+ it("should append tenantId parameter to the URL", () => {
22
+ const url = "https://budibase.com"
23
+ const expectedUrl = "https://budibase.com?tenantId=budibase"
24
+ expect(addTenantToUrl(url)).toEqual(expectedUrl)
25
+ })
26
+
27
+ it("should append tenantId parameter to the URL query string", () => {
28
+ const url = "https://budibase.com?var=test"
29
+ const expectedUrl = "https://budibase.com?var=test&tenantId=budibase"
30
+ expect(addTenantToUrl(url)).toEqual(expectedUrl)
31
+ })
32
+
33
+ it("should not append tenantId parameter to the URL if isMultiTenant is false", () => {
34
+ mockedIsMultiTenant.mockImplementation(() => false)
35
+
36
+ const url = "https://budibase.com"
37
+ const expectedUrl = "https://budibase.com"
38
+ expect(addTenantToUrl(url)).toEqual(expectedUrl)
39
+ })
40
+ })
41
+
42
+ describe("isUserInAppTenant", () => {
43
+ mockedGetTenantIDFromAppID.mockImplementation(() => "budibase")
44
+ const mockUser = { tenantId: "budibase" }
45
+
46
+ it("returns true if user tenant ID matches app tenant ID", () => {
47
+ const appId = "app-budibase"
48
+ const result = isUserInAppTenant(appId, mockUser)
49
+ expect(result).toBe(true)
50
+ })
51
+
52
+ it("uses default tenant ID if user is not provided", () => {
53
+ const appId = "app-budibase"
54
+ const result = isUserInAppTenant(appId)
55
+ expect(result).toBe(true)
56
+ })
57
+
58
+ it("uses default tenant ID if app tenant ID is not found", () => {
59
+ const appId = "not-budibase-app"
60
+ const result = isUserInAppTenant(appId, mockUser)
61
+ expect(result).toBe(true)
62
+ })
63
+
64
+ it("returns false if user tenant ID does not match app tenant ID", () => {
65
+ const appId = "app-budibase"
66
+ mockedGetTenantIDFromAppID.mockImplementation(() => "not-budibase")
67
+ const result = isUserInAppTenant(appId, mockUser)
68
+ expect(result).toBe(false)
69
+ })
70
+ })
71
+
72
+ let mockOpts: any = {}
73
+ function createCtx(opts: {
74
+ originalUrl?: string
75
+ headers?: Record<string, string>
76
+ qsTenantId?: string
77
+ userTenantId?: string
78
+ host?: string
79
+ path?: string
80
+ }) {
81
+ const createdCtx: any = {
82
+ originalUrl: opts.originalUrl || "budibase.com",
83
+ matched: [{ name: "name" }],
84
+ throw: jest.fn(),
85
+ request: { headers: {} },
86
+ }
87
+ if (opts.headers) {
88
+ createdCtx.request.headers = opts.headers
89
+ }
90
+ if (opts.qsTenantId) {
91
+ createdCtx.request.query = { tenantId: opts.qsTenantId }
92
+ }
93
+ if (opts.userTenantId) {
94
+ createdCtx.user = { tenantId: opts.userTenantId }
95
+ }
96
+ if (opts.host) {
97
+ createdCtx.host = opts.host
98
+ }
99
+ if (opts.path) {
100
+ createdCtx.matched = [
101
+ {
102
+ paramNames: [{ name: "tenantId" }],
103
+ params: () => ({ tenantId: opts.path }),
104
+ captures: jest.fn(),
105
+ },
106
+ ]
107
+ }
108
+
109
+ return createdCtx as any
110
+ }
111
+
112
+ describe("getTenantIDFromCtx", () => {
113
+ describe("when tenant can be found", () => {
114
+ it("returns the tenant ID from the user object", () => {
115
+ mockedIsMultiTenant.mockImplementation(() => true)
116
+ const ctx = createCtx({ userTenantId: "budibase" })
117
+ expect(getTenantIDFromCtx(ctx, mockOpts)).toEqual("budibase")
118
+ })
119
+
120
+ it("returns the tenant ID from the header", () => {
121
+ mockedIsMultiTenant.mockImplementation(() => true)
122
+ const ctx = createCtx({ headers: { "x-budibase-tenant-id": "budibase" } })
123
+ mockOpts = { includeStrategies: [TenantResolutionStrategy.HEADER] }
124
+ expect(getTenantIDFromCtx(ctx, mockOpts)).toEqual("budibase")
125
+ })
126
+
127
+ it("returns the tenant ID from the query param", () => {
128
+ mockedIsMultiTenant.mockImplementation(() => true)
129
+ mockOpts = { includeStrategies: [TenantResolutionStrategy.QUERY] }
130
+ const ctx = createCtx({ qsTenantId: "budibase" })
131
+ expect(getTenantIDFromCtx(ctx, mockOpts)).toEqual("budibase")
132
+ })
133
+
134
+ it("returns the tenant ID from the subdomain", () => {
135
+ mockedIsMultiTenant.mockImplementation(() => true)
136
+ const ctx = createCtx({ host: "bb.app.com" })
137
+ mockOpts = { includeStrategies: [TenantResolutionStrategy.SUBDOMAIN] }
138
+ expect(getTenantIDFromCtx(ctx, mockOpts)).toEqual("bb")
139
+ })
140
+
141
+ it("returns the tenant ID from the path", () => {
142
+ mockedIsMultiTenant.mockImplementation(() => true)
143
+ const ctx = createCtx({ path: "bb" })
144
+ mockOpts = { includeStrategies: [TenantResolutionStrategy.PATH] }
145
+ expect(getTenantIDFromCtx(ctx, mockOpts)).toEqual("bb")
146
+ })
147
+ })
148
+
149
+ describe("when tenant cannot be found", () => {
150
+ it("throws a 403 error if allowNoTenant is false", () => {
151
+ const ctx = createCtx({})
152
+ mockOpts = {
153
+ allowNoTenant: false,
154
+ excludeStrategies: [
155
+ TenantResolutionStrategy.QUERY,
156
+ TenantResolutionStrategy.SUBDOMAIN,
157
+ TenantResolutionStrategy.PATH,
158
+ ],
159
+ }
160
+ expect(getTenantIDFromCtx(ctx, mockOpts)).toBeNull()
161
+ expect(ctx.throw).toBeCalledTimes(1)
162
+ expect(ctx.throw).toBeCalledWith(403, "Tenant id not set")
163
+ })
164
+
165
+ it("returns null if allowNoTenant is true", () => {
166
+ const ctx = createCtx({})
167
+ mockOpts = {
168
+ allowNoTenant: true,
169
+ excludeStrategies: [
170
+ TenantResolutionStrategy.QUERY,
171
+ TenantResolutionStrategy.SUBDOMAIN,
172
+ TenantResolutionStrategy.PATH,
173
+ ],
174
+ }
175
+ expect(getTenantIDFromCtx(ctx, mockOpts)).toBeNull()
176
+ })
177
+ })
178
+
179
+ it("returns the default tenant ID when isMultiTenant() returns false", () => {
180
+ mockedIsMultiTenant.mockImplementation(() => false)
181
+ const ctx = createCtx({})
182
+ expect(getTenantIDFromCtx(ctx, mockOpts)).toEqual("default")
183
+ })
184
+ })