import { Hono } from "jsr:@hono/hono@4"; import { assertEquals } from "jsr:@std/assert"; import { createAuthMiddleware, requireScope } from "./hono.ts"; import { stub } from "jsr:@std/testing/mock"; import { AuthSdk } from "./mod.ts"; type Variables = { userId: string; scopes: string[]; }; Deno.test("AuthMiddleware - Authorized request sets userId and scopes", async () => { const sdk = new AuthSdk({ authApiUrl: "http://localhost" }); const validateSessionStub = stub( sdk, "validateSession", () => Promise.resolve({ valid: true, uuid: "test-user-id", scopes: ["commander", "viewer"], }), ); const app = new Hono<{ Variables: Variables }>(); app.use("*", createAuthMiddleware(sdk)); app.get( "/", (c) => c.json({ userId: c.get("userId"), scopes: c.get("scopes") }), ); const req = new Request("http://localhost/", { headers: { "Authorization": "Bearer valid-token", }, }); const res = await app.request(req); assertEquals(res.status, 200); const json = await res.json(); assertEquals(json, { userId: "test-user-id", scopes: ["commander", "viewer"], }); validateSessionStub.restore(); }); Deno.test("AuthMiddleware - Unauthorized request (missing token)", async () => { const sdk = new AuthSdk({ authApiUrl: "http://localhost" }); const app = new Hono<{ Variables: Variables }>(); app.use("*", createAuthMiddleware(sdk)); app.get("/", (c) => c.text(`User: ${c.get("userId")}`)); const req = new Request("http://localhost/"); const res = await app.request(req); assertEquals(res.status, 401); const json = await res.json(); assertEquals(json, { error: "Unauthorized: Missing session token" }); }); Deno.test("AuthMiddleware - Unauthorized request (invalid token)", async () => { const sdk = new AuthSdk({ authApiUrl: "http://localhost" }); const validateSessionStub = stub( sdk, "validateSession", () => Promise.resolve({ valid: false, error: "Invalid token" }), ); const app = new Hono<{ Variables: Variables }>(); app.use("*", createAuthMiddleware(sdk)); app.get("/", (c) => c.text(`User: ${c.get("userId")}`)); const req = new Request("http://localhost/", { headers: { "Authorization": "Bearer invalid-token", }, }); const res = await app.request(req); assertEquals(res.status, 401); const json = await res.json(); assertEquals(json, { error: "Invalid token" }); validateSessionStub.restore(); }); Deno.test("requireScope - allows user when scope is present", async () => { const app = new Hono<{ Variables: Variables }>(); app.use("*", (c, next) => { c.set("userId", "test-user"); c.set("scopes", ["commander", "viewer"]); return next(); }); app.get("/command", requireScope("commander"), (c) => c.text("Command OK")); const req = new Request("http://localhost/command"); const res = await app.request(req); assertEquals(res.status, 200); assertEquals(await res.text(), "Command OK"); }); Deno.test("requireScope - allows user when global admin scope is present", async () => { const app = new Hono<{ Variables: Variables }>(); app.use("*", (c, next) => { c.set("userId", "admin-user"); c.set("scopes", ["admin"]); return next(); }); app.get( "/restricted", requireScope("special-scope"), (c) => c.text("Admin Override OK"), ); const req = new Request("http://localhost/restricted"); const res = await app.request(req); assertEquals(res.status, 200); assertEquals(await res.text(), "Admin Override OK"); }); Deno.test("requireScope - rejects user when scope is missing", async () => { const app = new Hono<{ Variables: Variables }>(); app.use("*", (c, next) => { c.set("userId", "test-user"); c.set("scopes", ["viewer"]); return next(); }); app.get("/command", requireScope("commander"), (c) => c.text("Command OK")); const req = new Request("http://localhost/command"); const res = await app.request(req); assertEquals(res.status, 403); const json = await res.json(); assertEquals(json, { error: "Forbidden: Required scope 'commander' missing.", }); });