Skip to content

Commit 90e9771

Browse files
authored
feat(cli): add auto-generate option to password prompt (#137)
* feat(cli): add auto-generate option to password prompt When setting a password during init or `pds secret password`, users can now choose to generate a strong random password (32-char base64url) instead of entering one manually. Generated passwords are displayed and automatically copied to the clipboard when available. * chore: add changeset * fix: make generatePassword module-private
1 parent 287c971 commit 90e9771

2 files changed

Lines changed: 39 additions & 1 deletion

File tree

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
---
2+
"@getcirrus/pds": minor
3+
---
4+
5+
Add option to auto-generate a password during `pds init` and `pds secret password`, with clipboard copy support

packages/pds/src/cli/utils/secrets.ts

Lines changed: 34 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ import bcrypt from "bcryptjs";
77
import * as p from "@clack/prompts";
88
import { setSecret, setVar, type SecretName } from "./wrangler.js";
99
import { setDevVar } from "./dotenv.js";
10+
import { promptSelect, copyToClipboard } from "./cli-helpers.js";
1011

1112
export interface SigningKeypair {
1213
privateKey: string; // hex-encoded
@@ -54,9 +55,41 @@ export async function hashPassword(password: string): Promise<string> {
5455
}
5556

5657
/**
57-
* Prompt for password with confirmation (max 3 attempts)
58+
* Generate a random password (base64url, 24 bytes = 32 chars)
59+
*/
60+
function generatePassword(): string {
61+
return randomBytes(24).toString("base64url");
62+
}
63+
64+
/**
65+
* Prompt for password with confirmation (max 3 attempts),
66+
* or generate one automatically
5867
*/
5968
export async function promptPassword(handle?: string): Promise<string> {
69+
const method = await promptSelect<"manual" | "generate">({
70+
message: handle
71+
? `Set a password for @${handle}:`
72+
: "Set a password:",
73+
options: [
74+
{ value: "manual", label: "Choose a password" },
75+
{ value: "generate", label: "Generate one automatically" },
76+
],
77+
});
78+
79+
if (method === "generate") {
80+
const password = generatePassword();
81+
p.note(password, "Generated password");
82+
const copied = await copyToClipboard(password);
83+
if (copied) {
84+
p.log.success("Copied to clipboard");
85+
} else {
86+
p.log.warn(
87+
"Could not copy to clipboard — save this password somewhere safe!",
88+
);
89+
}
90+
return password;
91+
}
92+
6093
const message = handle
6194
? `Choose a password for @${handle}:`
6295
: "Enter password:";

0 commit comments

Comments
 (0)