Skip to content

functionland/FxFiles

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

3 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

FxFiles - Fula File Manager

A minimalistic file manager with Fula decentralized storage backup support. Built with Flutter for cross-platform compatibility.

Features

  • Local File Browser: Browse and manage local files and folders
  • Fula Cloud Storage: Sync files to decentralized Fula network
  • Client-Side Encryption: AES-256-GCM encryption before upload
  • Authentication: Sign in with Google or Apple
  • File Viewers: Built-in viewers for images, videos, and text files
  • Search: Search local files by name
  • Trash Management: Safely delete and restore files
  • Dark/Light Theme: Automatic theme switching

Architecture

lib/
├── app/
│   ├── app.dart              # Root widget
│   ├── router.dart           # GoRouter navigation
│   └── theme/                # Theme configuration
├── core/
│   ├── models/               # Data models (LocalFile, FulaObject, SyncState)
│   └── services/             # Core services
│       ├── auth_service.dart         # Google/Apple authentication
│       ├── encryption_service.dart   # AES-256-GCM encryption
│       ├── file_service.dart         # Local file operations
│       ├── fula_api_service.dart     # Fula S3-compatible API
│       ├── local_storage_service.dart # Hive local storage
│       ├── secure_storage_service.dart # Secure key storage
│       └── sync_service.dart         # File synchronization
├── features/
│   ├── browser/              # Local file browser
│   ├── fula/                 # Fula cloud browser
│   ├── home/                 # Home screen with categories
│   ├── search/               # File search
│   ├── settings/             # App settings
│   ├── shared/               # Shared files
│   ├── sync/                 # Sync providers
│   ├── trash/                # Trash management
│   └── viewer/               # File viewers (image, video, text)
├── shared/
│   └── widgets/              # Reusable widgets
└── main.dart                 # App entry point

Getting Started

Prerequisites

  • Flutter SDK 3.2.0 or higher
  • Dart SDK 3.2.0 or higher
  • Android Studio / Xcode for mobile development

Installation

  1. Clone the repository:
git clone https://github.com/user/FxFiles.git
cd FxFiles
  1. Install dependencies:
flutter pub get
  1. Run the app:
flutter run

Configuration

