5.8 KiB
5.8 KiB
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
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:
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_nameupdateUserProfile(id, updates)- Update user profile (display_name)updateUserPassword(id, hashedPassword)- Update user passwordgetUserPasswordHash(id)- Get current password hash for verification
New Controllers (backend/controllers/users.controller.js)
getCurrentUser- GET authenticated user's profileupdateCurrentUser- 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 profilePATCH /api/users/me- Update display namePOST /api/users/me/change-password- Change password
Request bodies:
// 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 profileupdateCurrentUser(display_name)- Update display namechangePassword(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
- Navigate to Settings → Account tab
- Change Display Name:
- Enter new display name (1-100 chars)
- Click "Save Display Name"
- Change Password:
- Enter current password
- Enter new password (min 6 chars)
- Confirm new password
- Click "Change Password"
For Developers
Testing the endpoints:
# 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
- Password strength indicator - Visual feedback on password complexity
- Display name in navbar - Show display_name instead of username in UI
- Email verification - Add email field and verification
- 2FA support - Two-factor authentication option
- Password history - Prevent reusing recent passwords
- 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