@budibase/server 1.0.46-alpha.2 → 1.0.46-alpha.6

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (248) hide show
  1. package/builder/assets/{index.89280093.js → index.00221ff2.js} +244 -244
  2. package/builder/assets/{index.0df4f7ab.css → index.dd9e386f.css} +1 -1
  3. package/builder/assets/{vendor.10e2ad1b.js → vendor.3bd2f661.js} +1 -1
  4. package/builder/index.html +3 -3
  5. package/coverage/clover.xml +1802 -1639
  6. package/coverage/coverage-final.json +98 -94
  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 +192 -129
  10. package/coverage/lcov-report/api/controllers/auth.js.html +1 -1
  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 +27 -42
  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/permission.js.html +15 -15
  22. package/coverage/lcov-report/api/controllers/query/index.html +15 -15
  23. package/coverage/lcov-report/api/controllers/query/index.js.html +61 -28
  24. package/coverage/lcov-report/api/controllers/query/validation.js.html +6 -6
  25. package/coverage/lcov-report/api/controllers/role.js.html +9 -9
  26. package/coverage/lcov-report/api/controllers/routing.js.html +1 -1
  27. package/coverage/lcov-report/api/controllers/row/external.js.html +16 -16
  28. package/coverage/lcov-report/api/controllers/row/index.html +5 -5
  29. package/coverage/lcov-report/api/controllers/row/index.js.html +26 -26
  30. package/coverage/lcov-report/api/controllers/row/internal.js.html +44 -44
  31. package/coverage/lcov-report/api/controllers/row/internalSearch.js.html +8 -8
  32. package/coverage/lcov-report/api/controllers/row/utils.js.html +29 -38
  33. package/coverage/lcov-report/api/controllers/screen.js.html +7 -7
  34. package/coverage/lcov-report/api/controllers/script.js.html +4 -4
  35. package/coverage/lcov-report/api/controllers/table/external.js.html +12 -12
  36. package/coverage/lcov-report/api/controllers/table/index.html +16 -16
  37. package/coverage/lcov-report/api/controllers/table/index.js.html +25 -25
  38. package/coverage/lcov-report/api/controllers/table/internal.js.html +40 -34
  39. package/coverage/lcov-report/api/controllers/table/utils.js.html +76 -61
  40. package/coverage/lcov-report/api/controllers/templates.js.html +1 -1
  41. package/coverage/lcov-report/api/controllers/user.js.html +20 -20
  42. package/coverage/lcov-report/api/controllers/view/exporters.js.html +4 -4
  43. package/coverage/lcov-report/api/controllers/view/index.html +1 -1
  44. package/coverage/lcov-report/api/controllers/view/index.js.html +14 -14
  45. package/coverage/lcov-report/api/controllers/view/utils.js.html +11 -11
  46. package/coverage/lcov-report/api/controllers/view/viewBuilder.js.html +7 -7
  47. package/coverage/lcov-report/api/controllers/webhook.js.html +15 -15
  48. package/coverage/lcov-report/api/index.html +1 -1
  49. package/coverage/lcov-report/api/index.js.html +10 -10
  50. package/coverage/lcov-report/api/routes/analytics.js.html +1 -1
  51. package/coverage/lcov-report/api/routes/apikeys.js.html +1 -1
  52. package/coverage/lcov-report/api/routes/application.js.html +1 -1
  53. package/coverage/lcov-report/api/routes/auth.js.html +1 -1
  54. package/coverage/lcov-report/api/routes/automation.js.html +1 -1
  55. package/coverage/lcov-report/api/routes/backup.js.html +1 -1
  56. package/coverage/lcov-report/api/routes/cloud.js.html +1 -1
  57. package/coverage/lcov-report/api/routes/component.js.html +1 -1
  58. package/coverage/lcov-report/api/routes/datasource.js.html +1 -1
  59. package/coverage/lcov-report/api/routes/deploy.js.html +1 -1
  60. package/coverage/lcov-report/api/routes/dev.js.html +1 -1
  61. package/coverage/lcov-report/api/routes/index.html +7 -22
  62. package/coverage/lcov-report/api/routes/index.js.html +4 -10
  63. package/coverage/lcov-report/api/routes/integration.js.html +1 -1
  64. package/coverage/lcov-report/api/routes/layout.js.html +1 -1
  65. package/coverage/lcov-report/api/routes/metadata.js.html +1 -1
  66. package/coverage/lcov-report/api/routes/permission.js.html +1 -1
  67. package/coverage/lcov-report/api/routes/query.js.html +1 -1
  68. package/coverage/lcov-report/api/routes/role.js.html +1 -1
  69. package/coverage/lcov-report/api/routes/routing.js.html +1 -1
  70. package/coverage/lcov-report/api/routes/row.js.html +1 -1
  71. package/coverage/lcov-report/api/routes/screen.js.html +1 -1
  72. package/coverage/lcov-report/api/routes/script.js.html +1 -1
  73. package/coverage/lcov-report/api/routes/static.js.html +17 -2
  74. package/coverage/lcov-report/api/routes/table.js.html +1 -1
  75. package/coverage/lcov-report/api/routes/templates.js.html +1 -1
  76. package/coverage/lcov-report/api/routes/user.js.html +1 -1
  77. package/coverage/lcov-report/api/routes/view.js.html +1 -1
  78. package/coverage/lcov-report/api/routes/webhook.js.html +1 -1
  79. package/coverage/lcov-report/automations/actions.js.html +24 -24
  80. package/coverage/lcov-report/automations/automationUtils.js.html +5 -5
  81. package/coverage/lcov-report/automations/bullboard.js.html +16 -16
  82. package/coverage/lcov-report/automations/index.html +1 -1
  83. package/coverage/lcov-report/automations/index.js.html +1 -1
  84. package/coverage/lcov-report/automations/steps/bash.js.html +6 -6
  85. package/coverage/lcov-report/automations/steps/createRow.js.html +13 -19
  86. package/coverage/lcov-report/automations/steps/delay.js.html +4 -4
  87. package/coverage/lcov-report/automations/steps/deleteRow.js.html +11 -20
  88. package/coverage/lcov-report/automations/steps/discord.js.html +7 -7
  89. package/coverage/lcov-report/automations/steps/executeQuery.js.html +6 -6
  90. package/coverage/lcov-report/automations/steps/executeScript.js.html +6 -6
  91. package/coverage/lcov-report/automations/steps/filter.js.html +7 -7
  92. package/coverage/lcov-report/automations/steps/index.html +13 -13
  93. package/coverage/lcov-report/automations/steps/integromat.js.html +5 -5
  94. package/coverage/lcov-report/automations/steps/outgoingWebhook.js.html +8 -8
  95. package/coverage/lcov-report/automations/steps/queryRows.js.html +10 -10
  96. package/coverage/lcov-report/automations/steps/sendSmtpEmail.js.html +5 -5
  97. package/coverage/lcov-report/automations/steps/serverLog.js.html +3 -3
  98. package/coverage/lcov-report/automations/steps/slack.js.html +5 -5
  99. package/coverage/lcov-report/automations/steps/updateRow.js.html +6 -6
  100. package/coverage/lcov-report/automations/steps/utils.js.html +3 -3
  101. package/coverage/lcov-report/automations/steps/zapier.js.html +5 -5
  102. package/coverage/lcov-report/automations/triggerInfo/app.js.html +2 -2
  103. package/coverage/lcov-report/automations/triggerInfo/cron.js.html +2 -2
  104. package/coverage/lcov-report/automations/triggerInfo/index.html +1 -1
  105. package/coverage/lcov-report/automations/triggerInfo/index.js.html +8 -8
  106. package/coverage/lcov-report/automations/triggerInfo/rowDeleted.js.html +2 -2
  107. package/coverage/lcov-report/automations/triggerInfo/rowSaved.js.html +2 -2
  108. package/coverage/lcov-report/automations/triggerInfo/rowUpdated.js.html +2 -2
  109. package/coverage/lcov-report/automations/triggerInfo/webhook.js.html +2 -2
  110. package/coverage/lcov-report/automations/triggers.js.html +18 -18
  111. package/coverage/lcov-report/automations/utils.js.html +32 -32
  112. package/coverage/lcov-report/constants/index.html +5 -5
  113. package/coverage/lcov-report/constants/index.js.html +36 -24
  114. package/coverage/lcov-report/constants/layouts.js.html +5 -5
  115. package/coverage/lcov-report/constants/screens.js.html +4 -4
  116. package/coverage/lcov-report/db/client.js.html +18 -18
  117. package/coverage/lcov-report/db/inMemoryView.js.html +7 -7
  118. package/coverage/lcov-report/db/index.html +15 -15
  119. package/coverage/lcov-report/db/index.js.html +3 -3
  120. package/coverage/lcov-report/db/linkedRows/LinkController.js.html +18 -18
  121. package/coverage/lcov-report/db/linkedRows/index.html +1 -1
  122. package/coverage/lcov-report/db/linkedRows/index.js.html +31 -31
  123. package/coverage/lcov-report/db/linkedRows/linkUtils.js.html +15 -15
  124. package/coverage/lcov-report/db/newid.js.html +4 -4
  125. package/coverage/lcov-report/db/utils.js.html +85 -85
  126. package/coverage/lcov-report/events/AutomationEmitter.js.html +1 -1
  127. package/coverage/lcov-report/events/index.html +1 -1
  128. package/coverage/lcov-report/events/index.js.html +5 -5
  129. package/coverage/lcov-report/events/utils.js.html +3 -3
  130. package/coverage/lcov-report/index.html +110 -80
  131. package/coverage/lcov-report/integrations/tests/TestConfiguration.js.html +1 -1
  132. package/coverage/lcov-report/integrations/tests/index.html +1 -1
  133. package/coverage/lcov-report/middleware/appInfo.js.html +1 -1
  134. package/coverage/lcov-report/middleware/authorized.js.html +11 -11
  135. package/coverage/lcov-report/middleware/builder.js.html +8 -8
  136. package/coverage/lcov-report/middleware/currentapp.js.html +34 -61
  137. package/coverage/lcov-report/middleware/index.html +25 -25
  138. package/coverage/lcov-report/middleware/joi-validator.js.html +3 -3
  139. package/coverage/lcov-report/middleware/resourceId.js.html +1 -1
  140. package/coverage/lcov-report/middleware/selfhost.js.html +1 -1
  141. package/coverage/lcov-report/middleware/usageQuota.js.html +275 -41
  142. package/coverage/lcov-report/middleware/utils.js.html +2 -2
  143. package/coverage/lcov-report/migrations/usageQuotas/index.html +141 -0
  144. package/coverage/lcov-report/migrations/usageQuotas/index.js.html +152 -0
  145. package/coverage/lcov-report/{api/routes/hosting.js.html → migrations/usageQuotas/syncApps.js.html} +42 -27
  146. package/coverage/lcov-report/{api/controllers/hosting.js.html → migrations/usageQuotas/syncRows.js.html} +41 -44
  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 +1 -1
  164. package/coverage/lcov-report/utilities/rowProcessor/index.js.html +53 -53
  165. package/coverage/lcov-report/utilities/rowProcessor/utils.js.html +10 -10
  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/utilities/usageQuota/usageQuoteReset.js.html +134 -0
  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 +2644 -2356
  176. package/dist/api/controllers/application.js +45 -24
  177. package/dist/api/controllers/datasource.js +11 -0
  178. package/dist/api/controllers/query/index.js +11 -3
  179. package/dist/api/controllers/row/utils.js +1 -2
  180. package/dist/api/controllers/static/index.js +59 -10
  181. package/dist/api/controllers/table/internal.js +2 -0
  182. package/dist/api/controllers/table/utils.js +5 -0
  183. package/dist/api/routes/index.js +0 -2
  184. package/dist/api/routes/static.js +2 -1
  185. package/dist/automations/steps/createRow.js +2 -4
  186. package/dist/automations/steps/deleteRow.js +1 -4
  187. package/dist/constants/index.js +3 -0
  188. package/dist/definitions/datasource.js +1 -0
  189. package/dist/environment.js +1 -0
  190. package/dist/integrations/googlesheets.js +340 -0
  191. package/dist/integrations/index.js +3 -0
  192. package/dist/integrations/utils.js +6 -3
  193. package/dist/middleware/currentapp.js +0 -9
  194. package/dist/middleware/usageQuota.js +82 -13
  195. package/dist/migrations/usageQuotas/index.js +24 -0
  196. package/dist/migrations/usageQuotas/syncApps.js +26 -0
  197. package/dist/migrations/usageQuotas/syncRows.js +29 -0
  198. package/dist/package.json +8 -5
  199. package/dist/tests/utilities/TestConfiguration.js +3 -1
  200. package/dist/threads/query.js +4 -0
  201. package/dist/tsconfig.tsbuildinfo +1 -1
  202. package/dist/utilities/{usageQuota.js → usageQuota/index.js} +44 -31
  203. package/dist/utilities/usageQuota/rows.js +77 -0
  204. package/dist/utilities/usageQuota/usageQuoteReset.js +16 -0
  205. package/dist/utilities/workerRequests.js +0 -20
  206. package/nodemon.json +1 -1
  207. package/package.json +9 -6
  208. package/src/api/controllers/application.js +48 -27
  209. package/src/api/controllers/datasource.js +12 -0
  210. package/src/api/controllers/query/index.js +14 -3
  211. package/src/api/controllers/row/utils.js +1 -4
  212. package/src/api/controllers/static/index.js +63 -10
  213. package/src/api/controllers/table/internal.js +2 -0
  214. package/src/api/controllers/table/utils.js +5 -0
  215. package/src/api/routes/index.js +0 -2
  216. package/src/api/routes/static.js +5 -0
  217. package/src/api/routes/tests/application.spec.js +2 -2
  218. package/src/api/routes/tests/static.spec.js +98 -0
  219. package/src/automations/steps/createRow.js +2 -4
  220. package/src/automations/steps/deleteRow.js +1 -4
  221. package/src/constants/index.js +4 -0
  222. package/src/definitions/datasource.ts +3 -0
  223. package/src/environment.js +1 -0
  224. package/src/integrations/googlesheets.ts +353 -0
  225. package/src/integrations/index.ts +3 -0
  226. package/src/integrations/utils.ts +18 -5
  227. package/src/middleware/currentapp.js +0 -9
  228. package/src/middleware/tests/usageQuota.spec.js +18 -24
  229. package/src/middleware/usageQuota.js +93 -15
  230. package/src/migrations/tests/usageQuotas/index.spec.js +27 -0
  231. package/src/migrations/tests/usageQuotas/syncApps.spec.js +37 -0
  232. package/src/migrations/tests/usageQuotas/syncRows.spec.js +43 -0
  233. package/src/migrations/usageQuotas/index.js +24 -0
  234. package/src/migrations/usageQuotas/syncApps.js +18 -0
  235. package/src/migrations/usageQuotas/syncRows.js +21 -0
  236. package/src/tests/utilities/TestConfiguration.js +3 -1
  237. package/src/threads/query.js +5 -0
  238. package/src/utilities/tests/usageQuota/usageQuota.spec.js +72 -0
  239. package/src/utilities/usageQuota/index.js +92 -0
  240. package/src/utilities/usageQuota/rows.js +74 -0
  241. package/src/utilities/usageQuota/usageQuoteReset.js +18 -0
  242. package/src/utilities/workerRequests.js +0 -23
  243. package/dist/api/controllers/hosting.js +0 -30
  244. package/dist/api/routes/hosting.js +0 -11
  245. package/src/api/controllers/hosting.js +0 -22
  246. package/src/api/routes/hosting.js +0 -13
  247. package/src/api/routes/tests/hosting.spec.js +0 -36
  248. package/src/utilities/usageQuota.js +0 -73
