Files
HiveGrid-Wireframes/hivegrid-cloud/apps/web/app/services/auth/password-reset-token.server.test.ts
T

53 lines
2.4 KiB
TypeScript

import { describe, expect, it } from "vitest";
import {
createPasswordResetTokenUpdate,
createPasswordResetVerifyToken,
hashPasswordResetToken,
isPasswordResetTokenValid,
PASSWORD_RESET_TOKEN_TTL_MS,
} from "./password-reset-token.server";
describe("password reset token helpers", () => {
it("creates token update data with an issue timestamp", () => {
const issuedAt = new Date("2026-05-11T12:00:00.000Z");
expect(createPasswordResetTokenUpdate("token_1", issuedAt)).toEqual({
verifyToken: hashPasswordResetToken("token_1"),
verifyTokenCreatedAt: issuedAt,
});
});
it("creates high-entropy reset tokens as hex strings", () => {
const token = createPasswordResetVerifyToken();
expect(token).toMatch(/^[a-f0-9]{40}$/);
});
it("accepts matching tokens within the reset TTL", () => {
const issuedAt = new Date("2026-05-11T12:00:00.000Z");
const now = new Date(issuedAt.getTime() + PASSWORD_RESET_TOKEN_TTL_MS - 1);
expect(isPasswordResetTokenValid({ verifyToken: hashPasswordResetToken("token_1"), verifyTokenCreatedAt: issuedAt }, "token_1", now)).toBe(true);
});
it("accepts legacy plaintext tokens during migration", () => {
const issuedAt = new Date("2026-05-11T12:00:00.000Z");
expect(isPasswordResetTokenValid({ verifyToken: "token_1", verifyTokenCreatedAt: issuedAt }, "token_1", issuedAt)).toBe(true);
});
it("rejects missing, mismatched, or expired tokens", () => {
const issuedAt = new Date("2026-05-11T12:00:00.000Z");
const expiredNow = new Date(issuedAt.getTime() + PASSWORD_RESET_TOKEN_TTL_MS + 1);
expect(isPasswordResetTokenValid({ verifyToken: "token_1", verifyTokenCreatedAt: null }, "token_1", issuedAt)).toBe(false);
expect(isPasswordResetTokenValid({ verifyToken: hashPasswordResetToken("token_1"), verifyTokenCreatedAt: issuedAt }, "", issuedAt)).toBe(false);
expect(isPasswordResetTokenValid({ verifyToken: hashPasswordResetToken("token_1"), verifyTokenCreatedAt: issuedAt }, "wrong", issuedAt)).toBe(false);
expect(isPasswordResetTokenValid({ verifyToken: hashPasswordResetToken("token_1"), verifyTokenCreatedAt: issuedAt }, "token_1", expiredNow)).toBe(false);
});
it("rejects malformed token issue timestamps", () => {
expect(isPasswordResetTokenValid({ verifyToken: hashPasswordResetToken("token_1"), verifyTokenCreatedAt: "not-a-date" }, "token_1")).toBe(false);
});
});