@budibase/backend-core 2.5.9 → 2.5.10-alpha.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/package.json +13 -10
- package/dist/src/configs/configs.d.ts +2 -1
- package/dist/src/configs/configs.js +9 -1
- package/dist/src/configs/configs.js.map +1 -1
- package/dist/src/constants/db.d.ts +1 -0
- package/dist/src/constants/db.js +1 -0
- package/dist/src/constants/db.js.map +1 -1
- package/dist/src/constants/misc.d.ts +4 -2
- package/dist/src/constants/misc.js +2 -0
- package/dist/src/constants/misc.js.map +1 -1
- package/dist/src/context/mainContext.d.ts +5 -2
- package/dist/src/context/mainContext.js +20 -3
- package/dist/src/context/mainContext.js.map +1 -1
- package/dist/src/context/types.d.ts +1 -0
- package/dist/src/db/couch/DatabaseImpl.js +1 -1
- package/dist/src/db/couch/DatabaseImpl.js.map +1 -1
- package/dist/src/db/index.d.ts +2 -1
- package/dist/src/db/index.js +15 -2
- package/dist/src/db/index.js.map +1 -1
- package/dist/src/db/lucene.d.ts +8 -14
- package/dist/src/db/lucene.js +164 -97
- package/dist/src/db/lucene.js.map +1 -1
- package/dist/src/db/searchIndexes/index.d.ts +1 -0
- package/dist/src/db/searchIndexes/index.js +18 -0
- package/dist/src/db/searchIndexes/index.js.map +1 -0
- package/dist/src/db/searchIndexes/searchIndexes.d.ts +1 -0
- package/dist/src/db/searchIndexes/searchIndexes.js +77 -0
- package/dist/src/db/searchIndexes/searchIndexes.js.map +1 -0
- package/dist/src/db/utils.d.ts +5 -126
- package/dist/src/db/utils.js +20 -232
- package/dist/src/db/utils.js.map +1 -1
- package/dist/src/db/views.d.ts +3 -1
- package/dist/src/db/views.js +61 -30
- package/dist/src/db/views.js.map +1 -1
- package/dist/src/docIds/conversions.js.map +1 -0
- package/dist/src/docIds/ids.d.ts +53 -0
- package/dist/src/docIds/ids.js +101 -0
- package/dist/src/docIds/ids.js.map +1 -0
- package/dist/src/docIds/index.d.ts +2 -0
- package/dist/src/docIds/index.js +19 -0
- package/dist/src/docIds/index.js.map +1 -0
- package/dist/src/docIds/newid.js.map +1 -0
- package/dist/src/docIds/params.d.ts +69 -0
- package/dist/src/docIds/params.js +138 -0
- package/dist/src/docIds/params.js.map +1 -0
- package/dist/src/docUpdates/index.d.ts +2 -0
- package/dist/src/docUpdates/index.js +36 -0
- package/dist/src/docUpdates/index.js.map +1 -0
- package/dist/src/environment.d.ts +4 -2
- package/dist/src/environment.js +35 -2
- package/dist/src/environment.js.map +1 -1
- package/dist/src/errors/errors.d.ts +3 -0
- package/dist/src/errors/errors.js +8 -1
- package/dist/src/errors/errors.js.map +1 -1
- package/dist/src/events/asyncEvents/index.d.ts +2 -0
- package/dist/src/events/asyncEvents/index.js +19 -0
- package/dist/src/events/asyncEvents/index.js.map +1 -0
- package/dist/src/events/asyncEvents/publisher.d.ts +2 -0
- package/dist/src/events/asyncEvents/publisher.js +27 -0
- package/dist/src/events/asyncEvents/publisher.js.map +1 -0
- package/dist/src/events/asyncEvents/queue.d.ts +11 -0
- package/dist/src/events/asyncEvents/queue.js +26 -0
- package/dist/src/events/asyncEvents/queue.js.map +1 -0
- package/dist/src/events/documentId.d.ts +2 -0
- package/dist/src/events/documentId.js +28 -0
- package/dist/src/events/documentId.js.map +1 -0
- package/dist/src/events/events.js +9 -0
- package/dist/src/events/events.js.map +1 -1
- package/dist/src/events/identification.d.ts +1 -0
- package/dist/src/events/identification.js +3 -2
- package/dist/src/events/identification.js.map +1 -1
- package/dist/src/events/index.d.ts +1 -0
- package/dist/src/events/index.js +3 -1
- package/dist/src/events/index.js.map +1 -1
- package/dist/src/events/processors/LoggingProcessor.js +3 -17
- package/dist/src/events/processors/LoggingProcessor.js.map +1 -1
- package/dist/src/events/processors/Processors.js +9 -3
- package/dist/src/events/processors/Processors.js.map +1 -1
- package/dist/src/events/processors/async/DocumentUpdateProcessor.d.ts +13 -0
- package/dist/src/events/processors/async/DocumentUpdateProcessor.js +44 -0
- package/dist/src/events/processors/async/DocumentUpdateProcessor.js.map +1 -0
- package/dist/src/events/processors/posthog/PosthogProcessor.js +1 -2
- package/dist/src/events/processors/posthog/PosthogProcessor.js.map +1 -1
- package/dist/src/events/processors/types.d.ts +1 -11
- package/dist/src/events/processors/types.js +0 -6
- package/dist/src/events/processors/types.js.map +1 -1
- package/dist/src/events/publishers/group.js +6 -0
- package/dist/src/events/publishers/group.js.map +1 -1
- package/dist/src/events/publishers/license.d.ts +9 -4
- package/dist/src/events/publishers/license.js +2 -17
- package/dist/src/events/publishers/license.js.map +1 -1
- package/dist/src/events/publishers/user.js +4 -0
- package/dist/src/events/publishers/user.js.map +1 -1
- package/dist/src/index.d.ts +6 -2
- package/dist/src/index.js +2 -1
- package/dist/src/index.js.map +1 -1
- package/dist/src/installation.d.ts +1 -0
- package/dist/src/installation.js +7 -6
- package/dist/src/installation.js.map +1 -1
- package/dist/src/{logging.d.ts → logging/alerts.d.ts} +0 -5
- package/dist/src/logging/alerts.js +24 -0
- package/dist/src/logging/alerts.js.map +1 -0
- package/dist/src/logging/correlation/correlation.d.ts +2 -0
- package/dist/src/logging/correlation/correlation.js +17 -0
- package/dist/src/logging/correlation/correlation.js.map +1 -0
- package/dist/src/logging/correlation/index.d.ts +1 -0
- package/dist/src/logging/correlation/index.js +18 -0
- package/dist/src/logging/correlation/index.js.map +1 -0
- package/dist/src/logging/correlation/middleware.d.ts +2 -0
- package/dist/src/logging/correlation/middleware.js +17 -0
- package/dist/src/logging/correlation/middleware.js.map +1 -0
- package/dist/src/logging/index.d.ts +4 -0
- package/dist/src/logging/index.js +36 -0
- package/dist/src/logging/index.js.map +1 -0
- package/dist/src/logging/pino/logger.d.ts +2 -0
- package/dist/src/logging/pino/logger.js +167 -0
- package/dist/src/logging/pino/logger.js.map +1 -0
- package/dist/src/logging/pino/middleware.d.ts +4 -0
- package/dist/src/logging/pino/middleware.js +47 -0
- package/dist/src/logging/pino/middleware.js.map +1 -0
- package/dist/src/middleware/authenticated.js +6 -3
- package/dist/src/middleware/authenticated.js.map +1 -1
- package/dist/src/middleware/errorHandling.js +5 -7
- package/dist/src/middleware/errorHandling.js.map +1 -1
- package/dist/src/middleware/index.d.ts +2 -1
- package/dist/src/middleware/index.js +5 -3
- package/dist/src/middleware/index.js.map +1 -1
- package/dist/src/middleware/passport/sso/oidc.js +2 -5
- package/dist/src/middleware/passport/sso/oidc.js.map +1 -1
- package/dist/src/middleware/tenancy.d.ts +1 -1
- package/dist/src/migrations/migrations.js +4 -4
- package/dist/src/migrations/migrations.js.map +1 -1
- package/dist/src/objectStore/objectStore.js +3 -3
- package/dist/src/objectStore/objectStore.js.map +1 -1
- package/dist/src/plugin/utils.js +53 -2
- package/dist/src/plugin/utils.js.map +1 -1
- package/dist/src/queue/constants.d.ts +2 -1
- package/dist/src/queue/constants.js +1 -0
- package/dist/src/queue/constants.js.map +1 -1
- package/dist/src/redis/redlockImpl.js +4 -1
- package/dist/src/redis/redlockImpl.js.map +1 -1
- package/dist/src/security/encryption.d.ts +1 -0
- package/dist/src/security/encryption.js +2 -1
- package/dist/src/security/encryption.js.map +1 -1
- package/dist/src/security/permissions.d.ts +35 -2
- package/dist/src/security/permissions.js +9 -6
- package/dist/src/security/permissions.js.map +1 -1
- package/dist/src/tenancy/tenancy.js +1 -5
- package/dist/src/tenancy/tenancy.js.map +1 -1
- package/dist/src/users.d.ts +11 -1
- package/dist/src/users.js +45 -1
- package/dist/src/users.js.map +1 -1
- package/dist/src/utils/hashing.d.ts +1 -1
- package/dist/src/utils/hashing.js +1 -1
- package/dist/src/utils/hashing.js.map +1 -1
- package/dist/src/utils/index.d.ts +1 -0
- package/dist/src/utils/index.js +1 -0
- package/dist/src/utils/index.js.map +1 -1
- package/dist/src/utils/stringUtils.d.ts +1 -0
- package/dist/src/utils/stringUtils.js +9 -0
- package/dist/src/utils/stringUtils.js.map +1 -0
- package/dist/src/utils/utils.d.ts +0 -1
- package/dist/src/utils/utils.js +1 -24
- package/dist/src/utils/utils.js.map +1 -1
- package/dist/tests/core/logging.js.map +1 -0
- package/dist/tests/{utilities → core/utilities}/index.d.ts +1 -2
- package/dist/tests/{utilities → core/utilities}/index.js +2 -7
- package/dist/tests/core/utilities/index.js.map +1 -0
- package/dist/tests/core/utilities/jestUtils.js.map +1 -0
- package/dist/tests/core/utilities/mocks/alerts.d.ts +3 -0
- package/dist/tests/core/utilities/mocks/alerts.js +30 -0
- package/dist/tests/core/utilities/mocks/alerts.js.map +1 -0
- package/dist/tests/core/utilities/mocks/date.js.map +1 -0
- package/dist/tests/core/utilities/mocks/events.js +144 -0
- package/dist/tests/core/utilities/mocks/events.js.map +1 -0
- package/dist/tests/core/utilities/mocks/fetch.d.ts +33 -0
- package/dist/tests/core/utilities/mocks/fetch.js +15 -0
- package/dist/tests/core/utilities/mocks/fetch.js.map +1 -0
- package/dist/tests/{utilities → core/utilities}/mocks/index.d.ts +4 -3
- package/dist/tests/{utilities → core/utilities}/mocks/index.js +7 -3
- package/dist/tests/core/utilities/mocks/index.js.map +1 -0
- package/dist/tests/{utilities → core/utilities}/mocks/licenses.d.ts +1 -0
- package/dist/tests/{utilities → core/utilities}/mocks/licenses.js +5 -1
- package/dist/tests/core/utilities/mocks/licenses.js.map +1 -0
- package/dist/tests/core/utilities/mocks/posthog.js.map +1 -0
- package/dist/tests/core/utilities/structures/Chance.d.ts +7 -0
- package/dist/tests/core/utilities/structures/Chance.js +21 -0
- package/dist/tests/core/utilities/structures/Chance.js.map +1 -0
- package/dist/tests/{utilities → core/utilities}/structures/accounts.js +3 -25
- package/dist/tests/core/utilities/structures/accounts.js.map +1 -0
- package/dist/tests/{utilities → core/utilities}/structures/apps.js +1 -1
- package/dist/tests/core/utilities/structures/apps.js.map +1 -0
- package/dist/tests/core/utilities/structures/common.js.map +1 -0
- package/dist/tests/{utilities → core/utilities}/structures/db.js +1 -1
- package/dist/tests/core/utilities/structures/db.js.map +1 -0
- package/dist/tests/core/utilities/structures/generator.d.ts +2 -0
- package/dist/tests/{utilities → core/utilities}/structures/generator.js +2 -2
- package/dist/tests/core/utilities/structures/generator.js.map +1 -0
- package/dist/tests/{utilities → core/utilities}/structures/index.d.ts +2 -0
- package/dist/tests/{utilities → core/utilities}/structures/index.js +3 -1
- package/dist/tests/core/utilities/structures/index.js.map +1 -0
- package/dist/tests/core/utilities/structures/koa.js.map +1 -0
- package/dist/tests/core/utilities/structures/licenses.d.ts +17 -0
- package/dist/tests/core/utilities/structures/licenses.js +127 -0
- package/dist/tests/core/utilities/structures/licenses.js.map +1 -0
- package/dist/tests/core/utilities/structures/plugins.js.map +1 -0
- package/dist/tests/core/utilities/structures/quotas.d.ts +2 -0
- package/dist/tests/core/utilities/structures/quotas.js +71 -0
- package/dist/tests/core/utilities/structures/quotas.js.map +1 -0
- package/dist/tests/core/utilities/structures/scim.d.ts +14 -0
- package/dist/tests/core/utilities/structures/scim.js +67 -0
- package/dist/tests/core/utilities/structures/scim.js.map +1 -0
- package/dist/tests/core/utilities/structures/shared.js.map +1 -0
- package/dist/tests/core/utilities/structures/sso.js.map +1 -0
- package/dist/tests/{utilities → core/utilities}/structures/tenants.js +1 -1
- package/dist/tests/core/utilities/structures/tenants.js.map +1 -0
- package/dist/tests/core/utilities/structures/userGroups.js.map +1 -0
- package/dist/tests/core/utilities/structures/users.js.map +1 -0
- package/dist/tests/core/utilities/testContainerUtils.js.map +1 -0
- package/dist/tests/core/utilities/utils/index.d.ts +1 -0
- package/dist/tests/core/utilities/utils/index.js +28 -0
- package/dist/tests/core/utilities/utils/index.js.map +1 -0
- package/dist/tests/core/utilities/utils/time.d.ts +1 -0
- package/dist/tests/core/utilities/utils/time.js +8 -0
- package/dist/tests/core/utilities/utils/time.js.map +1 -0
- package/dist/tests/{utilities → extra}/DBTestConfiguration.d.ts +1 -1
- package/dist/tests/{utilities → extra}/DBTestConfiguration.js +2 -2
- package/dist/tests/extra/DBTestConfiguration.js.map +1 -0
- package/dist/tests/extra/index.d.ts +2 -0
- package/dist/tests/extra/index.js +33 -0
- package/dist/tests/extra/index.js.map +1 -0
- package/dist/tests/{utilities → extra}/testEnv.d.ts +1 -1
- package/dist/tests/{utilities → extra}/testEnv.js +1 -1
- package/dist/tests/extra/testEnv.js.map +1 -0
- package/dist/tests/index.d.ts +1 -1
- package/dist/tests/index.js +1 -1
- package/dist/tests/index.js.map +1 -1
- package/dist/tests/jestEnv.js +0 -1
- package/dist/tests/jestEnv.js.map +1 -1
- package/dist/tests/jestSetup.d.ts +1 -1
- package/dist/tests/jestSetup.js +2 -2
- package/dist/tests/jestSetup.js.map +1 -1
- package/dist/tsconfig.build.tsbuildinfo +1 -1
- package/package.json +13 -10
- package/src/auth/tests/auth.spec.ts +2 -1
- package/src/cache/tests/writethrough.spec.ts +4 -3
- package/src/configs/configs.ts +9 -0
- package/src/configs/tests/configs.spec.ts +2 -6
- package/src/constants/db.ts +1 -0
- package/src/constants/misc.ts +2 -0
- package/src/context/mainContext.ts +22 -5
- package/src/context/tests/index.spec.ts +16 -3
- package/src/context/types.ts +1 -0
- package/src/db/couch/DatabaseImpl.ts +1 -1
- package/src/db/index.ts +2 -1
- package/src/db/lucene.ts +156 -99
- package/src/db/searchIndexes/index.ts +1 -0
- package/src/db/searchIndexes/searchIndexes.ts +62 -0
- package/src/db/tests/lucene.spec.ts +101 -1
- package/src/db/tests/utils.spec.ts +1 -1
- package/src/db/utils.ts +7 -275
- package/src/db/views.ts +64 -25
- package/src/docIds/ids.ts +102 -0
- package/src/docIds/index.ts +2 -0
- package/src/docIds/params.ts +174 -0
- package/src/docUpdates/index.ts +29 -0
- package/src/environment.ts +44 -2
- package/src/errors/errors.ts +8 -0
- package/src/events/asyncEvents/index.ts +2 -0
- package/src/events/asyncEvents/publisher.ts +12 -0
- package/src/events/asyncEvents/queue.ts +22 -0
- package/src/events/documentId.ts +56 -0
- package/src/events/events.ts +10 -1
- package/src/events/identification.ts +3 -3
- package/src/events/index.ts +2 -0
- package/src/events/processors/LoggingProcessor.ts +3 -22
- package/src/events/processors/Processors.ts +9 -3
- package/src/events/processors/async/DocumentUpdateProcessor.ts +43 -0
- package/src/events/processors/posthog/PosthogProcessor.ts +1 -2
- package/src/events/processors/posthog/tests/PosthogProcessor.spec.ts +1 -1
- package/src/events/processors/types.ts +1 -18
- package/src/events/publishers/group.ts +6 -1
- package/src/events/publishers/license.ts +12 -13
- package/src/events/publishers/user.ts +4 -0
- package/src/index.ts +1 -0
- package/src/installation.ts +4 -5
- package/src/logging/alerts.ts +26 -0
- package/src/logging/correlation/correlation.ts +13 -0
- package/src/logging/correlation/index.ts +1 -0
- package/src/logging/correlation/middleware.ts +17 -0
- package/src/logging/index.ts +6 -0
- package/src/logging/pino/logger.ts +173 -0
- package/src/logging/pino/middleware.ts +45 -0
- package/src/middleware/authenticated.ts +9 -3
- package/src/middleware/errorHandling.ts +4 -4
- package/src/middleware/index.ts +2 -1
- package/src/middleware/passport/sso/oidc.ts +2 -9
- package/src/middleware/passport/sso/tests/sso.spec.ts +2 -1
- package/src/migrations/migrations.ts +4 -8
- package/src/migrations/tests/__snapshots__/migrations.spec.ts.snap +1 -1
- package/src/migrations/tests/migrations.spec.ts +1 -1
- package/src/objectStore/buckets/tests/app.spec.ts +1 -1
- package/src/objectStore/buckets/tests/global.spec.ts +1 -1
- package/src/objectStore/buckets/tests/plugins.spec.ts +2 -1
- package/src/objectStore/objectStore.ts +3 -3
- package/src/platform/tests/tenants.spec.ts +2 -1
- package/src/plugin/tests/validation.spec.ts +83 -0
- package/src/plugin/utils.ts +63 -3
- package/src/queue/constants.ts +1 -0
- package/src/redis/redlockImpl.ts +9 -3
- package/src/security/encryption.ts +1 -1
- package/src/security/permissions.ts +5 -5
- package/src/security/tests/encryption.spec.ts +31 -0
- package/src/security/tests/permissions.spec.ts +145 -0
- package/src/tenancy/tenancy.ts +2 -2
- package/src/tenancy/tests/tenancy.spec.ts +184 -0
- package/src/users.ts +56 -7
- package/src/utils/hashing.ts +1 -1
- package/src/utils/index.ts +1 -0
- package/src/utils/stringUtils.ts +8 -0
- package/src/utils/tests/utils.spec.ts +2 -1
- package/src/utils/utils.ts +3 -23
- package/tests/{utilities → core/utilities}/index.ts +1 -4
- package/tests/core/utilities/mocks/alerts.ts +3 -0
- package/tests/core/utilities/mocks/events.ts +133 -0
- package/tests/core/utilities/mocks/fetch.ts +17 -0
- package/tests/{utilities → core/utilities}/mocks/index.ts +4 -3
- package/tests/{utilities → core/utilities}/mocks/licenses.ts +4 -0
- package/tests/core/utilities/structures/Chance.ts +20 -0
- package/tests/{utilities → core/utilities}/structures/accounts.ts +4 -3
- package/tests/{utilities → core/utilities}/structures/apps.ts +1 -1
- package/tests/{utilities → core/utilities}/structures/db.ts +1 -1
- package/tests/{utilities → core/utilities}/structures/generator.ts +1 -1
- package/tests/{utilities → core/utilities}/structures/index.ts +2 -0
- package/tests/core/utilities/structures/licenses.ts +145 -0
- package/tests/core/utilities/structures/quotas.ts +67 -0
- package/tests/core/utilities/structures/scim.ts +81 -0
- package/tests/{utilities → core/utilities}/structures/tenants.ts +1 -1
- package/tests/core/utilities/utils/index.ts +1 -0
- package/tests/core/utilities/utils/time.ts +3 -0
- package/tests/{utilities → extra}/DBTestConfiguration.ts +2 -2
- package/tests/extra/index.ts +2 -0
- package/tests/{utilities → extra}/testEnv.ts +1 -1
- package/tests/index.ts +1 -1
- package/tests/jestEnv.ts +0 -1
- package/tests/jestSetup.ts +2 -2
- package/tsconfig.build.json +3 -7
- package/dist/src/db/conversions.js.map +0 -1
- package/dist/src/logging.js +0 -56
- package/dist/src/logging.js.map +0 -1
- package/dist/src/middleware/logging.d.ts +0 -2
- package/dist/src/middleware/logging.js +0 -106
- package/dist/src/middleware/logging.js.map +0 -1
- package/dist/src/newid.js.map +0 -1
- package/dist/tests/logging.js.map +0 -1
- package/dist/tests/utilities/DBTestConfiguration.js.map +0 -1
- package/dist/tests/utilities/index.js.map +0 -1
- package/dist/tests/utilities/jestUtils.js.map +0 -1
- package/dist/tests/utilities/mocks/date.js.map +0 -1
- package/dist/tests/utilities/mocks/events.js +0 -126
- package/dist/tests/utilities/mocks/events.js.map +0 -1
- package/dist/tests/utilities/mocks/fetch.d.ts +0 -31
- package/dist/tests/utilities/mocks/fetch.js +0 -8
- package/dist/tests/utilities/mocks/fetch.js.map +0 -1
- package/dist/tests/utilities/mocks/index.js.map +0 -1
- package/dist/tests/utilities/mocks/licenses.js.map +0 -1
- package/dist/tests/utilities/mocks/posthog.js.map +0 -1
- package/dist/tests/utilities/structures/accounts.js.map +0 -1
- package/dist/tests/utilities/structures/apps.js.map +0 -1
- package/dist/tests/utilities/structures/common.js.map +0 -1
- package/dist/tests/utilities/structures/db.js.map +0 -1
- package/dist/tests/utilities/structures/generator.d.ts +0 -1
- package/dist/tests/utilities/structures/generator.js.map +0 -1
- package/dist/tests/utilities/structures/index.js.map +0 -1
- package/dist/tests/utilities/structures/koa.js.map +0 -1
- package/dist/tests/utilities/structures/licenses.d.ts +0 -5
- package/dist/tests/utilities/structures/licenses.js +0 -18
- package/dist/tests/utilities/structures/licenses.js.map +0 -1
- package/dist/tests/utilities/structures/plugins.js.map +0 -1
- package/dist/tests/utilities/structures/shared.js.map +0 -1
- package/dist/tests/utilities/structures/sso.js.map +0 -1
- package/dist/tests/utilities/structures/tenants.js.map +0 -1
- package/dist/tests/utilities/structures/userGroups.js.map +0 -1
- package/dist/tests/utilities/structures/users.js.map +0 -1
- package/dist/tests/utilities/testContainerUtils.js.map +0 -1
- package/dist/tests/utilities/testEnv.js.map +0 -1
- package/src/logging.ts +0 -60
- package/src/middleware/logging.ts +0 -90
- package/tests/utilities/mocks/events.ts +0 -122
- package/tests/utilities/mocks/fetch.ts +0 -10
- package/tests/utilities/structures/licenses.ts +0 -18
- /package/dist/src/{db → docIds}/conversions.d.ts +0 -0
- /package/dist/src/{db → docIds}/conversions.js +0 -0
- /package/dist/src/{newid.d.ts → docIds/newid.d.ts} +0 -0
- /package/dist/src/{newid.js → docIds/newid.js} +0 -0
- /package/dist/tests/{logging.d.ts → core/logging.d.ts} +0 -0
- /package/dist/tests/{logging.js → core/logging.js} +0 -0
- /package/dist/tests/{utilities → core/utilities}/jestUtils.d.ts +0 -0
- /package/dist/tests/{utilities → core/utilities}/jestUtils.js +0 -0
- /package/dist/tests/{utilities → core/utilities}/mocks/date.d.ts +0 -0
- /package/dist/tests/{utilities → core/utilities}/mocks/date.js +0 -0
- /package/dist/tests/{utilities → core/utilities}/mocks/events.d.ts +0 -0
- /package/dist/tests/{utilities → core/utilities}/mocks/posthog.d.ts +0 -0
- /package/dist/tests/{utilities → core/utilities}/mocks/posthog.js +0 -0
- /package/dist/tests/{utilities → core/utilities}/structures/accounts.d.ts +0 -0
- /package/dist/tests/{utilities → core/utilities}/structures/apps.d.ts +0 -0
- /package/dist/tests/{utilities → core/utilities}/structures/common.d.ts +0 -0
- /package/dist/tests/{utilities → core/utilities}/structures/common.js +0 -0
- /package/dist/tests/{utilities → core/utilities}/structures/db.d.ts +0 -0
- /package/dist/tests/{utilities → core/utilities}/structures/koa.d.ts +0 -0
- /package/dist/tests/{utilities → core/utilities}/structures/koa.js +0 -0
- /package/dist/tests/{utilities → core/utilities}/structures/plugins.d.ts +0 -0
- /package/dist/tests/{utilities → core/utilities}/structures/plugins.js +0 -0
- /package/dist/tests/{utilities → core/utilities}/structures/shared.d.ts +0 -0
- /package/dist/tests/{utilities → core/utilities}/structures/shared.js +0 -0
- /package/dist/tests/{utilities → core/utilities}/structures/sso.d.ts +0 -0
- /package/dist/tests/{utilities → core/utilities}/structures/sso.js +0 -0
- /package/dist/tests/{utilities → core/utilities}/structures/tenants.d.ts +0 -0
- /package/dist/tests/{utilities → core/utilities}/structures/userGroups.d.ts +0 -0
- /package/dist/tests/{utilities → core/utilities}/structures/userGroups.js +0 -0
- /package/dist/tests/{utilities → core/utilities}/structures/users.d.ts +0 -0
- /package/dist/tests/{utilities → core/utilities}/structures/users.js +0 -0
- /package/dist/tests/{utilities → core/utilities}/testContainerUtils.d.ts +0 -0
- /package/dist/tests/{utilities → core/utilities}/testContainerUtils.js +0 -0
- /package/src/{db → docIds}/conversions.ts +0 -0
- /package/src/{newid.ts → docIds/newid.ts} +0 -0
- /package/tests/{logging.ts → core/logging.ts} +0 -0
- /package/tests/{utilities → core/utilities}/jestUtils.ts +0 -0
- /package/tests/{utilities → core/utilities}/mocks/date.ts +0 -0
- /package/tests/{utilities → core/utilities}/mocks/posthog.ts +0 -0
- /package/tests/{utilities → core/utilities}/structures/common.ts +0 -0
- /package/tests/{utilities → core/utilities}/structures/koa.ts +0 -0
- /package/tests/{utilities → core/utilities}/structures/plugins.ts +0 -0
- /package/tests/{utilities → core/utilities}/structures/shared.ts +0 -0
- /package/tests/{utilities → core/utilities}/structures/sso.ts +0 -0
- /package/tests/{utilities → core/utilities}/structures/userGroups.ts +0 -0
- /package/tests/{utilities → core/utilities}/structures/users.ts +0 -0
- /package/tests/{utilities → core/utilities}/testContainerUtils.ts +0 -0
|
@@ -0,0 +1,83 @@
|
|
|
1
|
+
import { validate } from "../utils"
|
|
2
|
+
import fetch from "node-fetch"
|
|
3
|
+
import { PluginType } from "@budibase/types"
|
|
4
|
+
|
|
5
|
+
const repoUrl =
|
|
6
|
+
"https://raw.githubusercontent.com/Budibase/budibase-skeleton/master"
|
|
7
|
+
const automationLink = `${repoUrl}/automation/schema.json.hbs`
|
|
8
|
+
const componentLink = `${repoUrl}/component/schema.json.hbs`
|
|
9
|
+
const datasourceLink = `${repoUrl}/datasource/schema.json.hbs`
|
|
10
|
+
|
|
11
|
+
async function getSchema(link: string) {
|
|
12
|
+
const response = await fetch(link)
|
|
13
|
+
if (response.status > 300) {
|
|
14
|
+
return
|
|
15
|
+
}
|
|
16
|
+
const text = await response.text()
|
|
17
|
+
return JSON.parse(text)
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
async function runTest(opts: { link?: string; schema?: any }) {
|
|
21
|
+
let error
|
|
22
|
+
try {
|
|
23
|
+
let schema = opts.schema
|
|
24
|
+
if (opts.link) {
|
|
25
|
+
schema = await getSchema(opts.link)
|
|
26
|
+
}
|
|
27
|
+
validate(schema)
|
|
28
|
+
} catch (err) {
|
|
29
|
+
error = err
|
|
30
|
+
}
|
|
31
|
+
return error
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
describe("it should be able to validate an automation schema", () => {
|
|
35
|
+
it("should return automation skeleton schema is valid", async () => {
|
|
36
|
+
const error = await runTest({ link: automationLink })
|
|
37
|
+
expect(error).toBeUndefined()
|
|
38
|
+
})
|
|
39
|
+
|
|
40
|
+
it("should fail given invalid automation schema", async () => {
|
|
41
|
+
const error = await runTest({
|
|
42
|
+
schema: {
|
|
43
|
+
type: PluginType.AUTOMATION,
|
|
44
|
+
schema: {},
|
|
45
|
+
},
|
|
46
|
+
})
|
|
47
|
+
expect(error).toBeDefined()
|
|
48
|
+
})
|
|
49
|
+
})
|
|
50
|
+
|
|
51
|
+
describe("it should be able to validate a component schema", () => {
|
|
52
|
+
it("should return component skeleton schema is valid", async () => {
|
|
53
|
+
const error = await runTest({ link: componentLink })
|
|
54
|
+
expect(error).toBeUndefined()
|
|
55
|
+
})
|
|
56
|
+
|
|
57
|
+
it("should fail given invalid component schema", async () => {
|
|
58
|
+
const error = await runTest({
|
|
59
|
+
schema: {
|
|
60
|
+
type: PluginType.COMPONENT,
|
|
61
|
+
schema: {},
|
|
62
|
+
},
|
|
63
|
+
})
|
|
64
|
+
expect(error).toBeDefined()
|
|
65
|
+
})
|
|
66
|
+
})
|
|
67
|
+
|
|
68
|
+
describe("it should be able to validate a datasource schema", () => {
|
|
69
|
+
it("should return datasource skeleton schema is valid", async () => {
|
|
70
|
+
const error = await runTest({ link: datasourceLink })
|
|
71
|
+
expect(error).toBeUndefined()
|
|
72
|
+
})
|
|
73
|
+
|
|
74
|
+
it("should fail given invalid datasource schema", async () => {
|
|
75
|
+
const error = await runTest({
|
|
76
|
+
schema: {
|
|
77
|
+
type: PluginType.DATASOURCE,
|
|
78
|
+
schema: {},
|
|
79
|
+
},
|
|
80
|
+
})
|
|
81
|
+
expect(error).toBeDefined()
|
|
82
|
+
})
|
|
83
|
+
})
|
package/src/plugin/utils.ts
CHANGED
|
@@ -1,4 +1,12 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import {
|
|
2
|
+
DatasourceFieldType,
|
|
3
|
+
QueryType,
|
|
4
|
+
PluginType,
|
|
5
|
+
AutomationStepType,
|
|
6
|
+
AutomationStepIdArray,
|
|
7
|
+
AutomationIOType,
|
|
8
|
+
AutomationCustomIOType,
|
|
9
|
+
} from "@budibase/types"
|
|
2
10
|
import joi from "joi"
|
|
3
11
|
|
|
4
12
|
const DATASOURCE_TYPES = [
|
|
@@ -19,7 +27,7 @@ function runJoi(validator: joi.Schema, schema: any) {
|
|
|
19
27
|
|
|
20
28
|
function validateComponent(schema: any) {
|
|
21
29
|
const validator = joi.object({
|
|
22
|
-
type: joi.string().allow(
|
|
30
|
+
type: joi.string().allow(PluginType.COMPONENT).required(),
|
|
23
31
|
metadata: joi.object().unknown(true).required(),
|
|
24
32
|
hash: joi.string().optional(),
|
|
25
33
|
version: joi.string().optional(),
|
|
@@ -53,7 +61,7 @@ function validateDatasource(schema: any) {
|
|
|
53
61
|
.required()
|
|
54
62
|
|
|
55
63
|
const validator = joi.object({
|
|
56
|
-
type: joi.string().allow(
|
|
64
|
+
type: joi.string().allow(PluginType.DATASOURCE).required(),
|
|
57
65
|
metadata: joi.object().unknown(true).required(),
|
|
58
66
|
hash: joi.string().optional(),
|
|
59
67
|
version: joi.string().optional(),
|
|
@@ -82,6 +90,55 @@ function validateDatasource(schema: any) {
|
|
|
82
90
|
runJoi(validator, schema)
|
|
83
91
|
}
|
|
84
92
|
|
|
93
|
+
function validateAutomation(schema: any) {
|
|
94
|
+
const basePropsValidator = joi.object().pattern(joi.string(), {
|
|
95
|
+
type: joi
|
|
96
|
+
.string()
|
|
97
|
+
.allow(...Object.values(AutomationIOType))
|
|
98
|
+
.required(),
|
|
99
|
+
customType: joi.string().allow(...Object.values(AutomationCustomIOType)),
|
|
100
|
+
title: joi.string(),
|
|
101
|
+
description: joi.string(),
|
|
102
|
+
enum: joi.array().items(joi.string()),
|
|
103
|
+
pretty: joi.array().items(joi.string()),
|
|
104
|
+
})
|
|
105
|
+
const stepSchemaValidator = joi
|
|
106
|
+
.object({
|
|
107
|
+
properties: basePropsValidator,
|
|
108
|
+
required: joi.array().items(joi.string()),
|
|
109
|
+
})
|
|
110
|
+
.concat(basePropsValidator)
|
|
111
|
+
.required()
|
|
112
|
+
const validator = joi.object({
|
|
113
|
+
type: joi.string().allow(PluginType.AUTOMATION).required(),
|
|
114
|
+
metadata: joi.object().unknown(true).required(),
|
|
115
|
+
hash: joi.string().optional(),
|
|
116
|
+
version: joi.string().optional(),
|
|
117
|
+
schema: joi.object({
|
|
118
|
+
name: joi.string().required(),
|
|
119
|
+
tagline: joi.string().required(),
|
|
120
|
+
icon: joi.string().required(),
|
|
121
|
+
description: joi.string().required(),
|
|
122
|
+
type: joi
|
|
123
|
+
.string()
|
|
124
|
+
.allow(AutomationStepType.ACTION, AutomationStepType.LOGIC)
|
|
125
|
+
.required(),
|
|
126
|
+
stepId: joi
|
|
127
|
+
.string()
|
|
128
|
+
.disallow(...AutomationStepIdArray)
|
|
129
|
+
.required(),
|
|
130
|
+
inputs: joi.object().optional(),
|
|
131
|
+
schema: joi
|
|
132
|
+
.object({
|
|
133
|
+
inputs: stepSchemaValidator,
|
|
134
|
+
outputs: stepSchemaValidator,
|
|
135
|
+
})
|
|
136
|
+
.required(),
|
|
137
|
+
}),
|
|
138
|
+
})
|
|
139
|
+
runJoi(validator, schema)
|
|
140
|
+
}
|
|
141
|
+
|
|
85
142
|
export function validate(schema: any) {
|
|
86
143
|
switch (schema?.type) {
|
|
87
144
|
case PluginType.COMPONENT:
|
|
@@ -90,6 +147,9 @@ export function validate(schema: any) {
|
|
|
90
147
|
case PluginType.DATASOURCE:
|
|
91
148
|
validateDatasource(schema)
|
|
92
149
|
break
|
|
150
|
+
case PluginType.AUTOMATION:
|
|
151
|
+
validateAutomation(schema)
|
|
152
|
+
break
|
|
93
153
|
default:
|
|
94
154
|
throw new Error(`Unknown plugin type - check schema.json: ${schema.type}`)
|
|
95
155
|
}
|
package/src/queue/constants.ts
CHANGED
package/src/redis/redlockImpl.ts
CHANGED
|
@@ -1,10 +1,16 @@
|
|
|
1
|
-
import Redlock
|
|
1
|
+
import Redlock from "redlock"
|
|
2
2
|
import { getLockClient } from "./init"
|
|
3
3
|
import { LockOptions, LockType } from "@budibase/types"
|
|
4
4
|
import * as context from "../context"
|
|
5
5
|
import env from "../environment"
|
|
6
6
|
|
|
7
|
-
const getClient = async (
|
|
7
|
+
const getClient = async (
|
|
8
|
+
type: LockType,
|
|
9
|
+
opts?: Redlock.Options
|
|
10
|
+
): Promise<Redlock> => {
|
|
11
|
+
if (type === LockType.CUSTOM) {
|
|
12
|
+
return newRedlock(opts)
|
|
13
|
+
}
|
|
8
14
|
if (env.isTest() && type !== LockType.TRY_ONCE) {
|
|
9
15
|
return newRedlock(OPTIONS.TEST)
|
|
10
16
|
}
|
|
@@ -56,7 +62,7 @@ const OPTIONS = {
|
|
|
56
62
|
},
|
|
57
63
|
}
|
|
58
64
|
|
|
59
|
-
const newRedlock = async (opts: Options = {}) => {
|
|
65
|
+
const newRedlock = async (opts: Redlock.Options = {}) => {
|
|
60
66
|
let options = { ...OPTIONS.DEFAULT, ...opts }
|
|
61
67
|
const redisWrapper = await getLockClient()
|
|
62
68
|
const client = redisWrapper.getClient()
|
|
@@ -12,7 +12,7 @@ export enum SecretOption {
|
|
|
12
12
|
ENCRYPTION = "encryption",
|
|
13
13
|
}
|
|
14
14
|
|
|
15
|
-
function getSecret(secretOption: SecretOption): string {
|
|
15
|
+
export function getSecret(secretOption: SecretOption): string {
|
|
16
16
|
let secret, secretName
|
|
17
17
|
switch (secretOption) {
|
|
18
18
|
case SecretOption.ENCRYPTION:
|
|
@@ -24,7 +24,7 @@ export enum PermissionType {
|
|
|
24
24
|
QUERY = "query",
|
|
25
25
|
}
|
|
26
26
|
|
|
27
|
-
class Permission {
|
|
27
|
+
export class Permission {
|
|
28
28
|
type: PermissionType
|
|
29
29
|
level: PermissionLevel
|
|
30
30
|
|
|
@@ -34,7 +34,7 @@ class Permission {
|
|
|
34
34
|
}
|
|
35
35
|
}
|
|
36
36
|
|
|
37
|
-
function levelToNumber(perm: PermissionLevel) {
|
|
37
|
+
export function levelToNumber(perm: PermissionLevel) {
|
|
38
38
|
switch (perm) {
|
|
39
39
|
// not everything has execute privileges
|
|
40
40
|
case PermissionLevel.EXECUTE:
|
|
@@ -55,7 +55,7 @@ function levelToNumber(perm: PermissionLevel) {
|
|
|
55
55
|
* @param {string} userPermLevel The permission level of the user.
|
|
56
56
|
* @return {string[]} All the permission levels this user is allowed to carry out.
|
|
57
57
|
*/
|
|
58
|
-
function getAllowedLevels(userPermLevel: PermissionLevel) {
|
|
58
|
+
export function getAllowedLevels(userPermLevel: PermissionLevel): string[] {
|
|
59
59
|
switch (userPermLevel) {
|
|
60
60
|
case PermissionLevel.EXECUTE:
|
|
61
61
|
return [PermissionLevel.EXECUTE]
|
|
@@ -64,9 +64,9 @@ function getAllowedLevels(userPermLevel: PermissionLevel) {
|
|
|
64
64
|
case PermissionLevel.WRITE:
|
|
65
65
|
case PermissionLevel.ADMIN:
|
|
66
66
|
return [
|
|
67
|
+
PermissionLevel.EXECUTE,
|
|
67
68
|
PermissionLevel.READ,
|
|
68
69
|
PermissionLevel.WRITE,
|
|
69
|
-
PermissionLevel.EXECUTE,
|
|
70
70
|
]
|
|
71
71
|
default:
|
|
72
72
|
return []
|
|
@@ -81,7 +81,7 @@ export enum BuiltinPermissionID {
|
|
|
81
81
|
POWER = "power",
|
|
82
82
|
}
|
|
83
83
|
|
|
84
|
-
const BUILTIN_PERMISSIONS = {
|
|
84
|
+
export const BUILTIN_PERMISSIONS = {
|
|
85
85
|
PUBLIC: {
|
|
86
86
|
_id: BuiltinPermissionID.PUBLIC,
|
|
87
87
|
name: "Public",
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
import { encrypt, decrypt, SecretOption, getSecret } from "../encryption"
|
|
2
|
+
import env from "../../environment"
|
|
3
|
+
|
|
4
|
+
describe("encryption", () => {
|
|
5
|
+
it("should throw an error if API encryption key is not set", () => {
|
|
6
|
+
const jwt = getSecret(SecretOption.API)
|
|
7
|
+
expect(jwt).toBe(env.JWT_SECRET)
|
|
8
|
+
})
|
|
9
|
+
|
|
10
|
+
it("should throw an error if encryption key is not set", () => {
|
|
11
|
+
expect(() => getSecret(SecretOption.ENCRYPTION)).toThrow(
|
|
12
|
+
'Secret "ENCRYPTION_KEY" has not been set in environment.'
|
|
13
|
+
)
|
|
14
|
+
})
|
|
15
|
+
|
|
16
|
+
it("should encrypt and decrypt a string using API encryption key", () => {
|
|
17
|
+
env._set("API_ENCRYPTION_KEY", "api_secret")
|
|
18
|
+
const plaintext = "budibase"
|
|
19
|
+
const apiEncrypted = encrypt(plaintext, SecretOption.API)
|
|
20
|
+
const decrypted = decrypt(apiEncrypted, SecretOption.API)
|
|
21
|
+
expect(decrypted).toEqual(plaintext)
|
|
22
|
+
})
|
|
23
|
+
|
|
24
|
+
it("should encrypt and decrypt a string using encryption key", () => {
|
|
25
|
+
env._set("ENCRYPTION_KEY", "normal_secret")
|
|
26
|
+
const plaintext = "budibase"
|
|
27
|
+
const encryptionEncrypted = encrypt(plaintext, SecretOption.ENCRYPTION)
|
|
28
|
+
const decrypted = decrypt(encryptionEncrypted, SecretOption.ENCRYPTION)
|
|
29
|
+
expect(decrypted).toEqual(plaintext)
|
|
30
|
+
})
|
|
31
|
+
})
|
|
@@ -0,0 +1,145 @@
|
|
|
1
|
+
import { cloneDeep } from "lodash"
|
|
2
|
+
import * as permissions from "../permissions"
|
|
3
|
+
import { BUILTIN_ROLE_IDS } from "../roles"
|
|
4
|
+
|
|
5
|
+
describe("levelToNumber", () => {
|
|
6
|
+
it("should return 0 for EXECUTE", () => {
|
|
7
|
+
expect(permissions.levelToNumber(permissions.PermissionLevel.EXECUTE)).toBe(
|
|
8
|
+
0
|
|
9
|
+
)
|
|
10
|
+
})
|
|
11
|
+
|
|
12
|
+
it("should return 1 for READ", () => {
|
|
13
|
+
expect(permissions.levelToNumber(permissions.PermissionLevel.READ)).toBe(1)
|
|
14
|
+
})
|
|
15
|
+
|
|
16
|
+
it("should return 2 for WRITE", () => {
|
|
17
|
+
expect(permissions.levelToNumber(permissions.PermissionLevel.WRITE)).toBe(2)
|
|
18
|
+
})
|
|
19
|
+
|
|
20
|
+
it("should return 3 for ADMIN", () => {
|
|
21
|
+
expect(permissions.levelToNumber(permissions.PermissionLevel.ADMIN)).toBe(3)
|
|
22
|
+
})
|
|
23
|
+
|
|
24
|
+
it("should return -1 for an unknown permission level", () => {
|
|
25
|
+
expect(
|
|
26
|
+
permissions.levelToNumber("unknown" as permissions.PermissionLevel)
|
|
27
|
+
).toBe(-1)
|
|
28
|
+
})
|
|
29
|
+
})
|
|
30
|
+
describe("getAllowedLevels", () => {
|
|
31
|
+
it('should return ["execute"] for EXECUTE', () => {
|
|
32
|
+
expect(
|
|
33
|
+
permissions.getAllowedLevels(permissions.PermissionLevel.EXECUTE)
|
|
34
|
+
).toEqual([permissions.PermissionLevel.EXECUTE])
|
|
35
|
+
})
|
|
36
|
+
|
|
37
|
+
it('should return ["execute", "read"] for READ', () => {
|
|
38
|
+
expect(
|
|
39
|
+
permissions.getAllowedLevels(permissions.PermissionLevel.READ)
|
|
40
|
+
).toEqual([
|
|
41
|
+
permissions.PermissionLevel.EXECUTE,
|
|
42
|
+
permissions.PermissionLevel.READ,
|
|
43
|
+
])
|
|
44
|
+
})
|
|
45
|
+
|
|
46
|
+
it('should return ["execute", "read", "write"] for WRITE', () => {
|
|
47
|
+
expect(
|
|
48
|
+
permissions.getAllowedLevels(permissions.PermissionLevel.WRITE)
|
|
49
|
+
).toEqual([
|
|
50
|
+
permissions.PermissionLevel.EXECUTE,
|
|
51
|
+
permissions.PermissionLevel.READ,
|
|
52
|
+
permissions.PermissionLevel.WRITE,
|
|
53
|
+
])
|
|
54
|
+
})
|
|
55
|
+
|
|
56
|
+
it('should return ["execute", "read", "write"] for ADMIN', () => {
|
|
57
|
+
expect(
|
|
58
|
+
permissions.getAllowedLevels(permissions.PermissionLevel.ADMIN)
|
|
59
|
+
).toEqual([
|
|
60
|
+
permissions.PermissionLevel.EXECUTE,
|
|
61
|
+
permissions.PermissionLevel.READ,
|
|
62
|
+
permissions.PermissionLevel.WRITE,
|
|
63
|
+
])
|
|
64
|
+
})
|
|
65
|
+
|
|
66
|
+
it("should return [] for an unknown permission level", () => {
|
|
67
|
+
expect(
|
|
68
|
+
permissions.getAllowedLevels("unknown" as permissions.PermissionLevel)
|
|
69
|
+
).toEqual([])
|
|
70
|
+
})
|
|
71
|
+
})
|
|
72
|
+
|
|
73
|
+
describe("doesHaveBasePermission", () => {
|
|
74
|
+
it("should return true if base permission has the required level", () => {
|
|
75
|
+
const permType = permissions.PermissionType.USER
|
|
76
|
+
const permLevel = permissions.PermissionLevel.READ
|
|
77
|
+
const rolesHierarchy = [
|
|
78
|
+
{
|
|
79
|
+
roleId: BUILTIN_ROLE_IDS.ADMIN,
|
|
80
|
+
permissionId: permissions.BuiltinPermissionID.ADMIN,
|
|
81
|
+
},
|
|
82
|
+
]
|
|
83
|
+
expect(
|
|
84
|
+
permissions.doesHaveBasePermission(permType, permLevel, rolesHierarchy)
|
|
85
|
+
).toBe(true)
|
|
86
|
+
})
|
|
87
|
+
|
|
88
|
+
it("should return false if base permission does not have the required level", () => {
|
|
89
|
+
const permType = permissions.PermissionType.APP
|
|
90
|
+
const permLevel = permissions.PermissionLevel.READ
|
|
91
|
+
const rolesHierarchy = [
|
|
92
|
+
{
|
|
93
|
+
roleId: BUILTIN_ROLE_IDS.PUBLIC,
|
|
94
|
+
permissionId: permissions.BuiltinPermissionID.PUBLIC,
|
|
95
|
+
},
|
|
96
|
+
]
|
|
97
|
+
expect(
|
|
98
|
+
permissions.doesHaveBasePermission(permType, permLevel, rolesHierarchy)
|
|
99
|
+
).toBe(false)
|
|
100
|
+
})
|
|
101
|
+
})
|
|
102
|
+
|
|
103
|
+
describe("isPermissionLevelHigherThanRead", () => {
|
|
104
|
+
it("should return true if level is higher than read", () => {
|
|
105
|
+
expect(
|
|
106
|
+
permissions.isPermissionLevelHigherThanRead(
|
|
107
|
+
permissions.PermissionLevel.WRITE
|
|
108
|
+
)
|
|
109
|
+
).toBe(true)
|
|
110
|
+
})
|
|
111
|
+
|
|
112
|
+
it("should return false if level is read or lower", () => {
|
|
113
|
+
expect(
|
|
114
|
+
permissions.isPermissionLevelHigherThanRead(
|
|
115
|
+
permissions.PermissionLevel.READ
|
|
116
|
+
)
|
|
117
|
+
).toBe(false)
|
|
118
|
+
})
|
|
119
|
+
})
|
|
120
|
+
|
|
121
|
+
describe("getBuiltinPermissions", () => {
|
|
122
|
+
it("returns a clone of the builtin permissions", () => {
|
|
123
|
+
const builtins = permissions.getBuiltinPermissions()
|
|
124
|
+
expect(builtins).toEqual(cloneDeep(permissions.BUILTIN_PERMISSIONS))
|
|
125
|
+
expect(builtins).not.toBe(permissions.BUILTIN_PERMISSIONS)
|
|
126
|
+
})
|
|
127
|
+
})
|
|
128
|
+
|
|
129
|
+
describe("getBuiltinPermissionByID", () => {
|
|
130
|
+
it("returns correct permission object for valid ID", () => {
|
|
131
|
+
const expectedPermission = {
|
|
132
|
+
_id: permissions.BuiltinPermissionID.PUBLIC,
|
|
133
|
+
name: "Public",
|
|
134
|
+
permissions: [
|
|
135
|
+
new permissions.Permission(
|
|
136
|
+
permissions.PermissionType.WEBHOOK,
|
|
137
|
+
permissions.PermissionLevel.EXECUTE
|
|
138
|
+
),
|
|
139
|
+
],
|
|
140
|
+
}
|
|
141
|
+
expect(permissions.getBuiltinPermissionByID("public")).toEqual(
|
|
142
|
+
expectedPermission
|
|
143
|
+
)
|
|
144
|
+
})
|
|
145
|
+
})
|
package/src/tenancy/tenancy.ts
CHANGED
|
@@ -3,8 +3,8 @@ import {
|
|
|
3
3
|
getTenantId,
|
|
4
4
|
getTenantIDFromAppID,
|
|
5
5
|
isMultiTenant,
|
|
6
|
+
getPlatformURL,
|
|
6
7
|
} from "../context"
|
|
7
|
-
import env from "../environment"
|
|
8
8
|
import {
|
|
9
9
|
BBContext,
|
|
10
10
|
TenantResolutionStrategy,
|
|
@@ -93,7 +93,7 @@ export const getTenantIDFromCtx = (
|
|
|
93
93
|
// subdomain
|
|
94
94
|
if (isAllowed(TenantResolutionStrategy.SUBDOMAIN)) {
|
|
95
95
|
// e.g. budibase.app or local.com:10000
|
|
96
|
-
const platformHost = new URL(
|
|
96
|
+
const platformHost = new URL(getPlatformURL()).host.split(":")[0]
|
|
97
97
|
// e.g. tenant.budibase.app or tenant.local.com
|
|
98
98
|
const requestHost = ctx.host
|
|
99
99
|
// parse the tenant id from the difference
|
|
@@ -0,0 +1,184 @@
|
|
|
1
|
+
import { TenantResolutionStrategy } from "@budibase/types"
|
|
2
|
+
import { addTenantToUrl, isUserInAppTenant, getTenantIDFromCtx } from "../"
|
|
3
|
+
import { isMultiTenant, getTenantIDFromAppID } from "../../context"
|
|
4
|
+
|
|
5
|
+
jest.mock("../../context", () => ({
|
|
6
|
+
getTenantId: jest.fn(() => "budibase"),
|
|
7
|
+
isMultiTenant: jest.fn(() => true),
|
|
8
|
+
getTenantIDFromAppID: jest.fn(),
|
|
9
|
+
getPlatformURL: jest.fn(() => "https://app.com"),
|
|
10
|
+
DEFAULT_TENANT_ID: "default",
|
|
11
|
+
}))
|
|
12
|
+
|
|
13
|
+
const mockedIsMultiTenant = isMultiTenant as jest.MockedFunction<
|
|
14
|
+
typeof isMultiTenant
|
|
15
|
+
>
|
|
16
|
+
const mockedGetTenantIDFromAppID = getTenantIDFromAppID as jest.MockedFunction<
|
|
17
|
+
typeof getTenantIDFromAppID
|
|
18
|
+
>
|
|
19
|
+
|
|
20
|
+
describe("addTenantToUrl", () => {
|
|
21
|
+
it("should append tenantId parameter to the URL", () => {
|
|
22
|
+
const url = "https://budibase.com"
|
|
23
|
+
const expectedUrl = "https://budibase.com?tenantId=budibase"
|
|
24
|
+
expect(addTenantToUrl(url)).toEqual(expectedUrl)
|
|
25
|
+
})
|
|
26
|
+
|
|
27
|
+
it("should append tenantId parameter to the URL query string", () => {
|
|
28
|
+
const url = "https://budibase.com?var=test"
|
|
29
|
+
const expectedUrl = "https://budibase.com?var=test&tenantId=budibase"
|
|
30
|
+
expect(addTenantToUrl(url)).toEqual(expectedUrl)
|
|
31
|
+
})
|
|
32
|
+
|
|
33
|
+
it("should not append tenantId parameter to the URL if isMultiTenant is false", () => {
|
|
34
|
+
mockedIsMultiTenant.mockImplementation(() => false)
|
|
35
|
+
|
|
36
|
+
const url = "https://budibase.com"
|
|
37
|
+
const expectedUrl = "https://budibase.com"
|
|
38
|
+
expect(addTenantToUrl(url)).toEqual(expectedUrl)
|
|
39
|
+
})
|
|
40
|
+
})
|
|
41
|
+
|
|
42
|
+
describe("isUserInAppTenant", () => {
|
|
43
|
+
mockedGetTenantIDFromAppID.mockImplementation(() => "budibase")
|
|
44
|
+
const mockUser = { tenantId: "budibase" }
|
|
45
|
+
|
|
46
|
+
it("returns true if user tenant ID matches app tenant ID", () => {
|
|
47
|
+
const appId = "app-budibase"
|
|
48
|
+
const result = isUserInAppTenant(appId, mockUser)
|
|
49
|
+
expect(result).toBe(true)
|
|
50
|
+
})
|
|
51
|
+
|
|
52
|
+
it("uses default tenant ID if user is not provided", () => {
|
|
53
|
+
const appId = "app-budibase"
|
|
54
|
+
const result = isUserInAppTenant(appId)
|
|
55
|
+
expect(result).toBe(true)
|
|
56
|
+
})
|
|
57
|
+
|
|
58
|
+
it("uses default tenant ID if app tenant ID is not found", () => {
|
|
59
|
+
const appId = "not-budibase-app"
|
|
60
|
+
const result = isUserInAppTenant(appId, mockUser)
|
|
61
|
+
expect(result).toBe(true)
|
|
62
|
+
})
|
|
63
|
+
|
|
64
|
+
it("returns false if user tenant ID does not match app tenant ID", () => {
|
|
65
|
+
const appId = "app-budibase"
|
|
66
|
+
mockedGetTenantIDFromAppID.mockImplementation(() => "not-budibase")
|
|
67
|
+
const result = isUserInAppTenant(appId, mockUser)
|
|
68
|
+
expect(result).toBe(false)
|
|
69
|
+
})
|
|
70
|
+
})
|
|
71
|
+
|
|
72
|
+
let mockOpts: any = {}
|
|
73
|
+
function createCtx(opts: {
|
|
74
|
+
originalUrl?: string
|
|
75
|
+
headers?: Record<string, string>
|
|
76
|
+
qsTenantId?: string
|
|
77
|
+
userTenantId?: string
|
|
78
|
+
host?: string
|
|
79
|
+
path?: string
|
|
80
|
+
}) {
|
|
81
|
+
const createdCtx: any = {
|
|
82
|
+
originalUrl: opts.originalUrl || "budibase.com",
|
|
83
|
+
matched: [{ name: "name" }],
|
|
84
|
+
throw: jest.fn(),
|
|
85
|
+
request: { headers: {} },
|
|
86
|
+
}
|
|
87
|
+
if (opts.headers) {
|
|
88
|
+
createdCtx.request.headers = opts.headers
|
|
89
|
+
}
|
|
90
|
+
if (opts.qsTenantId) {
|
|
91
|
+
createdCtx.request.query = { tenantId: opts.qsTenantId }
|
|
92
|
+
}
|
|
93
|
+
if (opts.userTenantId) {
|
|
94
|
+
createdCtx.user = { tenantId: opts.userTenantId }
|
|
95
|
+
}
|
|
96
|
+
if (opts.host) {
|
|
97
|
+
createdCtx.host = opts.host
|
|
98
|
+
}
|
|
99
|
+
if (opts.path) {
|
|
100
|
+
createdCtx.matched = [
|
|
101
|
+
{
|
|
102
|
+
paramNames: [{ name: "tenantId" }],
|
|
103
|
+
params: () => ({ tenantId: opts.path }),
|
|
104
|
+
captures: jest.fn(),
|
|
105
|
+
},
|
|
106
|
+
]
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
return createdCtx as any
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
describe("getTenantIDFromCtx", () => {
|
|
113
|
+
describe("when tenant can be found", () => {
|
|
114
|
+
it("returns the tenant ID from the user object", () => {
|
|
115
|
+
mockedIsMultiTenant.mockImplementation(() => true)
|
|
116
|
+
const ctx = createCtx({ userTenantId: "budibase" })
|
|
117
|
+
expect(getTenantIDFromCtx(ctx, mockOpts)).toEqual("budibase")
|
|
118
|
+
})
|
|
119
|
+
|
|
120
|
+
it("returns the tenant ID from the header", () => {
|
|
121
|
+
mockedIsMultiTenant.mockImplementation(() => true)
|
|
122
|
+
const ctx = createCtx({ headers: { "x-budibase-tenant-id": "budibase" } })
|
|
123
|
+
mockOpts = { includeStrategies: [TenantResolutionStrategy.HEADER] }
|
|
124
|
+
expect(getTenantIDFromCtx(ctx, mockOpts)).toEqual("budibase")
|
|
125
|
+
})
|
|
126
|
+
|
|
127
|
+
it("returns the tenant ID from the query param", () => {
|
|
128
|
+
mockedIsMultiTenant.mockImplementation(() => true)
|
|
129
|
+
mockOpts = { includeStrategies: [TenantResolutionStrategy.QUERY] }
|
|
130
|
+
const ctx = createCtx({ qsTenantId: "budibase" })
|
|
131
|
+
expect(getTenantIDFromCtx(ctx, mockOpts)).toEqual("budibase")
|
|
132
|
+
})
|
|
133
|
+
|
|
134
|
+
it("returns the tenant ID from the subdomain", () => {
|
|
135
|
+
mockedIsMultiTenant.mockImplementation(() => true)
|
|
136
|
+
const ctx = createCtx({ host: "bb.app.com" })
|
|
137
|
+
mockOpts = { includeStrategies: [TenantResolutionStrategy.SUBDOMAIN] }
|
|
138
|
+
expect(getTenantIDFromCtx(ctx, mockOpts)).toEqual("bb")
|
|
139
|
+
})
|
|
140
|
+
|
|
141
|
+
it("returns the tenant ID from the path", () => {
|
|
142
|
+
mockedIsMultiTenant.mockImplementation(() => true)
|
|
143
|
+
const ctx = createCtx({ path: "bb" })
|
|
144
|
+
mockOpts = { includeStrategies: [TenantResolutionStrategy.PATH] }
|
|
145
|
+
expect(getTenantIDFromCtx(ctx, mockOpts)).toEqual("bb")
|
|
146
|
+
})
|
|
147
|
+
})
|
|
148
|
+
|
|
149
|
+
describe("when tenant cannot be found", () => {
|
|
150
|
+
it("throws a 403 error if allowNoTenant is false", () => {
|
|
151
|
+
const ctx = createCtx({})
|
|
152
|
+
mockOpts = {
|
|
153
|
+
allowNoTenant: false,
|
|
154
|
+
excludeStrategies: [
|
|
155
|
+
TenantResolutionStrategy.QUERY,
|
|
156
|
+
TenantResolutionStrategy.SUBDOMAIN,
|
|
157
|
+
TenantResolutionStrategy.PATH,
|
|
158
|
+
],
|
|
159
|
+
}
|
|
160
|
+
expect(getTenantIDFromCtx(ctx, mockOpts)).toBeNull()
|
|
161
|
+
expect(ctx.throw).toBeCalledTimes(1)
|
|
162
|
+
expect(ctx.throw).toBeCalledWith(403, "Tenant id not set")
|
|
163
|
+
})
|
|
164
|
+
|
|
165
|
+
it("returns null if allowNoTenant is true", () => {
|
|
166
|
+
const ctx = createCtx({})
|
|
167
|
+
mockOpts = {
|
|
168
|
+
allowNoTenant: true,
|
|
169
|
+
excludeStrategies: [
|
|
170
|
+
TenantResolutionStrategy.QUERY,
|
|
171
|
+
TenantResolutionStrategy.SUBDOMAIN,
|
|
172
|
+
TenantResolutionStrategy.PATH,
|
|
173
|
+
],
|
|
174
|
+
}
|
|
175
|
+
expect(getTenantIDFromCtx(ctx, mockOpts)).toBeNull()
|
|
176
|
+
})
|
|
177
|
+
})
|
|
178
|
+
|
|
179
|
+
it("returns the default tenant ID when isMultiTenant() returns false", () => {
|
|
180
|
+
mockedIsMultiTenant.mockImplementation(() => false)
|
|
181
|
+
const ctx = createCtx({})
|
|
182
|
+
expect(getTenantIDFromCtx(ctx, mockOpts)).toEqual("default")
|
|
183
|
+
})
|
|
184
|
+
})
|