costco-grocery-list/ACCOUNT_MANAGEMENT_IMPLEMENTATION.md
Nico 1281c91c28
All checks were successful
Build & Deploy Costco Grocery List / build (push) Successful in 13s
Build & Deploy Costco Grocery List / deploy (push) Successful in 6s
Build & Deploy Costco Grocery List / notify (push) Successful in 1s
add password and display name manipulation
2026-01-24 21:38:33 -08:00

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_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:

// 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:

# 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