Fula API Setup

  1. Open the app and go to Settings
  2. Under Fula Configuration, enter:
    • API Gateway URL: Your Fula gateway endpoint (e.g., https://gateway.fula.network)
    • JWT Token: Your authentication token
    • IPFS Server (optional): Custom IPFS server URL

Authentication

Sign in with Google or Apple to enable:

  • Encrypted file uploads
  • Per-user encryption keys derived from authentication
  • Cross-device sync

Security

Encryption

  • Algorithm: AES-256-GCM for symmetric encryption
  • Key Derivation: PBKDF2 with SHA-256 for password-based keys
  • Per-User Keys: Encryption keys derived from user authentication
  • Client-Side: All encryption happens locally before upload

Data Flow

Local File → Encrypt (AES-256-GCM) → Upload to Fula → IPFS Storage
                    ↑
            User's Encryption Key

Dependencies

Package Purpose
flutter_riverpod State management
go_router Navigation
minio_new S3-compatible API client
cryptography Encryption primitives
hive_flutter Local storage
flutter_secure_storage Secure key storage
google_sign_in Google authentication
sign_in_with_apple Apple authentication
workmanager Background sync tasks
connectivity_plus Network monitoring

Usage

Upload Files to Fula

  1. Browse to local files
  2. Select files to upload
  3. Tap the upload button
  4. Files are encrypted and uploaded automatically

Download from Fula

  1. Open Fula Browser from home screen
  2. Browse buckets and files
  3. Tap a file to download and decrypt

Sync Folders

await SyncService.instance.syncFolder(
  localPath: '/storage/emulated/0/Documents',
  remoteBucket: 'my-bucket',
  remotePrefix: 'documents',
  direction: SyncDirection.bidirectional,
);

API Reference

SyncService

// Queue file upload
await SyncService.instance.queueUpload(
  localPath: '/path/to/file.txt',
  remoteBucket: 'my-bucket',
  remoteKey: 'file.txt',
  encrypt: true,
);

// Queue file download
await SyncService.instance.queueDownload(
  remoteBucket: 'my-bucket',
  remoteKey: 'file.txt',
  localPath: '/path/to/file.txt',
  decrypt: true,
);

// Retry failed syncs
await SyncService.instance.retryFailed();

FulaApiService

// List objects in bucket
final objects = await FulaApiService.instance.listObjects(
  'my-bucket',
  prefix: 'folder/',
);

// Upload with encryption
await FulaApiService.instance.encryptAndUpload(
  'my-bucket',
  'file.txt',
  fileBytes,
  encryptionKey,
);

// Download and decrypt
final bytes = await FulaApiService.instance.downloadAndDecrypt(
  'my-bucket',
  'file.txt',
  encryptionKey,
);

Multipart Upload (Large Files)

For files larger than 5MB, multipart upload is used automatically with progress tracking:

// Upload large file with progress (>5MB uses multipart automatically)
await FulaApiService.instance.uploadLargeFile(
  'my-bucket',
  'large-video.mp4',
  fileBytes,
  onProgress: (progress) {
    print('Upload: ${progress.percentage.toStringAsFixed(1)}%');
  },
);

// Encrypted large file upload
await FulaApiService.instance.encryptAndUploadLargeFile(
  'my-bucket',
  'large-video.mp4',
  fileBytes,
  encryptionKey,
  originalFilename: 'vacation.mp4',
  onProgress: (progress) {
    print('Encrypted upload: ${progress.percentage.toStringAsFixed(1)}%');
  },
);

Background Sync (WorkManager)

Background sync runs automatically when the app is closed:

// Initialize background sync (called in main.dart)
await BackgroundSyncService.instance.initialize();

// Schedule periodic sync (every 15 minutes on WiFi)
await BackgroundSyncService.instance.schedulePeriodicSync(
  frequency: Duration(minutes: 15),
  requiresWifi: true,
);

// Schedule one-time upload
await BackgroundSyncService.instance.scheduleUpload(
  localPath: '/path/to/file.txt',
  bucket: 'my-bucket',
  key: 'file.txt',
  encrypt: true,
  useMultipart: true,
);

// Schedule one-time download
await BackgroundSyncService.instance.scheduleDownload(
  bucket: 'my-bucket',
  key: 'file.txt',
  localPath: '/path/to/file.txt',
  decrypt: true,
);

// Retry failed operations
await BackgroundSyncService.instance.scheduleRetryFailed();

// Cancel all background tasks
await BackgroundSyncService.instance.cancelAll();

Secure Sharing (HPKE)

Share encrypted files with others without exposing your master key:

// Get your public key to share with others
final myPublicKey = await AuthService.instance.getPublicKeyString();

// Create a share for another user
final token = await SharingService.instance.createShare(
  pathScope: '/photos/vacation/',
  bucket: 'my-bucket',
  recipientPublicKey: recipientPublicKeyBytes,
  dek: folderEncryptionKey,
  permissions: SharePermissions.readOnly,
  expiryDays: 30,
  label: 'Vacation photos',
);

// Generate shareable link
final link = SharingService.instance.generateShareLink(token);
// Result: fula://share/eyJpZCI6Ii4uLiJ9...

// Accept a share from link
final accepted = await SharingService.instance.acceptShareFromString(encodedToken);
print('Access to: ${accepted.pathScope}');
print('Can write: ${accepted.canWrite}');

// Revoke a share
await SharingService.instance.revokeShare(shareId);

Sharing Model (from Fula API):

  • Path-Scoped: Share only specific folders
  • Time-Limited: Access expires automatically
  • Permission-Based: Read-only, read-write, or full access
  • Revocable: Cancel access at any time
  • Zero Knowledge: Server can't read shared content

How it works:

  1. Owner creates share token with recipient's public key
  2. DEK is re-encrypted for recipient using HPKE (X25519 + AES-256-GCM)
  3. Token sent via any channel (link, QR code, message)
  4. Recipient decrypts with their private key
  5. Owner's master key is never exposed

Contributing

  1. Fork the repository
  2. Create a feature branch
  3. Commit changes
  4. Push to the branch
  5. Open a Pull Request

License

This project is licensed under the MIT License - see the LICENSE file for details.

Acknowledgments

  • Fula Network for decentralized storage
  • Flutter team for the amazing framework
  • All open-source contributors

About

FxFiles Flutter app integrated with S3 API

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published

Languages