feat: Add password hash generation scripts
- Add simple hash-password script for quick hash generation - Add interactive generate-password script with hidden input - Include password validation and requirements display - Add npm scripts for easy execution - Create comprehensive PASSWORD_GENERATION.md guide - Use existing bcrypt infrastructure with 12 salt rounds Usage: npm run hash-password YourPassword123\! npm run generate-password (interactive) This solves the issue where bcrypt command line tools don't work properly for generating compatible hashes. 🤖 Generated with [Claude Code](https://claude.ai/code) Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
@@ -0,0 +1,166 @@
|
|||||||
|
# Password Generation Guide for MinIO WebUI
|
||||||
|
|
||||||
|
## Quick Start
|
||||||
|
|
||||||
|
### Method 1: Simple Command (Recommended)
|
||||||
|
|
||||||
|
```bash
|
||||||
|
cd backend
|
||||||
|
npm run hash-password YourSecurePassword123!
|
||||||
|
```
|
||||||
|
|
||||||
|
This will output:
|
||||||
|
```
|
||||||
|
=== Generated Password Hash ===
|
||||||
|
ADMIN_PASSWORD_HASH=$2b$12$...your.hash.here...
|
||||||
|
|
||||||
|
Copy the above line to your .env file
|
||||||
|
```
|
||||||
|
|
||||||
|
### Method 2: Interactive Mode
|
||||||
|
|
||||||
|
```bash
|
||||||
|
cd backend
|
||||||
|
npm run generate-password
|
||||||
|
```
|
||||||
|
|
||||||
|
This will:
|
||||||
|
- Prompt you for a password (hidden input)
|
||||||
|
- Generate the bcrypt hash
|
||||||
|
- Show you the hash to copy to your .env file
|
||||||
|
- Verify the hash works correctly
|
||||||
|
|
||||||
|
## Docker Usage
|
||||||
|
|
||||||
|
If you're using Docker, you can run the password generator inside the container:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# Method 1: Quick hash
|
||||||
|
docker exec -it minio-webui-backend npm run hash-password YourPassword123!
|
||||||
|
|
||||||
|
# Method 2: Interactive
|
||||||
|
docker exec -it minio-webui-backend npm run generate-password
|
||||||
|
```
|
||||||
|
|
||||||
|
## Password Requirements
|
||||||
|
|
||||||
|
Your password should meet these criteria:
|
||||||
|
- Minimum 8 characters
|
||||||
|
- At least one uppercase letter (A-Z)
|
||||||
|
- At least one lowercase letter (a-z)
|
||||||
|
- At least one number (0-9)
|
||||||
|
- At least one special character (!@#$%^&* etc.)
|
||||||
|
|
||||||
|
## Example Passwords
|
||||||
|
|
||||||
|
Good passwords:
|
||||||
|
- `MySecure@Pass123`
|
||||||
|
- `Admin#2024!Strong`
|
||||||
|
- `MinIO$WebUI&Safe99`
|
||||||
|
|
||||||
|
## Step-by-Step Instructions
|
||||||
|
|
||||||
|
1. **Navigate to backend directory:**
|
||||||
|
```bash
|
||||||
|
cd backend
|
||||||
|
```
|
||||||
|
|
||||||
|
2. **Generate your password hash:**
|
||||||
|
```bash
|
||||||
|
npm run hash-password MyChosenPassword123!
|
||||||
|
```
|
||||||
|
|
||||||
|
3. **Copy the output** (it will look like this):
|
||||||
|
```
|
||||||
|
ADMIN_PASSWORD_HASH=$2b$12$abcdefghijklmnopqrstuvwxyz...
|
||||||
|
```
|
||||||
|
|
||||||
|
4. **Add to your .env file:**
|
||||||
|
```bash
|
||||||
|
# Edit your .env file
|
||||||
|
nano ../.env
|
||||||
|
|
||||||
|
# Or append directly
|
||||||
|
echo "ADMIN_PASSWORD_HASH=\$2b\$12\$your_hash_here" >> ../.env
|
||||||
|
```
|
||||||
|
|
||||||
|
5. **Restart the backend:**
|
||||||
|
```bash
|
||||||
|
# If using Docker
|
||||||
|
docker-compose restart backend
|
||||||
|
|
||||||
|
# If running locally
|
||||||
|
npm start
|
||||||
|
```
|
||||||
|
|
||||||
|
## Troubleshooting
|
||||||
|
|
||||||
|
### "bcrypt: command not found"
|
||||||
|
|
||||||
|
The script uses the Node.js bcrypt library, not the system bcrypt. Make sure you're in the backend directory and have run `npm install`.
|
||||||
|
|
||||||
|
### "Cannot find module 'bcrypt'"
|
||||||
|
|
||||||
|
Install dependencies first:
|
||||||
|
```bash
|
||||||
|
cd backend
|
||||||
|
npm install
|
||||||
|
```
|
||||||
|
|
||||||
|
### Hash not working
|
||||||
|
|
||||||
|
1. Make sure you copied the entire hash including the `$2b$12$` prefix
|
||||||
|
2. Check for any extra spaces or line breaks
|
||||||
|
3. Ensure the .env file is in the project root directory
|
||||||
|
4. Try generating a new hash
|
||||||
|
|
||||||
|
### Special characters in password
|
||||||
|
|
||||||
|
If your password contains special shell characters, wrap it in single quotes:
|
||||||
|
```bash
|
||||||
|
npm run hash-password 'My$uper!Pass@123'
|
||||||
|
```
|
||||||
|
|
||||||
|
## Security Notes
|
||||||
|
|
||||||
|
1. **Never commit your .env file** to version control
|
||||||
|
2. **Use strong passwords** - the hash is only as secure as your password
|
||||||
|
3. **Change default passwords** immediately in production
|
||||||
|
4. **Store .env securely** with appropriate file permissions:
|
||||||
|
```bash
|
||||||
|
chmod 600 .env
|
||||||
|
```
|
||||||
|
|
||||||
|
## Advanced Usage
|
||||||
|
|
||||||
|
### Custom Salt Rounds
|
||||||
|
|
||||||
|
The scripts use 12 salt rounds by default (recommended). If you need to change this, edit the script:
|
||||||
|
|
||||||
|
```javascript
|
||||||
|
const saltRounds = 12; // Change this value if needed
|
||||||
|
```
|
||||||
|
|
||||||
|
Higher numbers are more secure but slower to compute.
|
||||||
|
|
||||||
|
### Verify a Hash
|
||||||
|
|
||||||
|
To verify if a password matches a hash:
|
||||||
|
|
||||||
|
```javascript
|
||||||
|
// In Node.js
|
||||||
|
const bcrypt = require('bcrypt');
|
||||||
|
const isValid = await bcrypt.compare('YourPassword', '$2b$12$...');
|
||||||
|
console.log(isValid); // true or false
|
||||||
|
```
|
||||||
|
|
||||||
|
## Integration with MinIO WebUI
|
||||||
|
|
||||||
|
Once you've set the `ADMIN_PASSWORD_HASH` in your .env file:
|
||||||
|
|
||||||
|
1. Start/restart the application
|
||||||
|
2. Navigate to the login page
|
||||||
|
3. Username: `admin` (fixed)
|
||||||
|
4. Password: The password you used to generate the hash
|
||||||
|
|
||||||
|
The application will compare your entered password with the stored hash for authentication.
|
||||||
Executable
+76
@@ -0,0 +1,76 @@
|
|||||||
|
#!/usr/bin/env node
|
||||||
|
|
||||||
|
const bcrypt = require('bcrypt');
|
||||||
|
const readline = require('readline');
|
||||||
|
|
||||||
|
// Colors for console output
|
||||||
|
const colors = {
|
||||||
|
reset: '\x1b[0m',
|
||||||
|
green: '\x1b[32m',
|
||||||
|
yellow: '\x1b[33m',
|
||||||
|
blue: '\x1b[36m',
|
||||||
|
red: '\x1b[31m'
|
||||||
|
};
|
||||||
|
|
||||||
|
const rl = readline.createInterface({
|
||||||
|
input: process.stdin,
|
||||||
|
output: process.stdout
|
||||||
|
});
|
||||||
|
|
||||||
|
// Hide password input
|
||||||
|
rl._writeToOutput = function _writeToOutput(stringToWrite) {
|
||||||
|
if (rl.stdoutMuted)
|
||||||
|
rl.output.write("*");
|
||||||
|
else
|
||||||
|
rl.output.write(stringToWrite);
|
||||||
|
};
|
||||||
|
|
||||||
|
console.log(`${colors.blue}=== MinIO WebUI Password Hash Generator ===${colors.reset}\n`);
|
||||||
|
|
||||||
|
rl.question('Enter the password you want to hash: ', async (password) => {
|
||||||
|
rl.stdoutMuted = true;
|
||||||
|
|
||||||
|
if (!password || password.length === 0) {
|
||||||
|
console.log(`\n${colors.red}Error: Password cannot be empty${colors.reset}`);
|
||||||
|
rl.close();
|
||||||
|
process.exit(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
console.log(`\n${colors.yellow}Generating hash...${colors.reset}`);
|
||||||
|
|
||||||
|
// Use the same salt rounds as in the application (default is 10)
|
||||||
|
const saltRounds = 12;
|
||||||
|
const hash = await bcrypt.hash(password, saltRounds);
|
||||||
|
|
||||||
|
console.log(`\n${colors.green}✓ Password hash generated successfully!${colors.reset}\n`);
|
||||||
|
console.log('Add this to your .env file:');
|
||||||
|
console.log(`${colors.yellow}ADMIN_PASSWORD_HASH=${hash}${colors.reset}`);
|
||||||
|
|
||||||
|
// Verify the hash works
|
||||||
|
const verifyResult = await bcrypt.compare(password, hash);
|
||||||
|
if (verifyResult) {
|
||||||
|
console.log(`\n${colors.green}✓ Hash verification successful${colors.reset}`);
|
||||||
|
} else {
|
||||||
|
console.log(`\n${colors.red}✗ Hash verification failed${colors.reset}`);
|
||||||
|
}
|
||||||
|
|
||||||
|
console.log('\nPassword requirements:');
|
||||||
|
console.log('- Minimum 8 characters');
|
||||||
|
console.log('- At least one uppercase letter');
|
||||||
|
console.log('- At least one lowercase letter');
|
||||||
|
console.log('- At least one number');
|
||||||
|
console.log('- At least one special character');
|
||||||
|
|
||||||
|
} catch (error) {
|
||||||
|
console.error(`\n${colors.red}Error generating hash:${colors.reset}`, error.message);
|
||||||
|
process.exit(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
rl.close();
|
||||||
|
});
|
||||||
|
|
||||||
|
rl.on('close', () => {
|
||||||
|
console.log(`\n${colors.blue}Done!${colors.reset}`);
|
||||||
|
process.exit(0);
|
||||||
|
});
|
||||||
@@ -9,7 +9,9 @@
|
|||||||
"dev:node": "node --watch src/app.js",
|
"dev:node": "node --watch src/app.js",
|
||||||
"test": "jest --coverage",
|
"test": "jest --coverage",
|
||||||
"lint": "eslint src/",
|
"lint": "eslint src/",
|
||||||
"lint:fix": "eslint src/ --fix"
|
"lint:fix": "eslint src/ --fix",
|
||||||
|
"hash-password": "node scripts/hash-password.js",
|
||||||
|
"generate-password": "node generate-password.js"
|
||||||
},
|
},
|
||||||
"keywords": ["minio", "api", "backend"],
|
"keywords": ["minio", "api", "backend"],
|
||||||
"author": "",
|
"author": "",
|
||||||
|
|||||||
@@ -0,0 +1,23 @@
|
|||||||
|
const bcrypt = require('bcrypt');
|
||||||
|
|
||||||
|
const password = process.argv[2];
|
||||||
|
|
||||||
|
if (!password) {
|
||||||
|
console.error('Usage: npm run hash-password <your-password>');
|
||||||
|
console.error('Example: npm run hash-password MySecurePass123!');
|
||||||
|
process.exit(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
async function hashPassword() {
|
||||||
|
try {
|
||||||
|
const hash = await bcrypt.hash(password, 12);
|
||||||
|
console.log('\n=== Generated Password Hash ===');
|
||||||
|
console.log(`ADMIN_PASSWORD_HASH=${hash}`);
|
||||||
|
console.log('\nCopy the above line to your .env file');
|
||||||
|
} catch (error) {
|
||||||
|
console.error('Error:', error.message);
|
||||||
|
process.exit(1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
hashPassword();
|
||||||
Reference in New Issue
Block a user