Enhance DJ management with password reset and deactivation features

This commit introduces the ability to reset user passwords, both temporary and permanent, within the DJ management interface. It also adds soft deactivation and hard deletion options for users. The InvitationManagement component has been updated to improve clarity and user experience during the user creation process. Backend changes include password hashing using bcrypt, new API endpoints for status checks and password management, and modifications to storage functions to handle sanitized user data and password verification.

Replit-Commit-Author: Agent
Replit-Commit-Session-Id: 3a22ac80-cd1d-4441-9e36-f24fc2f4c3de
Replit-Commit-Checkpoint-Type: full_checkpoint
Replit-Commit-Screenshot-Url: https://storage.googleapis.com/screenshot-production-us-central1/3478f7c3-db8c-4fca-9165-3adbdf1b5829/3a22ac80-cd1d-4441-9e36-f24fc2f4c3de/Yn4xAWn
This commit is contained in:
spliceboti
2025-09-12 21:18:07 +00:00
parent 60b5735588
commit 4e17b6d5c3
8 changed files with 460 additions and 77 deletions
+32 -2
View File
@@ -613,7 +613,7 @@ export async function registerRoutes(app: Express): Promise<Server> {
res.json({
message: "User created successfully",
user: { ...user, tempPassword: undefined } // Don't send password back
user
});
} catch (error) {
console.error("Error creating user manually:", error);
@@ -628,6 +628,12 @@ export async function registerRoutes(app: Express): Promise<Server> {
if (!password) {
return res.status(400).json({ message: "Password is required" });
}
// Basic password strength validation
if (password.length < 8) {
return res.status(400).json({ message: "Password must be at least 8 characters long" });
}
await storage.setUserPassword(req.params.id, password, isTemporary || false);
res.json({ message: "Password updated successfully" });
} catch (error) {
@@ -658,7 +664,31 @@ export async function registerRoutes(app: Express): Promise<Server> {
}
});
// Get user active status
// Get user status (for frontend to check password status without exposing passwords)
app.get('/api/users/:id/status', isAuthenticated, async (req: any, res) => {
try {
const userId = req.user.claims.sub;
const targetUserId = req.params.id;
const user = await storage.getUser(userId);
// Allow users to check their own status or admins to check any status
if (userId !== targetUserId && user?.role !== "admin") {
return res.status(403).json({ message: "Permission denied" });
}
const status = await storage.getUserStatus(targetUserId);
res.json({
isActive: status.derivedActive,
hasPassword: status.hasPassword,
needsPasswordChange: status.needsPasswordChange
});
} catch (error) {
console.error("Error getting user status:", error);
res.status(500).json({ message: "Failed to get user status" });
}
});
// Get user active status (admin only)
app.get('/api/users/:id/active-status', isAuthenticated, isAdmin, async (req, res) => {
try {
const isActive = await storage.getUserActiveStatus(req.params.id);