fix: high-severity findings from code audit

- backend/photos: whitelist sortable columns instead of getattr(Photo, sort).
  Previously any client-supplied string was passed to SQLAlchemy, exposing
  every Photo attribute (filepath, file_hash, etc.) as a sort target.
- App: move the auto-show-right-sidebar logic out of the render body and
  into a useEffect. The previous version called setState during render,
  causing extra re-render passes the audit caught.
- types/photo: add added_at and tighten folder_id from optional to nullable.
  Drops a (photo as any).added_at cast in Timeline.
- constants/colorLabels: extract a single COLOR_LABEL_OPTIONS used by
  FilterBar, RightSidebar, and PhotoInfoPanel. filterStore re-exports the
  ColorLabel type so existing imports keep working.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
2026-04-08 20:18:19 +02:00
parent 07b9660e92
commit 749e836617
9 changed files with 50 additions and 42 deletions

View File

@@ -7,17 +7,7 @@ import { useActiveHeapMembers } from '../../hooks/useActiveHeapMembersQuery'
import { HEAPS_QUERY_KEY } from '../../hooks/useHeapsQuery'
import { toast } from '../ToastContainer'
import { PhotoInfoPanel } from '../sidebar/PhotoInfoPanel'
type ColorLabel = 'red' | 'orange' | 'yellow' | 'green' | 'blue' | 'purple'
const COLOR_LABEL_OPTIONS: { value: ColorLabel; className: string }[] = [
{ value: 'red', className: 'bg-red-500' },
{ value: 'orange', className: 'bg-orange-500' },
{ value: 'yellow', className: 'bg-yellow-400' },
{ value: 'green', className: 'bg-green-500' },
{ value: 'blue', className: 'bg-blue-500' },
{ value: 'purple', className: 'bg-purple-500' },
]
import { COLOR_LABEL_OPTIONS } from '../../constants/colorLabels'
/**
* Right-hand details panel.