feat: Add Scripts for listing users and resetting passwords (#5438)

*  feat: Add user management scripts for listing users and resetting passwords

* chore: update package.json

---------

Co-authored-by: Danny Avila <danacordially@gmail.com>
This commit is contained in:
JM Addington 2025-01-31 07:40:06 -05:00 committed by GitHub
parent 6f0ded058f
commit 9373f77bb7
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
3 changed files with 101 additions and 0 deletions

31
config/list-users.js Normal file
View file

@ -0,0 +1,31 @@
const path = require('path');
require('module-alias')({ base: path.resolve(__dirname, '..', 'api') });
const { askQuestion, silentExit } = require('./helpers');
const connect = require('./connect');
const User = require('../api/models/User');
const listUsers = async () => {
try {
await connect();
const users = await User.find({}, 'email provider avatar username name createdAt');
console.log('\nUser List:');
console.log('----------------------------------------');
users.forEach(user => {
console.log(`Email: ${user.email}`);
console.log(`Username: ${user.username || 'N/A'}`);
console.log(`Name: ${user.name || 'N/A'}`);
console.log(`Provider: ${user.provider || 'email'}`);
console.log(`Created: ${user.createdAt}`);
console.log('----------------------------------------');
});
console.log(`\nTotal Users: ${users.length}`);
process.exit(0);
} catch (err) {
console.error('Error listing users:', err);
process.exit(1);
}
};
listUsers();

68
config/reset-password.js Normal file
View file

@ -0,0 +1,68 @@
const path = require('path');
require('module-alias')({ base: path.resolve(__dirname, '..', 'api') });
const { askQuestion, silentExit } = require('./helpers');
const connect = require('./connect');
const User = require('../api/models/User');
const bcrypt = require('bcryptjs');
const readline = require('readline');
const rl = readline.createInterface({
input: process.stdin,
output: process.stdout
});
const question = (query) => new Promise((resolve) => rl.question(query, resolve));
const resetPassword = async () => {
try {
await connect();
const email = await question('Enter user email: ');
const user = await User.findOne({ email });
if (!user) {
console.error('User not found!');
process.exit(1);
}
let validPassword = false;
let newPassword;
while (!validPassword) {
newPassword = await question('Enter new password: ');
if (newPassword.length < 8) {
console.log('Password must be at least 8 characters! Please try again.');
continue;
}
const confirmPassword = await question('Confirm new password: ');
if (newPassword !== confirmPassword) {
console.log('Passwords do not match! Please try again.');
continue;
}
validPassword = true;
}
const salt = await bcrypt.genSalt(10);
const hashedPassword = await bcrypt.hash(newPassword, salt);
await User.updateOne(
{ email },
{
password: hashedPassword,
passwordVersion: Date.now() // Invalidate old sessions
}
);
console.log('Password successfully reset!');
process.exit(0);
} catch (err) {
console.error('Error resetting password:', err);
process.exit(1);
} finally {
rl.close();
}
};
resetPassword();

View file

@ -28,6 +28,8 @@
"upgrade": "node config/upgrade.js",
"create-user": "node config/create-user.js",
"invite-user": "node config/invite-user.js",
"list-users": "node config/list-users.js",
"reset-password": "node config/reset-password.js",
"ban-user": "node config/ban-user.js",
"delete-user": "node config/delete-user.js",
"update-banner": "node config/update-banner.js",