4 changed files with 49 additions and 0 deletions
@ -0,0 +1,9 @@ |
|||
import { createHash, randomBytes } from "node:crypto"; |
|||
|
|||
export function randomUrlToken(): string { |
|||
return randomBytes(32).toString("base64url"); |
|||
} |
|||
|
|||
export function hashChallengeToken(token: string): string { |
|||
return createHash("sha256").update(token, "utf8").digest("hex"); |
|||
} |
|||
@ -0,0 +1,15 @@ |
|||
import bcrypt from "bcryptjs"; |
|||
|
|||
const ROUNDS = 10; |
|||
|
|||
export async function hashPassword(plain: string): Promise<string> { |
|||
const salt = await bcrypt.genSalt(ROUNDS); |
|||
return bcrypt.hash(plain, salt); |
|||
} |
|||
|
|||
export async function verifyPassword( |
|||
plain: string, |
|||
hash: string, |
|||
): Promise<boolean> { |
|||
return bcrypt.compare(plain, hash); |
|||
} |
|||
@ -0,0 +1,15 @@ |
|||
import { describe, expect, it } from "bun:test"; |
|||
import { |
|||
hashChallengeToken, |
|||
randomUrlToken, |
|||
} from "../../server/utils/challenge-token"; |
|||
|
|||
describe("challenge-token", () => { |
|||
it("hash is stable", () => { |
|||
expect(hashChallengeToken("abc")).toBe(hashChallengeToken("abc")); |
|||
}); |
|||
|
|||
it("random has reasonable length", () => { |
|||
expect(randomUrlToken().length).toBeGreaterThan(20); |
|||
}); |
|||
}); |
|||
@ -0,0 +1,10 @@ |
|||
import { describe, expect, it } from "bun:test"; |
|||
import { hashPassword, verifyPassword } from "../../server/utils/password"; |
|||
|
|||
describe("password", () => { |
|||
it("hashes and verifies", async () => { |
|||
const h = await hashPassword("hunter2"); |
|||
expect(await verifyPassword("hunter2", h)).toBe(true); |
|||
expect(await verifyPassword("wrong", h)).toBe(false); |
|||
}); |
|||
}); |
|||
Loading…
Reference in new issue