Skip to content
48 linesCodeBlameRaw

Pick any line to see why it is the way it is: the commit, the pull request and issue it came from, and what the agent was thinking.

The sidebar asks billing whether it is on, not for the account, so no page waits on the card processor1// Creates a user (or resets their password) in the remote D1 database and
2// writes the generated password to the gitignored .credentials directory.
3//
4// node scripts/create-user.mjs <username> [email]
5import { execSync } from "node:child_process";
6import { pbkdf2Sync, randomBytes } from "node:crypto";
7import { mkdirSync, rmSync, writeFileSync } from "node:fs";
8import { tmpdir } from "node:os";
9import { join } from "node:path";
10
11const [username, email] = process.argv.slice(2);
12if (!/^[a-z0-9](?:[a-z0-9]|-(?=[a-z0-9])){0,38}$/.test(username ?? "")) {
13 console.error("usage: node scripts/create-user.mjs <username> [email]");
14 process.exit(1);
15}
16if (email && !/^[^\s'@]+@[^\s'@]+$/.test(email)) {
17 console.error("invalid email");
18 process.exit(1);
19}
20
21// Must match hashPassword in src/crypto.ts.
22const iterations = 100_000;
23const password = randomBytes(18).toString("base64url");
24const salt = randomBytes(16);
25const hash = pbkdf2Sync(password, salt, iterations, 32, "sha256");
26const stored = `pbkdf2$${iterations}$${salt.toString("base64")}$${hash.toString("base64")}`;
27
28const sqlFile = join(tmpdir(), `g1t-create-user-${process.pid}.sql`);
29writeFileSync(
30 sqlFile,
31 `INSERT INTO users (id, username, email, password_hash)
32 VALUES ('usr_' || lower(hex(randomblob(13))), '${username}', ${email ? `'${email}'` : "NULL"}, '${stored}')
33 ON CONFLICT (username) DO UPDATE SET password_hash = excluded.password_hash;`,
34);
35try {
36 execSync(`npx wrangler d1 execute g1t --remote --yes --file "${sqlFile}"`, {
37 cwd: join(import.meta.dirname, ".."),
38 stdio: ["ignore", "ignore", "inherit"],
39 });
40} finally {
41 rmSync(sqlFile, { force: true });
42}
43
44const directory = join(import.meta.dirname, "../../../.credentials");
45mkdirSync(directory, { recursive: true });
46const file = join(directory, `${username}.txt`);
47writeFileSync(file, `username: ${username}\npassword: ${password}\n`);
48console.log(`Password for ${username} written to ${file}`);

This file's history is long; its oldest lines are credited to the oldest commit read.