Merge branch 'master' of github.com:budibase/budibase into fix-automation-loop-test-output-2

This commit is contained in:
Sam Rose 2025-02-17 11:11:14 +00:00
commit 8a84a70608
No known key found for this signature in database
5 changed files with 26 additions and 9 deletions

View File

@ -1,6 +1,6 @@
{ {
"$schema": "node_modules/lerna/schemas/lerna-schema.json", "$schema": "node_modules/lerna/schemas/lerna-schema.json",
"version": "3.4.10", "version": "3.4.11",
"npmClient": "yarn", "npmClient": "yarn",
"concurrency": 20, "concurrency": 20,
"command": { "command": {

View File

@ -67,6 +67,15 @@ describe("utils", () => {
}) })
}) })
it("gets appId from query params", async () => {
const ctx = structures.koa.newContext()
const expected = db.generateAppID()
ctx.query = { appId: expected }
const actual = await utils.getAppIdFromCtx(ctx)
expect(actual).toBe(expected)
})
it("doesn't get appId from url when previewing", async () => { it("doesn't get appId from url when previewing", async () => {
const ctx = structures.koa.newContext() const ctx = structures.koa.newContext()
const appId = db.generateAppID() const appId = db.generateAppID()

View File

@ -101,6 +101,11 @@ export async function getAppIdFromCtx(ctx: Ctx) {
appId = confirmAppId(pathId) appId = confirmAppId(pathId)
} }
// look in queryParams
if (!appId && ctx.query?.appId) {
appId = confirmAppId(ctx.query?.appId as string)
}
// lookup using custom url - prod apps only // lookup using custom url - prod apps only
// filter out the builder preview path which collides with the prod app path // filter out the builder preview path which collides with the prod app path
// to ensure we don't load all apps excessively // to ensure we don't load all apps excessively

View File

@ -1,4 +1,4 @@
import { tenancy, utils } from "@budibase/backend-core" import { tenancy, utils, context } from "@budibase/backend-core"
import { UserCtx } from "@budibase/types" import { UserCtx } from "@budibase/types"
async function ensureTenantAppOwnership(ctx: UserCtx, next: any) { async function ensureTenantAppOwnership(ctx: UserCtx, next: any) {
@ -6,9 +6,12 @@ async function ensureTenantAppOwnership(ctx: UserCtx, next: any) {
if (!appId) { if (!appId) {
ctx.throw(400, "appId must be provided") ctx.throw(400, "appId must be provided")
} }
const appTenantId = context.getTenantIDFromAppID(appId)
const tenantId = tenancy.getTenantId() const tenantId = tenancy.getTenantId()
if (appId !== tenantId) {
ctx.throw(403, `App does not belong to tenant`) if (appTenantId !== tenantId) {
ctx.throw(403, "Unauthorized")
} }
await next() await next()
} }

View File

@ -2,6 +2,7 @@ import ensureTenantAppOwnership from "../ensureTenantAppOwnership"
import { tenancy, utils } from "@budibase/backend-core" import { tenancy, utils } from "@budibase/backend-core"
jest.mock("@budibase/backend-core", () => ({ jest.mock("@budibase/backend-core", () => ({
...jest.requireActual("@budibase/backend-core"),
tenancy: { tenancy: {
getTenantId: jest.fn(), getTenantId: jest.fn(),
}, },
@ -53,16 +54,15 @@ describe("Ensure Tenant Ownership Middleware", () => {
expect(config.next).toHaveBeenCalled() expect(config.next).toHaveBeenCalled()
}) })
it("throws 403 when appId does not match tenant ID", async () => { it("throws when tenant appId does not match tenant ID", async () => {
const appId = "app_dev_tenant3_fce449c4d75b4e4a9c7a6980d82a3e22"
utils.getAppIdFromCtx.mockResolvedValue(appId)
tenancy.getTenantId.mockReturnValue("tenant_2") tenancy.getTenantId.mockReturnValue("tenant_2")
await config.executeMiddleware() await config.executeMiddleware()
expect(utils.getAppIdFromCtx).toHaveBeenCalledWith(config.ctx) expect(utils.getAppIdFromCtx).toHaveBeenCalledWith(config.ctx)
expect(config.throw).toHaveBeenCalledWith( expect(config.throw).toHaveBeenCalledWith(403, "Unauthorized")
403,
"App does not belong to tenant"
)
}) })
it("throws 400 when appId is missing", async () => { it("throws 400 when appId is missing", async () => {