mirror of
https://github.com/R0m1k3/xtremflow.git
synced 2026-10-12 01:36:20 +02:00
Security: - Replace unsalted SHA-256 password hashing with bcrypt (lazy rehash on login) - Add authenticated /api/xtream-api gateway: Xtream credentials are injected server-side and never sent to the frontend; /api/playlists no longer returns passwords - Redact credentials from all logs (login body, proxy/FFmpeg/scheduler URLs) - Add auth to recordings, EPG, season-passes and streaming routes (HttpOnly session cookie for hls.js; loopback bypass for local FFmpeg) - Lock player postMessage to same-origin in both directions - Vendor and pin hls.js 1.6.7 / mpegts.js 1.7.3 (drop CDN @latest) - Fix rate limiter (client IP was never resolved), add login rate limit, restrict CORS, add CSP Report-Only, block private-IP SSRF targets, fix path traversal in recording log retrieval, chmod 777 -> 770 - Remove dead HiveService (seeded admin/admin into IndexedDB with SHA-256) - Fix authMiddleware not populating 'user' context (getPlaylist ignored the logged-in user; admin purge always returned 403) Streaming: - New FfmpegSessionManager: process registry, idle reaper (4 min live / 15 min VOD), orphan cleanup at startup, clean SIGTERM shutdown, fast-fail with stderr instead of 30 s timeout - Quality selection (source/high/medium/low) for live and VOD; source mode streams with -c:v copy (zero transcoding); selector wired into the player - Concurrent recordings (MAX_CONCURRENT_RECORDINGS, default 2); conflicts retry on the next tick instead of silently failing - Lower live latency (HLS window 20 -> 10 segments, liveSync 10 -> 3) - Fix recording log lookup (.mp4 vs .mkv mismatch) Design: - Replace hardcoded colors with AppColors tokens (12 files) - web/theme.css syncs HTML players with the Flutter palette - DPAD/keyboard navigation (arrow-key focus, player shortcuts) - Tooltips on player icon buttons, Semantics on content cards - Remove 7 dead widgets broken since the Stitch merge Quality: - bin/test/: 21 unit tests (bcrypt, redaction, traversal, SSRF, recording conflicts) plus a quality-selector widget test - GitHub Actions CI (analyze + test + build web) - Archive stale status docs into docs/archive/ Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
6.8 KiB
6.8 KiB
🚀 Guide d'Intégration - Nouveau Système d'Enregistrement
⚠️ BACKUP D'ABORD!
# Sauvegarder avant de modifier
git add .
git commit -m "backup: before recording system upgrade"
🔄 Étapes de Migration
ÉTAPE 1️⃣: Supprimer les anciens fichiers
# Ancien système (à supprimer):
rm bin/services/recording_scheduler.dart
rm bin/api/recordings_api.dart
rm bin/api/season_passes_api.dart
rm lib/features/iptv/widgets/recording_modal.dart
rm lib/features/iptv/widgets/recordings_tab.dart
Les nouveaux fichiers:
bin/services/simple_recorder.dart✅bin/api/simple_recording_api.dart✅lib/features/iptv/widgets/simple_recording_widget.dart✅
ÉTAPE 2️⃣: Mettre à jour bin/server.dart
AVANT:
// ❌ OLD
import 'services/recording_scheduler.dart';
import 'api/recordings_api.dart';
// Dans main()
final recordingScheduler = RecordingScheduler(db);
recordingScheduler.start();
// Injecter la config playlist
Future<void> _injectPlaylistToScheduler() async {
// ... 30+ lignes de code compliqué
}
Future.delayed(const Duration(seconds: 5), _injectPlaylistToScheduler);
// Routes
router.post('/api/recordings', recordingsApi.handlePost);
router.get('/api/recordings', recordingsApi.handleGetAll);
router.delete('/api/recordings/<id>', (req, id) => recordingsApi.handleDelete(req, id));
// ... plus d'endpoints compliqués
APRÈS:
// ✅ NEW
import 'services/simple_recorder.dart';
import 'api/simple_recording_api.dart';
// Dans main()
final recorder = SimpleRecorder(db);
await recorder.init();
// Vérifier les enregistrements programmés toutes les minutes
Timer.periodic(Duration(minutes: 1), (_) => recorder.checkScheduled());
// Cleanup automatique toutes les 6 heures (garde 20 derniers)
Timer.periodic(Duration(hours: 6), (_) => recorder.cleanupOld(keepCount: 20));
// Routes
final recordingApi = SimpleRecordingApi(db, recorder);
router.mount('/api/record/', recordingApi.router);
ÉTAPE 3️⃣: Mettre à jour la base de données (optionnel mais recommandé)
Les tables ne changent pas - les anciens enregistrements restent valides. Mais vous pouvez nettoyer:
-- Nettoyer les season passes (plus utilisés)
DELETE FROM season_passes;
-- Supprimer les anciens enregistrements failed/orphaned
DELETE FROM tv_recordings WHERE status = 'failed' AND updated_at < datetime('now', '-1 week');
ÉTAPE 4️⃣: Remplacer l'UI quelque part
AVANT (compliqué):
// ❌ Ancien widget avec 3 onglets, modal complexe, state compliqué
RecordingsTab(playlist: playlist)
// + 250 lignes de code pour recording_modal.dart
APRÈS (simple):
// ✅ Nouveau widget - 3 lignes pour afficher
ElevatedButton(
onPressed: () => SimpleRecordingWidget.show(context, channel, streamUrl),
child: const Text('Record'),
)
Ou dans une liste de chaînes:
// Ajouter le bouton dans votre Channel card
Card(
child: ListTile(
title: Text(channel.name),
trailing: IconButton(
icon: const Icon(Icons.fiber_manual_record),
onPressed: () {
SimpleRecordingWidget.show(
context,
channel,
'/api/live/${channel.streamId}.ts',
);
},
),
),
)
ÉTAPE 5️⃣: Compiler et tester
# Flutter
flutter pub get
flutter run -d chrome
# Docker
docker-compose build
docker-compose up
✅ Vérification Post-Migration
1. API Testing
# 1. Record NOW
curl -X POST http://localhost:8089/api/record/now \
-H 'Content-Type: application/json' \
-d '{
"channel_id": "1001",
"stream_url": "http://localhost:8089/api/live/1001.ts",
"title": "Test Channel",
"duration_minutes": 2
}'
✅ Expected: {"status": "recording", "id": "xxx", "message": "Recording started!"}
# 2. See active
curl http://localhost:8089/api/record/active
✅ Expected: {"active": [...], "count": 1}
# 3. Stop it
curl -X POST http://localhost:8089/api/record/stop/1001
✅ Expected: {"status": "stopped", "message": "Recording stopped!"}
# 4. List all
curl http://localhost:8089/api/record/list
✅ Expected: {"total": 1, "recordings": [...]}
2. UI Testing
- Click a channel
- Click "Record"
- Select "1 hour"
- ✅ Should say "Recording started!"
- Check files in
/app/recordings/ - File should exist:
channelname_20260326T123456.mkv
3. Schedule Testing
- Click channel
- Click "Schedule for Later"
- Set time 2 minutes in future
- Set duration 1 minute
- Click "SCHEDULE"
- Wait 2+ minutes
- Check if file appears in
/app/recordings/ - ✅ Auto-started!
🔍 Troubleshooting
Problem: "No recordings showing"
# Check if directory exists
ls -la /app/recordings/
# If not, create it
mkdir -p /app/recordings
chmod 777 /app/recordings
Problem: "FFmpeg not found"
# Check if FFmpeg installed
which ffmpeg
# If not, install it
apt-get install ffmpeg
# Or in Docker, it's already there
Problem: "API returns "Already recording""
# Channel is already being recorded
# Either wait for it to finish or use /api/record/stop/<channelId>
curl -X POST http://localhost:8089/api/record/stop/1001
Problem: "Recording starts but creates empty file"
# Stream URL is probably wrong
# Test the stream manually:
ffmpeg -i "http://localhost:8089/api/live/1001.ts" -t 10 test.mkv
# If that fails, the stream URL is bad
📊 Avant/Après Checklist
| Feature | Before | After | Notes |
|---|---|---|---|
| Record NOW | ✅ Works | ✅ Works | Simpler code |
| Record Later | ✅ Works | ✅ Works | Uses simple scheduling |
| Stop Recording | ✅ Works | ✅ Works | One endpoint |
| File Storage | ✅ Works | ✅ Works | Same directory |
| Status History | ✅ Works | ✅ Works | Same DB |
| Season Passes | ✅ Works | ❌ Removed | Not needed! (just use Schedule) |
| Logs | ✅ Works | ⚠️ Minimal | Simpler error tracking |
| Cleanup | ✅ Works | ✅ Works | Auto every 6h |
🎯 Quick Summary
A faire:
- ✅ Delete old files (3 files)
- ✅ Replace server.dart (5 lines)
- ✅ Update UI (1-2 buttons)
- ✅ Test APIs (5 calls)
- ✅ Deploy
Temps total: 30 minutes ⚡
Résultat:
- Système 10x plus simple
- Même fonctionnalité
- Code cleaner
- Maintenance easier
🆘 Besoin de support?
Si ça ne marche pas:
- Check
/app/logsfor errors - Run
curl http://localhost:8089/api/record/listto verify API - Make sure FFmpeg is installed:
ffmpeg -version - Check
/app/recordings/exists and writable
Questions?
- API endpoints: See
SIMPLE_RECORDING.md - Code structure: See
simple_recorder.dart(260 lines, very documented) - UI usage: See
simple_recording_widget.dart(shows all options)
✨ Migration complete! Your recording system is now 10x simpler! ✨