scripts/hash-password.ts 1.3 K raw
1
// Usage: bun run scripts/hash-password.ts <password> <session-secret>
2
// Or: npx tsx scripts/hash-password.ts <password> <session-secret>
3
4
const encoder = new TextEncoder();
5
6
async function hashPassword(password: string, secret: string): Promise<string> {
7
	const key = await crypto.subtle.importKey(
8
		"raw",
9
		encoder.encode(secret),
10
		{ name: "HMAC", hash: "SHA-256" },
11
		false,
12
		["sign"],
13
	);
14
	const signature = await crypto.subtle.sign(
15
		"HMAC",
16
		key,
17
		encoder.encode(password),
18
	);
19
	return Array.from(new Uint8Array(signature))
20
		.map((b) => b.toString(16).padStart(2, "0"))
21
		.join("");
22
}
23
24
const [password, secret] = process.argv.slice(2);
25
26
if (!password || !secret) {
27
	console.error(
28
		"Usage: bun run scripts/hash-password.ts <password> <session-secret>",
29
	);
30
	console.error("\nExample:");
31
	console.error(
32
		"  bun run scripts/hash-password.ts mypassword $(openssl rand -hex 32)",
33
	);
34
	process.exit(1);
35
}
36
37
const hash = await hashPassword(password, secret);
38
39
console.log(
40
	"\nAdd these to your .dev.vars file (for local dev) or Cloudflare secrets (for production):\n",
41
);
42
console.log(`SESSION_SECRET=${secret}`);
43
console.log(`ADMIN_PASSWORD_HASH=${hash}`);
44
console.log("\nTo set Cloudflare secrets, run:");
45
console.log(`  wrangler secret put SESSION_SECRET`);
46
console.log(`  wrangler secret put ADMIN_PASSWORD_HASH`);