diff --git a/app/__test__/integration/auth.integration.test.ts b/app/__test__/integration/auth.integration.test.ts index abd8ed5..c103848 100644 --- a/app/__test__/integration/auth.integration.test.ts +++ b/app/__test__/integration/auth.integration.test.ts @@ -1,7 +1,7 @@ import { afterAll, beforeAll, describe, expect, it } from "bun:test"; import { App, createApp } from "../../src"; import type { AuthResponse } from "../../src/auth"; -import { randomString, secureRandomString } from "../../src/core/utils"; +import { randomString, secureRandomString, withDisabledConsole } from "../../src/core/utils"; import { disableConsoleLog, enableConsoleLog } from "../helper"; beforeAll(disableConsoleLog); @@ -200,4 +200,14 @@ describe("integration auth", () => { expect(await $fns.me()).toEqual({ user: null as any }); } }); + + it("should check for permissions", async () => { + const app = createAuthApp(); + await app.build(); + + await withDisabledConsole(async () => { + const res = await app.server.request("/api/system/schema"); + expect(res.status).toBe(403); + }); + }); }); diff --git a/app/src/auth/middlewares.ts b/app/src/auth/middlewares.ts index 78a24cc..9f1aebb 100644 --- a/app/src/auth/middlewares.ts +++ b/app/src/auth/middlewares.ts @@ -3,8 +3,13 @@ import type { Context } from "hono"; import { createMiddleware } from "hono/factory"; import type { ServerEnv } from "modules/Module"; +function getPath(reqOrCtx: Request | Context) { + const req = reqOrCtx instanceof Request ? reqOrCtx : reqOrCtx.req.raw; + return new URL(req.url).pathname; +} + export function shouldSkipAuth(req: Request) { - const skip = new URL(req.url).pathname.startsWith(config.server.assets_path); + const skip = getPath(req).startsWith(config.server.assets_path); if (skip) { //console.log("skip auth for", req.url); } @@ -14,7 +19,7 @@ export function shouldSkipAuth(req: Request) { export const auth = createMiddleware(async (c, next) => { // make sure to only register once if (c.get("auth_registered")) { - throw new Error("auth middleware already registered"); + throw new Error(`auth middleware already registered for ${getPath(c)}`); } c.set("auth_registered", true); @@ -47,20 +52,20 @@ export const auth = createMiddleware(async (c, next) => { export const permission = (...permissions: Permission[]) => createMiddleware(async (c, next) => { + const app = c.get("app"); + // in tests, app is not defined if (!c.get("auth_registered")) { - throw new Error("auth middleware not registered, cannot check permissions"); - } - - if (!shouldSkipAuth(c.req.raw)) { - const app = c.get("app"); - if (app) { - const p = Array.isArray(permissions) ? permissions : [permissions]; - const guard = app.modules.ctx().guard; - for (const permission of p) { - guard.throwUnlessGranted(permission); - } + const msg = `auth middleware not registered, cannot check permissions for ${getPath(c)}`; + if (app?.module.auth.enabled) { + throw new Error(msg); } else { - console.warn("app not in context, skip permission check"); + console.warn(msg); + } + } else if (!shouldSkipAuth(c.req.raw)) { + const p = Array.isArray(permissions) ? permissions : [permissions]; + const guard = app.modules.ctx().guard; + for (const permission of p) { + guard.throwUnlessGranted(permission); } } diff --git a/app/src/core/utils/test.ts b/app/src/core/utils/test.ts index b06ac55..662b33c 100644 --- a/app/src/core/utils/test.ts +++ b/app/src/core/utils/test.ts @@ -7,7 +7,7 @@ const _oldConsoles = { export async function withDisabledConsole( fn: () => Promise, - severities: ConsoleSeverity[] = ["log"] + severities: ConsoleSeverity[] = ["log", "warn", "error"] ): Promise { const _oldConsoles = { log: console.log, @@ -30,7 +30,7 @@ export async function withDisabledConsole( } } -export function disableConsoleLog(severities: ConsoleSeverity[] = ["log"]) { +export function disableConsoleLog(severities: ConsoleSeverity[] = ["log", "warn"]) { severities.forEach((severity) => { console[severity] = () => null; });