@budibase/server 1.0.49-alpha.9 → 1.0.49
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/__mocks__/arangojs.ts +1 -1
- package/__mocks__/aws-sdk.ts +4 -4
- package/__mocks__/mongodb.ts +5 -4
- package/__mocks__/mssql.ts +3 -3
- package/__mocks__/node-fetch.ts +1 -2
- package/__mocks__/pg.ts +5 -3
- package/builder/assets/{index.ad5370ae.js → index.2c37968e.js} +246 -249
- package/builder/assets/index.39e01193.css +1 -0
- package/builder/assets/{vendor.d526bfe8.js → vendor.f9faf6ab.js} +12 -12
- package/builder/index.html +3 -3
- package/coverage/clover.xml +2827 -3117
- package/coverage/coverage-final.json +101 -106
- package/coverage/lcov-report/api/controllers/analytics.js.html +1 -1
- package/coverage/lcov-report/api/controllers/apikeys.js.html +1 -1
- package/coverage/lcov-report/api/controllers/application.js.html +152 -257
- package/coverage/lcov-report/api/controllers/auth.js.html +13 -22
- package/coverage/lcov-report/api/controllers/automation.js.html +69 -39
- package/coverage/lcov-report/api/controllers/backup.js.html +1 -1
- package/coverage/lcov-report/api/controllers/cloud.js.html +11 -8
- package/coverage/lcov-report/api/controllers/component.js.html +16 -13
- package/coverage/lcov-report/api/controllers/datasource.js.html +51 -81
- package/coverage/lcov-report/api/controllers/dev.js.html +6 -6
- package/coverage/lcov-report/{utilities/usageQuota/usageQuoteReset.js.html → api/controllers/hosting.js.html} +48 -36
- package/coverage/lcov-report/api/controllers/index.html +76 -76
- package/coverage/lcov-report/api/controllers/integration.js.html +1 -1
- package/coverage/lcov-report/api/controllers/layout.js.html +9 -9
- package/coverage/lcov-report/api/controllers/metadata.js.html +21 -6
- package/coverage/lcov-report/api/controllers/permission.js.html +19 -19
- package/coverage/lcov-report/api/controllers/query/index.html +10 -10
- package/coverage/lcov-report/api/controllers/query/index.js.html +35 -38
- package/coverage/lcov-report/api/controllers/query/validation.js.html +6 -6
- package/coverage/lcov-report/api/controllers/role.js.html +16 -16
- package/coverage/lcov-report/api/controllers/routing.js.html +10 -7
- package/coverage/lcov-report/api/controllers/row/external.js.html +141 -48
- package/coverage/lcov-report/api/controllers/row/index.html +40 -55
- package/coverage/lcov-report/api/controllers/row/index.js.html +26 -26
- package/coverage/lcov-report/api/controllers/row/internal.js.html +226 -118
- package/coverage/lcov-report/api/controllers/row/internalSearch.js.html +34 -52
- package/coverage/lcov-report/api/controllers/row/utils.js.html +62 -47
- package/coverage/lcov-report/api/controllers/screen.js.html +21 -15
- package/coverage/lcov-report/api/controllers/script.js.html +4 -4
- package/coverage/lcov-report/api/controllers/table/external.js.html +34 -25
- package/coverage/lcov-report/api/controllers/table/index.html +43 -58
- package/coverage/lcov-report/api/controllers/table/index.js.html +82 -58
- package/coverage/lcov-report/api/controllers/table/internal.js.html +66 -81
- package/coverage/lcov-report/api/controllers/table/utils.js.html +110 -218
- package/coverage/lcov-report/api/controllers/templates.js.html +1 -1
- package/coverage/lcov-report/api/controllers/user.js.html +50 -47
- package/coverage/lcov-report/api/controllers/view/exporters.js.html +4 -4
- package/coverage/lcov-report/api/controllers/view/index.html +16 -16
- package/coverage/lcov-report/api/controllers/view/index.js.html +33 -27
- package/coverage/lcov-report/api/controllers/view/utils.js.html +20 -35
- package/coverage/lcov-report/api/controllers/view/viewBuilder.js.html +7 -7
- package/coverage/lcov-report/api/controllers/webhook.js.html +28 -34
- package/coverage/lcov-report/api/index.html +1 -1
- package/coverage/lcov-report/api/index.js.html +8 -8
- package/coverage/lcov-report/api/routes/analytics.js.html +1 -1
- package/coverage/lcov-report/api/routes/apikeys.js.html +1 -1
- package/coverage/lcov-report/api/routes/application.js.html +1 -1
- package/coverage/lcov-report/api/routes/auth.js.html +1 -1
- package/coverage/lcov-report/api/routes/automation.js.html +1 -1
- package/coverage/lcov-report/api/routes/backup.js.html +1 -1
- package/coverage/lcov-report/api/routes/cloud.js.html +1 -1
- package/coverage/lcov-report/api/routes/component.js.html +1 -1
- package/coverage/lcov-report/api/routes/datasource.js.html +1 -1
- package/coverage/lcov-report/api/routes/deploy.js.html +1 -1
- package/coverage/lcov-report/api/routes/dev.js.html +1 -1
- package/coverage/lcov-report/api/routes/{migrations.js.html → hosting.js.html} +14 -17
- package/coverage/lcov-report/api/routes/index.html +18 -18
- package/coverage/lcov-report/api/routes/index.js.html +3 -3
- package/coverage/lcov-report/api/routes/integration.js.html +1 -1
- package/coverage/lcov-report/api/routes/layout.js.html +1 -1
- package/coverage/lcov-report/api/routes/metadata.js.html +1 -1
- package/coverage/lcov-report/api/routes/permission.js.html +1 -1
- package/coverage/lcov-report/api/routes/query.js.html +1 -1
- package/coverage/lcov-report/api/routes/role.js.html +1 -1
- package/coverage/lcov-report/api/routes/routing.js.html +1 -1
- package/coverage/lcov-report/api/routes/row.js.html +1 -1
- package/coverage/lcov-report/api/routes/screen.js.html +1 -1
- package/coverage/lcov-report/api/routes/script.js.html +1 -1
- package/coverage/lcov-report/api/routes/static.js.html +2 -17
- package/coverage/lcov-report/api/routes/table.js.html +1 -1
- package/coverage/lcov-report/api/routes/templates.js.html +1 -1
- package/coverage/lcov-report/api/routes/user.js.html +1 -1
- package/coverage/lcov-report/api/routes/view.js.html +1 -1
- package/coverage/lcov-report/api/routes/webhook.js.html +1 -1
- package/coverage/lcov-report/automations/actions.js.html +24 -24
- package/coverage/lcov-report/automations/automationUtils.js.html +10 -7
- package/coverage/lcov-report/automations/bullboard.js.html +16 -16
- package/coverage/lcov-report/automations/index.html +18 -18
- package/coverage/lcov-report/automations/index.js.html +1 -1
- package/coverage/lcov-report/automations/steps/bash.js.html +6 -6
- package/coverage/lcov-report/automations/steps/createRow.js.html +22 -13
- package/coverage/lcov-report/automations/steps/delay.js.html +4 -4
- package/coverage/lcov-report/automations/steps/deleteRow.js.html +20 -11
- package/coverage/lcov-report/automations/steps/discord.js.html +7 -7
- package/coverage/lcov-report/automations/steps/executeQuery.js.html +6 -6
- package/coverage/lcov-report/automations/steps/executeScript.js.html +6 -6
- package/coverage/lcov-report/automations/steps/filter.js.html +7 -7
- package/coverage/lcov-report/automations/steps/index.html +13 -13
- package/coverage/lcov-report/automations/steps/integromat.js.html +5 -5
- package/coverage/lcov-report/automations/steps/outgoingWebhook.js.html +8 -8
- package/coverage/lcov-report/automations/steps/queryRows.js.html +10 -10
- package/coverage/lcov-report/automations/steps/sendSmtpEmail.js.html +5 -5
- package/coverage/lcov-report/automations/steps/serverLog.js.html +3 -3
- package/coverage/lcov-report/automations/steps/slack.js.html +5 -5
- package/coverage/lcov-report/automations/steps/updateRow.js.html +7 -7
- package/coverage/lcov-report/automations/steps/utils.js.html +3 -3
- package/coverage/lcov-report/automations/steps/zapier.js.html +5 -5
- package/coverage/lcov-report/automations/triggerInfo/app.js.html +2 -2
- package/coverage/lcov-report/automations/triggerInfo/cron.js.html +2 -2
- package/coverage/lcov-report/automations/triggerInfo/index.html +1 -1
- package/coverage/lcov-report/automations/triggerInfo/index.js.html +8 -8
- package/coverage/lcov-report/automations/triggerInfo/rowDeleted.js.html +2 -2
- package/coverage/lcov-report/automations/triggerInfo/rowSaved.js.html +2 -2
- package/coverage/lcov-report/automations/triggerInfo/rowUpdated.js.html +2 -2
- package/coverage/lcov-report/automations/triggerInfo/webhook.js.html +2 -2
- package/coverage/lcov-report/automations/triggers.js.html +55 -61
- package/coverage/lcov-report/automations/utils.js.html +42 -54
- package/coverage/lcov-report/constants/index.html +5 -5
- package/coverage/lcov-report/constants/index.js.html +26 -53
- package/coverage/lcov-report/constants/layouts.js.html +5 -5
- package/coverage/lcov-report/constants/screens.js.html +4 -4
- package/coverage/lcov-report/db/client.js.html +18 -18
- package/coverage/lcov-report/db/inMemoryView.js.html +7 -7
- package/coverage/lcov-report/db/index.html +15 -15
- package/coverage/lcov-report/db/index.js.html +3 -3
- package/coverage/lcov-report/db/linkedRows/LinkController.js.html +37 -25
- package/coverage/lcov-report/db/linkedRows/index.html +27 -27
- package/coverage/lcov-report/db/linkedRows/index.js.html +96 -51
- package/coverage/lcov-report/db/linkedRows/linkUtils.js.html +42 -42
- package/coverage/lcov-report/db/newid.js.html +4 -4
- package/coverage/lcov-report/db/utils.js.html +87 -87
- package/coverage/lcov-report/events/AutomationEmitter.js.html +1 -1
- package/coverage/lcov-report/events/index.html +1 -1
- package/coverage/lcov-report/events/index.js.html +5 -5
- package/coverage/lcov-report/events/utils.js.html +3 -3
- package/coverage/lcov-report/index.html +120 -135
- package/coverage/lcov-report/integrations/tests/TestConfiguration.js.html +1 -1
- package/coverage/lcov-report/integrations/tests/index.html +1 -1
- package/coverage/lcov-report/middleware/appInfo.js.html +1 -1
- package/coverage/lcov-report/middleware/authorized.js.html +65 -173
- package/coverage/lcov-report/middleware/builder.js.html +10 -10
- package/coverage/lcov-report/middleware/currentapp.js.html +83 -95
- package/coverage/lcov-report/middleware/index.html +38 -38
- package/coverage/lcov-report/middleware/joi-validator.js.html +3 -3
- package/coverage/lcov-report/middleware/resourceId.js.html +1 -1
- package/coverage/lcov-report/middleware/selfhost.js.html +1 -1
- package/coverage/lcov-report/middleware/usageQuota.js.html +53 -281
- package/coverage/lcov-report/middleware/utils.js.html +2 -2
- package/coverage/lcov-report/threads/automation.js.html +24 -30
- package/coverage/lcov-report/threads/index.html +26 -26
- package/coverage/lcov-report/threads/index.js.html +10 -10
- package/coverage/lcov-report/threads/query.js.html +24 -39
- package/coverage/lcov-report/threads/utils.js.html +14 -14
- package/coverage/lcov-report/utilities/bcrypt.js.html +1 -1
- package/coverage/lcov-report/utilities/budibaseDir.js.html +7 -7
- package/coverage/lcov-report/utilities/centralPath.js.html +4 -4
- package/coverage/lcov-report/utilities/csvParser.js.html +6 -6
- package/coverage/lcov-report/utilities/global.js.html +49 -58
- package/coverage/lcov-report/utilities/index.html +37 -37
- package/coverage/lcov-report/utilities/index.js.html +73 -43
- package/coverage/lcov-report/utilities/queue/inMemoryQueue.js.html +8 -8
- package/coverage/lcov-report/utilities/queue/index.html +1 -1
- package/coverage/lcov-report/utilities/routing/index.html +1 -1
- package/coverage/lcov-report/utilities/routing/index.js.html +7 -7
- package/coverage/lcov-report/utilities/rowProcessor/index.html +27 -27
- package/coverage/lcov-report/utilities/rowProcessor/index.js.html +103 -97
- package/coverage/lcov-report/utilities/rowProcessor/utils.js.html +27 -75
- package/coverage/lcov-report/utilities/scriptRunner.js.html +5 -5
- package/coverage/lcov-report/utilities/security.js.html +8 -8
- package/coverage/lcov-report/utilities/statusCodes.js.html +1 -1
- package/coverage/lcov-report/utilities/users.js.html +9 -9
- package/coverage/lcov-report/utilities/workerRequests.js.html +112 -43
- package/coverage/lcov.info +4431 -5013
- package/dist/api/controllers/application.js +60 -90
- package/dist/api/controllers/auth.js +5 -8
- package/dist/api/controllers/automation.js +19 -14
- package/dist/api/controllers/cloud.js +3 -2
- package/dist/api/controllers/component.js +4 -3
- package/dist/api/controllers/datasource.js +10 -20
- package/dist/api/controllers/deploy/Deployment.js +6 -3
- package/dist/api/controllers/deploy/index.js +13 -12
- package/dist/api/controllers/dev.js +5 -5
- package/dist/api/controllers/hosting.js +30 -0
- package/dist/api/controllers/layout.js +3 -3
- package/dist/api/controllers/metadata.js +4 -4
- package/dist/api/controllers/permission.js +4 -4
- package/dist/api/controllers/query/import/index.js +6 -4
- package/dist/api/controllers/query/index.js +10 -11
- package/dist/api/controllers/role.js +5 -5
- package/dist/api/controllers/routing.js +6 -5
- package/dist/api/controllers/row/ExternalRequest.js +67 -90
- package/dist/api/controllers/row/external.js +22 -14
- package/dist/api/controllers/row/internal.js +93 -55
- package/dist/api/controllers/row/internalSearch.js +17 -23
- package/dist/api/controllers/row/utils.js +14 -13
- package/dist/api/controllers/screen.js +7 -5
- package/dist/api/controllers/static/index.js +12 -61
- package/dist/api/controllers/table/external.js +10 -7
- package/dist/api/controllers/table/index.js +13 -16
- package/dist/api/controllers/table/internal.js +16 -22
- package/dist/api/controllers/table/utils.js +35 -62
- package/dist/api/controllers/user.js +20 -18
- package/dist/api/controllers/view/index.js +10 -8
- package/dist/api/controllers/view/utils.js +4 -9
- package/dist/api/controllers/webhook.js +8 -10
- package/dist/api/routes/hosting.js +11 -0
- package/dist/api/routes/index.js +2 -2
- package/dist/api/routes/static.js +1 -2
- package/dist/api/routes/tests/utilities/TestFunctions.js +17 -37
- package/dist/app.js +5 -35
- package/dist/automations/automationUtils.js +3 -2
- package/dist/automations/steps/createRow.js +5 -3
- package/dist/automations/steps/deleteRow.js +4 -1
- package/dist/automations/steps/updateRow.js +1 -1
- package/dist/automations/triggers.js +25 -27
- package/dist/automations/utils.js +5 -10
- package/dist/constants/index.js +0 -7
- package/dist/db/linkedRows/LinkController.js +7 -3
- package/dist/db/linkedRows/index.js +27 -16
- package/dist/db/linkedRows/linkUtils.js +6 -6
- package/dist/db/views/staticViews.js +10 -9
- package/dist/definitions/datasource.js +0 -1
- package/dist/environment.js +1 -4
- package/dist/integrations/base/sql.js +14 -56
- package/dist/integrations/index.js +0 -3
- package/dist/integrations/utils.js +9 -60
- package/dist/middleware/authorized.js +30 -57
- package/dist/middleware/builder.js +2 -2
- package/dist/middleware/currentapp.js +37 -41
- package/dist/middleware/usageQuota.js +15 -82
- package/dist/package.json +5 -8
- package/dist/tests/utilities/TestConfiguration.js +50 -80
- package/dist/threads/automation.js +11 -13
- package/dist/threads/query.js +11 -15
- package/dist/tsconfig.tsbuildinfo +1 -1
- package/dist/utilities/fileSystem/index.js +3 -4
- package/dist/utilities/global.js +12 -15
- package/dist/utilities/index.js +17 -7
- package/dist/utilities/routing/index.js +5 -5
- package/dist/utilities/rowProcessor/index.js +17 -23
- package/dist/utilities/rowProcessor/utils.js +4 -14
- package/dist/utilities/{usageQuota/index.js → usageQuota.js} +31 -45
- package/dist/utilities/users.js +3 -3
- package/dist/utilities/workerRequests.js +24 -4
- package/nodemon.json +1 -1
- package/package.json +6 -9
- package/scripts/integrations/postgres/init.sql +6 -11
- package/scripts/likeCypress.ts +1 -1
- package/src/api/controllers/application.js +50 -85
- package/src/api/controllers/auth.js +5 -8
- package/src/api/controllers/automation.js +23 -13
- package/src/api/controllers/cloud.js +3 -2
- package/src/api/controllers/component.js +4 -3
- package/src/api/controllers/datasource.js +11 -21
- package/src/api/controllers/deploy/Deployment.js +7 -3
- package/src/api/controllers/deploy/index.js +13 -20
- package/src/api/controllers/dev.js +5 -5
- package/src/api/controllers/hosting.js +22 -0
- package/src/api/controllers/layout.js +3 -3
- package/src/api/controllers/metadata.js +9 -4
- package/src/api/controllers/permission.js +4 -4
- package/src/api/controllers/query/import/index.ts +6 -4
- package/src/api/controllers/query/import/tests/index.spec.js +1 -2
- package/src/api/controllers/query/index.js +10 -11
- package/src/api/controllers/role.js +5 -5
- package/src/api/controllers/routing.js +6 -5
- package/src/api/controllers/row/ExternalRequest.ts +43 -67
- package/src/api/controllers/row/external.js +58 -27
- package/src/api/controllers/row/internal.js +90 -54
- package/src/api/controllers/row/internalSearch.js +17 -23
- package/src/api/controllers/row/utils.js +18 -13
- package/src/api/controllers/screen.js +7 -5
- package/src/api/controllers/static/index.js +12 -65
- package/src/api/controllers/table/external.js +10 -7
- package/src/api/controllers/table/index.js +28 -20
- package/src/api/controllers/table/internal.js +19 -24
- package/src/api/controllers/table/utils.js +42 -78
- package/src/api/controllers/user.js +20 -19
- package/src/api/controllers/view/index.js +10 -8
- package/src/api/controllers/view/utils.js +4 -9
- package/src/api/controllers/webhook.js +8 -10
- package/src/api/routes/hosting.js +13 -0
- package/src/api/routes/index.js +2 -2
- package/src/api/routes/static.js +0 -5
- package/src/api/routes/tests/application.spec.js +2 -2
- package/src/api/routes/tests/auth.spec.js +2 -1
- package/src/api/routes/tests/automation.spec.js +0 -1
- package/src/api/routes/tests/hosting.spec.js +36 -0
- package/src/api/routes/tests/misc.spec.js +1 -0
- package/src/api/routes/tests/routing.spec.js +12 -21
- package/src/api/routes/tests/row.spec.js +4 -7
- package/src/api/routes/tests/utilities/TestFunctions.js +17 -39
- package/src/app.ts +5 -18
- package/src/automations/automationUtils.js +3 -2
- package/src/automations/steps/createRow.js +5 -2
- package/src/automations/steps/deleteRow.js +4 -1
- package/src/automations/steps/updateRow.js +1 -1
- package/src/automations/triggers.js +31 -33
- package/src/automations/utils.js +5 -9
- package/src/constants/index.js +0 -9
- package/src/db/linkedRows/LinkController.js +7 -3
- package/src/db/linkedRows/index.js +31 -16
- package/src/db/linkedRows/linkUtils.js +6 -6
- package/src/db/tests/linkController.spec.js +1 -0
- package/src/db/tests/linkTests.spec.js +6 -5
- package/src/db/views/staticViews.js +10 -8
- package/src/definitions/common.ts +0 -3
- package/src/definitions/datasource.ts +0 -3
- package/src/environment.js +1 -4
- package/src/integrations/base/sql.ts +21 -69
- package/src/integrations/index.ts +0 -3
- package/src/integrations/tests/sql.spec.js +0 -16
- package/src/integrations/utils.ts +12 -75
- package/src/middleware/authorized.js +30 -66
- package/src/middleware/builder.js +2 -2
- package/src/middleware/currentapp.js +46 -50
- package/src/middleware/tests/authorized.spec.js +6 -13
- package/src/middleware/tests/currentapp.spec.js +0 -6
- package/src/middleware/tests/usageQuota.spec.js +24 -18
- package/src/middleware/usageQuota.js +17 -93
- package/src/tests/utilities/TestConfiguration.js +55 -82
- package/src/threads/automation.js +15 -17
- package/src/threads/query.js +12 -17
- package/src/utilities/fileSystem/index.js +3 -4
- package/src/utilities/global.js +12 -15
- package/src/utilities/index.js +17 -7
- package/src/utilities/routing/index.js +5 -5
- package/src/utilities/rowProcessor/index.js +27 -25
- package/src/utilities/rowProcessor/utils.js +7 -23
- package/src/utilities/usageQuota.js +73 -0
- package/src/utilities/users.js +3 -3
- package/src/utilities/workerRequests.js +27 -4
- package/tsconfig.json +1 -2
- package/builder/assets/index.83c0944f.css +0 -1
- package/coverage/lcov-report/api/controllers/migrations.js.html +0 -119
- package/coverage/lcov-report/api/controllers/row/staticFormula.js.html +0 -548
- package/coverage/lcov-report/api/controllers/table/bulkFormula.js.html +0 -599
- package/coverage/lcov-report/utilities/usageQuota/index.html +0 -141
- package/coverage/lcov-report/utilities/usageQuota/index.js.html +0 -359
- package/coverage/lcov-report/utilities/usageQuota/rows.js.html +0 -305
- package/dist/api/controllers/migrations.js +0 -21
- package/dist/api/controllers/row/staticFormula.js +0 -147
- package/dist/api/controllers/table/bulkFormula.js +0 -159
- package/dist/api/routes/migrations.js +0 -9
- package/dist/integrations/googlesheets.js +0 -340
- package/dist/migrations/functions/appUrls.js +0 -46
- package/dist/migrations/functions/quotas1.js +0 -50
- package/dist/migrations/functions/usageQuotas/index.js +0 -20
- package/dist/migrations/functions/usageQuotas/syncApps.js +0 -29
- package/dist/migrations/functions/usageQuotas/syncRows.js +0 -33
- package/dist/migrations/functions/userEmailViewCasing.js +0 -24
- package/dist/migrations/index.js +0 -62
- package/dist/utilities/usageQuota/rows.js +0 -78
- package/dist/utilities/usageQuota/usageQuoteReset.js +0 -16
- package/src/api/controllers/migrations.js +0 -13
- package/src/api/controllers/row/staticFormula.js +0 -156
- package/src/api/controllers/table/bulkFormula.js +0 -173
- package/src/api/routes/migrations.js +0 -14
- package/src/api/routes/tests/static.spec.js +0 -98
- package/src/integrations/googlesheets.ts +0 -353
- package/src/migrations/functions/appUrls.ts +0 -34
- package/src/migrations/functions/quotas1.ts +0 -20
- package/src/migrations/functions/tests/appUrls.spec.js +0 -29
- package/src/migrations/functions/tests/quotas1.spec.js +0 -27
- package/src/migrations/functions/tests/userEmailViewCasing.spec.js +0 -25
- package/src/migrations/functions/usageQuotas/index.ts +0 -8
- package/src/migrations/functions/usageQuotas/syncApps.ts +0 -18
- package/src/migrations/functions/usageQuotas/syncRows.ts +0 -22
- package/src/migrations/functions/usageQuotas/tests/syncApps.spec.js +0 -37
- package/src/migrations/functions/usageQuotas/tests/syncRows.spec.js +0 -43
- package/src/migrations/functions/userEmailViewCasing.ts +0 -13
- package/src/migrations/index.ts +0 -56
- package/src/module.d.ts +0 -3
- package/src/utilities/tests/usageQuota/usageQuota.spec.js +0 -72
- package/src/utilities/usageQuota/index.js +0 -93
- package/src/utilities/usageQuota/rows.js +0 -75
- package/src/utilities/usageQuota/usageQuoteReset.js +0 -18
|
@@ -72,22 +72,16 @@ class InternalBuilder {
|
|
|
72
72
|
|
|
73
73
|
// right now we only do filters on the specific table being queried
|
|
74
74
|
addFilters(
|
|
75
|
+
tableName: string,
|
|
75
76
|
query: KnexQuery,
|
|
76
|
-
filters: SearchFilters | undefined
|
|
77
|
-
opts: { relationship?: boolean; tableName?: string }
|
|
77
|
+
filters: SearchFilters | undefined
|
|
78
78
|
): KnexQuery {
|
|
79
79
|
function iterate(
|
|
80
80
|
structure: { [key: string]: any },
|
|
81
81
|
fn: (key: string, value: any) => void
|
|
82
82
|
) {
|
|
83
83
|
for (let [key, value] of Object.entries(structure)) {
|
|
84
|
-
|
|
85
|
-
if (!opts.relationship && !isRelationshipField) {
|
|
86
|
-
fn(`${opts.tableName}.${key}`, value)
|
|
87
|
-
}
|
|
88
|
-
if (opts.relationship && isRelationshipField) {
|
|
89
|
-
fn(key, value)
|
|
90
|
-
}
|
|
84
|
+
fn(`${tableName}.${key}`, value)
|
|
91
85
|
}
|
|
92
86
|
}
|
|
93
87
|
if (!filters) {
|
|
@@ -191,70 +185,29 @@ class InternalBuilder {
|
|
|
191
185
|
if (!relationships) {
|
|
192
186
|
return query
|
|
193
187
|
}
|
|
194
|
-
const tableSets: Record<string, [any]> = {}
|
|
195
|
-
// aggregate into table sets (all the same to tables)
|
|
196
188
|
for (let relationship of relationships) {
|
|
197
|
-
const
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
if (relationship.through) {
|
|
202
|
-
keyObj.throughTable = relationship.through
|
|
203
|
-
}
|
|
204
|
-
const key = JSON.stringify(keyObj)
|
|
205
|
-
if (tableSets[key]) {
|
|
206
|
-
tableSets[key].push(relationship)
|
|
207
|
-
} else {
|
|
208
|
-
tableSets[key] = [relationship]
|
|
209
|
-
}
|
|
210
|
-
}
|
|
211
|
-
for (let [key, relationships] of Object.entries(tableSets)) {
|
|
212
|
-
const { toTable, throughTable } = JSON.parse(key)
|
|
213
|
-
if (!throughTable) {
|
|
189
|
+
const from = relationship.from,
|
|
190
|
+
to = relationship.to,
|
|
191
|
+
toTable = relationship.tableName
|
|
192
|
+
if (!relationship.through) {
|
|
214
193
|
// @ts-ignore
|
|
215
|
-
query = query.
|
|
194
|
+
query = query.leftJoin(
|
|
216
195
|
toTable,
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
const from = relationship.from,
|
|
220
|
-
to = relationship.to
|
|
221
|
-
// @ts-ignore
|
|
222
|
-
this.orOn(`${fromTable}.${from}`, "=", `${toTable}.${to}`)
|
|
223
|
-
}
|
|
224
|
-
},
|
|
225
|
-
"left"
|
|
196
|
+
`${fromTable}.${from}`,
|
|
197
|
+
`${toTable}.${to}`
|
|
226
198
|
)
|
|
227
199
|
} else {
|
|
200
|
+
const throughTable = relationship.through
|
|
201
|
+
const fromPrimary = relationship.fromPrimary
|
|
202
|
+
const toPrimary = relationship.toPrimary
|
|
228
203
|
query = query
|
|
229
204
|
// @ts-ignore
|
|
230
|
-
.
|
|
205
|
+
.leftJoin(
|
|
231
206
|
throughTable,
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
const fromPrimary = relationship.fromPrimary
|
|
235
|
-
const from = relationship.from
|
|
236
|
-
// @ts-ignore
|
|
237
|
-
this.orOn(
|
|
238
|
-
`${fromTable}.${fromPrimary}`,
|
|
239
|
-
"=",
|
|
240
|
-
`${throughTable}.${from}`
|
|
241
|
-
)
|
|
242
|
-
}
|
|
243
|
-
},
|
|
244
|
-
"left"
|
|
245
|
-
)
|
|
246
|
-
.join(
|
|
247
|
-
toTable,
|
|
248
|
-
function () {
|
|
249
|
-
for (let relationship of relationships) {
|
|
250
|
-
const toPrimary = relationship.toPrimary
|
|
251
|
-
const to = relationship.to
|
|
252
|
-
// @ts-ignore
|
|
253
|
-
this.orOn(`${toTable}.${toPrimary}`, `${throughTable}.${to}`)
|
|
254
|
-
}
|
|
255
|
-
},
|
|
256
|
-
"left"
|
|
207
|
+
`${fromTable}.${fromPrimary}`,
|
|
208
|
+
`${throughTable}.${from}`
|
|
257
209
|
)
|
|
210
|
+
.leftJoin(toTable, `${toTable}.${toPrimary}`, `${throughTable}.${to}`)
|
|
258
211
|
}
|
|
259
212
|
}
|
|
260
213
|
return query.limit(BASE_LIMIT)
|
|
@@ -319,7 +272,7 @@ class InternalBuilder {
|
|
|
319
272
|
if (foundOffset) {
|
|
320
273
|
query = query.offset(foundOffset)
|
|
321
274
|
}
|
|
322
|
-
query = this.addFilters(query, filters
|
|
275
|
+
query = this.addFilters(tableName, query, filters)
|
|
323
276
|
// add sorting to pre-query
|
|
324
277
|
query = this.addSorting(query, json)
|
|
325
278
|
// @ts-ignore
|
|
@@ -332,21 +285,20 @@ class InternalBuilder {
|
|
|
332
285
|
preQuery = this.addSorting(preQuery, json)
|
|
333
286
|
}
|
|
334
287
|
// handle joins
|
|
335
|
-
|
|
288
|
+
return this.addRelationships(
|
|
336
289
|
knex,
|
|
337
290
|
preQuery,
|
|
338
291
|
selectStatement,
|
|
339
292
|
tableName,
|
|
340
293
|
relationships
|
|
341
294
|
)
|
|
342
|
-
return this.addFilters(query, filters, { relationship: true })
|
|
343
295
|
}
|
|
344
296
|
|
|
345
297
|
update(knex: Knex, json: QueryJson, opts: QueryOptions): KnexQuery {
|
|
346
298
|
const { endpoint, body, filters } = json
|
|
347
299
|
let query: KnexQuery = knex(endpoint.entityId)
|
|
348
300
|
const parsedBody = parseBody(body)
|
|
349
|
-
query = this.addFilters(query, filters
|
|
301
|
+
query = this.addFilters(endpoint.entityId, query, filters)
|
|
350
302
|
// mysql can't use returning
|
|
351
303
|
if (opts.disableReturning) {
|
|
352
304
|
return query.update(parsedBody)
|
|
@@ -358,7 +310,7 @@ class InternalBuilder {
|
|
|
358
310
|
delete(knex: Knex, json: QueryJson, opts: QueryOptions): KnexQuery {
|
|
359
311
|
const { endpoint, filters } = json
|
|
360
312
|
let query: KnexQuery = knex(endpoint.entityId)
|
|
361
|
-
query = this.addFilters(query, filters
|
|
313
|
+
query = this.addFilters(endpoint.entityId, query, filters)
|
|
362
314
|
// mysql can't use returning
|
|
363
315
|
if (opts.disableReturning) {
|
|
364
316
|
return query.delete()
|
|
@@ -9,7 +9,6 @@ const airtable = require("./airtable")
|
|
|
9
9
|
const mysql = require("./mysql")
|
|
10
10
|
const arangodb = require("./arangodb")
|
|
11
11
|
const rest = require("./rest")
|
|
12
|
-
const googlesheets = require("./googlesheets")
|
|
13
12
|
const { SourceNames } = require("../definitions/datasource")
|
|
14
13
|
|
|
15
14
|
const DEFINITIONS = {
|
|
@@ -24,7 +23,6 @@ const DEFINITIONS = {
|
|
|
24
23
|
[SourceNames.MYSQL]: mysql.schema,
|
|
25
24
|
[SourceNames.ARANGODB]: arangodb.schema,
|
|
26
25
|
[SourceNames.REST]: rest.schema,
|
|
27
|
-
[SourceNames.GOOGLE_SHEETS]: googlesheets.schema,
|
|
28
26
|
}
|
|
29
27
|
|
|
30
28
|
const INTEGRATIONS = {
|
|
@@ -39,7 +37,6 @@ const INTEGRATIONS = {
|
|
|
39
37
|
[SourceNames.MYSQL]: mysql.integration,
|
|
40
38
|
[SourceNames.ARANGODB]: arangodb.integration,
|
|
41
39
|
[SourceNames.REST]: rest.integration,
|
|
42
|
-
[SourceNames.GOOGLE_SHEETS]: googlesheets.integration,
|
|
43
40
|
}
|
|
44
41
|
|
|
45
42
|
// optionally add oracle integration if the oracle binary can be installed
|
|
@@ -119,22 +119,6 @@ describe("SQL query builder", () => {
|
|
|
119
119
|
})
|
|
120
120
|
})
|
|
121
121
|
|
|
122
|
-
it("should allow filtering on a related field", () => {
|
|
123
|
-
const query = sql._query(generateReadJson({
|
|
124
|
-
filters: {
|
|
125
|
-
equal: {
|
|
126
|
-
age: 10,
|
|
127
|
-
"task.name": "task 1",
|
|
128
|
-
},
|
|
129
|
-
},
|
|
130
|
-
}))
|
|
131
|
-
// order of bindings changes because relationship filters occur outside inner query
|
|
132
|
-
expect(query).toEqual({
|
|
133
|
-
bindings: [10, limit, "task 1"],
|
|
134
|
-
sql: `select * from (select * from "${TABLE_NAME}" where "${TABLE_NAME}"."age" = $1 limit $2) as "${TABLE_NAME}" where "task"."name" = $3`
|
|
135
|
-
})
|
|
136
|
-
})
|
|
137
|
-
|
|
138
122
|
it("should test an create statement", () => {
|
|
139
123
|
const query = sql._query(generateCreateJson(TABLE_NAME, {
|
|
140
124
|
name: "Michael",
|
|
@@ -1,5 +1,6 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { SqlQuery } from "../definitions/datasource"
|
|
2
2
|
import { Datasource, Table } from "../definitions/common"
|
|
3
|
+
import { SourceNames } from "../definitions/datasource"
|
|
3
4
|
import { DocumentTypes, SEPARATOR } from "../db/utils"
|
|
4
5
|
import { FieldTypes, BuildSchemaErrors, InvalidColumns } from "../constants"
|
|
5
6
|
|
|
@@ -52,10 +53,7 @@ export function buildExternalTableId(datasourceId: string, tableName: string) {
|
|
|
52
53
|
return `${datasourceId}${DOUBLE_SEPARATOR}${tableName}`
|
|
53
54
|
}
|
|
54
55
|
|
|
55
|
-
export function breakExternalTableId(tableId: string
|
|
56
|
-
if (!tableId) {
|
|
57
|
-
return {}
|
|
58
|
-
}
|
|
56
|
+
export function breakExternalTableId(tableId: string) {
|
|
59
57
|
const parts = tableId.split(DOUBLE_SEPARATOR)
|
|
60
58
|
let tableName = parts.pop()
|
|
61
59
|
// if they need joined
|
|
@@ -129,12 +127,7 @@ export function isSQL(datasource: Datasource): boolean {
|
|
|
129
127
|
if (!datasource || !datasource.source) {
|
|
130
128
|
return false
|
|
131
129
|
}
|
|
132
|
-
const SQL = [
|
|
133
|
-
SourceNames.POSTGRES,
|
|
134
|
-
SourceNames.SQL_SERVER,
|
|
135
|
-
SourceNames.MYSQL,
|
|
136
|
-
SourceNames.ORACLE,
|
|
137
|
-
]
|
|
130
|
+
const SQL = [SourceNames.POSTGRES, SourceNames.SQL_SERVER, SourceNames.MYSQL]
|
|
138
131
|
return SQL.indexOf(datasource.source) !== -1
|
|
139
132
|
}
|
|
140
133
|
|
|
@@ -146,60 +139,11 @@ export function isIsoDateString(str: string) {
|
|
|
146
139
|
return d.toISOString() === str
|
|
147
140
|
}
|
|
148
141
|
|
|
149
|
-
|
|
150
|
-
* This function will determine whether a column is a relationship and whether it
|
|
151
|
-
* is currently valid. The reason for the validity check is that tables can be deleted
|
|
152
|
-
* outside of Budibase control and if this is the case it will break Budibase relationships.
|
|
153
|
-
* The tableIds is a list passed down from the main finalise tables function, which is
|
|
154
|
-
* based on the tables that have just been fetched. This will only really be used on subsequent
|
|
155
|
-
* fetches to the first one - if the user is periodically refreshing Budibase knowledge of tables.
|
|
156
|
-
* @param column The column to check, to see if it is a valid relationship.
|
|
157
|
-
* @param tableIds The IDs of the tables which currently exist.
|
|
158
|
-
*/
|
|
159
|
-
function shouldCopyRelationship(
|
|
160
|
-
column: { type: string; tableId?: string },
|
|
161
|
-
tableIds: [string]
|
|
162
|
-
) {
|
|
163
|
-
return (
|
|
164
|
-
column.type === FieldTypes.LINK &&
|
|
165
|
-
column.tableId &&
|
|
166
|
-
tableIds.includes(column.tableId)
|
|
167
|
-
)
|
|
168
|
-
}
|
|
169
|
-
|
|
170
|
-
/**
|
|
171
|
-
* Similar function to the shouldCopyRelationship function, but instead this looks for options and boolean
|
|
172
|
-
* types. It is possible to switch a string -> options and a number -> boolean (and vice versus) need to make
|
|
173
|
-
* sure that these get copied over when tables are fetched. Also checks whether they are still valid, if a
|
|
174
|
-
* column has changed type in the external database then copying it over may not be possible.
|
|
175
|
-
* @param column The column to check for options or boolean type.
|
|
176
|
-
* @param fetchedColumn The fetched column to check for the type in the external database.
|
|
177
|
-
*/
|
|
178
|
-
function shouldCopySpecialColumn(
|
|
179
|
-
column: { type: string },
|
|
180
|
-
fetchedColumn: { type: string } | undefined
|
|
181
|
-
) {
|
|
182
|
-
return (
|
|
183
|
-
column.type === FieldTypes.OPTIONS ||
|
|
184
|
-
column.type === FieldTypes.ARRAY ||
|
|
185
|
-
((!fetchedColumn || fetchedColumn.type === FieldTypes.NUMBER) &&
|
|
186
|
-
column.type === FieldTypes.BOOLEAN)
|
|
187
|
-
)
|
|
188
|
-
}
|
|
189
|
-
|
|
190
|
-
/**
|
|
191
|
-
* Looks for columns which need to be copied over into the new table definitions, like relationships
|
|
192
|
-
* and options types.
|
|
193
|
-
* @param tableName The name of the table which is being checked.
|
|
194
|
-
* @param table The specific table which is being checked.
|
|
195
|
-
* @param entities All the tables that existed before - the old table definitions.
|
|
196
|
-
* @param tableIds The IDs of the tables which exist now, to check if anything has been removed.
|
|
197
|
-
*/
|
|
142
|
+
// add the existing relationships from the entities if they exist, to prevent them from being overridden
|
|
198
143
|
function copyExistingPropsOver(
|
|
199
144
|
tableName: string,
|
|
200
145
|
table: Table,
|
|
201
|
-
entities: { [key: string]: any }
|
|
202
|
-
tableIds: [string]
|
|
146
|
+
entities: { [key: string]: any }
|
|
203
147
|
) {
|
|
204
148
|
if (entities && entities[tableName]) {
|
|
205
149
|
if (entities[tableName].primaryDisplay) {
|
|
@@ -210,10 +154,12 @@ function copyExistingPropsOver(
|
|
|
210
154
|
if (!existingTableSchema.hasOwnProperty(key)) {
|
|
211
155
|
continue
|
|
212
156
|
}
|
|
213
|
-
const column = existingTableSchema[key]
|
|
214
157
|
if (
|
|
215
|
-
|
|
216
|
-
|
|
158
|
+
existingTableSchema[key].type === FieldTypes.LINK ||
|
|
159
|
+
existingTableSchema[key].type === FieldTypes.OPTIONS ||
|
|
160
|
+
existingTableSchema[key].type === FieldTypes.ARRAY ||
|
|
161
|
+
((!table.schema[key] || table.schema[key].type === FieldTypes.NUMBER) &&
|
|
162
|
+
existingTableSchema[key].type === FieldTypes.BOOLEAN)
|
|
217
163
|
) {
|
|
218
164
|
table.schema[key] = existingTableSchema[key]
|
|
219
165
|
}
|
|
@@ -222,13 +168,6 @@ function copyExistingPropsOver(
|
|
|
222
168
|
return table
|
|
223
169
|
}
|
|
224
170
|
|
|
225
|
-
/**
|
|
226
|
-
* Look through the final table definitions to see if anything needs to be
|
|
227
|
-
* copied over from the old and if any errors have occurred mark them so
|
|
228
|
-
* that the user can be made aware.
|
|
229
|
-
* @param tables The list of tables that have been retrieved from the external database.
|
|
230
|
-
* @param entities The old list of tables, if there was any to look for definitions in.
|
|
231
|
-
*/
|
|
232
171
|
export function finaliseExternalTables(
|
|
233
172
|
tables: { [key: string]: any },
|
|
234
173
|
entities: { [key: string]: any }
|
|
@@ -236,8 +175,6 @@ export function finaliseExternalTables(
|
|
|
236
175
|
const invalidColumns = Object.values(InvalidColumns)
|
|
237
176
|
let finalTables: { [key: string]: any } = {}
|
|
238
177
|
const errors: { [key: string]: string } = {}
|
|
239
|
-
// @ts-ignore
|
|
240
|
-
const tableIds: [string] = Object.values(tables).map(table => table._id)
|
|
241
178
|
for (let [name, table] of Object.entries(tables)) {
|
|
242
179
|
const schemaFields = Object.keys(table.schema)
|
|
243
180
|
// make sure every table has a key
|
|
@@ -249,7 +186,7 @@ export function finaliseExternalTables(
|
|
|
249
186
|
continue
|
|
250
187
|
}
|
|
251
188
|
// make sure all previous props have been added back
|
|
252
|
-
finalTables[name] = copyExistingPropsOver(name, table, entities
|
|
189
|
+
finalTables[name] = copyExistingPropsOver(name, table, entities)
|
|
253
190
|
}
|
|
254
191
|
// sort the tables by name
|
|
255
192
|
finalTables = Object.entries(finalTables)
|
|
@@ -9,60 +9,11 @@ const {
|
|
|
9
9
|
} = require("@budibase/backend-core/permissions")
|
|
10
10
|
const builderMiddleware = require("./builder")
|
|
11
11
|
const { isWebhookEndpoint } = require("./utils")
|
|
12
|
-
const { buildCsrfMiddleware } = require("@budibase/backend-core/auth")
|
|
13
|
-
const { getAppId } = require("@budibase/backend-core/context")
|
|
14
12
|
|
|
15
13
|
function hasResource(ctx) {
|
|
16
14
|
return ctx.resourceId != null
|
|
17
15
|
}
|
|
18
16
|
|
|
19
|
-
const csrf = buildCsrfMiddleware()
|
|
20
|
-
|
|
21
|
-
/**
|
|
22
|
-
* Apply authorization to the requested resource:
|
|
23
|
-
* - If this is a builder resource the user must be a builder.
|
|
24
|
-
* - Builders can access all resources.
|
|
25
|
-
* - Otherwise the user must have the required role.
|
|
26
|
-
*/
|
|
27
|
-
const checkAuthorized = async (ctx, resourceRoles, permType, permLevel) => {
|
|
28
|
-
// check if this is a builder api and the user is not a builder
|
|
29
|
-
const isBuilder = ctx.user && ctx.user.builder && ctx.user.builder.global
|
|
30
|
-
const isBuilderApi = permType === PermissionTypes.BUILDER
|
|
31
|
-
if (isBuilderApi && !isBuilder) {
|
|
32
|
-
return ctx.throw(403, "Not Authorized")
|
|
33
|
-
}
|
|
34
|
-
|
|
35
|
-
// check for resource authorization
|
|
36
|
-
if (!isBuilder) {
|
|
37
|
-
await checkAuthorizedResource(ctx, resourceRoles, permType, permLevel)
|
|
38
|
-
}
|
|
39
|
-
}
|
|
40
|
-
|
|
41
|
-
const checkAuthorizedResource = async (
|
|
42
|
-
ctx,
|
|
43
|
-
resourceRoles,
|
|
44
|
-
permType,
|
|
45
|
-
permLevel
|
|
46
|
-
) => {
|
|
47
|
-
// get the user's roles
|
|
48
|
-
const roleId = ctx.roleId || BUILTIN_ROLE_IDS.PUBLIC
|
|
49
|
-
const userRoles = await getUserRoleHierarchy(roleId, {
|
|
50
|
-
idOnly: false,
|
|
51
|
-
})
|
|
52
|
-
const permError = "User does not have permission"
|
|
53
|
-
// check if the user has the required role
|
|
54
|
-
if (resourceRoles.length > 0) {
|
|
55
|
-
// deny access if the user doesn't have the required resource role
|
|
56
|
-
const found = userRoles.find(role => resourceRoles.indexOf(role._id) !== -1)
|
|
57
|
-
if (!found) {
|
|
58
|
-
ctx.throw(403, permError)
|
|
59
|
-
}
|
|
60
|
-
// fallback to the base permissions when no resource roles are found
|
|
61
|
-
} else if (!doesHaveBasePermission(permType, permLevel, userRoles)) {
|
|
62
|
-
ctx.throw(403, permError)
|
|
63
|
-
}
|
|
64
|
-
}
|
|
65
|
-
|
|
66
17
|
module.exports =
|
|
67
18
|
(permType, permLevel = null) =>
|
|
68
19
|
async (ctx, next) => {
|
|
@@ -80,27 +31,40 @@ module.exports =
|
|
|
80
31
|
// to find API endpoints which are builder focused
|
|
81
32
|
await builderMiddleware(ctx, permType)
|
|
82
33
|
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
}
|
|
89
|
-
|
|
90
|
-
// if the resource is public, proceed
|
|
91
|
-
const isPublicResource = resourceRoles.includes(BUILTIN_ROLE_IDS.PUBLIC)
|
|
92
|
-
if (isPublicResource) {
|
|
34
|
+
const isAuthed = ctx.isAuthenticated
|
|
35
|
+
// builders for now have permission to do anything
|
|
36
|
+
let isBuilder = ctx.user && ctx.user.builder && ctx.user.builder.global
|
|
37
|
+
const isBuilderApi = permType === PermissionTypes.BUILDER
|
|
38
|
+
if (isBuilder) {
|
|
93
39
|
return next()
|
|
40
|
+
} else if (isBuilderApi && !isBuilder) {
|
|
41
|
+
return ctx.throw(403, "Not Authorized")
|
|
94
42
|
}
|
|
95
43
|
|
|
96
|
-
// check
|
|
97
|
-
|
|
98
|
-
|
|
44
|
+
// need to check this first, in-case public access, don't check authed until last
|
|
45
|
+
const roleId = ctx.roleId || BUILTIN_ROLE_IDS.PUBLIC
|
|
46
|
+
const hierarchy = await getUserRoleHierarchy(ctx.appId, roleId, {
|
|
47
|
+
idOnly: false,
|
|
48
|
+
})
|
|
49
|
+
const permError = "User does not have permission"
|
|
50
|
+
let possibleRoleIds = []
|
|
51
|
+
if (hasResource(ctx)) {
|
|
52
|
+
possibleRoleIds = await getRequiredResourceRole(ctx.appId, permLevel, ctx)
|
|
53
|
+
}
|
|
54
|
+
// check if we found a role, if not fallback to base permissions
|
|
55
|
+
if (possibleRoleIds.length > 0) {
|
|
56
|
+
const found = hierarchy.find(
|
|
57
|
+
role => possibleRoleIds.indexOf(role._id) !== -1
|
|
58
|
+
)
|
|
59
|
+
return found ? next() : ctx.throw(403, permError)
|
|
60
|
+
} else if (!doesHaveBasePermission(permType, permLevel, hierarchy)) {
|
|
61
|
+
ctx.throw(403, permError)
|
|
99
62
|
}
|
|
100
63
|
|
|
101
|
-
//
|
|
102
|
-
|
|
64
|
+
// if they are not authed, then anything using the authorized middleware will fail
|
|
65
|
+
if (!isAuthed) {
|
|
66
|
+
ctx.throw(403, "Session not authenticated")
|
|
67
|
+
}
|
|
103
68
|
|
|
104
|
-
|
|
105
|
-
return csrf(ctx, next)
|
|
69
|
+
return next()
|
|
106
70
|
}
|
|
@@ -5,7 +5,7 @@ const {
|
|
|
5
5
|
checkDebounce,
|
|
6
6
|
setDebounce,
|
|
7
7
|
} = require("../utilities/redis")
|
|
8
|
-
const
|
|
8
|
+
const CouchDB = require("../db")
|
|
9
9
|
const { DocumentTypes } = require("../db/utils")
|
|
10
10
|
const { PermissionTypes } = require("@budibase/backend-core/permissions")
|
|
11
11
|
const { app: appCache } = require("@budibase/backend-core/cache")
|
|
@@ -48,7 +48,7 @@ async function updateAppUpdatedAt(ctx) {
|
|
|
48
48
|
if (ctx.method === "GET" || (await checkDebounce(appId))) {
|
|
49
49
|
return
|
|
50
50
|
}
|
|
51
|
-
const db =
|
|
51
|
+
const db = new CouchDB(appId)
|
|
52
52
|
const metadata = await db.get(DocumentTypes.APP_METADATA)
|
|
53
53
|
metadata.updatedAt = new Date().toISOString()
|
|
54
54
|
const response = await db.put(metadata)
|
|
@@ -11,9 +11,9 @@ const { generateUserMetadataID, isDevAppID } = require("../db/utils")
|
|
|
11
11
|
const { dbExists } = require("@budibase/backend-core/db")
|
|
12
12
|
const { isUserInAppTenant } = require("@budibase/backend-core/tenancy")
|
|
13
13
|
const { getCachedSelf } = require("../utilities/global")
|
|
14
|
+
const CouchDB = require("../db")
|
|
14
15
|
const env = require("../environment")
|
|
15
16
|
const { isWebhookEndpoint } = require("./utils")
|
|
16
|
-
const { doInAppContext } = require("@budibase/backend-core/context")
|
|
17
17
|
|
|
18
18
|
module.exports = async (ctx, next) => {
|
|
19
19
|
// try to get the appID from the request
|
|
@@ -31,7 +31,7 @@ module.exports = async (ctx, next) => {
|
|
|
31
31
|
// check the app exists referenced in cookie
|
|
32
32
|
if (appCookie) {
|
|
33
33
|
const appId = appCookie.appId
|
|
34
|
-
const exists = await dbExists(appId)
|
|
34
|
+
const exists = await dbExists(CouchDB, appId)
|
|
35
35
|
if (!exists) {
|
|
36
36
|
clearCookie(ctx, Cookies.CurrentApp)
|
|
37
37
|
return next()
|
|
@@ -41,15 +41,13 @@ module.exports = async (ctx, next) => {
|
|
|
41
41
|
}
|
|
42
42
|
|
|
43
43
|
// deny access to application preview
|
|
44
|
-
if (
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
)
|
|
50
|
-
|
|
51
|
-
return ctx.redirect("/")
|
|
52
|
-
}
|
|
44
|
+
if (
|
|
45
|
+
isDevAppID(requestAppId) &&
|
|
46
|
+
!isWebhookEndpoint(ctx) &&
|
|
47
|
+
(!ctx.user || !ctx.user.builder || !ctx.user.builder.global)
|
|
48
|
+
) {
|
|
49
|
+
clearCookie(ctx, Cookies.CurrentApp)
|
|
50
|
+
return ctx.redirect("/")
|
|
53
51
|
}
|
|
54
52
|
|
|
55
53
|
let appId,
|
|
@@ -70,46 +68,44 @@ module.exports = async (ctx, next) => {
|
|
|
70
68
|
return next()
|
|
71
69
|
}
|
|
72
70
|
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
)
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
}
|
|
71
|
+
let noCookieSet = false
|
|
72
|
+
// if the user not in the right tenant then make sure they have no permissions
|
|
73
|
+
// need to judge this only based on the request app ID,
|
|
74
|
+
if (
|
|
75
|
+
env.MULTI_TENANCY &&
|
|
76
|
+
ctx.user &&
|
|
77
|
+
requestAppId &&
|
|
78
|
+
!isUserInAppTenant(requestAppId)
|
|
79
|
+
) {
|
|
80
|
+
// don't error, simply remove the users rights (they are a public user)
|
|
81
|
+
delete ctx.user.builder
|
|
82
|
+
delete ctx.user.admin
|
|
83
|
+
delete ctx.user.roles
|
|
84
|
+
roleId = BUILTIN_ROLE_IDS.PUBLIC
|
|
85
|
+
noCookieSet = true
|
|
86
|
+
}
|
|
90
87
|
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
}
|
|
103
|
-
}
|
|
104
|
-
if (
|
|
105
|
-
(requestAppId !== appId ||
|
|
106
|
-
appCookie == null ||
|
|
107
|
-
appCookie.appId !== requestAppId) &&
|
|
108
|
-
!noCookieSet
|
|
109
|
-
) {
|
|
110
|
-
setCookie(ctx, { appId }, Cookies.CurrentApp)
|
|
88
|
+
ctx.appId = appId
|
|
89
|
+
if (roleId) {
|
|
90
|
+
ctx.roleId = roleId
|
|
91
|
+
const userId = ctx.user ? generateUserMetadataID(ctx.user._id) : null
|
|
92
|
+
ctx.user = {
|
|
93
|
+
...ctx.user,
|
|
94
|
+
// override userID with metadata one
|
|
95
|
+
_id: userId,
|
|
96
|
+
userId,
|
|
97
|
+
roleId,
|
|
98
|
+
role: await getRole(appId, roleId),
|
|
111
99
|
}
|
|
100
|
+
}
|
|
101
|
+
if (
|
|
102
|
+
(requestAppId !== appId ||
|
|
103
|
+
appCookie == null ||
|
|
104
|
+
appCookie.appId !== requestAppId) &&
|
|
105
|
+
!noCookieSet
|
|
106
|
+
) {
|
|
107
|
+
setCookie(ctx, { appId }, Cookies.CurrentApp)
|
|
108
|
+
}
|
|
112
109
|
|
|
113
|
-
|
|
114
|
-
})
|
|
110
|
+
return next()
|
|
115
111
|
}
|
|
@@ -11,33 +11,26 @@ const authorizedMiddleware = require("../authorized")
|
|
|
11
11
|
const env = require("../../environment")
|
|
12
12
|
const { PermissionTypes, PermissionLevels } = require("@budibase/backend-core/permissions")
|
|
13
13
|
require("@budibase/backend-core").init(require("../../db"))
|
|
14
|
-
const { doInAppContext } = require("@budibase/backend-core/context")
|
|
15
|
-
|
|
16
|
-
const APP_ID = ""
|
|
17
14
|
|
|
18
15
|
class TestConfiguration {
|
|
19
16
|
constructor(role) {
|
|
20
17
|
this.middleware = authorizedMiddleware(role)
|
|
21
18
|
this.next = jest.fn()
|
|
22
19
|
this.throw = jest.fn()
|
|
23
|
-
this.headers = {}
|
|
24
20
|
this.ctx = {
|
|
25
21
|
headers: {},
|
|
26
22
|
request: {
|
|
27
23
|
url: ""
|
|
28
24
|
},
|
|
29
|
-
appId:
|
|
25
|
+
appId: "",
|
|
30
26
|
auth: {},
|
|
31
27
|
next: this.next,
|
|
32
|
-
throw: this.throw
|
|
33
|
-
get: (name) => this.headers[name],
|
|
28
|
+
throw: this.throw
|
|
34
29
|
}
|
|
35
30
|
}
|
|
36
31
|
|
|
37
32
|
executeMiddleware() {
|
|
38
|
-
return
|
|
39
|
-
return this.middleware(this.ctx, this.next)
|
|
40
|
-
})
|
|
33
|
+
return this.middleware(this.ctx, this.next)
|
|
41
34
|
}
|
|
42
35
|
|
|
43
36
|
setUser(user) {
|
|
@@ -53,7 +46,7 @@ class TestConfiguration {
|
|
|
53
46
|
}
|
|
54
47
|
|
|
55
48
|
setAuthenticated(isAuthed) {
|
|
56
|
-
this.ctx.
|
|
49
|
+
this.ctx.auth = { authenticated: isAuthed }
|
|
57
50
|
}
|
|
58
51
|
|
|
59
52
|
setRequestUrl(url) {
|
|
@@ -114,7 +107,7 @@ describe("Authorization middleware", () => {
|
|
|
114
107
|
expect(config.next).toHaveBeenCalled()
|
|
115
108
|
})
|
|
116
109
|
|
|
117
|
-
it("throws if the user
|
|
110
|
+
it("throws if the user has only builder permissions", async () => {
|
|
118
111
|
config.setEnvironment(false)
|
|
119
112
|
config.setMiddlewareRequiredPermission(PermissionTypes.BUILDER)
|
|
120
113
|
config.setUser({
|
|
@@ -140,7 +133,7 @@ describe("Authorization middleware", () => {
|
|
|
140
133
|
expect(config.next).toHaveBeenCalled()
|
|
141
134
|
})
|
|
142
135
|
|
|
143
|
-
it("throws if the user session is not authenticated", async () => {
|
|
136
|
+
it("throws if the user session is not authenticated after permission checks", async () => {
|
|
144
137
|
config.setUser({
|
|
145
138
|
role: {
|
|
146
139
|
_id: ""
|