feat: zitadel token auth middleware
This commit is contained in:
65
tests/auth.test.ts
Normal file
65
tests/auth.test.ts
Normal file
@@ -0,0 +1,65 @@
|
||||
import { describe, expect, it } from "vitest";
|
||||
import { SignJWT, generateKeyPair } from "jose";
|
||||
import { makeVerifier } from "../server/utils/auth";
|
||||
|
||||
const ISS = "https://auth.kuns.dev";
|
||||
|
||||
async function setup() {
|
||||
const { publicKey, privateKey } = await generateKeyPair("RS256");
|
||||
const verify = makeVerifier({
|
||||
issuer: ISS,
|
||||
audiences: ["aud-web", "proj-1"],
|
||||
allowedSubs: ["owner-1"],
|
||||
keyResolver: async () => publicKey,
|
||||
});
|
||||
const sign = (claims: Record<string, unknown>) =>
|
||||
new SignJWT(claims)
|
||||
.setProtectedHeader({ alg: "RS256" })
|
||||
.setIssuer(ISS)
|
||||
.setIssuedAt()
|
||||
.setExpirationTime("5m")
|
||||
.sign(privateKey);
|
||||
return { verify, sign };
|
||||
}
|
||||
|
||||
describe("token verification", () => {
|
||||
it("accepts an owner token with a valid audience", async () => {
|
||||
const { verify, sign } = await setup();
|
||||
const t = await sign({ sub: "owner-1", aud: ["aud-web"] });
|
||||
await expect(verify(t)).resolves.toMatchObject({ sub: "owner-1" });
|
||||
});
|
||||
|
||||
it("accepts when aud is a single string in the allowed set", async () => {
|
||||
const { verify, sign } = await setup();
|
||||
const t = await sign({ sub: "owner-1", aud: "proj-1" });
|
||||
await expect(verify(t)).resolves.toMatchObject({ sub: "owner-1" });
|
||||
});
|
||||
|
||||
it("rejects a non-owner sub", async () => {
|
||||
const { verify, sign } = await setup();
|
||||
const t = await sign({ sub: "intruder", aud: ["aud-web"] });
|
||||
await expect(verify(t)).rejects.toThrow();
|
||||
});
|
||||
|
||||
it("rejects a token with no accepted audience", async () => {
|
||||
const { verify, sign } = await setup();
|
||||
const t = await sign({ sub: "owner-1", aud: ["other"] });
|
||||
await expect(verify(t)).rejects.toThrow();
|
||||
});
|
||||
|
||||
it("rejects a wrong issuer", async () => {
|
||||
const { publicKey, privateKey } = await generateKeyPair("RS256");
|
||||
const verify = makeVerifier({
|
||||
issuer: ISS,
|
||||
audiences: ["aud-web"],
|
||||
allowedSubs: ["owner-1"],
|
||||
keyResolver: async () => publicKey,
|
||||
});
|
||||
const t = await new SignJWT({ sub: "owner-1", aud: ["aud-web"] })
|
||||
.setProtectedHeader({ alg: "RS256" })
|
||||
.setIssuer("https://evil.example")
|
||||
.setExpirationTime("5m")
|
||||
.sign(privateKey);
|
||||
await expect(verify(t)).rejects.toThrow();
|
||||
});
|
||||
});
|
||||
Reference in New Issue
Block a user