Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
27 changes: 23 additions & 4 deletions backend/controller/user.controller.js
Original file line number Diff line number Diff line change
Expand Up @@ -44,30 +44,49 @@ const updatelanguage = expressAsyncHandler(async (req, res) => {
const registeruser = expressAsyncHandler (async (req,res) => {
const {name,email,password,pic} = req.body

// Validate required fields
if (!name || !email || !password) {
return res.status(400).json({ success: false, message: "Please provide all fields" });
}

if (name.length < 2 || name.length > 50) {
// Validate name length
const trimmedName = name.trim();
if (trimmedName.length < 2 || trimmedName.length > 50) {
return res.status(400).json({ success: false, message: "Name must be between 2 and 50 characters" });
}

// Validate email format
const emailRegex = /^[^\s@]+@[^\s@]+\.[^\s@]+$/;
if (!emailRegex.test(email)) {
const trimmedEmail = email.trim().toLowerCase();
if (!emailRegex.test(trimmedEmail)) {
return res.status(400).json({ success: false, message: "Please provide a valid email address" });
}

// Validate password strength
if (password.length < 6) {
return res.status(400).json({ success: false, message: "Password must be at least 6 characters long" });
}

// Additional password validation: check for at least one letter and one number
if (!/(?=.*[a-zA-Z])(?=.*\d)/.test(password)) {
return res.status(400).json({ success: false, message: "Password must contain at least one letter and one number" });
}


const userExists = await User.findOne({email})
// Check if user already exists
const userExists = await User.findOne({ email: trimmedEmail })

if(userExists) {
return res.status(409).json({ success: false, message: "User already exists" });
}
const user = await User.create({name, email, password,pic})

// Create new user with trimmed and normalized data
const user = await User.create({
name: trimmedName,
email: trimmedEmail,
password,
pic: pic || undefined
})

if(user){
res.status(201).json({
Expand Down
66 changes: 62 additions & 4 deletions frontend/src/lib/utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,14 +5,72 @@ export function cn(...inputs: ClassValue[]) {
return twMerge(clsx(inputs));
}

/**
* Get user profile pictures from a chat
* @param chat - The chat object containing users
* @param currentUserId - The ID of the current user to exclude
* @returns Array of user profile picture URLs
*/
export function getUserPics(chat, currentUserId) {
if (!chat?.users) return [];
if (!chat?.users || !Array.isArray(chat.users)) return [];

const otherUsers = chat.users.filter(user => user?._id?.toString() !== currentUserId?.toString());
const otherUsers = chat.users.filter(user => {
if (!user?._id) return false;
return user._id.toString() !== currentUserId?.toString();
});

if (chat.isGroupChat) {
return otherUsers.slice(0, 3).map(user => user?.pic).filter(Boolean);
// For group chats, return up to 3 user pics
return otherUsers
.slice(0, 3)
.map(user => user?.pic)
.filter(Boolean);
} else {
return otherUsers.length > 0 && otherUsers[0]?.pic ? [otherUsers[0].pic] : [];
// For one-on-one chats, return the other user's pic
return otherUsers.length > 0 && otherUsers[0]?.pic
? [otherUsers[0].pic]
: [];
}
}

/**
* Validate email format
* @param email - Email string to validate
* @returns Boolean indicating if email is valid
*/
export function isValidEmail(email) {
if (!email || typeof email !== 'string') return false;
const emailRegex = /^[^\s@]+@[^\s@]+\.[^\s@]+$/;
return emailRegex.test(email.trim());
}

/**
* Format file size to human-readable format
* @param bytes - File size in bytes
* @returns Formatted string (e.g., "1.5 MB")
*/
export function formatFileSize(bytes) {
if (!bytes || bytes === 0) return '0 Bytes';
const k = 1024;
const sizes = ['Bytes', 'KB', 'MB', 'GB'];
const i = Math.floor(Math.log(bytes) / Math.log(k));
return Math.round((bytes / Math.pow(k, i)) * 100) / 100 + ' ' + sizes[i];
}

/**
* Debounce function to limit function calls
* @param func - Function to debounce
* @param wait - Wait time in milliseconds
* @returns Debounced function
*/
export function debounce(func, wait) {
let timeout;
return function executedFunction(...args) {
const later = () => {
clearTimeout(timeout);
func(...args);
};
clearTimeout(timeout);
timeout = setTimeout(later, wait);
};
}
Loading