# Account Management Implementation (Phase 4) ## Overview Phase 4 adds account management features allowing users to: - Change their display name (friendly name separate from username) - Change their password with current password verification ## Database Changes ### Migration: `add_display_name_column.sql` ```sql ALTER TABLE users ADD COLUMN IF NOT EXISTS display_name VARCHAR(100); UPDATE users SET display_name = name WHERE display_name IS NULL; ``` **To run migration:** Connect to your PostgreSQL database and execute: ```bash psql -U your_user -d your_database -f backend/migrations/add_display_name_column.sql ``` ## Backend Implementation ### New Model Functions (`backend/models/user.model.js`) - `getUserById(id)` - Fetch user by ID including display_name - `updateUserProfile(id, updates)` - Update user profile (display_name) - `updateUserPassword(id, hashedPassword)` - Update user password - `getUserPasswordHash(id)` - Get current password hash for verification ### New Controllers (`backend/controllers/users.controller.js`) - `getCurrentUser` - GET authenticated user's profile - `updateCurrentUser` - PATCH user's display name - Validates: 1-100 characters, trims whitespace - `changePassword` - POST password change - Validates: current password correct, new password min 6 chars, passwords match - Uses bcrypt for password verification and hashing ### New Routes (`backend/routes/users.routes.js`) All routes require authentication (`auth` middleware): - `GET /api/users/me` - Get current user profile - `PATCH /api/users/me` - Update display name - `POST /api/users/me/change-password` - Change password **Request bodies:** ```javascript // Update display name PATCH /api/users/me { "display_name": "New Display Name" } // Change password POST /api/users/me/change-password { "current_password": "oldpass123", "new_password": "newpass123" } ``` ## Frontend Implementation ### API Functions (`frontend/src/api/users.js`) - `getCurrentUser()` - Fetch current user profile - `updateCurrentUser(display_name)` - Update display name - `changePassword(current_password, new_password)` - Change password ### Settings Page Updates (`frontend/src/pages/Settings.jsx`) Added new "Account" tab with two sections: **Display Name Section:** - Input field with character counter (max 100) - Real-time validation - Save button with loading state **Password Change Section:** - Current password field - New password field (min 6 chars) - Confirm password field - Client-side validation before submission - Loading state during submission **Features:** - Success/error messages displayed at top of tab - Form validation (character limits, password matching) - Disabled buttons during API calls - Auto-clears password fields on success ### Styling (`frontend/src/styles/pages/Settings.css`) Added: - `.account-form` - Form container styling - `.account-message` - Success/error message styling - `.account-message.success` - Green success messages - `.account-message.error` - Red error messages ## Security Features ### Password Requirements - **Backend validation:** - Minimum 6 characters - Current password verification before change - bcrypt hashing (10 rounds) - **Frontend validation:** - HTML5 minlength attribute - Client-side password matching check - Current password required ### Display Name Validation - **Backend:** - 1-100 character limit - Whitespace trimming - **Frontend:** - HTML5 maxlength attribute - Character counter ## Usage ### For Users 1. Navigate to Settings → Account tab 2. **Change Display Name:** - Enter new display name (1-100 chars) - Click "Save Display Name" 3. **Change Password:** - Enter current password - Enter new password (min 6 chars) - Confirm new password - Click "Change Password" ### For Developers **Testing the endpoints:** ```bash # Get current user curl -X GET http://localhost:5000/api/users/me \ -H "Authorization: Bearer YOUR_TOKEN" # Update display name curl -X PATCH http://localhost:5000/api/users/me \ -H "Authorization: Bearer YOUR_TOKEN" \ -H "Content-Type: application/json" \ -d '{"display_name": "New Name"}' # Change password curl -X POST http://localhost:5000/api/users/me/change-password \ -H "Authorization: Bearer YOUR_TOKEN" \ -H "Content-Type: application/json" \ -d '{ "current_password": "oldpass", "new_password": "newpass" }' ``` ## Next Steps ### Optional Enhancements 1. **Password strength indicator** - Visual feedback on password complexity 2. **Display name in navbar** - Show display_name instead of username in UI 3. **Email verification** - Add email field and verification 4. **2FA support** - Two-factor authentication option 5. **Password history** - Prevent reusing recent passwords 6. **Session management** - View/revoke active sessions ### Integration with AuthContext Consider updating `AuthContext` to: - Store and expose display_name - Refresh user data after profile updates - Show display_name in navbar/profile components ## Files Modified ### Backend - ✅ `backend/migrations/add_display_name_column.sql` (NEW) - ✅ `backend/models/user.model.js` - ✅ `backend/controllers/users.controller.js` - ✅ `backend/routes/users.routes.js` ### Frontend - ✅ `frontend/src/api/users.js` - ✅ `frontend/src/pages/Settings.jsx` - ✅ `frontend/src/styles/pages/Settings.css` ## Testing Checklist - [ ] Run database migration - [ ] Test GET /api/users/me endpoint - [ ] Test display name update with valid data - [ ] Test display name update with invalid data (empty, too long) - [ ] Test password change with correct current password - [ ] Test password change with incorrect current password - [ ] Test password change with mismatched new passwords - [ ] Test password change with weak password (< 6 chars) - [ ] Verify frontend validation prevents invalid submissions - [ ] Verify success/error messages display correctly - [ ] Test UI responsiveness on mobile