@@ -20,7 +20,7 @@ const { cloneDeep } = require("lodash/fp");
20
20
  const { processObject } = require("@budibase/string-templates");
21
21
  const { getAllApps, isDevAppID, getDeployedAppID, Replication, } = require("@budibase/backend-core/db");
22
22
  const { USERS_TABLE_SCHEMA } = require("../../constants");
23
- const { getDeployedApps, removeAppFromUserRoles, } = require("../../utilities/workerRequests");
23
+ const { removeAppFromUserRoles } = require("../../utilities/workerRequests");
24
24
  const { clientLibraryPath, stringToReadStream } = require("../../utilities");
25
25
  const { getAllLocks } = require("../../utilities/redis");
26
26
  const { updateClientLibrary, backupClientLibrary, revertClientLibrary, } = require("../../utilities/fileSystem/clientLibrary");
@@ -49,31 +49,42 @@ function getUserRoleId(ctx) {
49
49
  ? BUILTIN_ROLE_IDS.PUBLIC
50
50
  : ctx.user.role._id;
51
51
  }
52
- function getAppUrlIfNotInUse(ctx) {
52
+ function getAppUrl(ctx) {
53
53
  return __awaiter(this, void 0, void 0, function* () {
54
+ // construct the url
54
55
  let url;
55
56
  if (ctx.request.body.url) {
57
+ // if the url is provided, use that
56
58
  url = encodeURI(ctx.request.body.url);
57
59
  }
58
- else if (ctx.request.body.name) {
60
+ else {
61
+ // otherwise use the name
59
62
  url = encodeURI(`${ctx.request.body.name}`);
60
63
  }
61
- if (url) {
62
- url = `/${url.replace(URL_REGEX_SLASH, "")}`.toLowerCase();
63
- }
64
- if (!env.SELF_HOSTED) {
65
- return url;
66
- }
67
- const deployedApps = yield getDeployedApps();
68
- if (url &&
69
- deployedApps[url] != null &&
70
- ctx.params != null &&
71
- deployedApps[url].appId !== ctx.params.appId) {
72
- ctx.throw(400, "App name/URL is already in use.");
73
- }
64
+ url = `/${url.replace(URL_REGEX_SLASH, "")}`.toLowerCase();
74
65
  return url;
75
66
  });
76
67
  }
68
+ const checkAppUrl = (ctx, apps, url, currentAppId) => {
69
+ if (currentAppId) {
70
+ apps = apps.filter(app => app.appId !== currentAppId);
71
+ }
72
+ if (apps.some(app => app.url === url)) {
73
+ ctx.throw(400, "App URL is already in use.");
74
+ }
75
+ };
76
+ const checkAppName = (ctx, apps, name, currentAppId) => {
77
+ // TODO: Replace with Joi
78
+ if (!name) {
79
+ ctx.throw(400, "Name is required");
80
+ }
81
+ if (currentAppId) {
82
+ apps = apps.filter(app => app.appId !== currentAppId);
83
+ }
84
+ if (apps.some(app => app.name === name)) {
85
+ ctx.throw(400, "App name is already in use.");
86
+ }
87
+ };
77
88
  function createInstance(template) {
78
89
  return __awaiter(this, void 0, void 0, function* () {
79
90
  const tenantId = isMultiTenant() ? getTenantId() : null;
@@ -167,6 +178,11 @@ exports.fetchAppPackage = (ctx) => __awaiter(void 0, void 0, void 0, function* (
167
178
  };
168
179
  });
169
180
  exports.create = (ctx) => __awaiter(void 0, void 0, void 0, function* () {
181
+ const apps = yield getAllApps(CouchDB, { dev: true });
182
+ const name = ctx.request.body.name;
183
+ checkAppName(ctx, apps, name);
184
+ const url = yield getAppUrl(ctx);
185
+ checkAppUrl(ctx, apps, url);
170
186
  const { useTemplate, templateKey, templateString } = ctx.request.body;
171
187
  const instanceConfig = {
172
188
  useTemplate,
@@ -178,7 +194,6 @@ exports.create = (ctx) => __awaiter(void 0, void 0, void 0, function* () {
178
194
  }
179
195
  const instance = yield createInstance(instanceConfig);
180
196
  const appId = instance._id;
181
- const url = yield getAppUrlIfNotInUse(ctx);
182
197
  const db = new CouchDB(appId);
183
198
  let _rev;
184
199
  try {
@@ -196,7 +211,7 @@ exports.create = (ctx) => __awaiter(void 0, void 0, void 0, function* () {
196
211
  type: "app",
197
212
  version: packageJson.version,
198
213
  componentLibraries: ["@budibase/standard-components"],
199
- name: ctx.request.body.name,
214
+ name: name,
200
215
  url: url,
201
216
  template: ctx.request.body.template,
202
217
  instance: instance,
@@ -220,7 +235,14 @@ exports.create = (ctx) => __awaiter(void 0, void 0, void 0, function* () {
220
235
  ctx.body = newApplication;
221
236
  });
222
237
  exports.update = (ctx) => __awaiter(void 0, void 0, void 0, function* () {
223
- const data = yield updateAppPackage(ctx, ctx.request.body, ctx.params.appId);
238
+ const apps = yield getAllApps(CouchDB, { dev: true });
239
+ // validation
240
+ const name = ctx.request.body.name;
241
+ checkAppName(ctx, apps, name, ctx.params.appId);
242
+ const url = yield getAppUrl(ctx);
243
+ checkAppUrl(ctx, apps, url, ctx.params.appId);
244
+ const appPackageUpdates = { name, url };
245
+ const data = yield updateAppPackage(appPackageUpdates, ctx.params.appId);
224
246
  ctx.status = 200;
225
247
  ctx.body = data;
226
248
  });
@@ -239,7 +261,7 @@ exports.updateClient = (ctx) => __awaiter(void 0, void 0, void 0, function* () {
239
261
  version: packageJson.version,
240
262
  revertableVersion: currentVersion,
241
263
  };
242
- const data = yield updateAppPackage(ctx, appPackageUpdates, ctx.params.appId);
264
+ const data = yield updateAppPackage(appPackageUpdates, ctx.params.appId);
243
265
  ctx.status = 200;
244
266
  ctx.body = data;
245
267
  });
@@ -259,7 +281,7 @@ exports.revertClient = (ctx) => __awaiter(void 0, void 0, void 0, function* () {
259
281
  version: application.revertableVersion,
260
282
  revertableVersion: null,
261
283
  };
262
- const data = yield updateAppPackage(ctx, appPackageUpdates, ctx.params.appId);
284
+ const data = yield updateAppPackage(appPackageUpdates, ctx.params.appId);
263
285
  ctx.status = 200;
264
286
  ctx.body = data;
265
287
  });
@@ -326,11 +348,10 @@ exports.sync = (ctx, next) => __awaiter(void 0, void 0, void 0, function* () {
326
348
  };
327
349
  }
328
350
  });
329
- const updateAppPackage = (ctx, appPackage, appId) => __awaiter(void 0, void 0, void 0, function* () {
330
- const url = yield getAppUrlIfNotInUse(ctx);
351
+ const updateAppPackage = (appPackage, appId) => __awaiter(void 0, void 0, void 0, function* () {
331
352
  const db = new CouchDB(appId);
332
353
  const application = yield db.get(DocumentTypes.APP_METADATA);
333
- const newAppPackage = Object.assign(Object.assign(Object.assign({}, application), appPackage), { url });
354
+ const newAppPackage = Object.assign(Object.assign({}, application), appPackage);
334
355
  if (appPackage._rev !== application._rev) {
335
356
  newAppPackage._rev = application._rev;
336
357
  }
@@ -28,6 +28,12 @@ exports.fetch = function (ctx) {
28
28
  const datasources = (yield database.allDocs(getDatasourceParams(null, {
29
29
  include_docs: true,
30
30
  }))).rows.map(row => row.doc);
31
+ for (let datasource of datasources) {
32
+ if (datasource.config && datasource.config.auth) {
33
+ // strip secrets from response so they don't show in the network request
34
+ delete datasource.config.auth;
35
+ }
36
+ }
31
37
  ctx.body = [bbInternalDb, ...datasources];
32
38
  });
33
39
  };
@@ -78,8 +84,13 @@ exports.update = function (ctx) {
78
84
  const db = new CouchDB(ctx.appId);
79
85
  const datasourceId = ctx.params.datasourceId;
80
86
  let datasource = yield db.get(datasourceId);
87
+ const auth = datasource.config.auth;
81
88
  yield invalidateVariables(datasource, ctx.request.body);
82
89
  datasource = Object.assign(Object.assign({}, datasource), ctx.request.body);
90
+ if (auth && !ctx.request.body.auth) {
91
+ // don't strip auth config from DB
92
+ datasource.config.auth = auth;
93
+ }
83
94
  const response = yield db.put(datasource);
84
95
  datasource._rev = response.rev;
85
96
  // Drain connection pools when configuration is changed
@@ -130,6 +130,15 @@ function execute(ctx, opts = { rowsOnly: false }) {
130
130
  const db = new CouchDB(ctx.appId);
131
131
  const query = yield db.get(ctx.params.queryId);
132
132
  const datasource = yield db.get(query.datasourceId);
133
+ const enrichedParameters = ctx.request.body.parameters || {};
134
+ // make sure parameters are fully enriched with defaults
135
+ if (query && query.parameters) {
136
+ for (let parameter of query.parameters) {
137
+ if (!enrichedParameters[parameter.name]) {
138
+ enrichedParameters[parameter.name] = parameter.default;
139
+ }
140
+ }
141
+ }
133
142
  // call the relevant CRUD method on the integration class
134
143
  try {
135
144
  const { rows, pagination, extra } = yield Runner.run({
@@ -138,7 +147,7 @@ function execute(ctx, opts = { rowsOnly: false }) {
138
147
  queryVerb: query.queryVerb,
139
148
  fields: query.fields,
140
149
  pagination: ctx.request.body.pagination,
141
- parameters: ctx.request.body.parameters,
150
+ parameters: enrichedParameters,
142
151
  transformer: query.transformer,
143
152
  queryId: ctx.params.queryId,
144
153
  });
@@ -170,8 +179,7 @@ const removeDynamicVariables = (db, queryId) => __awaiter(void 0, void 0, void 0
170
179
  const dynamicVariables = datasource.config.dynamicVariables;
171
180
  if (dynamicVariables) {
172
181
  // delete dynamic variables from the datasource
173
- const newVariables = dynamicVariables.filter(dv => dv.queryId !== queryId);
174
- datasource.config.dynamicVariables = newVariables;
182
+ datasource.config.dynamicVariables = dynamicVariables.filter(dv => dv.queryId !== queryId);
175
183
  yield db.put(datasource);
176
184
  // invalidate the deleted variables
177
185
  const variablesToDelete = dynamicVariables.filter(dv => dv.queryId === queryId);
@@ -59,8 +59,7 @@ exports.validate = ({ appId, tableId, row, table }) => __awaiter(void 0, void 0,
59
59
  const constraints = cloneDeep(table.schema[fieldName].constraints);
60
60
  const type = table.schema[fieldName].type;
61
61
  // special case for options, need to always allow unselected (null)
62
- if ((type === FieldTypes.OPTIONS || type === FieldTypes.ARRAY) &&
63
- constraints.inclusion) {
62
+ if (type === FieldTypes.OPTIONS && constraints.inclusion) {
64
63
  constraints.inclusion.push(null);
65
64
  }
66
65
  let res;
@@ -14,7 +14,7 @@ const { resolve, join } = require("../../../utilities/centralPath");
14
14
  const uuid = require("uuid");
15
15
  const { ObjectStoreBuckets } = require("../../../constants");
16
16
  const { processString } = require("@budibase/string-templates");
17
- const { getDeployedApps } = require("../../../utilities/workerRequests");
17
+ const { getAllApps } = require("@budibase/backend-core/db");
18
18
  const CouchDB = require("../../../db");
19
19
  const { loadHandlebarsFile, NODE_MODULES_PATH, TOP_LEVEL_PATH, } = require("../../../utilities/fileSystem");
20
20
  const env = require("../../../environment");
@@ -22,6 +22,8 @@ const { clientLibraryPath } = require("../../../utilities");
22
22
  const { upload } = require("../../../utilities/fileSystem");
23
23
  const { attachmentsRelativeURL } = require("../../../utilities");
24
24
  const { DocumentTypes } = require("../../../db/utils");
25
+ const AWS = require("aws-sdk");
26
+ const AWS_REGION = env.AWS_REGION ? env.AWS_REGION : "eu-west-1";
25
27
  function prepareUpload({ s3Key, bucket, metadata, file }) {
26
28
  return __awaiter(this, void 0, void 0, function* () {
27
29
  const response = yield upload({
@@ -41,13 +43,15 @@ function prepareUpload({ s3Key, bucket, metadata, file }) {
41
43
  };
42
44
  });
43
45
  }
44
- function checkForSelfHostedURL(ctx) {
46
+ function getAppIdFromUrl(ctx) {
45
47
  return __awaiter(this, void 0, void 0, function* () {
46
- // the "appId" component of the URL may actually be a specific self hosted URL
48
+ // the "appId" component of the URL can be the id or the custom url
47
49
  let possibleAppUrl = `/${encodeURI(ctx.params.appId).toLowerCase()}`;
48
- const apps = yield getDeployedApps();
49
- if (apps[possibleAppUrl] && apps[possibleAppUrl].appId) {
50
- return apps[possibleAppUrl].appId;
50
+ // search prod apps for a url that matches, exclude dev where id is always used
51
+ const apps = yield getAllApps(CouchDB, { dev: false });
52
+ const app = apps.filter(a => a.url && a.url.toLowerCase() === possibleAppUrl)[0];
53
+ if (app && app.appId) {
54
+ return app.appId;
51
55
  }
52
56
  else {
53
57
  return ctx.params.appId;
@@ -80,10 +84,7 @@ exports.uploadFile = function (ctx) {
80
84
  };
81
85
  exports.serveApp = function (ctx) {
82
86
  return __awaiter(this, void 0, void 0, function* () {
83
- let appId = ctx.params.appId;
84
- if (env.SELF_HOSTED) {
85
- appId = yield checkForSelfHostedURL(ctx);
86
- }
87
+ let appId = yield getAppIdFromUrl(ctx);
87
88
  const App = require("./templates/BudibaseApp.svelte").default;
88
89
  const db = new CouchDB(appId, { skip_setup: true });
89
90
  const appInfo = yield db.get(DocumentTypes.APP_METADATA);
@@ -109,3 +110,51 @@ exports.serveClientLibrary = function (ctx) {
109
110
  });
110
111
  });
111
112
  };
113
+ exports.getSignedUploadURL = function (ctx) {
114
+ var _a, _b, _c;
115
+ return __awaiter(this, void 0, void 0, function* () {
116
+ const database = new CouchDB(ctx.appId);
117
+ // Ensure datasource is valid
118
+ let datasource;
119
+ try {
120
+ const { datasourceId } = ctx.params;
121
+ datasource = yield database.get(datasourceId);
122
+ if (!datasource) {
123
+ ctx.throw(400, "The specified datasource could not be found");
124
+ }
125
+ }
126
+ catch (error) {
127
+ ctx.throw(400, "The specified datasource could not be found");
128
+ }
129
+ // Ensure we aren't using a custom endpoint
130
+ if ((_a = datasource === null || datasource === void 0 ? void 0 : datasource.config) === null || _a === void 0 ? void 0 : _a.endpoint) {
131
+ ctx.throw(400, "S3 datasources with custom endpoints are not supported");
132
+ }
133
+ // Determine type of datasource and generate signed URL
134
+ let signedUrl;
135
+ let publicUrl;
136
+ if (datasource.source === "S3") {
137
+ const { bucket, key } = ctx.request.body || {};
138
+ if (!bucket || !key) {
139
+ ctx.throw(400, "bucket and key values are required");
140
+ return;
141
+ }
142
+ try {
143
+ const s3 = new AWS.S3({
144
+ region: AWS_REGION,
145
+ accessKeyId: (_b = datasource === null || datasource === void 0 ? void 0 : datasource.config) === null || _b === void 0 ? void 0 : _b.accessKeyId,
146
+ secretAccessKey: (_c = datasource === null || datasource === void 0 ? void 0 : datasource.config) === null || _c === void 0 ? void 0 : _c.secretAccessKey,
147
+ apiVersion: "2006-03-01",
148
+ signatureVersion: "v4",
149
+ });
150
+ const params = { Bucket: bucket, Key: key };
151
+ signedUrl = s3.getSignedUrl("putObject", params);
152
+ publicUrl = `https://${bucket}.s3.${AWS_REGION}.amazonaws.com/${key}`;
153
+ }
154
+ catch (error) {
155
+ ctx.throw(400, error);
156
+ }
157
+ }
158
+ ctx.body = { signedUrl, publicUrl };
159
+ });
160
+ };
@@ -24,6 +24,7 @@ const linkRows = require("../../../db/linkedRows");
24
24
  const { getRowParams, generateTableID } = require("../../../db/utils");
25
25
  const { FieldTypes } = require("../../../constants");
26
26
  const { TableSaveFunctions, hasTypeChanged, getTable, handleDataImport, } = require("./utils");
27
+ const usageQuota = require("../../../utilities/usageQuota");
27
28
  exports.save = function (ctx) {
28
29
  return __awaiter(this, void 0, void 0, function* () {
29
30
  const appId = ctx.appId;
@@ -118,6 +119,7 @@ exports.destroy = function (ctx) {
118
119
  include_docs: true,
119
120
  }));
120
121
  yield db.bulkDocs(rows.rows.map(row => (Object.assign(Object.assign({}, row.doc), { _deleted: true }))));
122
+ yield usageQuota.update(usageQuota.Properties.ROW, -rows.rows.length);
121
123
  // update linked rows
122
124
  yield linkRows.updateLinks({
123
125
  appId,
@@ -18,6 +18,7 @@ const { USERS_TABLE_SCHEMA, SwitchableTypes } = require("../../../constants");
18
18
  const { isExternalTable, breakExternalTableId, isSQL, } = require("../../../integrations/utils");
19
19
  const { getViews, saveView } = require("../view/utils");
20
20
  const viewTemplate = require("../view/viewBuilder");
21
+ const usageQuota = require("../../../utilities/usageQuota");
21
22
  exports.checkForColumnUpdates = (db, oldTable, updatedTable) => __awaiter(void 0, void 0, void 0, function* () {
22
23
  let updatedRows = [];
23
24
  const rename = updatedTable._rename;
@@ -95,7 +96,11 @@ exports.handleDataImport = (appId, user, table, dataImport) => __awaiter(void 0,
95
96
  }
96
97
  finalData.push(row);
97
98
  }
99
+ yield usageQuota.update(usageQuota.Properties.ROW, finalData.length, {
100
+ dryRun: true,
101
+ });
98
102
  yield db.bulkDocs(finalData);
103
+ yield usageQuota.update(usageQuota.Properties.ROW, finalData.length);
99
104
  let response = yield db.put(table);
100
105
  table._rev = response._rev;
101
106
  return table;
@@ -21,7 +21,6 @@ const integrationRoutes = require("./integration");
21
21
  const permissionRoutes = require("./permission");
22
22
  const datasourceRoutes = require("./datasource");
23
23
  const queryRoutes = require("./query");
24
- const hostingRoutes = require("./hosting");
25
24
  const backupRoutes = require("./backup");
26
25
  const metadataRoutes = require("./metadata");
27
26
  const devRoutes = require("./dev");
@@ -46,7 +45,6 @@ exports.mainRoutes = [
46
45
  permissionRoutes,
47
46
  datasourceRoutes,
48
47
  queryRoutes,
49
- hostingRoutes,
50
48
  backupRoutes,
51
49
  metadataRoutes,
52
50
  devRoutes,
@@ -43,5 +43,6 @@ router
43
43
  .post("/api/attachments/process", authorized(BUILDER), controller.uploadFile)
44
44
  .post("/api/attachments/:tableId/upload", paramResource("tableId"), authorized(PermissionTypes.TABLE, PermissionLevels.WRITE), controller.uploadFile)
45
45
  // TODO: this likely needs to be secured in some way
46
- .get("/:appId/:path*", controller.serveApp);
46
+ .get("/:appId/:path*", controller.serveApp)
47
+ .post("/api/attachments/:datasourceId/url", authorized(PermissionTypes.TABLE, PermissionLevels.READ), controller.getSignedUploadURL);
47
48
  module.exports = router;
@@ -10,7 +10,6 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge
10
10
  };
11
11
  const rowController = require("../../api/controllers/row");
12
12
  const automationUtils = require("../automationUtils");
13
- const env = require("../../environment");
14
13
  const usage = require("../../utilities/usageQuota");
15
14
  const { buildCtx } = require("./utils");
16
15
  exports.definition = {
@@ -87,10 +86,9 @@ exports.run = function ({ inputs, appId, emitter }) {
87
86
  });
88
87
  try {
89
88
  inputs.row = yield automationUtils.cleanUpRow(appId, inputs.row.tableId, inputs.row);
90
- if (env.USE_QUOTAS) {
91
- yield usage.update(usage.Properties.ROW, 1);
92
- }
89
+ yield usage.update(usage.Properties.ROW, 1, { dryRun: true });
93
90
  yield rowController.save(ctx);
91
+ yield usage.update(usage.Properties.ROW, 1);
94
92
  return {
95
93
  row: inputs.row,
96
94
  response: ctx.body,
@@ -9,7 +9,6 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge
9
9
  });
10
10
  };
11
11
  const rowController = require("../../api/controllers/row");
12
- const env = require("../../environment");
13
12
  const usage = require("../../utilities/usageQuota");
14
13
  const { buildCtx } = require("./utils");
15
14
  const automationUtils = require("../automationUtils");
@@ -81,9 +80,7 @@ exports.run = function ({ inputs, appId, emitter }) {
81
80
  },
82
81
  });
83
82
  try {
84
- if (env.isProd()) {
85
- yield usage.update(usage.Properties.ROW, -1);
86
- }
83
+ yield usage.update(usage.Properties.ROW, -1);
87
84
  yield rowController.destroy(ctx);
88
85
  return {
89
86
  response: ctx.body,
@@ -67,6 +67,9 @@ exports.DataSourceOperation = {
67
67
  UPDATE_TABLE: "UPDATE_TABLE",
68
68
  DELETE_TABLE: "DELETE_TABLE",
69
69
  };
70
+ exports.DatasourceAuthTypes = {
71
+ GOOGLE: "google",
72
+ };
70
73
  exports.SortDirection = {
71
74
  ASCENDING: "ASCENDING",
72
75
  DESCENDING: "DESCENDING",
@@ -49,6 +49,7 @@ var SourceNames;
49
49
  SourceNames["ARANGODB"] = "ARANGODB";
50
50
  SourceNames["REST"] = "REST";
51
51
  SourceNames["ORACLE"] = "ORACLE";
52
+ SourceNames["GOOGLE_SHEETS"] = "GOOGLE_SHEETS";
52
53
  })(SourceNames = exports.SourceNames || (exports.SourceNames = {}));
53
54
  var IncludeRelationships;
54
55
  (function (IncludeRelationships) {
@@ -30,6 +30,7 @@ module.exports = {
30
30
  MINIO_ACCESS_KEY: process.env.MINIO_ACCESS_KEY,
31
31
  MINIO_SECRET_KEY: process.env.MINIO_SECRET_KEY,
32
32
  USE_QUOTAS: process.env.USE_QUOTAS,
33
+ EXCLUDE_QUOTAS_TENANTS: process.env.EXCLUDE_QUOTAS_TENANTS,
33
34
  REDIS_URL: process.env.REDIS_URL,
34
35
  REDIS_PASSWORD: process.env.REDIS_PASSWORD,
35
36
  INTERNAL_API_KEY: process.env.INTERNAL_API_KEY,