feat: implement user profile system #40

Merged
addison merged 48 commits from feature/user-profile into main 2025-12-24 13:37:55 -05:00
Owner
  • Add theme persistence to database with localStorage migration
  • Create API endpoints for saving user settings and profile updates
  • Implement contact info management with dialog-based editing
  • Add /profile/edit page for profile editing
  • Add /profile/[user_id] page for viewing user profiles
  • Add /{vendor_id} route for public vendor profiles
  • Update dashboard with 'Edit Profile' quick action link
  • Add validation for vendor_id (alphanumeric + hyphens, 3-50 chars)
  • RLS policies enforce visibility rules for contact info
  • All features pass type-check, lint, and format checks
- Add theme persistence to database with localStorage migration - Create API endpoints for saving user settings and profile updates - Implement contact info management with dialog-based editing - Add /profile/edit page for profile editing - Add /profile/[user_id] page for viewing user profiles - Add /{vendor_id} route for public vendor profiles - Update dashboard with 'Edit Profile' quick action link - Add validation for vendor_id (alphanumeric + hyphens, 3-50 chars) - RLS policies enforce visibility rules for contact info - All features pass type-check, lint, and format checks
feat: implement user profile system with settings persistence
Some checks failed
CI / Unit Tests (pull_request) Failing after 1m37s
CI / Type Check (pull_request) Failing after 1m41s
CI / Lint (pull_request) Failing after 1m43s
CI / Format Check (pull_request) Failing after 2m3s
CI / E2E Tests (pull_request) Failing after 4m14s
d87cc15592
- Add theme persistence to database with localStorage migration
- Create API endpoints for saving user settings and profile updates
- Implement contact info management with dialog-based editing
- Add /profile/edit page for profile editing
- Add /profile/[user_id] page for viewing user profiles
- Add /{vendor_id} route for public vendor profiles
- Update dashboard with 'Edit Profile' quick action link
- Add validation for vendor_id (alphanumeric + hyphens, 3-50 chars)
- RLS policies enforce visibility rules for contact info
- All features pass type-check, lint, and format checks
refactor: dialog system
Some checks failed
CI / Unit Tests (pull_request) Failing after 16m4s
CI / Format Check (pull_request) Failing after 16m6s
CI / Type Check (pull_request) Failing after 16m8s
CI / Lint (pull_request) Failing after 16m10s
CI / E2E Tests (pull_request) Failing after 45s
bf7dd45d45
refactor: developer docs
Some checks failed
CI / Type Check (pull_request) Failing after 1m3s
CI / Format Check (pull_request) Failing after 1m15s
CI / Unit Tests (pull_request) Failing after 1m31s
CI / Lint (pull_request) Failing after 1m41s
CI / E2E Tests (pull_request) Failing after 1m24s
35f0819055
refactor: vendor profile pages
Some checks failed
CI / Lint (pull_request) Failing after 1m4s
CI / Format Check (pull_request) Failing after 1m22s
CI / Type Check (pull_request) Failing after 1m27s
CI / Unit Tests (pull_request) Failing after 1m50s
CI / E2E Tests (pull_request) Failing after 1m54s
90d06ccf9b
fix(storage): use signed URLs for avatar display on profile pages
Some checks failed
CI / Lint (pull_request) Failing after 1m19s
CI / Unit Tests (pull_request) Failing after 1m16s
CI / E2E Tests (pull_request) Failing after 14s
CI / Type Check (pull_request) Failing after 1m40s
CI / Format Check (pull_request) Failing after 1m51s
feec918b48
feat: improve profile buttons
Some checks failed
CI / Type Check (pull_request) Failing after 52s
CI / Lint (pull_request) Failing after 52s
CI / Format Check (pull_request) Failing after 48s
CI / E2E Tests (pull_request) Failing after 38s
CI / Unit Tests (pull_request) Failing after 1m28s
3cb816956f
fix: remove redundant contact info filtering from profile pages
Some checks failed
CI / Lint (pull_request) Failing after 1m5s
CI / E2E Tests (pull_request) Failing after 17s
CI / Unit Tests (pull_request) Failing after 1m21s
CI / Format Check (pull_request) Failing after 1m21s
CI / Type Check (pull_request) Failing after 1m22s
417585c980
RLS policies already enforce visibility at the database level. Remove
post-fetch filtering from both user profile and vendor pages to rely
entirely on RLS for security enforcement.
feat: add visibility badges to contact info on profile pages
Some checks failed
CI / Lint (pull_request) Failing after 41s
CI / Type Check (pull_request) Failing after 1m18s
CI / E2E Tests (pull_request) Failing after 50s
CI / Unit Tests (pull_request) Failing after 1m30s
CI / Format Check (pull_request) Failing after 1m59s
2287430d26
Display inline badges showing whether each contact is Public, Connections-only,
or Hidden. This clarifies visibility settings when users view their own profiles.
feat: add copy-to-clipboard buttons on contact info
Some checks failed
CI / Type Check (pull_request) Failing after 20s
CI / Format Check (pull_request) Failing after 17s
CI / E2E Tests (pull_request) Failing after 45s
CI / Lint (pull_request) Failing after 1m31s
CI / Unit Tests (pull_request) Failing after 1m9s
11e9e80b4d
Add CopyButton component that lets users quickly copy contact info on both
profile pages. Button shows hover tooltip and brief success feedback with
a checkmark icon when clicked.
Allow users to preview how their profile appears to different audiences:
- Myself (full access, including hidden contacts)
- A Connection (connections-only contacts visible)
- Public (public contacts only)

