119 lines
4.3 KiB
TypeScript
119 lines
4.3 KiB
TypeScript
import { describe, expect, it } from "vitest";
|
|
import { extractAdminSsoClaims, hasAllowedAdminGroup, isAllowedAdminGroup, mapGroupsToRole } from "./claims.server";
|
|
|
|
describe("mapGroupsToRole", () => {
|
|
it("maps toolctrl-admin to super_admin", () => {
|
|
expect(mapGroupsToRole(["toolctrl-admin"])).toBe("super_admin");
|
|
});
|
|
|
|
it("maps toolctrl-staff to staff", () => {
|
|
expect(mapGroupsToRole(["toolctrl-staff"])).toBe("staff");
|
|
});
|
|
|
|
it("prefers super_admin when both groups are present", () => {
|
|
expect(mapGroupsToRole(["toolctrl-staff", "toolctrl-admin"])).toBe("super_admin");
|
|
});
|
|
|
|
it("returns null for an unknown group", () => {
|
|
expect(mapGroupsToRole(["random-group"])).toBeNull();
|
|
});
|
|
|
|
it("returns null for an empty list", () => {
|
|
expect(mapGroupsToRole([])).toBeNull();
|
|
});
|
|
|
|
it("returns null for null/undefined input", () => {
|
|
expect(mapGroupsToRole(undefined)).toBeNull();
|
|
expect(mapGroupsToRole(null)).toBeNull();
|
|
});
|
|
});
|
|
|
|
describe("isAllowedAdminGroup / hasAllowedAdminGroup", () => {
|
|
it("recognizes the two allowlisted groups", () => {
|
|
expect(isAllowedAdminGroup("toolctrl-admin")).toBe(true);
|
|
expect(isAllowedAdminGroup("toolctrl-staff")).toBe(true);
|
|
expect(isAllowedAdminGroup("toolctrl-rando")).toBe(false);
|
|
});
|
|
|
|
it("returns false when claim list has no allowed group", () => {
|
|
expect(hasAllowedAdminGroup(["other"])).toBe(false);
|
|
expect(hasAllowedAdminGroup([])).toBe(false);
|
|
expect(hasAllowedAdminGroup(undefined)).toBe(false);
|
|
});
|
|
|
|
it("returns true when at least one allowed group is present", () => {
|
|
expect(hasAllowedAdminGroup(["other", "toolctrl-staff"])).toBe(true);
|
|
});
|
|
});
|
|
|
|
describe("extractAdminSsoClaims", () => {
|
|
const validClaims = {
|
|
sub: "auth-uid-123",
|
|
email: "Admin@Example.test",
|
|
email_verified: true,
|
|
name: "Admin Person",
|
|
groups: ["toolctrl-admin"],
|
|
};
|
|
|
|
it("extracts and normalizes a valid claim set", () => {
|
|
const result = extractAdminSsoClaims(validClaims);
|
|
expect(result.ok).toBe(true);
|
|
if (result.ok) {
|
|
expect(result.claims.subject).toBe("auth-uid-123");
|
|
expect(result.claims.email).toBe("admin@example.test");
|
|
expect(result.claims.name).toBe("Admin Person");
|
|
expect(result.claims.groups).toEqual(["toolctrl-admin"]);
|
|
expect(result.claims.emailVerified).toBe(true);
|
|
}
|
|
});
|
|
|
|
it("falls back to preferred_username when name is missing", () => {
|
|
const result = extractAdminSsoClaims({ ...validClaims, name: undefined, preferred_username: "admin-handle" });
|
|
expect(result.ok).toBe(true);
|
|
if (result.ok) expect(result.claims.name).toBe("admin-handle");
|
|
});
|
|
|
|
it("falls back to email when both name and preferred_username are missing", () => {
|
|
const result = extractAdminSsoClaims({ ...validClaims, name: undefined });
|
|
expect(result.ok).toBe(true);
|
|
if (result.ok) expect(result.claims.name).toBe("admin@example.test");
|
|
});
|
|
|
|
it("rejects missing sub", () => {
|
|
const result = extractAdminSsoClaims({ ...validClaims, sub: undefined });
|
|
expect(result.ok).toBe(false);
|
|
if (!result.ok) expect(result.reason).toBe("missing-sub");
|
|
});
|
|
|
|
it("rejects missing email", () => {
|
|
const result = extractAdminSsoClaims({ ...validClaims, email: "" });
|
|
expect(result.ok).toBe(false);
|
|
if (!result.ok) expect(result.reason).toBe("missing-email");
|
|
});
|
|
|
|
it("rejects email_verified=false", () => {
|
|
const result = extractAdminSsoClaims({ ...validClaims, email_verified: false });
|
|
expect(result.ok).toBe(false);
|
|
if (!result.ok) expect(result.reason).toBe("email-not-verified");
|
|
});
|
|
|
|
it("treats missing email_verified as true (Authentik does not always emit it)", () => {
|
|
const claims = { ...validClaims } as Record<string, unknown>;
|
|
delete claims.email_verified;
|
|
const result = extractAdminSsoClaims(claims);
|
|
expect(result.ok).toBe(true);
|
|
});
|
|
|
|
it("filters non-string entries from groups", () => {
|
|
const result = extractAdminSsoClaims({ ...validClaims, groups: ["toolctrl-admin", null, 7, "ok"] });
|
|
expect(result.ok).toBe(true);
|
|
if (result.ok) expect(result.claims.groups).toEqual(["toolctrl-admin", "ok"]);
|
|
});
|
|
|
|
it("returns missing-sub for null claims", () => {
|
|
const result = extractAdminSsoClaims(null);
|
|
expect(result.ok).toBe(false);
|
|
if (!result.ok) expect(result.reason).toBe("missing-sub");
|
|
});
|
|
});
|