- Simplify parseApkFilename to use version delimiter split
- Update tests to match new data structure with rawEnvironment
- Remove unnecessary test cases and assertions
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- Add rawEnvironment field to preserve extracted environment name
- Display rawEnvironment (e.g., 'timeshift') instead of 'other' in badge
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Update parseApkFilename call to include the version parameter,
allowing the parser to use version-based configuration when
parsing APK filenames.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Split lib/utils.ts into:
- lib/utils.ts: Client-safe utilities only (no Node.js imports)
- lib/project-utils.ts: Server-only utilities with Node.js imports
This fixes the Next.js build error where client components were importing
modules that contained Node.js dependencies (fs, path).
All tests pass and build succeeds.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- Add Project interface with name and displayName
- Fetch projects via SWR
- Add getProjectDisplayName helper function
- Use display name in the download page title
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Replaced card-based layout with tabbed interface for APK environments.
Now displays APKs grouped by dev/product/sandbox/other tabs with counts.
- Replaced ApkCard with ApkTable component
- Added tab navigation with active state styling
- Group APKs by environment using reduce
- Show count badges for each environment tab
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Add Project interface with name and displayName fields to support project aliases. Update SWR hook to type projects as Project[]. Display project.displayName in dropdown while using project.name as the option value for API compatibility.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- Replace spread operator with explicit field selection to avoid
duplicate commit field from getApks() and parseApkFilename()
- Add test case for commitId parameter filtering to ensure
the filter parameter works correctly with new metadata extraction
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- Add parseApkFilename() integration to extract environment and commit info
- Return environment field (dev/sandbox/product/other) in API response
- Return commit field (short commit ID) in API response
- Add comprehensive test coverage for the new metadata
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- Modified projects API route to return objects with name and displayName fields
- Added comprehensive tests for the updated API response structure
- Tests verify display name mapping and error handling
- All existing tests continue to pass
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Fix login issue when accessing via IP address over HTTP. Previously,
the cookie secure flag was set based on NODE_ENV which caused
cookies to not be sent when accessing via HTTP in production mode.
Now it uses the actual request protocol (checking x-forwarded-proto
header or request URL).
Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
- Move test files to lib/__tests__/ directory
- Extract formatting utilities (formatVersion, formatFileSize, formatDateTime)
from fs-utils.ts to new utils.ts module
- Add Jest test configuration and test scripts
- Update component imports to use new utils module
- Add CLAUDE.md documentation for project structure
Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
- Add 'use client' directive at top of ApkList.tsx to support useSWR hook
- Remove highlightCommit prop from ApkCard component call as it's not accepted by ApkCard interface
Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
- Removed dangerouslySetInnerHTML with unsanitized user input
- Removed highlightCommit prop and related highlighting logic
- Added download and rel="noopener noreferrer" attributes to download link
- Simplified component to safely display filename without HTML rendering
Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
- Add secure and sameSite attributes to cookie configuration
- Add try-catch block to handle malformed JSON and other errors
- Add validation for missing username or password fields
Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
- Replace fs.readFileSync() with fs.createReadStream() to prevent memory exhaustion
- Export validatePath() from fs-utils.ts
- Use validatePath() to validate full path including project and version parameters
- Fix incomplete path traversal protection
- Add filename encoding in Content-Disposition header
Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
- Add encodeURIComponent() for project, version, and filename parameters in downloadUrl to prevent XSS and URL breakage
- Remove unused formatDateTime import
Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>