@budibase/server 1.0.48 → 1.0.49-alpha.3

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 (289) hide show
  1. package/builder/assets/{index.e083dcaf.js → index.21e57eb4.js} +234 -231
  2. package/builder/assets/index.83c0944f.css +1 -0
  3. package/builder/assets/{vendor.f9faf6ab.js → vendor.d526bfe8.js} +12 -12
  4. package/builder/index.html +3 -3
  5. package/coverage/clover.xml +2338 -2028
  6. package/coverage/coverage-final.json +100 -95
  7. package/coverage/lcov-report/api/controllers/analytics.js.html +1 -1
  8. package/coverage/lcov-report/api/controllers/apikeys.js.html +1 -1
  9. package/coverage/lcov-report/api/controllers/application.js.html +210 -126
  10. package/coverage/lcov-report/api/controllers/auth.js.html +18 -6
  11. package/coverage/lcov-report/api/controllers/automation.js.html +21 -21
  12. package/coverage/lcov-report/api/controllers/backup.js.html +1 -1
  13. package/coverage/lcov-report/api/controllers/cloud.js.html +1 -1
  14. package/coverage/lcov-report/api/controllers/component.js.html +4 -4
  15. package/coverage/lcov-report/api/controllers/datasource.js.html +72 -36
  16. package/coverage/lcov-report/api/controllers/dev.js.html +1 -1
  17. package/coverage/lcov-report/api/controllers/index.html +53 -53
  18. package/coverage/lcov-report/api/controllers/integration.js.html +1 -1
  19. package/coverage/lcov-report/api/controllers/layout.js.html +6 -6
  20. package/coverage/lcov-report/api/controllers/metadata.js.html +1 -1
  21. package/coverage/lcov-report/api/controllers/migrations.js.html +119 -0
  22. package/coverage/lcov-report/api/controllers/permission.js.html +15 -15
  23. package/coverage/lcov-report/api/controllers/query/index.html +1 -1
  24. package/coverage/lcov-report/api/controllers/query/index.js.html +19 -19
  25. package/coverage/lcov-report/api/controllers/query/validation.js.html +6 -6
  26. package/coverage/lcov-report/api/controllers/role.js.html +9 -9
  27. package/coverage/lcov-report/api/controllers/routing.js.html +1 -1
  28. package/coverage/lcov-report/api/controllers/row/external.js.html +16 -16
  29. package/coverage/lcov-report/api/controllers/row/index.html +48 -33
  30. package/coverage/lcov-report/api/controllers/row/index.js.html +26 -26
  31. package/coverage/lcov-report/api/controllers/row/internal.js.html +95 -158
  32. package/coverage/lcov-report/api/controllers/row/internalSearch.js.html +41 -17
  33. package/coverage/lcov-report/api/controllers/row/staticFormula.js.html +551 -0
  34. package/coverage/lcov-report/api/controllers/row/utils.js.html +39 -57
  35. package/coverage/lcov-report/api/controllers/screen.js.html +7 -7
  36. package/coverage/lcov-report/api/controllers/script.js.html +4 -4
  37. package/coverage/lcov-report/api/controllers/table/bulkFormula.js.html +629 -0
  38. package/coverage/lcov-report/api/controllers/table/external.js.html +12 -12
  39. package/coverage/lcov-report/api/controllers/table/index.html +46 -31
  40. package/coverage/lcov-report/api/controllers/table/index.js.html +53 -77
  41. package/coverage/lcov-report/api/controllers/table/internal.js.html +59 -35
  42. package/coverage/lcov-report/api/controllers/table/utils.js.html +217 -73
  43. package/coverage/lcov-report/api/controllers/templates.js.html +1 -1
  44. package/coverage/lcov-report/api/controllers/user.js.html +30 -24
  45. package/coverage/lcov-report/api/controllers/view/exporters.js.html +4 -4
  46. package/coverage/lcov-report/api/controllers/view/index.html +1 -1
  47. package/coverage/lcov-report/api/controllers/view/index.js.html +14 -14
  48. package/coverage/lcov-report/api/controllers/view/utils.js.html +11 -11
  49. package/coverage/lcov-report/api/controllers/view/viewBuilder.js.html +7 -7
  50. package/coverage/lcov-report/api/controllers/webhook.js.html +15 -15
  51. package/coverage/lcov-report/api/index.html +1 -1
  52. package/coverage/lcov-report/api/index.js.html +8 -8
  53. package/coverage/lcov-report/api/routes/analytics.js.html +1 -1
  54. package/coverage/lcov-report/api/routes/apikeys.js.html +1 -1
  55. package/coverage/lcov-report/api/routes/application.js.html +1 -1
  56. package/coverage/lcov-report/api/routes/auth.js.html +1 -1
  57. package/coverage/lcov-report/api/routes/automation.js.html +1 -1
  58. package/coverage/lcov-report/api/routes/backup.js.html +1 -1
  59. package/coverage/lcov-report/api/routes/cloud.js.html +1 -1
  60. package/coverage/lcov-report/api/routes/component.js.html +1 -1
  61. package/coverage/lcov-report/api/routes/datasource.js.html +1 -1
  62. package/coverage/lcov-report/api/routes/deploy.js.html +1 -1
  63. package/coverage/lcov-report/api/routes/dev.js.html +1 -1
  64. package/coverage/lcov-report/api/routes/index.html +18 -18
  65. package/coverage/lcov-report/api/routes/index.js.html +3 -3
  66. package/coverage/lcov-report/api/routes/integration.js.html +1 -1
  67. package/coverage/lcov-report/api/routes/layout.js.html +1 -1
  68. package/coverage/lcov-report/api/routes/metadata.js.html +1 -1
  69. package/coverage/lcov-report/api/routes/{hosting.js.html → migrations.js.html} +17 -14
  70. package/coverage/lcov-report/api/routes/permission.js.html +1 -1
  71. package/coverage/lcov-report/api/routes/query.js.html +1 -1
  72. package/coverage/lcov-report/api/routes/role.js.html +1 -1
  73. package/coverage/lcov-report/api/routes/routing.js.html +1 -1
  74. package/coverage/lcov-report/api/routes/row.js.html +1 -1
  75. package/coverage/lcov-report/api/routes/screen.js.html +1 -1
  76. package/coverage/lcov-report/api/routes/script.js.html +1 -1
  77. package/coverage/lcov-report/api/routes/static.js.html +17 -2
  78. package/coverage/lcov-report/api/routes/table.js.html +1 -1
  79. package/coverage/lcov-report/api/routes/templates.js.html +1 -1
  80. package/coverage/lcov-report/api/routes/user.js.html +1 -1
  81. package/coverage/lcov-report/api/routes/view.js.html +1 -1
  82. package/coverage/lcov-report/api/routes/webhook.js.html +1 -1
  83. package/coverage/lcov-report/automations/actions.js.html +24 -24
  84. package/coverage/lcov-report/automations/automationUtils.js.html +5 -5
  85. package/coverage/lcov-report/automations/bullboard.js.html +16 -16
  86. package/coverage/lcov-report/automations/index.html +1 -1
  87. package/coverage/lcov-report/automations/index.js.html +1 -1
  88. package/coverage/lcov-report/automations/steps/bash.js.html +6 -6
  89. package/coverage/lcov-report/automations/steps/createRow.js.html +13 -19
  90. package/coverage/lcov-report/automations/steps/delay.js.html +4 -4
  91. package/coverage/lcov-report/automations/steps/deleteRow.js.html +11 -20
  92. package/coverage/lcov-report/automations/steps/discord.js.html +7 -7
  93. package/coverage/lcov-report/automations/steps/executeQuery.js.html +6 -6
  94. package/coverage/lcov-report/automations/steps/executeScript.js.html +6 -6
  95. package/coverage/lcov-report/automations/steps/filter.js.html +7 -7
  96. package/coverage/lcov-report/automations/steps/index.html +13 -13
  97. package/coverage/lcov-report/automations/steps/integromat.js.html +5 -5
  98. package/coverage/lcov-report/automations/steps/outgoingWebhook.js.html +8 -8
  99. package/coverage/lcov-report/automations/steps/queryRows.js.html +10 -10
  100. package/coverage/lcov-report/automations/steps/sendSmtpEmail.js.html +5 -5
  101. package/coverage/lcov-report/automations/steps/serverLog.js.html +3 -3
  102. package/coverage/lcov-report/automations/steps/slack.js.html +5 -5
  103. package/coverage/lcov-report/automations/steps/updateRow.js.html +6 -6
  104. package/coverage/lcov-report/automations/steps/utils.js.html +3 -3
  105. package/coverage/lcov-report/automations/steps/zapier.js.html +5 -5
  106. package/coverage/lcov-report/automations/triggerInfo/app.js.html +2 -2
  107. package/coverage/lcov-report/automations/triggerInfo/cron.js.html +2 -2
  108. package/coverage/lcov-report/automations/triggerInfo/index.html +1 -1
  109. package/coverage/lcov-report/automations/triggerInfo/index.js.html +8 -8
  110. package/coverage/lcov-report/automations/triggerInfo/rowDeleted.js.html +2 -2
  111. package/coverage/lcov-report/automations/triggerInfo/rowSaved.js.html +2 -2
  112. package/coverage/lcov-report/automations/triggerInfo/rowUpdated.js.html +2 -2
  113. package/coverage/lcov-report/automations/triggerInfo/webhook.js.html +2 -2
  114. package/coverage/lcov-report/automations/triggers.js.html +18 -18
  115. package/coverage/lcov-report/automations/utils.js.html +32 -32
  116. package/coverage/lcov-report/constants/index.html +5 -5
  117. package/coverage/lcov-report/constants/index.js.html +53 -26
  118. package/coverage/lcov-report/constants/layouts.js.html +5 -5
  119. package/coverage/lcov-report/constants/screens.js.html +4 -4
  120. package/coverage/lcov-report/db/client.js.html +18 -18
  121. package/coverage/lcov-report/db/inMemoryView.js.html +7 -7
  122. package/coverage/lcov-report/db/index.html +15 -15
  123. package/coverage/lcov-report/db/index.js.html +3 -3
  124. package/coverage/lcov-report/db/linkedRows/LinkController.js.html +18 -18
  125. package/coverage/lcov-report/db/linkedRows/index.html +10 -10
  126. package/coverage/lcov-report/db/linkedRows/index.js.html +38 -41
  127. package/coverage/lcov-report/db/linkedRows/linkUtils.js.html +15 -15
  128. package/coverage/lcov-report/db/newid.js.html +4 -4
  129. package/coverage/lcov-report/db/utils.js.html +86 -86
  130. package/coverage/lcov-report/events/AutomationEmitter.js.html +1 -1
  131. package/coverage/lcov-report/events/index.html +1 -1
  132. package/coverage/lcov-report/events/index.js.html +5 -5
  133. package/coverage/lcov-report/events/utils.js.html +3 -3
  134. package/coverage/lcov-report/index.html +114 -99
  135. package/coverage/lcov-report/integrations/tests/TestConfiguration.js.html +1 -1
  136. package/coverage/lcov-report/integrations/tests/index.html +1 -1
  137. package/coverage/lcov-report/middleware/appInfo.js.html +1 -1
  138. package/coverage/lcov-report/middleware/authorized.js.html +166 -64
  139. package/coverage/lcov-report/middleware/builder.js.html +8 -8
  140. package/coverage/lcov-report/middleware/currentapp.js.html +29 -29
  141. package/coverage/lcov-report/middleware/index.html +30 -30
  142. package/coverage/lcov-report/middleware/joi-validator.js.html +3 -3
  143. package/coverage/lcov-report/middleware/resourceId.js.html +1 -1
  144. package/coverage/lcov-report/middleware/selfhost.js.html +1 -1
  145. package/coverage/lcov-report/middleware/usageQuota.js.html +270 -42
  146. package/coverage/lcov-report/middleware/utils.js.html +2 -2
  147. package/coverage/lcov-report/threads/automation.js.html +1 -1
  148. package/coverage/lcov-report/threads/index.html +15 -15
  149. package/coverage/lcov-report/threads/index.js.html +10 -10
  150. package/coverage/lcov-report/threads/query.js.html +23 -8
  151. package/coverage/lcov-report/threads/utils.js.html +14 -14
  152. package/coverage/lcov-report/utilities/bcrypt.js.html +1 -1
  153. package/coverage/lcov-report/utilities/budibaseDir.js.html +7 -7
  154. package/coverage/lcov-report/utilities/centralPath.js.html +4 -4
  155. package/coverage/lcov-report/utilities/csvParser.js.html +6 -6
  156. package/coverage/lcov-report/utilities/global.js.html +26 -26
  157. package/coverage/lcov-report/utilities/index.html +19 -19
  158. package/coverage/lcov-report/utilities/index.js.html +25 -25
  159. package/coverage/lcov-report/utilities/queue/inMemoryQueue.js.html +8 -8
  160. package/coverage/lcov-report/utilities/queue/index.html +1 -1
  161. package/coverage/lcov-report/utilities/routing/index.html +1 -1
  162. package/coverage/lcov-report/utilities/routing/index.js.html +1 -1
  163. package/coverage/lcov-report/utilities/rowProcessor/index.html +27 -27
  164. package/coverage/lcov-report/utilities/rowProcessor/index.js.html +115 -79
  165. package/coverage/lcov-report/utilities/rowProcessor/utils.js.html +75 -27
  166. package/coverage/lcov-report/utilities/scriptRunner.js.html +5 -5
  167. package/coverage/lcov-report/utilities/security.js.html +8 -8
  168. package/coverage/lcov-report/utilities/statusCodes.js.html +1 -1
  169. package/coverage/lcov-report/utilities/usageQuota/index.html +141 -0
  170. package/coverage/lcov-report/utilities/usageQuota/index.js.html +356 -0
  171. package/coverage/lcov-report/utilities/usageQuota/rows.js.html +302 -0
  172. package/coverage/lcov-report/{api/controllers/hosting.js.html → utilities/usageQuota/usageQuoteReset.js.html} +36 -48
  173. package/coverage/lcov-report/utilities/users.js.html +5 -5
  174. package/coverage/lcov-report/utilities/workerRequests.js.html +39 -108
  175. package/coverage/lcov.info +3656 -3057
  176. package/dist/api/controllers/application.js +61 -34
  177. package/dist/api/controllers/auth.js +4 -0
  178. package/dist/api/controllers/datasource.js +11 -0
  179. package/dist/api/controllers/migrations.js +21 -0
  180. package/dist/api/controllers/row/internal.js +30 -53
  181. package/dist/api/controllers/row/internalSearch.js +12 -4
  182. package/dist/api/controllers/row/staticFormula.js +147 -0
  183. package/dist/api/controllers/row/utils.js +6 -8
  184. package/dist/api/controllers/static/index.js +59 -10
  185. package/dist/api/controllers/table/bulkFormula.js +160 -0
  186. package/dist/api/controllers/table/index.js +12 -9
  187. package/dist/api/controllers/table/internal.js +9 -0
  188. package/dist/api/controllers/table/utils.js +41 -12
  189. package/dist/api/controllers/user.js +2 -0
  190. package/dist/api/routes/index.js +2 -2
  191. package/dist/api/routes/migrations.js +9 -0
  192. package/dist/api/routes/static.js +2 -1
  193. package/dist/app.js +35 -5
  194. package/dist/automations/steps/createRow.js +2 -4
  195. package/dist/automations/steps/deleteRow.js +1 -4
  196. package/dist/constants/index.js +7 -0
  197. package/dist/db/linkedRows/index.js +4 -5
  198. package/dist/definitions/datasource.js +1 -0
  199. package/dist/environment.js +2 -0
  200. package/dist/integrations/base/sql.js +13 -6
  201. package/dist/integrations/googlesheets.js +340 -0
  202. package/dist/integrations/index.js +3 -0
  203. package/dist/integrations/utils.js +57 -9
  204. package/dist/middleware/authorized.js +55 -30
  205. package/dist/middleware/usageQuota.js +80 -13
  206. package/dist/migrations/functions/appUrls.js +46 -0
  207. package/dist/migrations/functions/quotas1.js +50 -0
  208. package/dist/migrations/functions/usageQuotas/index.js +20 -0
  209. package/dist/migrations/functions/usageQuotas/syncApps.js +32 -0
  210. package/dist/migrations/functions/usageQuotas/syncRows.js +35 -0
  211. package/dist/migrations/functions/userEmailViewCasing.js +24 -0
  212. package/dist/migrations/index.js +62 -0
  213. package/dist/package.json +8 -5
  214. package/dist/tests/utilities/TestConfiguration.js +13 -6
  215. package/dist/threads/query.js +4 -0
  216. package/dist/tsconfig.tsbuildinfo +1 -1
  217. package/dist/utilities/rowProcessor/index.js +18 -11
  218. package/dist/utilities/rowProcessor/utils.js +14 -4
  219. package/dist/utilities/{usageQuota.js → usageQuota/index.js} +44 -31
  220. package/dist/utilities/usageQuota/rows.js +77 -0
  221. package/dist/utilities/usageQuota/usageQuoteReset.js +16 -0
  222. package/dist/utilities/workerRequests.js +0 -20
  223. package/nodemon.json +1 -1
  224. package/package.json +9 -6
  225. package/src/api/controllers/application.js +52 -24
  226. package/src/api/controllers/auth.js +4 -0
  227. package/src/api/controllers/datasource.js +12 -0
  228. package/src/api/controllers/migrations.js +13 -0
  229. package/src/api/controllers/row/internal.js +29 -50
  230. package/src/api/controllers/row/internalSearch.js +12 -4
  231. package/src/api/controllers/row/staticFormula.js +157 -0
  232. package/src/api/controllers/row/utils.js +6 -12
  233. package/src/api/controllers/static/index.js +63 -10
  234. package/src/api/controllers/table/bulkFormula.js +183 -0
  235. package/src/api/controllers/table/index.js +16 -24
  236. package/src/api/controllers/table/internal.js +9 -1
  237. package/src/api/controllers/table/utils.js +57 -9
  238. package/src/api/controllers/user.js +2 -0
  239. package/src/api/routes/index.js +2 -2
  240. package/src/api/routes/migrations.js +14 -0
  241. package/src/api/routes/static.js +5 -0
  242. package/src/api/routes/tests/application.spec.js +2 -2
  243. package/src/api/routes/tests/auth.spec.js +1 -2
  244. package/src/api/routes/tests/static.spec.js +98 -0
  245. package/src/app.ts +18 -5
  246. package/src/automations/steps/createRow.js +2 -4
  247. package/src/automations/steps/deleteRow.js +1 -4
  248. package/src/constants/index.js +9 -0
  249. package/src/db/linkedRows/index.js +4 -5
  250. package/src/definitions/common.ts +3 -0
  251. package/src/definitions/datasource.ts +3 -0
  252. package/src/environment.js +2 -0
  253. package/src/integrations/base/sql.ts +14 -7
  254. package/src/integrations/googlesheets.ts +353 -0
  255. package/src/integrations/index.ts +3 -0
  256. package/src/integrations/tests/sql.spec.js +16 -0
  257. package/src/integrations/utils.ts +71 -11
  258. package/src/middleware/authorized.js +64 -30
  259. package/src/middleware/tests/authorized.spec.js +6 -4
  260. package/src/middleware/tests/usageQuota.spec.js +18 -24
  261. package/src/middleware/usageQuota.js +91 -15
  262. package/src/migrations/functions/appUrls.ts +34 -0
  263. package/src/migrations/functions/quotas1.ts +20 -0
  264. package/src/migrations/functions/tests/appUrls.spec.js +29 -0
  265. package/src/migrations/functions/tests/quotas1.spec.js +27 -0
  266. package/src/migrations/functions/tests/userEmailViewCasing.spec.js +25 -0
  267. package/src/migrations/functions/usageQuotas/index.ts +8 -0
  268. package/src/migrations/functions/usageQuotas/syncApps.ts +18 -0
  269. package/src/migrations/functions/usageQuotas/syncRows.ts +21 -0
  270. package/src/migrations/functions/usageQuotas/tests/syncApps.spec.js +37 -0
  271. package/src/migrations/functions/usageQuotas/tests/syncRows.spec.js +43 -0
  272. package/src/migrations/functions/userEmailViewCasing.ts +13 -0
  273. package/src/migrations/index.ts +56 -0
  274. package/src/tests/utilities/TestConfiguration.js +14 -6
  275. package/src/threads/query.js +5 -0
  276. package/src/utilities/rowProcessor/index.js +24 -12
  277. package/src/utilities/rowProcessor/utils.js +23 -7
  278. package/src/utilities/tests/usageQuota/usageQuota.spec.js +72 -0
  279. package/src/utilities/usageQuota/index.js +92 -0
  280. package/src/utilities/usageQuota/rows.js +74 -0
  281. package/src/utilities/usageQuota/usageQuoteReset.js +18 -0
  282. package/src/utilities/workerRequests.js +0 -23
  283. package/builder/assets/index.39e01193.css +0 -1
  284. package/dist/api/controllers/hosting.js +0 -30
  285. package/dist/api/routes/hosting.js +0 -11
  286. package/src/api/controllers/hosting.js +0 -22
  287. package/src/api/routes/hosting.js +0 -13
  288. package/src/api/routes/tests/hosting.spec.js +0 -36
  289. package/src/utilities/usageQuota.js +0 -73