The selector only appears when viewing your own profile and uses RLS
policies to enforce correct visibility at the database level.
Instead of a separate FilteredContactInfo component, add viewAs prop
directly to ContactInfoSection for cleaner code. Now filtering is
handled server-side in the Astro component.
fix: no need for vendor ID on user profile page
Some checks failed
CI / Type Check (pull_request) Failing after 1m6s
CI / Format Check (pull_request) Failing after 1m16s
CI / Unit Tests (pull_request) Failing after 1m18s
CI / Lint (pull_request) Failing after 1m55s
CI / E2E Tests (pull_request) Failing after 1m33s
99b4a1dae9
fix: invite page
Some checks failed
CI / Unit Tests (pull_request) Failing after 38s
CI / Lint (pull_request) Failing after 48s
CI / Format Check (pull_request) Failing after 1m6s
CI / Type Check (pull_request) Failing after 1m22s
CI / E2E Tests (pull_request) Failing after 1m19s
82d0ebd44d
docs: wrapper pattern
Some checks failed
CI / Type Check (pull_request) Failing after 1m8s
CI / Lint (pull_request) Failing after 1m21s
CI / Unit Tests (pull_request) Failing after 1m16s
CI / Format Check (pull_request) Failing after 1m39s
CI / E2E Tests (pull_request) Failing after 1m13s
e4a1d98317
fix: address review feedback
Some checks failed
CI / Format Check (pull_request) Failing after 1m2s
CI / Type Check (pull_request) Failing after 1m17s
CI / Unit Tests (pull_request) Failing after 1m13s
CI / Lint (pull_request) Failing after 1m42s
CI / E2E Tests (pull_request) Failing after 1m27s
ed13b6fb1a
fix: address review feedback
Some checks failed
CI / Lint (pull_request) Failing after 14s
CI / Type Check (pull_request) Failing after 11s
CI / Format Check (pull_request) Failing after 10s
CI / Unit Tests (pull_request) Failing after 2s
CI / E2E Tests (pull_request) Failing after 3s
1d39fed260
test: validation
Some checks failed
CI / Format Check (pull_request) Failing after 59s
CI / Unit Tests (pull_request) Failing after 1m14s
CI / Lint (pull_request) Failing after 1m25s
CI / Type Check (pull_request) Failing after 1m54s
CI / E2E Tests (pull_request) Failing after 1m34s
69eb6d015e
spec: optimize onboarding
Some checks failed
CI / Type Check (pull_request) Failing after 18s
CI / Lint (pull_request) Failing after 1m13s
CI / Format Check (pull_request) Failing after 1m12s
CI / Unit Tests (pull_request) Failing after 1m20s
CI / E2E Tests (pull_request) Failing after 1m30s
e5f6feab87
- Avoid parsing error.message which is fragile and could leak information
- Use error.code directly for constraint violation detection (code 23505)
- Prevents potential security issue where error message format changes could cause bugs
- Remove response.statusText logging which varies and could leak server info
- Only log critical 5xx errors, silently handle auth/validation errors
- Theme is already saved locally so database failures are non-critical
- Don't rely solely on RLS policies for authorization
- Explicitly verify contact belongs to authenticated user before deletion
- Returns 404 if not found or user not authorized (prevents enumeration)
- Remove sessionStorage use for email in OTPForm (XSS vulnerable)
- Remove localStorage use for invite code in LoginForm
- Pass email and invite code via URL parameters instead
- More secure and doesn't expose data if browser is accessed by others
- Wrap event handlers (handleCodeChange, handleKeyDown, handlePaste) in useCallback
- Prevents stale closure issues and unnecessary re-renders
- Add theme loading on mount with AbortController cleanup
- Load theme before showing form to avoid FOUC
- Create abort controller for fetch operations
- Cancel pending requests when component unmounts
- Check aborted status before updating state to prevent memory leaks
- Ignore AbortError exceptions from cancelled requests
- Define ALLOWED_SETTINGS constant with 'theme', 'notifications', 'language'
- Validate setting_key against whitelist before upsert
- Prevents arbitrary setting injection attacks
- Returns clear error message with allowed values
- Replace loose regex with precise pattern: (optional +1)-(area)-(prefix)-(line)
- Supports formats: 1234567890, (123) 456-7890, 123-456-7890, +1 123 456 7890
- Prevents invalid patterns like '--+--+--' or leading spaces
- Clearer error message
- Change ALLOWED_SETTINGS from ['theme', 'notifications', 'language'] to ['theme']
- Only whitelist settings that are actually implemented
- Add comment to note where new settings should be registered
- Prevents future typos or unintended settings
- Check that stored contact_type matches enum values ('email', 'phone')
- Prevent silent failures from unexpected database values
- Return 500 error if corrupted contact record is found
- Logged in server error for debugging
- Validate vendor_id with regex /^[a-zA-Z0-9-]+$/ in vendor page
- Validate user_id as UUID format in profile page
- Redirect to home if validation fails instead of passing invalid values to DB
- Prevents invalid values from reaching database queries
- Wrap event handlers in useCallback to prevent stale closures
- Add proper dependency arrays for all handlers
- Prevents unnecessary re-renders and closures over stale state
- Use permissive character set with minimum 10 digits check
- Support formats: 123-456-7890, (123) 456-7890, +1 123 456 7890, +44 20 7946 0958
- Secondary validation checks digit count after removing non-digits
- More flexible than strict pattern matching
- Fix ViewAsSelector URL creation with window.location.href instead of Location object
- Add type assertions in DialogRenderer to satisfy discriminated union types
- Convert AstroCookies to empty Record for getPublicUrlServer compatibility
- Remove unused userId prop from ViewAsSelector component
- All type-check errors now resolved
- Remove _cookies parameter that was never used
- Simplifies function signature and calls
- Only cookieHeader was ever needed for the function logic
feat: add disable vendor profile button
Some checks failed
CI / Lint (pull_request) Failing after 1m5s
CI / Type Check (pull_request) Failing after 1m20s
CI / Format Check (pull_request) Failing after 1m17s
CI / Unit Tests (pull_request) Failing after 1m18s
CI / E2E Tests (pull_request) Failing after 5m44s
9db56dbcd2
- Add setValue import from useForm to enable clearing vendor_id
- Add "Disable Vendor Profile" button with danger variant
- Restructure vendor profile buttons into flex column layout
- Allow users to clear vendor_id and opt out of vendor profile
docs: improvements
Some checks failed
CI / Type Check (pull_request) Failing after 1m8s
CI / Format Check (pull_request) Failing after 1m7s
CI / Lint (pull_request) Failing after 1m11s
CI / Unit Tests (pull_request) Failing after 52s
CI / E2E Tests (pull_request) Failing after 1m14s
07330b7f83
docs: trim dialog docs
Some checks failed
CI / Lint (pull_request) Failing after 8s
CI / Format Check (pull_request) Failing after 12s
CI / Unit Tests (pull_request) Failing after 2m10s
CI / Type Check (pull_request) Successful in 3m2s
CI / E2E Tests (pull_request) Failing after 4m24s
39a791be6c
fix: default value
Some checks failed
CI / Lint (pull_request) Failing after 1m31s
CI / Type Check (pull_request) Failing after 1m30s
CI / Format Check (pull_request) Failing after 1m27s
CI / Unit Tests (pull_request) Successful in 1m29s
CI / E2E Tests (pull_request) Failing after 4m30s
251241ca55
- Rename getPublicUrlServer to getAvatarSignedUrl for clarity
- Add strict path validation using UUID and filename regex
- Prevents path traversal attacks (../, ./, special chars)
- Remove unnecessary cookieHeader parameter
- Add comprehensive unit tests (31 test cases)
- Tests cover valid paths, traversal attempts, UUID validation, filename validation
- Add 5 new security test cases ensuring items/ folder cannot be accessed
- Test direct item image path rejection
- Test message image path rejection
- Test path traversal attempts (../ sequences)
- Test mixed folder access attempts
- Brings total to 36 test cases
- All tests pass
chore: update pre-commit hooks to use just recipes
Some checks failed
CI / Unit Tests (pull_request) Failing after 1h47m2s
CI / Format Check (pull_request) Failing after 1h47m4s
CI / Type Check (pull_request) Failing after 1h47m6s
CI / Lint (pull_request) Failing after 1h47m9s
CI / E2E Tests (pull_request) Failing after 2m10s
57eec055c4
- Replace npm run scripts with just recipes
- format hook now runs: just format
- lint hook now runs: just lint
- Add test-unit-file recipe for running specific test files
- Consistency with project development workflow
chore: upgrade packages
Some checks failed
CI / Format Check (pull_request) Failing after 51s
CI / Type Check (pull_request) Failing after 1m2s
CI / Lint (pull_request) Failing after 1m5s
CI / Unit Tests (pull_request) Failing after 1m23s
CI / E2E Tests (pull_request) Failing after 1m21s
c0c6d1816c
addison changed title from feat: implement user profile system with settings persistence to feat: implement user profile system 2025-12-24 13:37:47 -05:00
addison deleted branch feature/user-profile 2025-12-24 13:37:55 -05:00
Sign in to join this conversation.
No reviewers
No labels
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set.

Reference
kwila/market!40
No description provided.