182 lines
4.1 KiB
TypeScript
182 lines
4.1 KiB
TypeScript
import { Hono } from "hono";
|
|
import { http, HttpResponse } from "msw";
|
|
import { setupServer } from "msw/node";
|
|
import { afterAll, afterEach, beforeAll, describe, expect, test } from "vitest";
|
|
import { z } from "zod";
|
|
import { UnkeyContext, unkey } from "./index";
|
|
|
|
const key = "test_key";
|
|
const apiId = "api_test";
|
|
|
|
const server = setupServer(
|
|
// @ts-expect-error
|
|
http.post("https://api.unkey.dev/v1/keys.verifyKey", async ({ request }) => {
|
|
const req = z
|
|
.object({
|
|
apiId: z.string(),
|
|
key: z.string(),
|
|
})
|
|
.parse(await request.json());
|
|
|
|
if (req.apiId !== apiId) {
|
|
return HttpResponse.json({
|
|
valid: false,
|
|
code: "FORBDIDDEN",
|
|
});
|
|
}
|
|
if (req.key !== key) {
|
|
return HttpResponse.json({
|
|
valid: false,
|
|
code: "NOT_FOUND",
|
|
});
|
|
}
|
|
|
|
return HttpResponse.json({
|
|
valid: true,
|
|
environment: "test",
|
|
});
|
|
}),
|
|
);
|
|
|
|
beforeAll(() => {
|
|
server.listen();
|
|
});
|
|
afterEach(() => {
|
|
server.resetHandlers();
|
|
});
|
|
afterAll(() => {
|
|
server.close();
|
|
});
|
|
|
|
describe("No custom Config", () => {
|
|
describe("happy path", () => {
|
|
const app = new Hono<{ Variables: { unkey: UnkeyContext } }>();
|
|
|
|
app.use(
|
|
"*",
|
|
unkey({
|
|
apiId,
|
|
}),
|
|
);
|
|
|
|
app.get("/", (c) => c.json(c.get("unkey")));
|
|
|
|
test("Should be hello message", async () => {
|
|
const res = await app.request("http://localhost/", {
|
|
headers: {
|
|
Authorization: `Bearer ${key}`,
|
|
},
|
|
});
|
|
expect(res.status).toBe(200);
|
|
expect(await res.json()).toMatchObject({ valid: true });
|
|
});
|
|
});
|
|
|
|
describe("No Authorization header", () => {
|
|
const app = new Hono<{ Variables: { unkey: UnkeyContext } }>();
|
|
|
|
app.use(
|
|
"*",
|
|
unkey({
|
|
apiId,
|
|
}),
|
|
);
|
|
|
|
app.get("/", (c) => c.json(c.get("unkey")));
|
|
|
|
test("should be unauthorized", async () => {
|
|
const res = await app.request("http://localhost/");
|
|
expect(res.status).toBe(401);
|
|
expect(await res.json()).toMatchObject({
|
|
error: "unauthorized",
|
|
});
|
|
});
|
|
});
|
|
});
|
|
|
|
describe("with key environment", () => {
|
|
const app = new Hono<{ Variables: { unkey: UnkeyContext } }>();
|
|
|
|
app.use(
|
|
"/*",
|
|
unkey({
|
|
apiId,
|
|
}),
|
|
);
|
|
|
|
let returnedEnvironment: string | undefined = undefined;
|
|
|
|
app.get("/", (c) => {
|
|
returnedEnvironment = c.get("unkey").environment;
|
|
return c.text("hello");
|
|
});
|
|
|
|
test("environment should be returned in context", async () => {
|
|
const res = await app.request("http://localhost/", {
|
|
headers: {
|
|
Authorization: `Bearer ${key}`,
|
|
},
|
|
});
|
|
expect(res.status).toBe(200);
|
|
expect(returnedEnvironment).toBe("test");
|
|
});
|
|
});
|
|
|
|
describe("With custom key getter", () => {
|
|
describe("No Authorization header", () => {
|
|
const app = new Hono<{ Variables: { unkey: UnkeyContext } }>();
|
|
|
|
app.use(
|
|
"/*",
|
|
unkey({
|
|
apiId,
|
|
getKey: (c) => {
|
|
return c.text("oh well");
|
|
},
|
|
}),
|
|
);
|
|
|
|
app.get("/", (c) => c.json(c.get("unkey")));
|
|
|
|
test("should be called with response", async () => {
|
|
const res = await app.request("http://localhost/");
|
|
expect(res.status).toBe(200);
|
|
expect(await res.text()).toEqual("oh well");
|
|
});
|
|
});
|
|
});
|
|
|
|
describe("With custom invald handler", () => {
|
|
describe("No Authorization header", () => {
|
|
const app = new Hono<{ Variables: { unkey: UnkeyContext } }>();
|
|
|
|
let calledWith: UnkeyContext | null = null;
|
|
app.use(
|
|
"/*",
|
|
unkey({
|
|
apiId,
|
|
handleInvalidKey: (c, result) => {
|
|
calledWith = result;
|
|
return c.text("oh well");
|
|
},
|
|
}),
|
|
);
|
|
|
|
app.get("/", (c) => c.json(c.get("unkey")));
|
|
|
|
test("should be called with response", async () => {
|
|
const res = await app.request("http://localhost/", {
|
|
headers: {
|
|
Authorization: "Bearer notakey",
|
|
},
|
|
});
|
|
expect(res.status).toBe(200);
|
|
expect(await res.text()).toEqual("oh well");
|
|
expect(calledWith).toMatchObject({
|
|
valid: false,
|
|
code: "NOT_FOUND",
|
|
});
|
|
});
|
|
});
|
|
});
|