My personal photography website
steve.phot
portfolio
photography
svelte
sveltekit
1// Usage: bun run scripts/hash-password.ts <password> <session-secret>
2// Or: npx tsx scripts/hash-password.ts <password> <session-secret>
3
4const encoder = new TextEncoder();
5
6async 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
24const [password, secret] = process.argv.slice(2);
25
26if (!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
37const hash = await hashPassword(password, secret);
38
39console.log(
40 "\nAdd these to your .dev.vars file (for local dev) or Cloudflare secrets (for production):\n",
41);
42console.log(`SESSION_SECRET=${secret}`);
43console.log(`ADMIN_PASSWORD_HASH=${hash}`);
44console.log("\nTo set Cloudflare secrets, run:");
45console.log(` wrangler secret put SESSION_SECRET`);
46console.log(` wrangler secret put ADMIN_PASSWORD_HASH`);