Changed metadata export to match Go CLI's timestamp format.
Timestamps now serialize as ISO 8601 strings with timezone offset
(e.g., "2025-07-23T19:48:06.098+05:30") instead of Unix microseconds.
Also fixed clippy warnings to ensure CI compliance.
Co-Authored-By: Claude <noreply@anthropic.com>
Fixed export to properly organize files into album folders by:
- Fetching files from all collections using /collections/v2/diff endpoint
- Decrypting encrypted collection names to get actual album names
- Using decrypted album names for folder organization
Files now export to proper album folders instead of all going to
"Uncategorized". Tested and verified with local data.
Co-Authored-By: Claude <noreply@anthropic.com>
Export album and file metadata to .meta folders within each album directory.
Enables incremental sync and compatibility with Go CLI exports.
Co-Authored-By: Claude <noreply@anthropic.com>
Switch from date-based (YYYY/MM-Month) to album-based directory structure
to ensure compatibility with Go CLI. Files now export to AlbumName/ folders
with "Uncategorized" for files without albums.
Co-Authored-By: Claude <noreply@anthropic.com>
Align with Go CLI by integrating sync into export workflow.
Update CLAUDE.md to prevent default template usage in commits.
Co-Authored-By: Claude <noreply@anthropic.com>
- Hash-based file deduplication prevents duplicate exports
- Live photo extraction from ZIP archives
- Update conversion status documenting feature completion
- Make commit guidelines prominent in CLAUDE.md
- Remove redundant commit format section
Co-Authored-By: Claude <noreply@anthropic.com>
Check both public magic metadata (for edited names) and regular metadata
when determining file names during export and sync, matching Go CLI behavior
Co-Authored-By: Claude <noreply@anthropic.com>
- Add configurable retry with exponential backoff for API calls
- Handle 429 and 5xx errors with automatic retries
- Add export filters for albums, shared, and hidden collections
- Fix formatting and clippy warnings to pass CI checks
Co-Authored-By: Claude <noreply@anthropic.com>
- Handle non-interactive mode in account add command
- Fix cross-filesystem file move issue by using copy+delete instead of rename
- Successfully tested downloading files from local server
Co-Authored-By: Claude <noreply@anthropic.com>
Since the CLI hasn't been released yet, we don't need to maintain
backward compatibility. This commit removes unnecessary compatibility
code to simplify the codebase.
Changes:
- Remove id field from Account struct (use user_id directly)
- Remove update_file_local_path legacy wrapper method
- Use mark_file_synced directly instead of the wrapper
- Update all references from account.id to account.user_id
This results in cleaner, more maintainable code without unnecessary
compatibility layers.
Co-Authored-By: Claude <noreply@anthropic.com>
Since user_id is globally unique in Ente's system (like collection_id and
file_id), we can eliminate artificial primary keys and use the actual IDs
directly. This simplifies the schema and reduces redundancy.
Changes:
- Use (user_id, app) composite primary key in accounts table
- Use (user_id, app) composite primary key in secrets table
- Remove account_id references, use user_id directly
- Update collections table to use owner field (user_id)
- Update files table to use owner_id field (user_id)
- Remove account_id from album_files table
- Update sync_state table to use (user_id, app) primary key
- Update all storage methods to use new schema
- Update commands to pass correct parameters to storage methods
- Update indices for better query performance
This aligns with Ente's API design where these IDs are guaranteed to be
globally unique, eliminating the need for artificial primary keys.
Co-Authored-By: Claude <noreply@anthropic.com>
Collapsed nested if statement in sync.rs to satisfy clippy's
collapsible-if lint rule. This change is required for CI to pass
with the updated Rust version.
Co-Authored-By: Claude <noreply@anthropic.com>
Since collection_id and file_id are globally unique across all users in
Ente's API, we can use them directly as primary keys instead of creating
artificial auto-increment IDs. This simplifies the schema and reduces
redundancy.
Changes:
- Use collection_id as primary key in collections table
- Use file_id as primary key in files table
- Use composite primary key (album_id, file_id) in album_files table
- Update all related SQL queries to match new schema
- Add appropriate foreign key constraints
- Optimize indices for the new structure
Co-Authored-By: Claude <noreply@anthropic.com>
- Fix collapsible if statement warnings in sync.rs and files.rs
- Update CLAUDE.md with clearer CI requirements
- Remove misleading auto-fix command that doesn't catch all issues
- Emphasize that ALL checks must pass before committing
🤖 Generated with Claude Code
Co-Authored-By: Claude <noreply@anthropic.com>
- Integrated DownloadManager with sync command for actual file downloads
- Implemented proper sync state tracking using is_synced_locally flag
- Fixed database persistence by preserving sync state during updates
- Added proper collection key decryption for file downloads
- Files are only downloaded once and marked as synced
- Cleaned up schema - removed migrations since this is new code
- Fixed deserialization issues with RemoteFile thumbnail field
- Added proper error handling for missing collection keys
The sync command now:
1. Fetches metadata for collections and files
2. Downloads files that haven't been synced yet
3. Marks files as synced to avoid re-downloading
4. Properly handles existing files on disk
This matches the Go CLI's approach of using a synced flag rather than
checking file existence on every sync.
Co-Authored-By: Claude <noreply@anthropic.com>
- Added local_path column to files table for tracking downloaded files
- Implemented get_pending_downloads() to find files without local_path
- Integrated DownloadManager into sync command for full file downloads
- Added collection key decryption for file downloads
- Generate proper export paths with date/album structure
- Track successful downloads and update database with local paths
- Added migration to add local_path column to existing databases
The sync command now supports full file downloads (not just metadata).
Files are downloaded to the export directory with proper organization.
Co-Authored-By: Claude <noreply@anthropic.com>
- Fixed formatting issues in sync/engine.rs
- Added #[allow(dead_code)] for unused storage field in DownloadManager
- Replaced manual clamp with .clamp() method
Co-Authored-By: Claude <noreply@anthropic.com>
- Add new `sync` command to fetch collections and file metadata
- Change config directory from ~/.ente/ to ~/.config/ente-cli/ to avoid conflicts with Go CLI
- Fix sync engine to use correct API endpoints (/collections/v2/diff instead of /diff)
- Implement per-collection file syncing matching Go CLI behavior
- Fix foreign key constraints in database schema
- Add metadata-only and full sync options
- Store database path in Storage struct for creating new instances
- Successfully tested with real account: syncs 5 files and exports correctly
The sync command now properly fetches all collections and files from the API,
storing them in SQLite for offline access and incremental sync support.
Co-Authored-By: Claude <noreply@anthropic.com>
Security improvements:
- Remove all debug logs that output tokens, keys, or credentials
- Remove email addresses from debug output
- Remove encrypted keys and nonces from logs
- Remove specific account references from documentation
- Add security guidelines to CLAUDE.md
No sensitive information (PII, credentials, tokens) should be logged
even in debug mode. Updated guidelines to prevent future occurrences.
Co-Authored-By: Claude <noreply@anthropic.com>
- Mark streaming XChaCha20-Poly1305 implementation as complete
- Document successful export functionality with all decryption working
- Update testing status with successful real account exports
- Add recent achievements section highlighting key milestones
- Update feature parity progress checklist
- Document what components are complete vs remaining
The export functionality is now fully working with proper decryption
of collections, files, and metadata. Updated PR description as well.
Co-Authored-By: Claude <noreply@anthropic.com>
- Show progress for each exported file with count
- Improve export summary with emojis and better formatting
- Add contextual success messages based on export results
- Make export output more user-friendly
The export now provides clear feedback during the process and
a helpful summary at the end.
Co-Authored-By: Claude <noreply@anthropic.com>
- Implement chunked streaming decryption matching Go's 4MB buffer size
- Update file decryption to use decrypt_file_data instead of decrypt_stream
- Successfully tested with 33MB RAW image file
- All test files now decrypt correctly
Large files are now properly handled with chunked decryption, preventing
memory issues and matching the Go implementation's behavior.
Co-Authored-By: Claude <noreply@anthropic.com>
- Add streaming cipher module using libsodium's secretstream API
- Update file and metadata decryption to use streaming XChaCha20-Poly1305
- Fix decryption issues - files now properly decrypt
- Successfully tested with real account - exports working for smaller files
The export now correctly decrypts files using the same streaming cipher
as the Go implementation. Large files may need chunked decryption support.
Co-Authored-By: Claude <noreply@anthropic.com>
- Create metadata module with FileMetadata struct
- Decrypt file metadata to extract original filename
- Use original filename in export path generation
- Add proper file type detection from metadata
- Implement filename sanitization for filesystem safety
Files are now exported with their original names instead of generic IDs.
Co-Authored-By: Claude <noreply@anthropic.com>
- Add ChaCha20-Poly1305 decryption for downloaded files
- Decrypt file keys using master key
- Extract nonce from encrypted file data
- Add basic filename generation with extension detection
- Comment out sync modules temporarily due to model mismatches
The export command now properly decrypts files instead of saving them encrypted.
Next steps: extract original filenames from decrypted metadata.
Co-Authored-By: Claude <noreply@anthropic.com>
Ensure clippy commands use --all-targets --all-features flags to match
the CI environment exactly. This prevents CI failures from warnings that
weren't caught locally.
Co-Authored-By: Claude <noreply@anthropic.com>
Add explicit pre-commit commands that must be run before every commit
to ensure CI passes. These commands simulate the CI environment locally.
Co-Authored-By: Claude <noreply@anthropic.com>
- Applied cargo fmt to ensure consistent formatting
- Fixed all clippy warnings (uninlined_format_args)
- Code now passes all CI checks with RUSTFLAGS="-D warnings"
Co-Authored-By: Claude <noreply@anthropic.com>
- Fix token encoding to use base64 URL with padding (matching Go implementation)
- Add export command that iterates through collections and fetches files
- Update API models to handle actual server response field names (ownerID vs ownerId)
- Fix file download URLs for local/dev environments
- Implement proper directory structure creation (YYYY/MM-Month format)
- Add collection attributes and public URL models for complete API compatibility
- Successfully exports encrypted files from both local and production endpoints
The export command now:
- Fetches all collections for an account
- Iterates through each collection to get files
- Downloads encrypted files and saves them to the export directory
- Skips already downloaded files to support incremental exports
Note: Files are still encrypted; decryption will be implemented in a future commit.
Co-Authored-By: Claude <noreply@anthropic.com>
- Add endpoint field to accounts database table with default to production API
- Update Account model to include endpoint field
- Add --endpoint flag to account add command only
- Remove ENTE_ENDPOINT environment variable support
- Update account list to display endpoints in readable format
- Each account now maintains its own endpoint, preventing confusion between test and production environments
Co-Authored-By: Claude <noreply@anthropic.com>
- Use std::ffi::c_char for libsodium FFI context parameter cast
- Fix all clippy warnings to pass CI with RUSTFLAGS="-D warnings"
- Update CLAUDE.md with FFI casting guidance for future development
This ensures the code passes all CI checks including the stricter
clippy settings used in GitHub Actions.
Co-Authored-By: Claude <noreply@anthropic.com>
Fixed issues preventing successful authentication:
- Corrected Argon2 memory limit handling (API sends bytes, not KB)
- Replaced Blake2b with crypto_kdf_derive_from_key for login subkey derivation
- Fixed serde field names to match API expectations (srpUserID, sessionID)
- Added non-interactive mode for CLI testing
- Added support for ENTE_ENDPOINT environment variable
The implementation now matches the web client's key derivation exactly,
enabling successful authentication with both local and production servers.
Co-Authored-By: Claude <noreply@anthropic.com>
Add comprehensive account management functionality with secure SRP authentication.
This enables users to add, list, update, and manage multiple Ente accounts
for photos, locker, and auth apps.
Key features:
- Complete account add flow with SRP authentication
- Two-factor authentication support (TOTP)
- Secure key decryption and storage
- Multi-account support with per-app configuration
- Account list and update commands
- Export directory management
- Interactive CLI prompts with dialoguer
The implementation integrates with the API client for authentication and
securely stores account credentials in SQLite.
Co-Authored-By: Claude <noreply@anthropic.com>
Add complete API client implementation with authentication, file operations,
and collection management. This enables the Rust CLI to interact with Ente
servers for photo backup and sync operations.
Key features:
- Multi-account token management with secure storage
- SRP authentication flow matching Go implementation
- Retry logic with exponential backoff for network resilience
- Full API coverage: auth, collections, files, trash, user details
- Request/response models for all API endpoints
- Separate download client for large file transfers
- Smart CDN routing for production file downloads
The implementation follows the conversion plan and maintains compatibility
with the existing Go CLI API patterns.
Co-Authored-By: Claude <noreply@anthropic.com>
Add detailed development commands, architecture overview, and module
descriptions to help future Claude instances understand the codebase
structure and development workflow.
Co-Authored-By: Claude <noreply@anthropic.com>
- Document current implementation status
- Detail API client implementation steps
- List all remaining components with specifications
- Include testing strategy and migration notes
- Provide file structure reference for navigation
- Add implementation guidelines and environment variables
This plan enables any developer to understand the project state
and continue the conversion work from the current point.
Co-Authored-By: Claude <noreply@anthropic.com>
- Replace sled with SQLite for better reliability and tooling
- Create schema with tables for accounts, secrets, collections, files, and sync state
- Implement account storage with multi-account support
- Add configuration and sync state management
- Support for storing encrypted credentials separately
- Add indices for performance optimization
SQLite provides ACID transactions, better debugging tools, and a proven
track record for reliability with user data.
Co-Authored-By: Claude <noreply@anthropic.com>