# Fix authentication issues and improve developer experience
## Summary
This MR fixes critical authentication issues that prevented login on localhost and improves the developer experience with consolidated rebuild scripts and a working help modal keyboard shortcut.
## Problems Fixed
### 1. Authentication Issues
- **UntrustedHost Error**: NextAuth v5 was rejecting localhost requests with "UntrustedHost: Host must be trusted" error
- **Cookie Prefix Errors**: Cookies were being set with `__Host-` and `__Secure-` prefixes on HTTP (localhost), causing browser rejection
- **MissingCSRF Error**: CSRF token cookies were not being set correctly due to cookie configuration issues
### 2. Help Modal Keyboard Shortcut
- **Shift+? not working**: The help modal keyboard shortcut was not detecting the question mark key correctly
### 3. Developer Experience
- **Multiple rebuild scripts**: Had several overlapping rebuild scripts that were confusing
- **Unused code**: Removed unused `useSecureCookies` variable and misleading comments
## Changes Made
### Authentication Fixes (`lib/auth.ts`)
- Set `trustHost: true` to fix UntrustedHost error (required for NextAuth v5)
- Added explicit cookie configuration for HTTP (localhost) to prevent prefix errors:
- Cookies use `secure: false` for HTTP
- Cookie names without prefixes for HTTP
- Let Auth.js defaults handle HTTPS (with prefixes and Secure flag)
- Removed unused `useSecureCookies` variable
- Simplified debug logging
### Help Modal Fix (`components/HelpModal.tsx`)
- Fixed keyboard shortcut detection to properly handle Shift+? (Shift+/)
- Updated help text to show correct shortcut (Shift+? instead of Ctrl+?)
### Developer Scripts
- **Consolidated rebuild scripts**: Merged `CLEAN_REBUILD.sh`, `FIX_AND_RESTART.sh`, and `start-server.sh` into single `rebuild.sh`
- **Added REBUILD.md**: Documentation for rebuild process
- Removed redundant script files
### Code Cleanup
- Removed unused `useSecureCookies` variable from `lib/auth.ts`
- Removed misleading comment from `app/api/auth/[...nextauth]/route.ts`
- Cleaned up verbose debug logging
## Technical Details
### Cookie Configuration
The fix works by explicitly configuring cookies for HTTP environments:
- **HTTP (localhost)**: Cookies without prefixes, `secure: false`
- **HTTPS (production)**: Let Auth.js defaults handle (prefixes + Secure flag)
This prevents NextAuth v5 from auto-detecting HTTPS from proxy headers and incorrectly adding cookie prefixes.
### Keyboard Shortcut
The question mark key requires Shift+/ on most keyboards. The fix now properly detects:
- `event.shiftKey && event.key === "/"`
- `event.key === "?"` (fallback)
- `event.code === "Slash" && event.shiftKey` (additional fallback)
## Testing
- ✅ Login works on localhost (http://localhost:3000)
- ✅ No cookie prefix errors in browser console
- ✅ No UntrustedHost errors in server logs
- ✅ Help modal opens/closes with Shift+?
- ✅ Rebuild script works in both dev and prod modes
## Files Changed
### Modified
- `lib/auth.ts` - Authentication configuration fixes
- `components/HelpModal.tsx` - Keyboard shortcut fix
- `app/api/auth/[...nextauth]/route.ts` - Removed misleading comment
### Added
- `rebuild.sh` - Consolidated rebuild script
- `REBUILD.md` - Rebuild documentation
## Migration Notes
No database migrations or environment variable changes required. The fix works with existing configuration.
## Related Issues
Fixes authentication issues preventing local development and testing.
Reviewed-on: #5
# Photo Management and Game Features
## Summary
This PR adds comprehensive photo management features, duplicate detection, attempt limits, penalty system improvements, and admin photo deletion capabilities to the MirrorMatch application.
## Features Added
### 1. Duplicate Photo Detection
- **File-based duplicates**: Calculates SHA256 hash of uploaded files to detect duplicate content
- **URL-based duplicates**: Checks for duplicate photo URLs
- Prevents users from uploading the same photo multiple times
- Returns HTTP 409 (Conflict) with clear error messages
### 2. Maximum Attempts Per Photo
- Uploaders can set a maximum number of guesses allowed per user for each photo
- Default: unlimited (null or 0)
- UI displays remaining attempts counter
- API enforces attempt limits before allowing guesses
- Shows warning message when max attempts reached
### 3. Penalty System Improvements
- **Simplified UI**: Removed checkbox - penalty automatically enabled when penalty points > 0
- **Score protection**: Scores cannot go below 0, even with large penalties
- If penalty would result in negative score, only deducts available points and sets to 0
### 4. Admin Photo Deletion
- Admins can delete photos from:
- Photos list page (hover to reveal delete icon)
- Individual photo detail page (delete button in header)
- Deletes associated guesses automatically
- Deletes local uploaded files from filesystem
- Confirmation dialog before deletion
- Proper error handling and user feedback
### 5. Navigation Improvements
- Logout button always visible in side menu (hamburger menu)
- Improved side menu layout with fixed footer for logout button
- Better mobile responsiveness
### 6. Self-Guess Prevention
- Users cannot guess on their own uploaded photos
- Shows informative message with answer for photo owners
## Technical Changes
### Database Schema
- Added `fileHash` field (String?) to Photo model for duplicate detection
- Added `maxAttempts` field (Int?) to Photo model for attempt limits
- Added indexes on `url` and `fileHash` for performance
### API Routes
- `POST /api/photos/upload-multiple`: Enhanced with duplicate checking and maxAttempts
- `POST /api/photos/[photoId]/guess`: Added maxAttempts enforcement and score floor protection
- `DELETE /api/photos/[photoId]`: New route for admin photo deletion
### Components
- `DeletePhotoButton`: New reusable component for photo deletion
- Updated upload form to remove penalty checkbox
- Enhanced photo display pages with attempt counters and admin controls
## Database Migrations
- Run `npm run db:push` to apply schema changes
- Run `npm run db:generate` to regenerate Prisma client
## Testing
- Test duplicate detection with same file and different filenames
- Test duplicate detection with same URL
- Test max attempts enforcement
- Test penalty system with various point values
- Test score floor (cannot go below 0)
- Test admin photo deletion
- Test self-guess prevention
## Breaking Changes
None - all changes are backward compatible. Existing photos will have `null` for `maxAttempts` (unlimited) and `fileHash` (for URL uploads).
Reviewed-on: #1
- Add duplicate photo detection (file hash and URL checking)
- Add max attempts per photo with UI counter
- Simplify penalty system (auto-enable when points > 0)
- Prevent scores from going below 0
- Add admin photo deletion functionality
- Improve navigation with always-visible logout
- Prevent users from guessing their own photos