@budibase/server 1.0.123-alpha.0 → 1.0.123
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.
- package/builder/assets/index.68a7f4e3.css +6 -0
- package/builder/assets/index.8d4a5b33.js +1291 -0
- package/builder/assets/{vendor.5240f480.js → vendor.8e34a169.js} +1 -1
- package/builder/index.html +3 -3
- package/coverage/clover.xml +1763 -758
- package/coverage/coverage-final.json +43 -28
- package/coverage/lcov-report/api/controllers/analytics.js.html +3 -8
- package/coverage/lcov-report/api/controllers/apikeys.js.html +4 -9
- package/coverage/lcov-report/api/controllers/application.js.html +1436 -0
- package/coverage/lcov-report/api/controllers/auth.js.html +3 -8
- package/coverage/lcov-report/api/controllers/automation.js.html +3 -8
- package/coverage/lcov-report/api/controllers/backup.js.html +3 -8
- package/coverage/lcov-report/api/controllers/cloud.js.html +3 -8
- package/coverage/lcov-report/api/controllers/component.js.html +3 -8
- package/coverage/lcov-report/api/controllers/datasource.js.html +6 -11
- package/coverage/lcov-report/api/controllers/dev.js.html +3 -8
- package/coverage/lcov-report/api/controllers/index.html +26 -16
- package/coverage/lcov-report/api/controllers/integration.js.html +3 -8
- package/coverage/lcov-report/api/controllers/layout.js.html +3 -8
- package/coverage/lcov-report/api/controllers/metadata.js.html +3 -8
- package/coverage/lcov-report/api/controllers/migrations.js.html +3 -8
- package/coverage/lcov-report/api/controllers/permission.js.html +3 -8
- package/coverage/lcov-report/api/controllers/query/index.html +26 -16
- package/coverage/lcov-report/api/controllers/query/index.js.html +713 -0
- package/coverage/lcov-report/api/controllers/query/validation.js.html +3 -8
- package/coverage/lcov-report/api/controllers/role.js.html +5 -10
- package/coverage/lcov-report/api/controllers/routing.js.html +4 -9
- package/coverage/lcov-report/api/controllers/row/external.js.html +3 -8
- package/coverage/lcov-report/api/controllers/row/index.html +35 -25
- package/coverage/lcov-report/api/controllers/row/index.js.html +524 -0
- package/coverage/lcov-report/api/controllers/row/internal.js.html +24 -32
- package/coverage/lcov-report/api/controllers/row/internalSearch.js.html +16 -21
- package/coverage/lcov-report/api/controllers/row/staticFormula.js.html +19 -24
- package/coverage/lcov-report/api/controllers/row/utils.js.html +19 -33
- package/coverage/lcov-report/api/controllers/screen.js.html +4 -9
- package/coverage/lcov-report/api/controllers/script.js.html +3 -8
- package/coverage/lcov-report/api/controllers/table/bulkFormula.js.html +50 -55
- package/coverage/lcov-report/api/controllers/table/external.js.html +3 -8
- package/coverage/lcov-report/api/controllers/table/index.html +44 -19
- package/coverage/lcov-report/api/controllers/table/index.js.html +15 -20
- package/coverage/lcov-report/api/controllers/table/internal.js.html +620 -0
- package/coverage/lcov-report/api/controllers/table/utils.js.html +1331 -0
- package/coverage/lcov-report/api/controllers/templates.js.html +3 -8
- package/coverage/lcov-report/api/controllers/user.js.html +3 -8
- package/coverage/lcov-report/api/controllers/view/exporters.js.html +3 -8
- package/coverage/lcov-report/api/controllers/view/index.html +3 -8
- package/coverage/lcov-report/api/controllers/view/index.js.html +5 -10
- package/coverage/lcov-report/api/controllers/view/utils.js.html +3 -8
- package/coverage/lcov-report/api/controllers/view/viewBuilder.js.html +3 -8
- package/coverage/lcov-report/api/controllers/webhook.js.html +5 -10
- package/coverage/lcov-report/api/index.html +13 -18
- package/coverage/lcov-report/api/index.js.html +8 -28
- package/coverage/lcov-report/api/routes/analytics.js.html +3 -8
- package/coverage/lcov-report/api/routes/apikeys.js.html +3 -8
- package/coverage/lcov-report/api/routes/application.js.html +179 -0
- package/coverage/lcov-report/api/routes/auth.js.html +3 -8
- package/coverage/lcov-report/api/routes/automation.js.html +3 -8
- package/coverage/lcov-report/api/routes/backup.js.html +3 -8
- package/coverage/lcov-report/api/routes/cloud.js.html +3 -8
- package/coverage/lcov-report/api/routes/component.js.html +3 -8
- package/coverage/lcov-report/api/routes/datasource.js.html +3 -8
- package/coverage/lcov-report/api/routes/deploy.js.html +3 -8
- package/coverage/lcov-report/api/routes/dev.js.html +4 -9
- package/coverage/lcov-report/api/routes/index.html +68 -13
- package/coverage/lcov-report/api/routes/index.js.html +266 -0
- package/coverage/lcov-report/api/routes/integration.js.html +3 -8
- package/coverage/lcov-report/api/routes/layout.js.html +3 -8
- package/coverage/lcov-report/api/routes/metadata.js.html +3 -8
- package/coverage/lcov-report/api/routes/migrations.js.html +3 -8
- package/coverage/lcov-report/api/routes/permission.js.html +3 -8
- package/coverage/lcov-report/api/routes/query.js.html +3 -8
- package/coverage/lcov-report/api/routes/role.js.html +3 -8
- package/coverage/lcov-report/api/routes/routing.js.html +3 -8
- package/coverage/lcov-report/api/routes/row.js.html +908 -0
- package/coverage/lcov-report/api/routes/screen.js.html +3 -8
- package/coverage/lcov-report/api/routes/script.js.html +3 -8
- package/coverage/lcov-report/{automations/steps/loop.js.html → api/routes/static.js.html} +80 -70
- package/coverage/lcov-report/api/routes/table.js.html +3 -8
- package/coverage/lcov-report/api/routes/templates.js.html +3 -8
- package/coverage/lcov-report/api/routes/user.js.html +3 -8
- package/coverage/lcov-report/api/routes/utils/index.html +3 -8
- package/coverage/lcov-report/api/routes/utils/validators.js.html +3 -8
- package/coverage/lcov-report/api/routes/view.js.html +3 -8
- package/coverage/lcov-report/api/routes/webhook.js.html +3 -8
- package/coverage/lcov-report/automations/actions.js.html +7 -21
- package/coverage/lcov-report/automations/automationUtils.js.html +23 -64
- package/coverage/lcov-report/automations/bullboard.js.html +3 -8
- package/coverage/lcov-report/automations/index.html +37 -27
- package/coverage/lcov-report/automations/index.js.html +3 -8
- package/coverage/lcov-report/automations/steps/bash.js.html +3 -8
- package/coverage/lcov-report/automations/steps/createRow.js.html +380 -0
- package/coverage/lcov-report/automations/steps/delay.js.html +3 -8
- package/coverage/lcov-report/automations/steps/deleteRow.js.html +347 -0
- package/coverage/lcov-report/automations/steps/discord.js.html +3 -8
- package/coverage/lcov-report/automations/steps/executeQuery.js.html +3 -8
- package/coverage/lcov-report/automations/steps/executeScript.js.html +3 -8
- package/coverage/lcov-report/automations/steps/filter.js.html +3 -8
- package/coverage/lcov-report/automations/steps/index.html +41 -31
- package/coverage/lcov-report/automations/steps/integromat.js.html +3 -8
- package/coverage/lcov-report/automations/steps/outgoingWebhook.js.html +4 -9
- package/coverage/lcov-report/automations/steps/queryRows.js.html +4 -9
- package/coverage/lcov-report/automations/steps/sendSmtpEmail.js.html +3 -8
- package/coverage/lcov-report/automations/steps/serverLog.js.html +3 -8
- package/coverage/lcov-report/automations/steps/slack.js.html +3 -8
- package/coverage/lcov-report/automations/steps/updateRow.js.html +3 -8
- package/coverage/lcov-report/automations/steps/utils.js.html +9 -14
- package/coverage/lcov-report/automations/steps/zapier.js.html +3 -8
- package/coverage/lcov-report/automations/triggerInfo/app.js.html +3 -8
- package/coverage/lcov-report/automations/triggerInfo/cron.js.html +3 -8
- package/coverage/lcov-report/automations/triggerInfo/index.html +3 -8
- package/coverage/lcov-report/automations/triggerInfo/index.js.html +3 -8
- package/coverage/lcov-report/automations/triggerInfo/rowDeleted.js.html +3 -8
- package/coverage/lcov-report/automations/triggerInfo/rowSaved.js.html +3 -8
- package/coverage/lcov-report/automations/triggerInfo/rowUpdated.js.html +3 -8
- package/coverage/lcov-report/automations/triggerInfo/webhook.js.html +3 -8
- package/coverage/lcov-report/automations/triggers.js.html +11 -16
- package/coverage/lcov-report/automations/utils.js.html +665 -0
- package/coverage/lcov-report/block-navigation.js +0 -8
- package/coverage/lcov-report/constants/index.html +3 -8
- package/coverage/lcov-report/constants/index.js.html +42 -41
- package/coverage/lcov-report/constants/layouts.js.html +3 -8
- package/coverage/lcov-report/constants/screens.js.html +3 -8
- package/coverage/lcov-report/db/inMemoryView.js.html +3 -8
- package/coverage/lcov-report/db/index.html +3 -8
- package/coverage/lcov-report/db/index.js.html +4 -9
- package/coverage/lcov-report/db/linkedRows/LinkController.js.html +23 -25
- package/coverage/lcov-report/db/linkedRows/index.html +12 -17
- package/coverage/lcov-report/db/linkedRows/index.js.html +17 -22
- package/coverage/lcov-report/db/linkedRows/linkUtils.js.html +7 -12
- package/coverage/lcov-report/db/newid.js.html +6 -11
- package/coverage/lcov-report/db/utils.js.html +79 -84
- package/coverage/lcov-report/events/AutomationEmitter.js.html +9 -14
- package/coverage/lcov-report/events/index.html +3 -8
- package/coverage/lcov-report/events/index.js.html +4 -9
- package/coverage/lcov-report/events/utils.js.html +13 -18
- package/coverage/lcov-report/index.html +132 -137
- package/coverage/lcov-report/integrations/tests/TestConfiguration.js.html +3 -8
- package/coverage/lcov-report/integrations/tests/index.html +3 -8
- package/coverage/lcov-report/middleware/appInfo.js.html +3 -8
- package/coverage/lcov-report/middleware/authorized.js.html +458 -0
- package/coverage/lcov-report/middleware/builder.js.html +3 -8
- package/coverage/lcov-report/middleware/currentapp.js.html +15 -65
- package/coverage/lcov-report/middleware/index.html +50 -25
- package/coverage/lcov-report/middleware/joi-validator.js.html +4 -9
- package/coverage/lcov-report/middleware/publicApi.js.html +3 -8
- package/coverage/lcov-report/middleware/resourceId.js.html +3 -8
- package/coverage/lcov-report/middleware/selfhost.js.html +4 -9
- package/coverage/lcov-report/middleware/usageQuota.js.html +572 -0
- package/coverage/lcov-report/middleware/utils.js.html +3 -8
- package/coverage/lcov-report/sorter.js +0 -26
- package/coverage/lcov-report/threads/automation.js.html +90 -581
- package/coverage/lcov-report/threads/index.html +40 -30
- package/coverage/lcov-report/threads/index.js.html +296 -0
- package/coverage/lcov-report/threads/query.js.html +4 -9
- package/coverage/lcov-report/threads/utils.js.html +9 -17
- package/coverage/lcov-report/utilities/bcrypt.js.html +3 -8
- package/coverage/lcov-report/utilities/budibaseDir.js.html +3 -8
- package/coverage/lcov-report/utilities/centralPath.js.html +3 -8
- package/coverage/lcov-report/utilities/csvParser.js.html +5 -10
- package/coverage/lcov-report/utilities/global.js.html +4 -9
- package/coverage/lcov-report/utilities/index.html +3 -8
- package/coverage/lcov-report/utilities/index.js.html +6 -11
- package/coverage/lcov-report/utilities/queue/inMemoryQueue.js.html +9 -32
- package/coverage/lcov-report/utilities/queue/index.html +7 -12
- package/coverage/lcov-report/utilities/routing/index.html +3 -8
- package/coverage/lcov-report/utilities/routing/index.js.html +3 -8
- package/coverage/lcov-report/utilities/rowProcessor/index.html +27 -32
- package/coverage/lcov-report/utilities/rowProcessor/index.js.html +71 -67
- package/coverage/lcov-report/utilities/rowProcessor/utils.js.html +106 -27
- package/coverage/lcov-report/utilities/scriptRunner.js.html +3 -8
- package/coverage/lcov-report/utilities/security.js.html +4 -9
- package/coverage/lcov-report/utilities/statusCodes.js.html +3 -8
- package/coverage/lcov-report/utilities/usageQuota/index.html +34 -24
- package/coverage/lcov-report/utilities/usageQuota/index.js.html +359 -0
- package/coverage/lcov-report/utilities/usageQuota/rows.js.html +39 -44
- package/coverage/lcov-report/utilities/usageQuota/usageQuoteReset.js.html +3 -8
- package/coverage/lcov-report/utilities/users.js.html +3 -8
- package/coverage/lcov-report/utilities/workerRequests.js.html +4 -9
- package/coverage/lcov.info +3061 -1290
- package/dist/api/controllers/application.js +73 -145
- package/dist/api/controllers/deploy/index.js +36 -68
- package/dist/api/controllers/public/applications.js +9 -29
- package/dist/api/controllers/public/queries.js +7 -27
- package/dist/api/controllers/public/rows.js +12 -32
- package/dist/api/controllers/public/tables.js +2 -2
- package/dist/api/controllers/public/users.js +8 -8
- package/dist/api/controllers/public/utils.js +1 -1
- package/dist/api/controllers/query/import/index.js +3 -3
- package/dist/api/controllers/query/index.js +44 -57
- package/dist/api/controllers/row/ExternalRequest.js +27 -27
- package/dist/api/controllers/row/index.js +60 -83
- package/dist/api/controllers/row/internal.js +1 -2
- package/dist/api/controllers/row/utils.js +1 -2
- package/dist/api/controllers/static/templates/BudibaseApp.svelte +0 -3
- package/dist/api/controllers/table/bulkFormula.js +1 -2
- package/dist/api/controllers/table/internal.js +55 -40
- package/dist/api/controllers/table/utils.js +229 -271
- package/dist/api/index.js +0 -5
- package/dist/api/routes/application.js +13 -39
- package/dist/api/routes/index.js +56 -61
- package/dist/api/routes/public/index.js +9 -6
- package/dist/api/routes/public/queries.js +1 -1
- package/dist/api/routes/public/rows.js +1 -1
- package/dist/api/routes/public/tables.js +3 -3
- package/dist/api/routes/public/users.js +1 -1
- package/dist/api/routes/row.js +17 -43
- package/dist/api/routes/static.js +13 -40
- package/dist/api/routes/tests/utilities/TestFunctions.js +33 -75
- package/dist/app.js +4 -8
- package/dist/automations/actions.js +0 -3
- package/dist/automations/automationUtils.js +0 -10
- package/dist/automations/steps/createRow.js +12 -12
- package/dist/automations/steps/deleteRow.js +16 -13
- package/dist/automations/tests/utilities/index.js +11 -13
- package/dist/automations/utils.js +133 -187
- package/dist/constants/index.js +7 -5
- package/dist/db/linkedRows/LinkController.js +1 -0
- package/dist/definitions/datasource.js +0 -1
- package/dist/environment.js +3 -2
- package/dist/index.js +0 -4
- package/dist/integrations/base/sql.js +2 -2
- package/dist/integrations/base/sqlTable.js +2 -2
- package/dist/integrations/googlesheets.js +1 -1
- package/dist/integrations/index.js +0 -4
- package/dist/integrations/microsoftSqlServer.js +8 -8
- package/dist/integrations/mysql.js +9 -9
- package/dist/integrations/oracle.js +7 -7
- package/dist/integrations/postgres.js +7 -7
- package/dist/integrations/queries/sql.js +2 -2
- package/dist/integrations/rest.js +1 -1
- package/dist/middleware/authorized.js +51 -51
- package/dist/middleware/currentapp.js +1 -15
- package/dist/middleware/usageQuota.js +154 -0
- package/dist/migrations/functions/appUrls.js +1 -1
- package/dist/migrations/functions/quotas1.js +2 -6
- package/dist/migrations/functions/usageQuotas/index.js +4 -0
- package/dist/migrations/functions/usageQuotas/syncApps.js +7 -4
- package/dist/migrations/functions/usageQuotas/syncRows.js +8 -5
- package/dist/migrations/index.js +1 -17
- package/dist/package.json +4 -10
- package/dist/threads/automation.js +27 -149
- package/dist/threads/index.js +10 -36
- package/dist/threads/utils.js +0 -1
- package/dist/tsconfig.tsbuildinfo +1 -0
- package/dist/utilities/queue/inMemoryQueue.js +1 -6
- package/dist/utilities/rowProcessor/index.js +11 -6
- package/dist/utilities/rowProcessor/utils.js +27 -1
- package/dist/utilities/usageQuota/index.js +86 -0
- package/nodemon.json +1 -1
- package/package.json +9 -15
- package/scripts/dev/manage.js +0 -2
- package/src/api/controllers/{application.ts → application.js} +51 -118
- package/src/api/controllers/deploy/{index.ts → index.js} +29 -53
- package/src/api/controllers/public/applications.ts +2 -2
- package/src/api/controllers/public/queries.ts +1 -1
- package/src/api/controllers/public/rows.ts +1 -1
- package/src/api/controllers/query/{index.ts → index.js} +48 -51
- package/src/api/controllers/row/ExternalRequest.ts +1 -1
- package/src/api/controllers/row/{index.ts → index.js} +17 -24
- package/src/api/controllers/row/internal.js +1 -2
- package/src/api/controllers/row/utils.js +1 -4
- package/src/api/controllers/static/templates/BudibaseApp.svelte +0 -3
- package/src/api/controllers/table/bulkFormula.js +1 -1
- package/src/api/controllers/table/{internal.ts → internal.js} +48 -27
- package/src/api/controllers/table/{utils.ts → utils.js} +69 -86
- package/src/api/index.js +0 -5
- package/src/api/routes/{application.ts → application.js} +14 -8
- package/src/api/routes/index.js +62 -0
- package/src/api/routes/public/index.ts +4 -1
- package/src/api/routes/{row.ts → row.js} +15 -7
- package/src/api/routes/{static.ts → static.js} +11 -11
- package/src/api/routes/tests/misc.spec.js +37 -39
- package/src/api/routes/tests/routing.spec.js +0 -1
- package/src/api/routes/tests/utilities/{TestFunctions.ts → TestFunctions.js} +33 -57
- package/src/app.ts +2 -1
- package/src/automations/actions.js +0 -3
- package/src/automations/automationUtils.js +0 -12
- package/src/automations/steps/{createRow.ts → createRow.js} +15 -9
- package/src/automations/steps/{deleteRow.ts → deleteRow.js} +16 -10
- package/src/automations/tests/automation.spec.js +1 -0
- package/src/automations/tests/{createRow.spec.ts → createRow.spec.js} +15 -4
- package/src/automations/tests/{deleteRow.spec.ts → deleteRow.spec.js} +5 -3
- package/src/automations/tests/utilities/index.js +10 -12
- package/src/automations/{utils.ts → utils.js} +28 -39
- package/src/constants/index.js +8 -6
- package/src/db/linkedRows/LinkController.js +1 -0
- package/src/definitions/datasource.ts +0 -1
- package/src/environment.js +3 -2
- package/src/index.ts +0 -3
- package/src/integrations/index.ts +0 -4
- package/src/middleware/{authorized.ts → authorized.js} +14 -20
- package/src/middleware/currentapp.js +1 -16
- package/src/middleware/tests/usageQuota.spec.js +120 -0
- package/src/middleware/usageQuota.js +164 -0
- package/src/migrations/functions/tests/quotas1.spec.js +2 -0
- package/src/migrations/functions/usageQuotas/index.ts +5 -0
- package/src/migrations/functions/usageQuotas/syncApps.ts +6 -3
- package/src/migrations/functions/usageQuotas/syncRows.ts +6 -3
- package/src/migrations/functions/usageQuotas/tests/syncApps.spec.js +41 -0
- package/src/migrations/functions/usageQuotas/tests/syncRows.spec.js +45 -0
- package/src/migrations/index.ts +1 -13
- package/src/threads/automation.js +34 -196
- package/src/threads/{index.ts → index.js} +14 -18
- package/src/threads/utils.js +0 -1
- package/src/utilities/queue/inMemoryQueue.js +1 -7
- package/src/utilities/rowProcessor/index.js +12 -9
- package/src/utilities/rowProcessor/utils.js +29 -1
- package/src/utilities/tests/usageQuota/usageQuota.spec.js +72 -0
- package/src/utilities/usageQuota/index.js +93 -0
- package/tsconfig.json +2 -2
- package/builder/assets/index.89795487.css +0 -6
- package/builder/assets/index.be9a1b80.js +0 -1299
- package/dist/automations/steps/loop.js +0 -51
- package/dist/integrations/redis.js +0 -158
- package/dist/migrations/functions/developerQuota.js +0 -49
- package/dist/migrations/functions/publishedAppsQuota.js +0 -47
- package/dist/migrations/functions/usageQuotas/syncDevelopers.js +0 -24
- package/dist/migrations/functions/usageQuotas/syncPublishedApps.js +0 -26
- package/dist/tsconfig.build.tsbuildinfo +0 -1
- package/src/api/routes/index.ts +0 -60
- package/src/automations/steps/loop.js +0 -50
- package/src/integrations/redis.ts +0 -152
- package/src/integrations/tests/redis.spec.js +0 -60
- package/src/migrations/functions/developerQuota.ts +0 -15
- package/src/migrations/functions/publishedAppsQuota.ts +0 -13
- package/src/migrations/functions/usageQuotas/syncDevelopers.ts +0 -19
- package/src/migrations/functions/usageQuotas/syncPublishedApps.ts +0 -21
- package/src/migrations/functions/usageQuotas/tests/syncApps.spec.ts +0 -34
- package/src/migrations/functions/usageQuotas/tests/syncRows.spec.ts +0 -40
- package/tsconfig.build.json +0 -10
|
@@ -1,31 +1,26 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
import { quotas } from "@budibase/pro"
|
|
1
|
+
const { Thread, ThreadType } = require("../threads")
|
|
2
|
+
const { definitions } = require("./triggerInfo")
|
|
3
|
+
const webhooks = require("../api/controllers/webhook")
|
|
4
|
+
const { queue } = require("./bullboard")
|
|
5
|
+
const newid = require("../db/newid")
|
|
6
|
+
const { updateEntityMetadata } = require("../utilities")
|
|
7
|
+
const { MetadataTypes, WebhookType } = require("../constants")
|
|
8
|
+
const { getProdAppID } = require("@budibase/backend-core/db")
|
|
9
|
+
const { cloneDeep } = require("lodash/fp")
|
|
10
|
+
const { doWithDB } = require("@budibase/backend-core/db")
|
|
11
|
+
const { getAppDB, getAppId } = require("@budibase/backend-core/context")
|
|
13
12
|
|
|
14
13
|
const WH_STEP_ID = definitions.WEBHOOK.stepId
|
|
15
14
|
const CRON_STEP_ID = definitions.CRON.stepId
|
|
16
15
|
const Runner = new Thread(ThreadType.AUTOMATION)
|
|
17
16
|
|
|
18
|
-
|
|
17
|
+
exports.processEvent = async job => {
|
|
19
18
|
try {
|
|
19
|
+
// need to actually await these so that an error can be captured properly
|
|
20
20
|
console.log(
|
|
21
21
|
`${job.data.automation.appId} automation ${job.data.automation._id} running`
|
|
22
22
|
)
|
|
23
|
-
|
|
24
|
-
const tenantId = tenancy.getTenantIDFromAppID(job.data.event.appId)
|
|
25
|
-
return await tenancy.doInTenant(tenantId, async () => {
|
|
26
|
-
const runFn = () => Runner.run(job)
|
|
27
|
-
return quotas.addAutomation(runFn)
|
|
28
|
-
})
|
|
23
|
+
return await Runner.run(job)
|
|
29
24
|
} catch (err) {
|
|
30
25
|
const errJson = JSON.stringify(err)
|
|
31
26
|
console.error(
|
|
@@ -36,15 +31,11 @@ export async function processEvent(job: any) {
|
|
|
36
31
|
}
|
|
37
32
|
}
|
|
38
33
|
|
|
39
|
-
|
|
40
|
-
appId: any,
|
|
41
|
-
automation: any,
|
|
42
|
-
history: any
|
|
43
|
-
) {
|
|
34
|
+
exports.updateTestHistory = async (appId, automation, history) => {
|
|
44
35
|
return updateEntityMetadata(
|
|
45
36
|
MetadataTypes.AUTOMATION_TEST_HISTORY,
|
|
46
37
|
automation._id,
|
|
47
|
-
|
|
38
|
+
metadata => {
|
|
48
39
|
if (metadata && Array.isArray(metadata.history)) {
|
|
49
40
|
metadata.history.push(history)
|
|
50
41
|
} else {
|
|
@@ -57,7 +48,7 @@ export async function updateTestHistory(
|
|
|
57
48
|
)
|
|
58
49
|
}
|
|
59
50
|
|
|
60
|
-
|
|
51
|
+
exports.removeDeprecated = definitions => {
|
|
61
52
|
const base = cloneDeep(definitions)
|
|
62
53
|
for (let key of Object.keys(base)) {
|
|
63
54
|
if (base[key].deprecated) {
|
|
@@ -68,15 +59,13 @@ export function removeDeprecated(definitions: any) {
|
|
|
68
59
|
}
|
|
69
60
|
|
|
70
61
|
// end the repetition and the job itself
|
|
71
|
-
|
|
62
|
+
exports.disableAllCrons = async appId => {
|
|
72
63
|
const promises = []
|
|
73
64
|
const jobs = await queue.getRepeatableJobs()
|
|
74
65
|
for (let job of jobs) {
|
|
75
66
|
if (job.key.includes(`${appId}_cron`)) {
|
|
76
67
|
promises.push(queue.removeRepeatableByKey(job.key))
|
|
77
|
-
|
|
78
|
-
promises.push(queue.removeJobs(job.id))
|
|
79
|
-
}
|
|
68
|
+
promises.push(queue.removeJobs(job.id))
|
|
80
69
|
}
|
|
81
70
|
}
|
|
82
71
|
return Promise.all(promises)
|
|
@@ -87,9 +76,9 @@ export async function disableAllCrons(appId: any) {
|
|
|
87
76
|
* @param {string} appId The ID of the app in which we are checking for webhooks
|
|
88
77
|
* @param {object|undefined} automation The automation object to be updated.
|
|
89
78
|
*/
|
|
90
|
-
|
|
79
|
+
exports.enableCronTrigger = async (appId, automation) => {
|
|
91
80
|
const trigger = automation ? automation.definition.trigger : null
|
|
92
|
-
function isCronTrigger(auto
|
|
81
|
+
function isCronTrigger(auto) {
|
|
93
82
|
return (
|
|
94
83
|
auto &&
|
|
95
84
|
auto.definition.trigger &&
|
|
@@ -100,7 +89,7 @@ export async function enableCronTrigger(appId: any, automation: any) {
|
|
|
100
89
|
if (isCronTrigger(automation)) {
|
|
101
90
|
// make a job id rather than letting Bull decide, makes it easier to handle on way out
|
|
102
91
|
const jobId = `${appId}_cron_${newid()}`
|
|
103
|
-
const job
|
|
92
|
+
const job = await queue.add(
|
|
104
93
|
{
|
|
105
94
|
automation,
|
|
106
95
|
event: { appId, timestamp: Date.now() },
|
|
@@ -112,7 +101,7 @@ export async function enableCronTrigger(appId: any, automation: any) {
|
|
|
112
101
|
// can't use getAppDB here as this is likely to be called from dev app,
|
|
113
102
|
// but this call could be for dev app or prod app, need to just use what
|
|
114
103
|
// was passed in
|
|
115
|
-
await doWithDB(appId, async
|
|
104
|
+
await doWithDB(appId, async db => {
|
|
116
105
|
const response = await db.put(automation)
|
|
117
106
|
automation._id = response.id
|
|
118
107
|
automation._rev = response.rev
|
|
@@ -129,13 +118,13 @@ export async function enableCronTrigger(appId: any, automation: any) {
|
|
|
129
118
|
* @returns {Promise<object|undefined>} After this is complete the new automation object may have been updated and should be
|
|
130
119
|
* written to DB (this does not write to DB as it would be wasteful to repeat).
|
|
131
120
|
*/
|
|
132
|
-
|
|
121
|
+
exports.checkForWebhooks = async ({ oldAuto, newAuto }) => {
|
|
133
122
|
const appId = getAppId()
|
|
134
123
|
const oldTrigger = oldAuto ? oldAuto.definition.trigger : null
|
|
135
124
|
const newTrigger = newAuto ? newAuto.definition.trigger : null
|
|
136
125
|
const triggerChanged =
|
|
137
126
|
oldTrigger && newTrigger && oldTrigger.id !== newTrigger.id
|
|
138
|
-
function isWebhookTrigger(auto
|
|
127
|
+
function isWebhookTrigger(auto) {
|
|
139
128
|
return (
|
|
140
129
|
auto &&
|
|
141
130
|
auto.definition.trigger &&
|
|
@@ -171,7 +160,7 @@ export async function checkForWebhooks({ oldAuto, newAuto }: any) {
|
|
|
171
160
|
(!isWebhookTrigger(oldAuto) || triggerChanged) &&
|
|
172
161
|
isWebhookTrigger(newAuto)
|
|
173
162
|
) {
|
|
174
|
-
const ctx
|
|
163
|
+
const ctx = {
|
|
175
164
|
appId,
|
|
176
165
|
request: {
|
|
177
166
|
body: new webhooks.Webhook(
|
|
@@ -201,6 +190,6 @@ export async function checkForWebhooks({ oldAuto, newAuto }: any) {
|
|
|
201
190
|
* @param appId {string} the app that is being removed.
|
|
202
191
|
* @return {Promise<void>} clean is complete if this succeeds.
|
|
203
192
|
*/
|
|
204
|
-
|
|
205
|
-
await disableAllCrons(appId)
|
|
193
|
+
exports.cleanupAutomations = async appId => {
|
|
194
|
+
await exports.disableAllCrons(appId)
|
|
206
195
|
}
|
package/src/constants/index.js
CHANGED
|
@@ -162,6 +162,14 @@ exports.AutoFieldSubTypes = {
|
|
|
162
162
|
AUTO_ID: "autoID",
|
|
163
163
|
}
|
|
164
164
|
|
|
165
|
+
exports.AutoFieldDefaultNames = {
|
|
166
|
+
CREATED_BY: "Created By",
|
|
167
|
+
CREATED_AT: "Created At",
|
|
168
|
+
UPDATED_BY: "Updated By",
|
|
169
|
+
UPDATED_AT: "Updated At",
|
|
170
|
+
AUTO_ID: "Auto ID",
|
|
171
|
+
}
|
|
172
|
+
|
|
165
173
|
exports.OBJ_STORE_DIRECTORY = "/prod-budi-app-assets"
|
|
166
174
|
exports.BaseQueryVerbs = {
|
|
167
175
|
CREATE: "create",
|
|
@@ -190,11 +198,5 @@ exports.WebhookType = {
|
|
|
190
198
|
AUTOMATION: "automation",
|
|
191
199
|
}
|
|
192
200
|
|
|
193
|
-
exports.AutomationErrors = {
|
|
194
|
-
INCORRECT_TYPE: "INCORRECT_TYPE",
|
|
195
|
-
MAX_ITERATIONS: "MAX_ITERATIONS_REACHED",
|
|
196
|
-
FAILURE_CONDITION: "FAILURE_CONDITION_MET",
|
|
197
|
-
}
|
|
198
|
-
|
|
199
201
|
// pass through the list from the auth/core lib
|
|
200
202
|
exports.ObjectStoreBuckets = ObjectStoreBuckets
|
package/src/environment.js
CHANGED
|
@@ -34,7 +34,7 @@ let inThread = false
|
|
|
34
34
|
|
|
35
35
|
module.exports = {
|
|
36
36
|
// important
|
|
37
|
-
PORT: process.env.PORT
|
|
37
|
+
PORT: process.env.PORT,
|
|
38
38
|
JWT_SECRET: process.env.JWT_SECRET,
|
|
39
39
|
COUCH_DB_URL: process.env.COUCH_DB_URL,
|
|
40
40
|
MINIO_URL: process.env.MINIO_URL,
|
|
@@ -44,6 +44,8 @@ module.exports = {
|
|
|
44
44
|
ENABLE_ANALYTICS: process.env.ENABLE_ANALYTICS,
|
|
45
45
|
MINIO_ACCESS_KEY: process.env.MINIO_ACCESS_KEY,
|
|
46
46
|
MINIO_SECRET_KEY: process.env.MINIO_SECRET_KEY,
|
|
47
|
+
USE_QUOTAS: process.env.USE_QUOTAS,
|
|
48
|
+
EXCLUDE_QUOTAS_TENANTS: process.env.EXCLUDE_QUOTAS_TENANTS,
|
|
47
49
|
REDIS_URL: process.env.REDIS_URL,
|
|
48
50
|
REDIS_PASSWORD: process.env.REDIS_PASSWORD,
|
|
49
51
|
INTERNAL_API_KEY: process.env.INTERNAL_API_KEY,
|
|
@@ -63,7 +65,6 @@ module.exports = {
|
|
|
63
65
|
LOG_LEVEL: process.env.LOG_LEVEL,
|
|
64
66
|
AUTOMATION_DIRECTORY: process.env.AUTOMATION_DIRECTORY,
|
|
65
67
|
AUTOMATION_BUCKET: process.env.AUTOMATION_BUCKET,
|
|
66
|
-
AUTOMATION_MAX_ITERATIONS: process.env.AUTOMATION_MAX_ITERATIONS,
|
|
67
68
|
SENDGRID_API_KEY: process.env.SENDGRID_API_KEY,
|
|
68
69
|
DYNAMO_ENDPOINT: process.env.DYNAMO_ENDPOINT,
|
|
69
70
|
POSTHOG_TOKEN: process.env.POSTHOG_TOKEN,
|
package/src/index.ts
CHANGED
|
@@ -1,4 +1,3 @@
|
|
|
1
|
-
import { bootstrap } from "global-agent"
|
|
2
1
|
const fixPath = require("fix-path")
|
|
3
2
|
const { checkDevelopmentEnvironment } = require("./utilities/fileSystem")
|
|
4
3
|
|
|
@@ -7,8 +6,6 @@ function runServer() {
|
|
|
7
6
|
// will print an error explaining what to do
|
|
8
7
|
checkDevelopmentEnvironment()
|
|
9
8
|
fixPath()
|
|
10
|
-
// this will setup http and https proxies form env variables
|
|
11
|
-
bootstrap()
|
|
12
9
|
require("./app")
|
|
13
10
|
}
|
|
14
11
|
|
|
@@ -11,7 +11,6 @@ const arangodb = require("./arangodb")
|
|
|
11
11
|
const rest = require("./rest")
|
|
12
12
|
const googlesheets = require("./googlesheets")
|
|
13
13
|
const firebase = require("./firebase")
|
|
14
|
-
const redis = require("./redis")
|
|
15
14
|
const { SourceNames } = require("../definitions/datasource")
|
|
16
15
|
const environment = require("../environment")
|
|
17
16
|
|
|
@@ -27,8 +26,6 @@ const DEFINITIONS = {
|
|
|
27
26
|
[SourceNames.MYSQL]: mysql.schema,
|
|
28
27
|
[SourceNames.ARANGODB]: arangodb.schema,
|
|
29
28
|
[SourceNames.REST]: rest.schema,
|
|
30
|
-
[SourceNames.FIREBASE]: firebase.schema,
|
|
31
|
-
[SourceNames.REDIS]: redis.schema,
|
|
32
29
|
}
|
|
33
30
|
|
|
34
31
|
const INTEGRATIONS = {
|
|
@@ -45,7 +42,6 @@ const INTEGRATIONS = {
|
|
|
45
42
|
[SourceNames.REST]: rest.integration,
|
|
46
43
|
[SourceNames.FIREBASE]: firebase.integration,
|
|
47
44
|
[SourceNames.GOOGLE_SHEETS]: googlesheets.integration,
|
|
48
|
-
[SourceNames.REDIS]: redis.integration,
|
|
49
45
|
}
|
|
50
46
|
|
|
51
47
|
// optionally add oracle integration if the oracle binary can be installed
|
|
@@ -1,8 +1,8 @@
|
|
|
1
|
-
|
|
1
|
+
const {
|
|
2
2
|
getUserRoleHierarchy,
|
|
3
3
|
getRequiredResourceRole,
|
|
4
4
|
BUILTIN_ROLE_IDS,
|
|
5
|
-
}
|
|
5
|
+
} = require("@budibase/backend-core/roles")
|
|
6
6
|
const {
|
|
7
7
|
PermissionTypes,
|
|
8
8
|
PermissionLevels,
|
|
@@ -13,7 +13,7 @@ const { isWebhookEndpoint } = require("./utils")
|
|
|
13
13
|
const { buildCsrfMiddleware } = require("@budibase/backend-core/auth")
|
|
14
14
|
const { getAppId } = require("@budibase/backend-core/context")
|
|
15
15
|
|
|
16
|
-
function hasResource(ctx
|
|
16
|
+
function hasResource(ctx) {
|
|
17
17
|
return ctx.resourceId != null
|
|
18
18
|
}
|
|
19
19
|
|
|
@@ -25,12 +25,7 @@ const csrf = buildCsrfMiddleware()
|
|
|
25
25
|
* - Builders can access all resources.
|
|
26
26
|
* - Otherwise the user must have the required role.
|
|
27
27
|
*/
|
|
28
|
-
const checkAuthorized = async (
|
|
29
|
-
ctx: any,
|
|
30
|
-
resourceRoles: any,
|
|
31
|
-
permType: any,
|
|
32
|
-
permLevel: any
|
|
33
|
-
) => {
|
|
28
|
+
const checkAuthorized = async (ctx, resourceRoles, permType, permLevel) => {
|
|
34
29
|
// check if this is a builder api and the user is not a builder
|
|
35
30
|
const isBuilder = ctx.user && ctx.user.builder && ctx.user.builder.global
|
|
36
31
|
const isBuilderApi = permType === PermissionTypes.BUILDER
|
|
@@ -45,10 +40,10 @@ const checkAuthorized = async (
|
|
|
45
40
|
}
|
|
46
41
|
|
|
47
42
|
const checkAuthorizedResource = async (
|
|
48
|
-
ctx
|
|
49
|
-
resourceRoles
|
|
50
|
-
permType
|
|
51
|
-
permLevel
|
|
43
|
+
ctx,
|
|
44
|
+
resourceRoles,
|
|
45
|
+
permType,
|
|
46
|
+
permLevel
|
|
52
47
|
) => {
|
|
53
48
|
// get the user's roles
|
|
54
49
|
const roleId = ctx.roleId || BUILTIN_ROLE_IDS.PUBLIC
|
|
@@ -59,9 +54,7 @@ const checkAuthorizedResource = async (
|
|
|
59
54
|
// check if the user has the required role
|
|
60
55
|
if (resourceRoles.length > 0) {
|
|
61
56
|
// deny access if the user doesn't have the required resource role
|
|
62
|
-
const found = userRoles.find(
|
|
63
|
-
(role: any) => resourceRoles.indexOf(role._id) !== -1
|
|
64
|
-
)
|
|
57
|
+
const found = userRoles.find(role => resourceRoles.indexOf(role._id) !== -1)
|
|
65
58
|
if (!found) {
|
|
66
59
|
ctx.throw(403, permError)
|
|
67
60
|
}
|
|
@@ -71,8 +64,9 @@ const checkAuthorizedResource = async (
|
|
|
71
64
|
}
|
|
72
65
|
}
|
|
73
66
|
|
|
74
|
-
|
|
75
|
-
|
|
67
|
+
module.exports =
|
|
68
|
+
(permType, permLevel = null, opts = { schema: false }) =>
|
|
69
|
+
async (ctx, next) => {
|
|
76
70
|
// webhooks don't need authentication, each webhook unique
|
|
77
71
|
// also internal requests (between services) don't need authorized
|
|
78
72
|
if (isWebhookEndpoint(ctx) || ctx.internal) {
|
|
@@ -88,8 +82,8 @@ export = (permType: any, permLevel: any = null, opts = { schema: false }) =>
|
|
|
88
82
|
await builderMiddleware(ctx, permType)
|
|
89
83
|
|
|
90
84
|
// get the resource roles
|
|
91
|
-
let resourceRoles
|
|
92
|
-
|
|
85
|
+
let resourceRoles = [],
|
|
86
|
+
otherLevelRoles
|
|
93
87
|
const otherLevel =
|
|
94
88
|
permLevel === PermissionLevels.READ
|
|
95
89
|
? PermissionLevels.WRITE
|
|
@@ -4,7 +4,7 @@ const {
|
|
|
4
4
|
getCookie,
|
|
5
5
|
clearCookie,
|
|
6
6
|
} = require("@budibase/backend-core/utils")
|
|
7
|
-
const { Cookies
|
|
7
|
+
const { Cookies } = require("@budibase/backend-core/constants")
|
|
8
8
|
const { getRole } = require("@budibase/backend-core/roles")
|
|
9
9
|
const { BUILTIN_ROLE_IDS } = require("@budibase/backend-core/roles")
|
|
10
10
|
const { generateUserMetadataID, isDevAppID } = require("../db/utils")
|
|
@@ -63,21 +63,6 @@ module.exports = async (ctx, next) => {
|
|
|
63
63
|
appId = requestAppId
|
|
64
64
|
// retrieving global user gets the right role
|
|
65
65
|
roleId = globalUser.roleId || roleId
|
|
66
|
-
|
|
67
|
-
// Allow builders to specify their role via a header
|
|
68
|
-
const isBuilder =
|
|
69
|
-
globalUser && globalUser.builder && globalUser.builder.global
|
|
70
|
-
const isDevApp = appId && isDevAppID(appId)
|
|
71
|
-
const roleHeader = ctx.request && ctx.request.headers[Headers.PREVIEW_ROLE]
|
|
72
|
-
if (isBuilder && isDevApp && roleHeader) {
|
|
73
|
-
// Ensure the role is valid by ensuring a definition exists
|
|
74
|
-
try {
|
|
75
|
-
await getRole(roleHeader)
|
|
76
|
-
roleId = roleHeader
|
|
77
|
-
} catch (error) {
|
|
78
|
-
// Swallow error and do nothing
|
|
79
|
-
}
|
|
80
|
-
}
|
|
81
66
|
}
|
|
82
67
|
|
|
83
68
|
// nothing more to do
|
|
@@ -0,0 +1,120 @@
|
|
|
1
|
+
jest.mock("../../db")
|
|
2
|
+
jest.mock("../../utilities/usageQuota")
|
|
3
|
+
jest.mock("@budibase/backend-core/tenancy", () => ({
|
|
4
|
+
getTenantId: () => "testing123"
|
|
5
|
+
}))
|
|
6
|
+
|
|
7
|
+
const usageQuotaMiddleware = require("../usageQuota")
|
|
8
|
+
const usageQuota = require("../../utilities/usageQuota")
|
|
9
|
+
|
|
10
|
+
jest.mock("@budibase/backend-core/db")
|
|
11
|
+
const { dangerousGetDB } = require("@budibase/backend-core/db")
|
|
12
|
+
|
|
13
|
+
const env = require("../../environment")
|
|
14
|
+
|
|
15
|
+
class TestConfiguration {
|
|
16
|
+
constructor() {
|
|
17
|
+
this.throw = jest.fn()
|
|
18
|
+
this.next = jest.fn()
|
|
19
|
+
this.middleware = usageQuotaMiddleware
|
|
20
|
+
this.ctx = {
|
|
21
|
+
throw: this.throw,
|
|
22
|
+
next: this.next,
|
|
23
|
+
appId: "test",
|
|
24
|
+
request: {
|
|
25
|
+
body: {}
|
|
26
|
+
},
|
|
27
|
+
req: {
|
|
28
|
+
method: "POST",
|
|
29
|
+
url: "/applications"
|
|
30
|
+
}
|
|
31
|
+
}
|
|
32
|
+
usageQuota.useQuotas = () => true
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
executeMiddleware() {
|
|
36
|
+
return this.middleware(this.ctx, this.next)
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
setProd(bool) {
|
|
40
|
+
if (bool) {
|
|
41
|
+
env.isDev = () => false
|
|
42
|
+
env.isProd = () => true
|
|
43
|
+
this.ctx.user = { tenantId: "test" }
|
|
44
|
+
} else {
|
|
45
|
+
env.isDev = () => true
|
|
46
|
+
env.isProd = () => false
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
setMethod(method) {
|
|
51
|
+
this.ctx.req.method = method
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
setUrl(url) {
|
|
55
|
+
this.ctx.req.url = url
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
setBody(body) {
|
|
59
|
+
this.ctx.request.body = body
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
setFiles(files) {
|
|
63
|
+
this.ctx.request.files = { file: files }
|
|
64
|
+
}
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
describe("usageQuota middleware", () => {
|
|
68
|
+
let config
|
|
69
|
+
|
|
70
|
+
beforeEach(() => {
|
|
71
|
+
config = new TestConfiguration()
|
|
72
|
+
})
|
|
73
|
+
|
|
74
|
+
it("skips the middleware if there is no usage property or method", async () => {
|
|
75
|
+
await config.executeMiddleware()
|
|
76
|
+
expect(config.next).toHaveBeenCalled()
|
|
77
|
+
})
|
|
78
|
+
|
|
79
|
+
it("passes through to next middleware if document already exists", async () => {
|
|
80
|
+
config.setProd(true)
|
|
81
|
+
config.setBody({
|
|
82
|
+
_id: "test",
|
|
83
|
+
_rev: "test",
|
|
84
|
+
})
|
|
85
|
+
|
|
86
|
+
dangerousGetDB.mockImplementationOnce(() => ({
|
|
87
|
+
get: async () => true
|
|
88
|
+
}))
|
|
89
|
+
|
|
90
|
+
await config.executeMiddleware()
|
|
91
|
+
|
|
92
|
+
expect(config.next).toHaveBeenCalled()
|
|
93
|
+
})
|
|
94
|
+
|
|
95
|
+
it("throws if request has _id, but the document no longer exists", async () => {
|
|
96
|
+
config.setBody({
|
|
97
|
+
_id: "123",
|
|
98
|
+
_rev: "test",
|
|
99
|
+
})
|
|
100
|
+
config.setProd(true)
|
|
101
|
+
|
|
102
|
+
dangerousGetDB.mockImplementationOnce(() => ({
|
|
103
|
+
get: async () => {
|
|
104
|
+
throw new Error()
|
|
105
|
+
}
|
|
106
|
+
}))
|
|
107
|
+
|
|
108
|
+
await config.executeMiddleware()
|
|
109
|
+
expect(config.throw).toHaveBeenCalledWith(404, `${config.ctx.request.body._id} does not exist`)
|
|
110
|
+
})
|
|
111
|
+
|
|
112
|
+
it("calculates and persists the correct usage quota for the relevant action", async () => {
|
|
113
|
+
config.setUrl("/rows")
|
|
114
|
+
|
|
115
|
+
await config.executeMiddleware()
|
|
116
|
+
|
|
117
|
+
expect(usageQuota.update).toHaveBeenCalledWith("rows", 1)
|
|
118
|
+
expect(config.next).toHaveBeenCalled()
|
|
119
|
+
})
|
|
120
|
+
})
|
|
@@ -0,0 +1,164 @@
|
|
|
1
|
+
const usageQuota = require("../utilities/usageQuota")
|
|
2
|
+
const { getUniqueRows } = require("../utilities/usageQuota/rows")
|
|
3
|
+
const {
|
|
4
|
+
isExternalTable,
|
|
5
|
+
isRowId: isExternalRowId,
|
|
6
|
+
} = require("../integrations/utils")
|
|
7
|
+
const { getAppDB } = require("@budibase/backend-core/context")
|
|
8
|
+
|
|
9
|
+
// currently only counting new writes and deletes
|
|
10
|
+
const METHOD_MAP = {
|
|
11
|
+
POST: 1,
|
|
12
|
+
DELETE: -1,
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
const DOMAIN_MAP = {
|
|
16
|
+
rows: usageQuota.Properties.ROW,
|
|
17
|
+
// upload: usageQuota.Properties.UPLOAD, // doesn't work yet
|
|
18
|
+
// views: usageQuota.Properties.VIEW, // doesn't work yet
|
|
19
|
+
// users: usageQuota.Properties.USER, // doesn't work yet
|
|
20
|
+
applications: usageQuota.Properties.APPS,
|
|
21
|
+
// this will not be updated by endpoint calls
|
|
22
|
+
// instead it will be updated by triggerInfo
|
|
23
|
+
// automationRuns: usageQuota.Properties.AUTOMATION, // doesn't work yet
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
function getProperty(url) {
|
|
27
|
+
for (let domain of Object.keys(DOMAIN_MAP)) {
|
|
28
|
+
if (url.indexOf(domain) !== -1) {
|
|
29
|
+
return DOMAIN_MAP[domain]
|
|
30
|
+
}
|
|
31
|
+
}
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
module.exports = async (ctx, next) => {
|
|
35
|
+
if (!usageQuota.useQuotas()) {
|
|
36
|
+
return next()
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
let usage = METHOD_MAP[ctx.req.method]
|
|
40
|
+
const property = getProperty(ctx.req.url)
|
|
41
|
+
if (usage == null || property == null) {
|
|
42
|
+
return next()
|
|
43
|
+
}
|
|
44
|
+
// post request could be a save of a pre-existing entry
|
|
45
|
+
if (ctx.request.body && ctx.request.body._id && ctx.request.body._rev) {
|
|
46
|
+
const usageId = ctx.request.body._id
|
|
47
|
+
try {
|
|
48
|
+
if (ctx.appId) {
|
|
49
|
+
const db = getAppDB()
|
|
50
|
+
await db.get(usageId)
|
|
51
|
+
}
|
|
52
|
+
return next()
|
|
53
|
+
} catch (err) {
|
|
54
|
+
if (
|
|
55
|
+
isExternalTable(usageId) ||
|
|
56
|
+
(ctx.request.body.tableId &&
|
|
57
|
+
isExternalTable(ctx.request.body.tableId)) ||
|
|
58
|
+
isExternalRowId(usageId)
|
|
59
|
+
) {
|
|
60
|
+
return next()
|
|
61
|
+
} else {
|
|
62
|
+
ctx.throw(404, `${usageId} does not exist`)
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
// update usage for uploads to be the total size
|
|
68
|
+
if (property === usageQuota.Properties.UPLOAD) {
|
|
69
|
+
const files =
|
|
70
|
+
ctx.request.files.file.length > 1
|
|
71
|
+
? Array.from(ctx.request.files.file)
|
|
72
|
+
: [ctx.request.files.file]
|
|
73
|
+
usage = files.map(file => file.size).reduce((total, size) => total + size)
|
|
74
|
+
}
|
|
75
|
+
try {
|
|
76
|
+
await performRequest(ctx, next, property, usage)
|
|
77
|
+
} catch (err) {
|
|
78
|
+
ctx.throw(400, err)
|
|
79
|
+
}
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
const performRequest = async (ctx, next, property, usage) => {
|
|
83
|
+
const usageContext = {
|
|
84
|
+
skipNext: false,
|
|
85
|
+
skipUsage: false,
|
|
86
|
+
[usageQuota.Properties.APPS]: {},
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
if (usage === -1) {
|
|
90
|
+
if (PRE_DELETE[property]) {
|
|
91
|
+
await PRE_DELETE[property](ctx, usageContext)
|
|
92
|
+
}
|
|
93
|
+
} else {
|
|
94
|
+
if (PRE_CREATE[property]) {
|
|
95
|
+
await PRE_CREATE[property](ctx, usageContext)
|
|
96
|
+
}
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
// run the request
|
|
100
|
+
if (!usageContext.skipNext) {
|
|
101
|
+
await usageQuota.update(property, usage, { dryRun: true })
|
|
102
|
+
await next()
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
if (usage === -1) {
|
|
106
|
+
if (POST_DELETE[property]) {
|
|
107
|
+
await POST_DELETE[property](ctx, usageContext)
|
|
108
|
+
}
|
|
109
|
+
} else {
|
|
110
|
+
if (POST_CREATE[property]) {
|
|
111
|
+
await POST_CREATE[property](ctx, usageContext)
|
|
112
|
+
}
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
// update the usage
|
|
116
|
+
if (!usageContext.skipUsage) {
|
|
117
|
+
await usageQuota.update(property, usage)
|
|
118
|
+
}
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
const appPreDelete = async (ctx, usageContext) => {
|
|
122
|
+
if (ctx.query.unpublish) {
|
|
123
|
+
// don't run usage decrement for unpublish
|
|
124
|
+
usageContext.skipUsage = true
|
|
125
|
+
return
|
|
126
|
+
}
|
|
127
|
+
|
|
128
|
+
// store the row count to delete
|
|
129
|
+
const rows = await getUniqueRows([ctx.appId])
|
|
130
|
+
if (rows.length) {
|
|
131
|
+
usageContext[usageQuota.Properties.APPS] = { rowCount: rows.length }
|
|
132
|
+
}
|
|
133
|
+
}
|
|
134
|
+
|
|
135
|
+
const appPostDelete = async (ctx, usageContext) => {
|
|
136
|
+
// delete the app rows from usage
|
|
137
|
+
const rowCount = usageContext[usageQuota.Properties.APPS].rowCount
|
|
138
|
+
if (rowCount) {
|
|
139
|
+
await usageQuota.update(usageQuota.Properties.ROW, -rowCount)
|
|
140
|
+
}
|
|
141
|
+
}
|
|
142
|
+
|
|
143
|
+
const appPostCreate = async ctx => {
|
|
144
|
+
// app import & template creation
|
|
145
|
+
if (ctx.request.body.useTemplate === "true") {
|
|
146
|
+
const rows = await getUniqueRows([ctx.response.body.appId])
|
|
147
|
+
const rowCount = rows ? rows.length : 0
|
|
148
|
+
await usageQuota.update(usageQuota.Properties.ROW, rowCount)
|
|
149
|
+
}
|
|
150
|
+
}
|
|
151
|
+
|
|
152
|
+
const PRE_DELETE = {
|
|
153
|
+
[usageQuota.Properties.APPS]: appPreDelete,
|
|
154
|
+
}
|
|
155
|
+
|
|
156
|
+
const POST_DELETE = {
|
|
157
|
+
[usageQuota.Properties.APPS]: appPostDelete,
|
|
158
|
+
}
|
|
159
|
+
|
|
160
|
+
const PRE_CREATE = {}
|
|
161
|
+
|
|
162
|
+
const POST_CREATE = {
|
|
163
|
+
[usageQuota.Properties.APPS]: appPostCreate,
|
|
164
|
+
}
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
const env = require("../../../environment")
|
|
1
2
|
const TestConfig = require("../../../tests/utilities/TestConfiguration")
|
|
2
3
|
|
|
3
4
|
const syncApps = jest.fn()
|
|
@@ -13,6 +14,7 @@ describe("run", () => {
|
|
|
13
14
|
|
|
14
15
|
beforeEach(async () => {
|
|
15
16
|
await config.init()
|
|
17
|
+
env._set("USE_QUOTAS", 1)
|
|
16
18
|
})
|
|
17
19
|
|
|
18
20
|
afterAll(config.end)
|