@@ -12,9 +12,49 @@ const { getUserRoleHierarchy, getRequiredResourceRole, BUILTIN_ROLE_IDS, } = req
12
12
  const { PermissionTypes, doesHaveBasePermission, } = require("@budibase/backend-core/permissions");
13
13
  const builderMiddleware = require("./builder");
14
14
  const { isWebhookEndpoint } = require("./utils");
15
+ const { buildCsrfMiddleware } = require("@budibase/backend-core/auth");
15
16
  function hasResource(ctx) {
16
17
  return ctx.resourceId != null;
17
18
  }
19
+ const csrf = buildCsrfMiddleware();
20
+ /**
21
+ * Apply authorization to the requested resource:
22
+ * - If this is a builder resource the user must be a builder.
23
+ * - Builders can access all resources.
24
+ * - Otherwise the user must have the required role.
25
+ */
26
+ const checkAuthorized = (ctx, resourceRoles, permType, permLevel) => __awaiter(void 0, void 0, void 0, function* () {
27
+ // check if this is a builder api and the user is not a builder
28
+ const isBuilder = ctx.user && ctx.user.builder && ctx.user.builder.global;
29
+ const isBuilderApi = permType === PermissionTypes.BUILDER;
30
+ if (isBuilderApi && !isBuilder) {
31
+ return ctx.throw(403, "Not Authorized");
32
+ }
33
+ // check for resource authorization
34
+ if (!isBuilder) {
35
+ yield checkAuthorizedResource(ctx, resourceRoles, permType, permLevel);
36
+ }
37
+ });
38
+ const checkAuthorizedResource = (ctx, resourceRoles, permType, permLevel) => __awaiter(void 0, void 0, void 0, function* () {
39
+ // get the user's roles
40
+ const roleId = ctx.roleId || BUILTIN_ROLE_IDS.PUBLIC;
41
+ const userRoles = yield getUserRoleHierarchy(ctx.appId, roleId, {
42
+ idOnly: false,
43
+ });
44
+ const permError = "User does not have permission";
45
+ // check if the user has the required role
46
+ if (resourceRoles.length > 0) {
47
+ // deny access if the user doesn't have the required resource role
48
+ const found = userRoles.find(role => resourceRoles.indexOf(role._id) !== -1);
49
+ if (!found) {
50
+ ctx.throw(403, permError);
51
+ }
52
+ // fallback to the base permissions when no resource roles are found
53
+ }
54
+ else if (!doesHaveBasePermission(permType, permLevel, userRoles)) {
55
+ ctx.throw(403, permError);
56
+ }
57
+ });
18
58
  module.exports =
