feat: add auth middleware for write endpoint protection
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
86
tests/middleware/auth.test.ts
Normal file
86
tests/middleware/auth.test.ts
Normal file
@@ -0,0 +1,86 @@
|
||||
import { beforeEach, describe, expect, test } from "bun:test";
|
||||
import { Hono } from "hono";
|
||||
import { requireAuth } from "../../src/server/middleware/auth";
|
||||
import {
|
||||
createApiKey,
|
||||
createSession,
|
||||
createUser,
|
||||
} from "../../src/server/services/auth.service";
|
||||
import { createTestDb } from "../helpers/db";
|
||||
|
||||
let db: ReturnType<typeof createTestDb>;
|
||||
|
||||
beforeEach(() => {
|
||||
db = createTestDb();
|
||||
});
|
||||
|
||||
function createApp() {
|
||||
const app = new Hono<{ Variables: { db?: any } }>();
|
||||
app.use("*", async (c, next) => {
|
||||
c.set("db", db);
|
||||
await next();
|
||||
});
|
||||
|
||||
// Public GET
|
||||
app.get("/items", (c) => c.json({ ok: true }));
|
||||
|
||||
// Protected POST
|
||||
app.post("/items", requireAuth, (c) => c.json({ ok: true }));
|
||||
|
||||
return app;
|
||||
}
|
||||
|
||||
describe("auth middleware", () => {
|
||||
test("allows GET requests without auth (middleware not applied to GET)", async () => {
|
||||
const app = createApp();
|
||||
const res = await app.request("/items");
|
||||
expect(res.status).toBe(200);
|
||||
});
|
||||
|
||||
test("returns 403 setup_required when no users exist", async () => {
|
||||
const app = createApp();
|
||||
const res = await app.request("/items", { method: "POST" });
|
||||
expect(res.status).toBe(403);
|
||||
const body = await res.json();
|
||||
expect(body.error).toBe("setup_required");
|
||||
});
|
||||
|
||||
test("rejects POST without auth when users exist", async () => {
|
||||
const app = createApp();
|
||||
await createUser(db, "admin", "pass");
|
||||
const res = await app.request("/items", { method: "POST" });
|
||||
expect(res.status).toBe(401);
|
||||
});
|
||||
|
||||
test("allows POST with valid session cookie", async () => {
|
||||
const app = createApp();
|
||||
const user = await createUser(db, "admin", "pass");
|
||||
const session = createSession(db, user.id);
|
||||
const res = await app.request("/items", {
|
||||
method: "POST",
|
||||
headers: { Cookie: `gearbox_session=${session.id}` },
|
||||
});
|
||||
expect(res.status).toBe(200);
|
||||
});
|
||||
|
||||
test("allows POST with valid API key", async () => {
|
||||
const app = createApp();
|
||||
await createUser(db, "admin", "pass");
|
||||
const key = await createApiKey(db, "test");
|
||||
const res = await app.request("/items", {
|
||||
method: "POST",
|
||||
headers: { "X-API-Key": key.rawKey },
|
||||
});
|
||||
expect(res.status).toBe(200);
|
||||
});
|
||||
|
||||
test("rejects POST with invalid API key", async () => {
|
||||
const app = createApp();
|
||||
await createUser(db, "admin", "pass");
|
||||
const res = await app.request("/items", {
|
||||
method: "POST",
|
||||
headers: { "X-API-Key": "invalid" },
|
||||
});
|
||||
expect(res.status).toBe(401);
|
||||
});
|
||||
});
|
||||
Reference in New Issue
Block a user