Skip to content

Commit 0367a7d

Browse files
committed
Initial Release - v1.0.1
1 parent d1be7ef commit 0367a7d

File tree

7 files changed

+840
-0
lines changed

7 files changed

+840
-0
lines changed

bin/cli.js

Lines changed: 171 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,171 @@
1+
#!/usr/bin/env node
2+
3+
/**
4+
* Secure Password Generator CLI
5+
*
6+
* This module provides a command-line interface for generating secure passwords
7+
* with customizable options including length, symbol inclusion, and readability.
8+
*
9+
* @author Achal Chaudhary
10+
* @version 1.0.0
11+
* @license MIT
12+
*/
13+
14+
import { Command } from "commander";
15+
import chalk from "chalk";
16+
import generatePassword from "../src/index.js";
17+
import clipboard from "clipboardy";
18+
import figlet from "figlet";
19+
import gradient from "gradient-string";
20+
21+
// Initialize the command-line interface using Commander.js
22+
const program = new Command();
23+
24+
// Logo
25+
console.log(
26+
gradient.pastel.multiline(
27+
figlet.textSync("SecurePass", {
28+
font: "Standard",
29+
horizontalLayout: "default",
30+
verticalLayout: "default",
31+
})
32+
)
33+
);
34+
35+
// Configure the CLI program with name, description, and available options
36+
program
37+
.name("secure-pass")
38+
.description("Generate secure passwords via CLI with customizable options")
39+
.version("1.0.0")
40+
.option("-l, --length <number>", "Length of the password (1-1000)", "12")
41+
.option("-s, --symbols", "Include special symbols (!@#$%^&* etc.)", false)
42+
.option(
43+
"-r, --readable",
44+
"Exclude confusing characters (O, 0, I, l, 1, |)",
45+
false
46+
)
47+
.option(
48+
"-v, --verbose",
49+
"Show detailed information about the generated password",
50+
false
51+
)
52+
.parse(process.argv);
53+
54+
// Extract command-line options
55+
const options = program.opts();
56+
57+
/**
58+
* Main CLI execution function
59+
* Generates a password based on user-provided options and displays the result
60+
*/
61+
function main() {
62+
try {
63+
// Validate and parse the length option
64+
const length = parseInt(options.length);
65+
if (isNaN(length) || length < 1 || length > 1000) {
66+
console.error(
67+
chalk.red("❌ Error: Length must be a number between 1 and 1000")
68+
);
69+
process.exit(1);
70+
}
71+
72+
// Generate password using the core password generation function
73+
const password = generatePassword({
74+
length: length,
75+
symbols: options.symbols,
76+
readable: options.readable,
77+
});
78+
79+
// Display the generated password with appropriate formatting
80+
displayPassword(password, options);
81+
} catch (error) {
82+
// Handle any errors that occur during password generation
83+
console.error(chalk.red("❌ Error generating password:"));
84+
console.error(chalk.red(error.message));
85+
process.exit(1);
86+
}
87+
}
88+
89+
/**
90+
* Displays the generated password with optional verbose information
91+
*
92+
* @param {string} password - The generated password to display
93+
* @param {Object} options - CLI options including verbose flag
94+
*/
95+
function displayPassword(password, options) {
96+
// Show success message
97+
console.log(chalk.green("✅ Generated Password:"));
98+
99+
// Display the password in bold for better visibility
100+
console.log(chalk.bold(password));
101+
102+
// Show additional information if verbose mode is enabled
103+
if (options.verbose) {
104+
console.log(chalk.cyan("\n📊 Password Details:"));
105+
console.log(chalk.cyan(` Length: ${password.length} characters`));
106+
console.log(
107+
chalk.cyan(
108+
` Contains symbols: ${
109+
/[!@#$%^&*()_+{}[\]<>?,.]/.test(password) ? "Yes" : "No"
110+
}`
111+
)
112+
);
113+
console.log(
114+
chalk.cyan(` Contains numbers: ${/\d/.test(password) ? "Yes" : "No"}`)
115+
);
116+
console.log(
117+
chalk.cyan(
118+
` Contains uppercase: ${/[A-Z]/.test(password) ? "Yes" : "No"}`
119+
)
120+
);
121+
console.log(
122+
chalk.cyan(
123+
` Contains lowercase: ${/[a-z]/.test(password) ? "Yes" : "No"}`
124+
)
125+
);
126+
127+
// Calculate and display entropy information
128+
const charsetSize = calculateCharsetSize(options);
129+
const entropy = Math.log2(Math.pow(charsetSize, password.length));
130+
console.log(chalk.cyan(` Estimated entropy: ${entropy.toFixed(1)} bits`));
131+
132+
// Security assessment
133+
if (entropy >= 128) {
134+
console.log(chalk.green(" Security: Excellent (128+ bits)"));
135+
} else if (entropy >= 64) {
136+
console.log(chalk.yellow(" Security: Good (64+ bits)"));
137+
} else {
138+
console.log(chalk.red(" Security: Weak (< 64 bits)"));
139+
}
140+
}
141+
// Copy password
142+
clipboard.writeSync(password);
143+
console.log(chalk.yellow("📋 Copied to clipboard!"));
144+
145+
// Show usage tip
146+
console.log(chalk.gray("\n💡 Tip: Use --help to see all available options"));
147+
}
148+
149+
/**
150+
* Calculates the size of the character set used for password generation
151+
*
152+
* @param {Object} options - CLI options
153+
* @returns {number} The number of characters in the charset
154+
*/
155+
function calculateCharsetSize(options) {
156+
let size = 52; // 26 lowercase + 26 uppercase letters
157+
size += 10; // 10 digits
158+
159+
if (options.symbols) {
160+
size += 18; // 18 special symbols
161+
}
162+
163+
if (options.readable) {
164+
size -= 6; // Remove 6 confusing characters (O, 0, I, l, 1, |)
165+
}
166+
167+
return size;
168+
}
169+
170+
// Execute the main function when the script is run
171+
main();

0 commit comments

Comments
 (0)