mirror of
https://github.com/Termix-SSH/Termix.git
synced 2026-10-28 14:15:24 +00:00
101 lines
2.6 KiB
TypeScript
101 lines
2.6 KiB
TypeScript
import { beforeEach, describe, expect, it, vi } from "vitest";
|
|
|
|
vi.mock("../../utils/logger.js", () => ({
|
|
authLogger: { warn: vi.fn() },
|
|
}));
|
|
|
|
const {
|
|
clearAuthPolicies,
|
|
evaluateAuthPolicy,
|
|
hasAuthPolicies,
|
|
provideAuthPolicy,
|
|
rememberDeviceAllowed,
|
|
} = await import("../../auth/policy.js");
|
|
|
|
const input = {
|
|
userId: "u1",
|
|
methodId: "password",
|
|
external: false,
|
|
deviceType: "web" as const,
|
|
trustedDevice: false,
|
|
mfaSatisfied: false,
|
|
secondFactors: [],
|
|
};
|
|
|
|
beforeEach(() => clearAuthPolicies());
|
|
|
|
describe("auth policy", () => {
|
|
it("changes nothing without a provider", async () => {
|
|
expect(hasAuthPolicies()).toBe(false);
|
|
expect(await evaluateAuthPolicy(input)).toEqual({
|
|
allowRememberDevice: true,
|
|
maxSessionSeconds: null,
|
|
idleTimeoutSeconds: null,
|
|
secondFactor: null,
|
|
});
|
|
expect(rememberDeviceAllowed()).toBe(true);
|
|
});
|
|
|
|
it("takes the strictest answer from every provider", async () => {
|
|
provideAuthPolicy("a", {
|
|
evaluate: () => ({
|
|
maxSessionSeconds: 3600,
|
|
idleTimeoutSeconds: 900,
|
|
secondFactor: "new-device",
|
|
}),
|
|
});
|
|
provideAuthPolicy("b", {
|
|
evaluate: async () => ({
|
|
allowRememberDevice: false,
|
|
maxSessionSeconds: 7200,
|
|
idleTimeoutSeconds: 300,
|
|
secondFactor: "always",
|
|
}),
|
|
allowRememberDevice: () => false,
|
|
});
|
|
expect(await evaluateAuthPolicy(input)).toEqual({
|
|
allowRememberDevice: false,
|
|
maxSessionSeconds: 3600,
|
|
idleTimeoutSeconds: 300,
|
|
secondFactor: "always",
|
|
});
|
|
expect(rememberDeviceAllowed()).toBe(false);
|
|
});
|
|
|
|
it("ignores zero and negative limits", async () => {
|
|
provideAuthPolicy("a", {
|
|
evaluate: () => ({ maxSessionSeconds: 0, idleTimeoutSeconds: -5 }),
|
|
});
|
|
expect(await evaluateAuthPolicy(input)).toMatchObject({
|
|
maxSessionSeconds: null,
|
|
idleTimeoutSeconds: null,
|
|
});
|
|
});
|
|
|
|
it("refuses the login when a provider throws, until it is removed", async () => {
|
|
const remove = provideAuthPolicy("a", {
|
|
evaluate: () => {
|
|
throw new Error("boom");
|
|
},
|
|
});
|
|
await expect(evaluateAuthPolicy(input)).rejects.toMatchObject({
|
|
status: 503,
|
|
code: "auth_policy_unavailable",
|
|
});
|
|
remove();
|
|
await expect(evaluateAuthPolicy(input)).resolves.toMatchObject({
|
|
secondFactor: null,
|
|
});
|
|
});
|
|
|
|
it("hides remember me when the hint throws", () => {
|
|
provideAuthPolicy("a", {
|
|
evaluate: () => ({}),
|
|
allowRememberDevice: () => {
|
|
throw new Error("boom");
|
|
},
|
|
});
|
|
expect(rememberDeviceAllowed()).toBe(false);
|
|
});
|
|
});
|