19
59
  (permType, permLevel = null) => (ctx, next) => __awaiter(void 0, void 0, void 0, function* () {
20
60
  // webhooks don't need authentication, each webhook unique
@@ -28,37 +68,22 @@ module.exports =
28
68
  // check general builder stuff, this middleware is a good way
29
69
  // to find API endpoints which are builder focused
30
70
  yield builderMiddleware(ctx, permType);
31
- const isAuthed = ctx.isAuthenticated;
32
- // builders for now have permission to do anything
33
- let isBuilder = ctx.user && ctx.user.builder && ctx.user.builder.global;
34
- const isBuilderApi = permType === PermissionTypes.BUILDER;
35
- if (isBuilder) {
36
- return next();
37
- }
38
- else if (isBuilderApi && !isBuilder) {
39
- return ctx.throw(403, "Not Authorized");
71
+ // get the resource roles
72
+ let resourceRoles = [];
73
+ if (ctx.appId && hasResource(ctx)) {
74
+ resourceRoles = yield getRequiredResourceRole(ctx.appId, permLevel, ctx);
40
75
  }
41
- // need to check this first, in-case public access, don't check authed until last
42
- const roleId = ctx.roleId || BUILTIN_ROLE_IDS.PUBLIC;
43
- const hierarchy = yield getUserRoleHierarchy(ctx.appId, roleId, {
44
- idOnly: false,
45
- });
46
- const permError = "User does not have permission";
47
- let possibleRoleIds = [];
48
- if (hasResource(ctx)) {
49
- possibleRoleIds = yield getRequiredResourceRole(ctx.appId, permLevel, ctx);
50
- }
51
- // check if we found a role, if not fallback to base permissions
52
- if (possibleRoleIds.length > 0) {
53
- const found = hierarchy.find(role => possibleRoleIds.indexOf(role._id) !== -1);
54
- return found ? next() : ctx.throw(403, permError);
55
- }
56
- else if (!doesHaveBasePermission(permType, permLevel, hierarchy)) {
57
- ctx.throw(403, permError);
76
+ // if the resource is public, proceed
77
+ const isPublicResource = resourceRoles.includes(BUILTIN_ROLE_IDS.PUBLIC);
78
+ if (isPublicResource) {
79
+ return next();
58
80
  }
59
- // if they are not authed, then anything using the authorized middleware will fail
60
- if (!isAuthed) {
61
- ctx.throw(403, "Session not authenticated");
81
+ // check authenticated
82
+ if (!ctx.isAuthenticated) {
83
+ return ctx.throw(403, "Session not authenticated");
62
84
  }
63
- return next();
85
+ // check authorized
86
+ yield checkAuthorized(ctx, resourceRoles, permType, permLevel);
87
+ // csrf protection
88
+ return csrf(ctx, next);
64
89
  });
@@ -10,11 +10,8 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge
10
10
  };
11
11
  const CouchDB = require("../db");
12
12
  const usageQuota = require("../utilities/usageQuota");
13
- const env = require("../environment");
14
- const { getTenantId } = require("@budibase/backend-core/tenancy");
13
+ const { getUniqueRows } = require("../utilities/usageQuota/rows");
15
14
  const { isExternalTable, isRowId: isExternalRowId, } = require("../integrations/utils");
16
- // tenants without limits
17
- const EXCLUDED_TENANTS = ["bb", "default", "bbtest", "bbstaging"];
18
15
  // currently only counting new writes and deletes
19
16
  const METHOD_MAP = {
20
17
  POST: 1,
@@ -22,13 +19,13 @@ const METHOD_MAP = {
22
19
  };
23
20
  const DOMAIN_MAP = {
24
21
  rows: usageQuota.Properties.ROW,
25
- upload: usageQuota.Properties.UPLOAD,
26
- views: usageQuota.Properties.VIEW,
27
- users: usageQuota.Properties.USER,
22
+ // upload: usageQuota.Properties.UPLOAD, // doesn't work yet
23
+ // views: usageQuota.Properties.VIEW, // doesn't work yet
24
+ // users: usageQuota.Properties.USER, // doesn't work yet
28
25
  applications: usageQuota.Properties.APPS,
29
26
  // this will not be updated by endpoint calls
30
27
  // instead it will be updated by triggerInfo
31
- automationRuns: usageQuota.Properties.AUTOMATION,
28
+ // automationRuns: usageQuota.Properties.AUTOMATION, // doesn't work yet
32
29
  };
33
30
  function getProperty(url) {
34
31
  for (let domain of Object.keys(DOMAIN_MAP)) {
@@ -38,9 +35,7 @@ function getProperty(url) {
38
35
  }
39
36
  }
40
37
  module.exports = (ctx, next) => __awaiter(void 0, void 0, void 0, function* () {
41
- const tenantId = getTenantId();
42
- // if in development or a self hosted cloud usage quotas should not be executed
43
- if (env.isDev() || env.SELF_HOSTED || EXCLUDED_TENANTS.includes(tenantId)) {
38
+ if (!usageQuota.useQuotas()) {
44
39
  return next();
45
40
  }
46
41
  let usage = METHOD_MAP[ctx.req.method];
@@ -78,10 +73,82 @@ module.exports = (ctx, next) => __awaiter(void 0, void 0, void 0, function* () {
78
73
  usage = files.map(file => file.size).reduce((total, size) => total + size);
79
74
  }
80
75
  try {
81
- yield usageQuota.update(property, usage);
82
- return next();
76
+ yield performRequest(ctx, next, property, usage);
83
77
  }
84
78
  catch (err) {
85
79
  ctx.throw(400, err);
86
80
  }
87
81
  });
82
+ const performRequest = (ctx, next, property, usage) => __awaiter(void 0, void 0, void 0, function* () {
83
+ const usageContext = {
84
+ skipNext: false,
85
+ skipUsage: false,
86
+ [usageQuota.Properties.APPS]: {},
87
+ };
88
+ if (usage === -1) {
89
+ if (PRE_DELETE[property]) {
90
+ yield PRE_DELETE[property](ctx, usageContext);
91
+ }
92
+ }
93
+ else {
94
+ if (PRE_CREATE[property]) {
95
+ yield PRE_CREATE[property](ctx, usageContext);
96
+ }
97
+ }
98
+ // run the request
99
+ if (!usageContext.skipNext) {
100
+ yield usageQuota.update(property, usage, { dryRun: true });
101
+ yield next();
102
+ }
103
+ if (usage === -1) {
104
+ if (POST_DELETE[property]) {
105
+ yield POST_DELETE[property](ctx, usageContext);
106
+ }
107
+ }
108
+ else {
109
+ if (POST_CREATE[property]) {
110
+ yield POST_CREATE[property](ctx, usageContext);
111
+ }
112
+ }
113
+ // update the usage
114
+ if (!usageContext.skipUsage) {
115
+ yield usageQuota.update(property, usage);
116
+ }
117
+ });
118
+ const appPreDelete = (ctx, usageContext) => __awaiter(void 0, void 0, void 0, function* () {
119
+ if (ctx.query.unpublish) {
120
+ // don't run usage decrement for unpublish
121
+ usageContext.skipUsage = true;
122
+ return;
123
+ }
124
+ // store the row count to delete
125
+ const rows = yield getUniqueRows([ctx.appId]);
126
+ if (rows.length) {
127
+ usageContext[usageQuota.Properties.APPS] = { rowCount: rows.length };
128
+ }
129
+ });
130
+ const appPostDelete = (ctx, usageContext) => __awaiter(void 0, void 0, void 0, function* () {
131
+ // delete the app rows from usage
132
+ const rowCount = usageContext[usageQuota.Properties.APPS].rowCount;
133
+ if (rowCount) {
134
+ yield usageQuota.update(usageQuota.Properties.ROW, -rowCount);
135
+ }
136
+ });
137
+ const appPostCreate = (ctx) => __awaiter(void 0, void 0, void 0, function* () {
138
+ // app import & template creation
139
+ if (ctx.request.body.useTemplate === "true") {
140
+ const rows = yield getUniqueRows([ctx.response.body.appId]);
141
+ const rowCount = rows ? rows.length : 0;
142
+ yield usageQuota.update(usageQuota.Properties.ROW, rowCount);
143
+ }
144
+ });
145
+ const PRE_DELETE = {
146
+ [usageQuota.Properties.APPS]: appPreDelete,
147
+ };
148
+ const POST_DELETE = {
149
+ [usageQuota.Properties.APPS]: appPostDelete,
150
+ };
151
+ const PRE_CREATE = {};
152
+ const POST_CREATE = {
153
+ [usageQuota.Properties.APPS]: appPostCreate,
154
+ };
@@ -0,0 +1,46 @@
1
+ "use strict";
2
+ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
3
+ function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
4
+ return new (P || (P = Promise))(function (resolve, reject) {
5
+ function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
6
+ function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
7
+ function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
8
+ step((generator = generator.apply(thisArg, _arguments || [])).next());
9
+ });
10
+ };
11
+ Object.defineProperty(exports, "__esModule", { value: true });
12
+ exports.run = void 0;
13
+ const { DocumentTypes } = require("@budibase/backend-core/db");
14
+ const application_1 = require("../../api/controllers/application");
15
+ /**
16
+ * Date:
17
+ * January 2022
18
+ *
19
+ * Description:
20
+ * Add the url to the app metadata if it doesn't exist
21
+ */
22
+ const run = (appDb) => __awaiter(void 0, void 0, void 0, function* () {
23
+ let metadata;
24
+ try {
25
+ metadata = yield appDb.get(DocumentTypes.APP_METADATA);
26
+ }
27
+ catch (e) {
28
+ // sometimes the metadata document doesn't exist
29
+ // exit early instead of failing the migration
30
+ console.error("Error retrieving app metadata. Skipping", e);
31
+ return;
32
+ }
33
+ if (!metadata.url) {
34
+ const context = {
35
+ request: {
36
+ body: {
37
+ name: metadata.name,
38
+ },
39
+ },
40
+ };
41
+ metadata.url = application_1.getAppUrl(context);
42
+ console.log(`Adding url to app: ${metadata.url}`);
43
+ yield appDb.put(metadata);
44
+ }
45
+ });
46
+ exports.run = run;
@@ -0,0 +1,50 @@
1
+ "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ Object.defineProperty(o, k2, { enumerable: true, get: function() { return m[k]; } });
5
+ }) : (function(o, m, k, k2) {
6
+ if (k2 === undefined) k2 = k;
7
+ o[k2] = m[k];
8
+ }));
9
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
10
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
11
+ }) : function(o, v) {
12
+ o["default"] = v;
13
+ });
14
+ var __importStar = (this && this.__importStar) || function (mod) {
15
+ if (mod && mod.__esModule) return mod;
16
+ var result = {};
17
+ if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
18
+ __setModuleDefault(result, mod);
19
+ return result;
20
+ };
21
+ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
22
+ function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
23
+ return new (P || (P = Promise))(function (resolve, reject) {
24
+ function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
25
+ function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
26
+ function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
27
+ step((generator = generator.apply(thisArg, _arguments || [])).next());
28
+ });
29
+ };
30
+ Object.defineProperty(exports, "__esModule", { value: true });
31
+ exports.run = void 0;
32
+ const usageQuotas_1 = require("./usageQuotas");
33
+ const syncApps = __importStar(require("./usageQuotas/syncApps"));
34
+ const syncRows = __importStar(require("./usageQuotas/syncRows"));
35
+ /**
36
+ * Date:
37
+ * January 2022
38
+ *
39
+ * Description:
40
+ * Synchronise the app and row quotas to the state of the db after it was
41
+ * discovered that the quota resets were still in place and the row quotas
42
+ * weren't being decremented correctly.
43
+ */
44
+ const run = () => __awaiter(void 0, void 0, void 0, function* () {
45
+ yield usageQuotas_1.runQuotaMigration(() => __awaiter(void 0, void 0, void 0, function* () {
46
+ yield syncApps.run();
47
+ yield syncRows.run();
48
+ }));
49
+ });
50
+ exports.run = run;
@@ -0,0 +1,20 @@
1
+ "use strict";
2
+ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
3
+ function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
4
+ return new (P || (P = Promise))(function (resolve, reject) {
5
+ function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
6
+ function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
7
+ function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
8
+ step((generator = generator.apply(thisArg, _arguments || [])).next());
9
+ });
10
+ };
11
+ Object.defineProperty(exports, "__esModule", { value: true });
12
+ exports.runQuotaMigration = void 0;
13
+ const { useQuotas } = require("../../../utilities/usageQuota");
14
+ const runQuotaMigration = (migration) => __awaiter(void 0, void 0, void 0, function* () {
15
+ if (!useQuotas()) {
16
+ return;
17
+ }
18
+ yield migration();
19
+ });
20
+ exports.runQuotaMigration = runQuotaMigration;
@@ -0,0 +1,32 @@
1
+ "use strict";
2
+ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
3
+ function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
4
+ return new (P || (P = Promise))(function (resolve, reject) {
5
+ function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
6
+ function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
7
+ function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
8
+ step((generator = generator.apply(thisArg, _arguments || [])).next());
9
+ });
10
+ };
11
+ var __importDefault = (this && this.__importDefault) || function (mod) {
12
+ return (mod && mod.__esModule) ? mod : { "default": mod };
13
+ };
14
+ Object.defineProperty(exports, "__esModule", { value: true });
15
+ exports.run = void 0;
16
+ const { getGlobalDB, getTenantId } = require("@budibase/backend-core/tenancy");
17
+ const { getAllApps } = require("@budibase/backend-core/db");
18
+ const db_1 = __importDefault(require("../../../db"));
19
+ const usageQuota_1 = require("../../../utilities/usageQuota");
20
+ const run = () => __awaiter(void 0, void 0, void 0, function* () {
21
+ const db = getGlobalDB();
22
+ // get app count
23
+ const devApps = yield getAllApps(db_1.default, { dev: true });
24
+ const appCount = devApps ? devApps.length : 0;
25
+ // sync app count
26
+ const tenantId = getTenantId();
27
+ console.log(`[Tenant: ${tenantId}] Syncing app count: ${appCount}`);
28
+ const usageDoc = yield usageQuota_1.getUsageQuotaDoc(db);
29
+ usageDoc.usageQuota.apps = appCount;
30
+ yield db.put(usageDoc);
31
+ });
32
+ exports.run = run;
@@ -0,0 +1,35 @@
1
+ "use strict";
2
+ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
3
+ function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
4
+ return new (P || (P = Promise))(function (resolve, reject) {
5
+ function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
6
+ function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
7
+ function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
8
+ step((generator = generator.apply(thisArg, _arguments || [])).next());
9
+ });
10
+ };
11
+ var __importDefault = (this && this.__importDefault) || function (mod) {
12
+ return (mod && mod.__esModule) ? mod : { "default": mod };
13
+ };
14
+ Object.defineProperty(exports, "__esModule", { value: true });
15
+ exports.run = void 0;
16
+ const { getGlobalDB, getTenantId } = require("@budibase/backend-core/tenancy");
17
+ const { getAllApps } = require("@budibase/backend-core/db");
18
+ const db_1 = __importDefault(require("../../../db"));
19
+ const usageQuota_1 = require("../../../utilities/usageQuota");
20
+ const rows_1 = require("../../../utilities/usageQuota/rows");
21
+ const run = () => __awaiter(void 0, void 0, void 0, function* () {
22
+ const db = getGlobalDB();
23
+ // get all rows in all apps
24
+ const allApps = yield getAllApps(db_1.default, { all: true });
25
+ const appIds = allApps ? allApps.map((app) => app.appId) : [];
26
+ const rows = yield rows_1.getUniqueRows(appIds);
27
+ const rowCount = rows ? rows.length : 0;
28
+ // sync row count
29
+ const tenantId = getTenantId();
30
+ console.log(`[Tenant: ${tenantId}] Syncing row count: ${rowCount}`);
31
+ const usageDoc = yield usageQuota_1.getUsageQuotaDoc(db);
32
+ usageDoc.usageQuota.rows = rowCount;
33
+ yield db.put(usageDoc);
34
+ });
35
+ exports.run = run;
@@ -0,0 +1,24 @@
1
+ "use strict";
2
+ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
3
+ function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
4
+ return new (P || (P = Promise))(function (resolve, reject) {
5
+ function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
6
+ function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
7
+ function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
8
+ step((generator = generator.apply(thisArg, _arguments || [])).next());
9
+ });
10
+ };
11
+ Object.defineProperty(exports, "__esModule", { value: true });
12
+ exports.run = void 0;
13
+ const { createUserEmailView } = require("@budibase/backend-core/db");
14
+ /**
15
+ * Date:
16
+ * October 2021
17
+ *
18
+ * Description:
19
+ * Recreate the user email view to include latest changes i.e. lower casing the email address
20
+ */
21
+ const run = (db) => __awaiter(void 0, void 0, void 0, function* () {
22
+ yield createUserEmailView(db);
23
+ });
24
+ exports.run = run;
@@ -0,0 +1,62 @@
1
+ "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ Object.defineProperty(o, k2, { enumerable: true, get: function() { return m[k]; } });
5
+ }) : (function(o, m, k, k2) {
6
+ if (k2 === undefined) k2 = k;
7
+ o[k2] = m[k];
8
+ }));
9
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
10
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
11
+ }) : function(o, v) {
12
+ o["default"] = v;
13
+ });
14
+ var __importStar = (this && this.__importStar) || function (mod) {
15
+ if (mod && mod.__esModule) return mod;
16
+ var result = {};
17
+ if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
18
+ __setModuleDefault(result, mod);
19
+ return result;
20
+ };
21
+ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
22
+ function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
23
+ return new (P || (P = Promise))(function (resolve, reject) {
24
+ function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
25
+ function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
26
+ function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
27
+ step((generator = generator.apply(thisArg, _arguments || [])).next());
28
+ });
29
+ };
30
+ var __importDefault = (this && this.__importDefault) || function (mod) {
31
+ return (mod && mod.__esModule) ? mod : { "default": mod };
32
+ };
33
+ Object.defineProperty(exports, "__esModule", { value: true });
34
+ exports.migrate = exports.MIGRATIONS = void 0;
35
+ const db_1 = __importDefault(require("../db"));
36
+ const { MIGRATION_TYPES, runMigrations, } = require("@budibase/backend-core/migrations");
37
+ // migration functions
38
+ const userEmailViewCasing = __importStar(require("./functions/userEmailViewCasing"));
39
+ const quota1 = __importStar(require("./functions/quotas1"));
40
+ const appUrls = __importStar(require("./functions/appUrls"));
41
+ exports.MIGRATIONS = [
42
+ {
43
+ type: MIGRATION_TYPES.GLOBAL,
44
+ name: "user_email_view_casing",
45
+ fn: userEmailViewCasing.run,
46
+ },
47
+ {
48
+ type: MIGRATION_TYPES.GLOBAL,
49
+ name: "quotas_1",
50
+ fn: quota1.run,
51
+ },
52
+ {
53
+ type: MIGRATION_TYPES.APP,
54
+ name: "app_urls",
55
+ opts: { all: true },
56
+ fn: appUrls.run,
57
+ },
58
+ ];
59
+ const migrate = (options) => __awaiter(void 0, void 0, void 0, function* () {
60
+ yield runMigrations(db_1.default, exports.MIGRATIONS, options);
61
+ });
62
+ exports.migrate = migrate;
package/dist/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@budibase/server",
3
3
  "email": "hi@budibase.com",
