feat(auth): add real-time username/email availability validation

Backend changes:
- Added checkAvailability endpoint (GET /api/auth/check-availability)
- Checks username and email availability in database
- Returns availability status for both fields

Frontend changes:
- Added real-time validation for username (3+ characters) and email
- Debounced API calls (500ms) to avoid excessive requests
- Visual feedback with loading spinner, success checkmark, and error icons
- Improved UX by showing availability before form submission

This prevents users from submitting forms with already-taken credentials
and provides immediate feedback during registration.
This commit is contained in:
Radosław Gierwiało
2025-12-06 19:18:21 +01:00
parent fbca0c9e94
commit 71d22cc42e
4 changed files with 174 additions and 22 deletions

View File

@@ -660,6 +660,50 @@ async function resetPassword(req, res, next) {
}
}
// Check username/email availability (for real-time validation)
async function checkAvailability(req, res, next) {
try {
const { username, email } = req.query;
if (!username && !email) {
return res.status(400).json({
success: false,
error: 'Username or email is required',
});
}
const result = {
usernameAvailable: true,
emailAvailable: true,
};
// Check username availability
if (username) {
const existingUsername = await prisma.user.findUnique({
where: { username },
select: { id: true },
});
result.usernameAvailable = !existingUsername;
}
// Check email availability
if (email) {
const existingEmail = await prisma.user.findUnique({
where: { email },
select: { id: true },
});
result.emailAvailable = !existingEmail;
}
res.json({
success: true,
data: result,
});
} catch (error) {
next(error);
}
}
module.exports = {
register,
login,
@@ -668,4 +712,5 @@ module.exports = {
resendVerification,
requestPasswordReset,
resetPassword,
checkAvailability,
};

View File

@@ -6,7 +6,8 @@ const {
verifyEmailByCode,
resendVerification,
requestPasswordReset,
resetPassword
resetPassword,
checkAvailability
} = require('../controllers/auth');
const {
registerValidation,
@@ -39,4 +40,7 @@ router.post('/request-password-reset', emailLimiter, requestPasswordReset);
// POST /api/auth/reset-password - Reset password with token
router.post('/reset-password', passwordResetValidation, resetPassword);
// GET /api/auth/check-availability?username=xxx&email=xxx - Check username/email availability
router.get('/check-availability', checkAvailability);
module.exports = router;