4
- "version": "1.0.47",
4
+ "version": "1.0.49-alpha.2",
5
5
  "description": "Budibase Web Server",
6
6
  "main": "src/index.ts",
7
7
  "repository": {
@@ -70,9 +70,9 @@
70
70
  "license": "GPL-3.0",
71
71
  "dependencies": {
72
72
  "@apidevtools/swagger-parser": "^10.0.3",
73
- "@budibase/backend-core": "^1.0.47",
74
- "@budibase/client": "^1.0.47",
75
- "@budibase/string-templates": "^1.0.47",
73
+ "@budibase/backend-core": "^1.0.49-alpha.2",
74
+ "@budibase/client": "^1.0.49-alpha.2",
75
+ "@budibase/string-templates": "^1.0.49-alpha.2",
76
76
  "@bull-board/api": "^3.7.0",
77
77
  "@bull-board/koa": "^3.7.0",
78
78
  "@elastic/elasticsearch": "7.10.0",
@@ -92,6 +92,8 @@
92
92
  "fix-path": "3.0.0",
93
93
  "form-data": "^4.0.0",
94
94
  "fs-extra": "8.1.0",
95
+ "google-auth-library": "^7.11.0",
96
+ "google-spreadsheet": "^3.2.0",
95
97
  "jimp": "0.16.1",
96
98
  "joi": "17.2.1",
97
99
  "js-yaml": "^4.1.0",
@@ -110,7 +112,7 @@
110
112
  "mongodb": "3.6.3",
111
113
  "mssql": "6.2.3",
112
114
  "mysql2": "^2.3.1",
113
- "node-fetch": "2.6.0",
115
+ "node-fetch": "2.6.7",
114
116
  "open": "^8.4.0",
115
117
  "pg": "8.5.1",
116
118
  "pino-pretty": "4.0.0",
@@ -139,6 +141,7 @@
139
141
  "@jest/test-sequencer": "^24.8.0",
140
142
  "@types/apidoc": "^0.50.0",
141
143
  "@types/bull": "^3.15.1",
144
+ "@types/google-spreadsheet": "^3.1.5",
142
145
  "@types/jest": "^26.0.23",
143
146
  "@types/koa": "^2.13.3",
144
147
  "@types/koa-router": "^7.4.2",
@@ -21,9 +21,11 @@ const { getGlobalDB } = require("@budibase/backend-core/tenancy");
21
21
  const { createASession } = require("@budibase/backend-core/sessions");
22
22
  const { user: userCache } = require("@budibase/backend-core/cache");
23
23
  const CouchDB = require("../../db");
24
+ const newid = require("../../db/newid");
24
25
  core.init(CouchDB);
25
26
  const GLOBAL_USER_ID = "us_uuid1";
26
27
  const EMAIL = "babs@babs.com";
28
+ const CSRF_TOKEN = "e3727778-7af0-4226-b5eb-f43cbe60a306";
27
29
  class TestConfiguration {
28
30
  constructor(openServer = true) {
29
31
  if (openServer) {
@@ -42,6 +44,9 @@ class TestConfiguration {
42
44
  getAppId() {
43
45
  return this.appId;
44
46
  }
47
+ getCouch() {
48
+ return CouchDB;
49
+ }
45
50
  _req(config, params, controlFunc) {
46
51
  return __awaiter(this, void 0, void 0, function* () {
47
52
  const request = {};
@@ -72,7 +77,11 @@ class TestConfiguration {
72
77
  existing = { email };
73
78
  }
74
79
  const user = Object.assign(Object.assign({ _id: id }, existing), { roles: roles || {}, tenantId: TENANT_ID });
75
- yield createASession(id, { sessionId: "sessionid", tenantId: TENANT_ID });
80
+ yield createASession(id, {
81
+ sessionId: "sessionid",
82
+ tenantId: TENANT_ID,
83
+ csrfToken: CSRF_TOKEN,
84
+ });
76
85
  if (builder) {
77
86
  user.builder = { global: true };
78
87
  }
@@ -83,7 +92,8 @@ class TestConfiguration {
83
92
  return Object.assign({ _rev: resp._rev }, user);
84
93
  });
85
94
  }
86
- init(appName = "test_application") {
95
+ // use a new id as the name to avoid name collisions
96
+ init(appName = newid()) {
87
97
  return __awaiter(this, void 0, void 0, function* () {
88
98
  yield this.globalUser();
89
99
  return this.createApp(appName);
@@ -116,6 +126,7 @@ class TestConfiguration {
116
126
  `${Cookies.Auth}=${authToken}`,
117
127
  `${Cookies.CurrentApp}=${appToken}`,
118
128
  ],
129
+ [Headers.CSRF_TOKEN]: CSRF_TOKEN,
119
130
  };
120
131
  if (this.appId) {
121
132
  headers[Headers.APP_ID] = this.appId;
@@ -394,10 +405,6 @@ class TestConfiguration {
394
405
  roles: { [this.prodAppId]: roleId },
395
406
  });
396
407
  }
397
- yield createASession(userId, {
398
- sessionId: "sessionid",
399
- tenantId: TENANT_ID,
400
- });
401
408
  // have to fake this
402
409
  const auth = {
403
410
  userId,
@@ -75,6 +75,10 @@ class QueryRunner {
75
75
  yield threadUtils.invalidateDynamicVariables(this.cachedVariables);
76
76
  return this.execute();
77
77
  }
78
+ // check for undefined response
79
+ if (!rows) {
80
+ rows = [];
81
+ }
78
82
  // needs to an array for next step
79
83
  if (!Array.isArray(rows)) {
80
84
  rows = [rows];