Documentation technique approfondie du projet SUPFile - Système de stockage de fichiers cloud sécurisé
- Introduction au Projet
- Architecture
- Fonctionnalités Détaillées
- Installation et Configuration
- Déploiement
- Authentification et OAuth2
- API Reference
- Sécurité
- Dépannage
- Roadmap
SUPFile est un projet académique développé dans le cadre du cursus SUPINFO. Il s'agit d'un système de stockage de fichiers cloud sécurisé, similaire à Dropbox, permettant aux utilisateurs de stocker, organiser, partager et gérer leurs fichiers de manière sécurisée dans le cloud.
- ✅ Développer une application web moderne avec architecture client-serveur
- ✅ Implémenter un système d'authentification robuste (JWT + OAuth2)
- ✅ Gérer le stockage de fichiers dans le cloud (Azure Blob Storage)
- ✅ Créer une interface utilisateur intuitive et responsive
- ✅ Assurer la sécurité des données et des communications
- ✅ Déployer l'application en production (Vercel + Railway)
- Frontend : React 18, TypeScript, Vite
- Backend : FastAPI, Python 3.11
- Base de données : PostgreSQL
- Stockage : Azure Blob Storage
- Déploiement : Vercel (Frontend), Railway (Backend)
SUPFile suit une architecture client-serveur moderne avec séparation frontend/backend :
┌─────────────────────────────────────────────────────────┐
│ Frontend (Vercel) │
│ React + TypeScript + Vite │
│ Port: 3000 (dev) │
└───────────────────────┬─────────────────────────────────┘
│ HTTPS/REST API
│ JWT Authentication
┌───────────────────────▼─────────────────────────────────┐
│ Backend (Railway) │
│ FastAPI + Python 3.11 │
│ Port: 8000 (dev) │
└───────┬───────────────────────────────┬─────────────────┘
│ │
┌───────▼────────┐ ┌────────▼──────────┐
│ PostgreSQL │ │ Azure Blob │
│ (Railway) │ │ Storage │
│ Métadonnées │ │ Fichiers binaires │
└────────────────┘ └────────────────────┘
SUPFile/
├── frontend/ # Application React
│ ├── src/
│ │ ├── components/ # Composants réutilisables
│ │ │ ├── Sidebar.tsx
│ │ │ ├── Breadcrumbs.tsx
│ │ │ ├── SearchBar.tsx
│ │ │ ├── FileViewer.tsx
│ │ │ ├── ShareModal.tsx
│ │ │ ├── RenameModal.tsx
│ │ │ ├── MoveModal.tsx
│ │ │ ├── Pagination.tsx
│ │ │ ├── ThemeToggle.tsx
│ │ │ └── LoadingSpinner.tsx
│ │ ├── pages/ # Pages de l'application
│ │ │ ├── Login.tsx
│ │ │ ├── Register.tsx
│ │ │ ├── Dashboard.tsx
│ │ │ ├── MyFilesPage.tsx
│ │ │ ├── TrashPage.tsx
│ │ │ ├── SharedFilesPage.tsx
│ │ │ ├── OAuthCallback.tsx
│ │ │ └── AboutPage.tsx
│ │ ├── services/ # Services API
│ │ │ ├── authService.ts
│ │ │ ├── fileService.ts
│ │ │ ├── folderService.ts
│ │ │ └── shareService.ts
│ │ ├── contexts/ # Contextes React
│ │ │ ├── AuthContext.tsx
│ │ │ └── ThemeContext.tsx
│ │ ├── hooks/ # Hooks personnalisés
│ │ │ └── useWebSocket.ts
│ │ └── utils/ # Utilitaires
│ │ └── fileIcons.ts
│ ├── public/ # Fichiers statiques
│ │ ├── sw.js # Service Worker (PWA)
│ │ └── manifest.json
│ └── package.json
│
├── backend/ # API FastAPI
│ ├── app/
│ │ ├── api/v1/ # Routes API version 1
│ │ │ ├── auth.py # Authentification JWT
│ │ │ ├── oauth.py # OAuth2 (Google, GitHub, Microsoft)
│ │ │ ├── files.py # Gestion fichiers
│ │ │ ├── folders.py # Gestion dossiers
│ │ │ ├── share.py # Partage de fichiers
│ │ │ ├── dashboard.py # Statistiques
│ │ │ ├── file_history.py
│ │ │ ├── file_comments.py
│ │ │ └── file_versions.py
│ │ ├── core/ # Configuration
│ │ │ ├── config.py # Settings (Pydantic)
│ │ │ ├── database.py # SQLAlchemy
│ │ │ ├── security.py # JWT, bcrypt
│ │ │ └── middleware.py # CORS, auth
│ │ ├── models/ # Modèles SQLAlchemy
│ │ │ ├── user.py
│ │ │ ├── file.py
│ │ │ ├── folder.py
│ │ │ ├── share_link.py
│ │ │ ├── oauth_account.py
│ │ │ ├── file_history.py
│ │ │ └── file_comment.py
│ │ └── services/ # Services métier
│ │ └── azure_blob.py # Azure Blob Storage
│ ├── alembic/ # Migrations base de données
│ └── requirements.txt
│
└── docker-compose.yml # Configuration Docker local
Inscription : Processus complet d'inscription d'un nouvel utilisateur.
- Inscription/Connexion :
Frontend → POST /api/v1/auth/register|login Backend → Vérification credentials Backend → Génération JWT (access + refresh) Backend → Retour tokens Frontend → Stockage tokens (localStorage)
Authentification JWT : Processus de connexion et génération de tokens JWT.
- OAuth2 :
Frontend → GET /api/v1/auth/{provider}/authorize Backend → Redirection vers provider OAuth Provider → Redirection callback avec code Backend → Échange code → token Backend → Création/compte utilisateur Backend → Génération JWT Backend → Redirection frontend avec tokens (fragment URL) Frontend → Extraction tokens → Stockage
Flux OAuth2 Complet : Flux pour les trois providers OAuth2 (Google, GitHub, Microsoft).
Séquence OAuth2 Détaillée - Google : Séquence détaillée du flux OAuth2 pour Google.
Protection contre les Codes Dupliqués : Mécanisme de protection contre la réutilisation de codes OAuth2.
Flux d'Upload Complet : Processus complet de téléchargement de fichiers.
Validation de Fichier : Processus de validation des fichiers avant upload.
-
Upload :
Frontend → Validation fichier (taille, extension) Frontend → POST /api/v1/files/upload (FormData) Backend → Validation (taille, extension, permissions) Backend → Génération blob_name unique Backend → Upload vers Azure Blob Storage Backend → Sauvegarde métadonnées PostgreSQL Backend → Retour métadonnées fichier Frontend → Mise à jour liste fichiers -
Téléchargement :
Frontend → GET /api/v1/files/{id}/download Backend → Vérification permissions Backend → Récupération fichier Azure Backend → Stream vers client Frontend → Téléchargement fichier
Création et Navigation : Processus de création de dossiers et navigation dans l'arborescence.
Breadcrumbs : Système de navigation avec fil d'Ariane.
-
Création :
Frontend → POST /api/v1/folders Backend → Validation nom, parent_id Backend → Création dossier PostgreSQL Backend → Retour métadonnées dossier Frontend → Mise à jour arborescence -
Navigation :
Frontend → GET /api/v1/files?folder_id={id} Backend → Filtrage fichiers par folder_id Backend → Retour liste fichiers Frontend → Affichage avec breadcrumbs
États d'un Fichier : Cycle de vie d'un fichier (actif, supprimé, restauré, supprimé définitivement).
Soft Delete et Restauration : Processus de suppression réversible et restauration.
-
Suppression (Soft Delete) :
Frontend → DELETE /api/v1/files/{id} Backend → Mise à jour deleted_at = timestamp Backend → Fichier masqué des listes normales Frontend → Mise à jour liste -
Restauration :
Frontend → POST /api/v1/files/{id}/restore Backend → Mise à jour deleted_at = NULL Backend → Fichier réapparaît dans listes Frontend → Mise à jour corbeille + listes -
Suppression définitive :
Frontend → DELETE /api/v1/files/{id}/permanent Backend → Suppression fichier Azure Blob Backend → Suppression enregistrement PostgreSQL Frontend → Mise à jour corbeille
- Inscription : Email, username, password avec validation
- Connexion : Username/password avec génération JWT
- Tokens : Access token (30 min) + Refresh token (7 jours)
- Sécurité : Hachage bcrypt (12 rounds), validation Pydantic
- Flux : Authorization Code Flow
- Cache : Protection contre appels multiples (codes OAuth)
- Redirection : JavaScript redirect pour éviter ERR_INVALID_REDIRECT
- Configuration : Variables d'environnement + URLs de callback
- Validation : Taille max (100MB), extensions autorisées
- Stockage : Azure Blob Storage avec nom unique
- Métadonnées : PostgreSQL (nom, taille, type, région)
- Interface : Drag & drop avec barre de progression
- Streaming : Téléchargement direct depuis Azure
- Permissions : Vérification propriétaire
- Headers : Content-Disposition pour nom original
- Types supportés : Images, PDF, texte
- URL signée : SAS URL Azure avec expiration
- Viewer : Composant React pour affichage
- Critères : Nom de fichier, type MIME
- Filtres : Par dossier, par type
- Pagination : skip/limit pour performance
- Hiérarchie : Relations parent-enfant (parent_id)
- Navigation : Breadcrumbs automatiques
- Racine : folder_id = NULL pour fichiers racine
- Création : Dossiers imbriqués
- Renommage : Modification nom
- Déplacement : Changement parent_id
- Suppression : Soft delete (comme fichiers)
Schéma Entité-Relation (ERD) : Modèle complet de la base de données avec toutes les relations.
- Marquage :
deleted_attimestamp - Masquage : Fichiers non visibles dans listes normales
- Récupération : Restauration possible
- Processus : Suppression Azure + PostgreSQL
- Irréversible : Confirmation requise
- Nettoyage : Libération espace de stockage
- Génération : Token UUID unique
- Expiration : Date d'expiration optionnelle
- Protection : Mot de passe optionnel
- Accès : Sans authentification
Flux de Partage Complet : Processus de partage de fichiers avec génération de liens publics.
Modèle de Partage : Modèle de données pour le système de partage.
- Création lien → Génération token
- Partage URL →
/share/{token} - Accès → Vérification token + expiration + mot de passe
- Téléchargement → URL signée Azure
- Fichiers : Nombre total, espace utilisé
- Stockage : Utilisé / Disponible / Pourcentage
- Graphiques : Visualisation espace (Chart.js)
- Tri : Par date de modification
- Limite : 10 fichiers récents
- Affichage : Liste avec métadonnées
- Python 3.11+
- Node.js 18+
- Docker & Docker Compose (recommandé)
- PostgreSQL (ou via Docker)
- Compte Azure (pour Blob Storage)
-
Cloner le projet :
git clone https://github.com/MEVENGUE/SUPFile-Vercel-App.git cd SUPFile-Vercel-App -
Configurer les variables d'environnement :
Créer
.envà la racine :# Backend DATABASE_URL=postgresql://supfile_user:supfile_password@postgres:5432/supfile SECRET_KEY=votre-secret-key-minimum-32-caracteres JWT_SECRET_KEY=votre-jwt-secret-key-minimum-32-caracteres # Azure Blob Storage AZURE_STORAGE_ACCOUNT_NAME=votre-compte-azure AZURE_STORAGE_ACCOUNT_KEY=votre-cle-azure AZURE_STORAGE_CONTAINER_NAME=supfile-files AZURE_STORAGE_CONNECTION_STRING=votre-connection-string # Frontend VITE_API_URL=http://localhost:8000/api/v1
-
Démarrer les services :
docker-compose up -d
-
Initialiser la base de données :
docker exec -it supfile-backend bash alembic upgrade head -
Accéder à l'application :
- Frontend : http://localhost:3000
- Backend : http://localhost:8000
- API Docs : http://localhost:8000/docs
cd backend
python -m venv venv
source venv/bin/activate # Windows: venv\Scripts\activate
pip install -r requirements.txt
# Créer .env
cp .env.example .env
# Éditer .env avec vos configurations
# Configurer PostgreSQL localement
# Puis exécuter les migrations
alembic upgrade head
# Démarrer le serveur
uvicorn app.main:app --reloadcd frontend
npm install
# Créer .env
echo "VITE_API_URL=http://localhost:8000/api/v1" > .env
# Démarrer le serveur de développement
npm run dev-
Connecter le dépôt GitHub :
- Allez sur vercel.com
- Connectez-vous avec GitHub
- Importez le dépôt
SUPFile-Vercel-App
-
Configurer le projet :
- Root Directory :
frontend - Framework Preset : Vite
- Build Command :
npm run build - Output Directory :
dist
- Root Directory :
-
Variables d'environnement :
VITE_API_URL=https://votre-backend.railway.app/api/v1 VITE_OPENAI_API_KEY=votre-cle-openai (optionnel)
-
Déployer :
- Cliquez sur "Deploy"
- Vercel déploie automatiquement
-
Créer un projet Railway :
- Allez sur railway.app
- Connectez-vous avec GitHub
- Créez un nouveau projet
-
Ajouter PostgreSQL :
- Cliquez sur "+ New" > "Database" > "Add PostgreSQL"
- Notez la variable
DATABASE_URL
-
Déployer le backend :
- Cliquez sur "+ New" > "GitHub Repo"
- Sélectionnez
SUPFile-Vercel-App - Railway détecte automatiquement le Dockerfile
-
Variables d'environnement :
# Base de données (OBLIGATOIRE) DATABASE_URL=${{Postgres.DATABASE_URL}} # Clés secrètes SECRET_KEY=votre-secret-key-32-caracteres JWT_SECRET_KEY=votre-jwt-secret-key-32-caracteres # Azure Blob Storage AZURE_STORAGE_ACCOUNT_NAME=votre-compte AZURE_STORAGE_ACCOUNT_KEY=votre-cle AZURE_STORAGE_CONTAINER_NAME=supfile-files AZURE_STORAGE_CONNECTION_STRING=votre-connection-string # CORS CORS_ORIGINS=https://votre-frontend.vercel.app # OAuth (optionnel) OAUTH_GOOGLE_CLIENT_ID=... OAUTH_GOOGLE_CLIENT_SECRET=... OAUTH_GITHUB_CLIENT_ID=... OAUTH_GITHUB_CLIENT_SECRET=... OAUTH_MICROSOFT_CLIENT_ID=... OAUTH_MICROSOFT_CLIENT_SECRET=... OAUTH_REDIRECT_BASE_URL=https://votre-frontend.vercel.app OAUTH_CALLBACK_BASE_URL=https://votre-backend.railway.app # Configuration serveur HOST=0.0.0.0 PORT=${{PORT}} DEBUG=False APP_ENV=production
-
Exécuter les migrations :
- Ouvrez la console Railway
- Exécutez :
alembic upgrade head
-
Activer le domaine :
- Allez dans "Settings"
- Activez "Generate Domain"
- Notez l'URL (ex:
https://supfile-backend.railway.app)
-
Créer un Storage Account :
- Allez sur portal.azure.com
- Créez un nouveau Storage Account
-
Créer un conteneur :
- Nom :
supfile-files - Niveau d'accès : Private (recommandé)
- Nom :
-
Obtenir les clés :
- Allez dans "Access keys"
- Copiez la Connection string
- Ajoutez dans Railway
POST /api/v1/auth/register
Content-Type: application/json
{
"email": "user@example.com",
"username": "username",
"password": "password123",
"full_name": "John Doe"
}POST /api/v1/auth/login
Content-Type: application/json
{
"username": "username",
"password": "password123"
}Réponse :
{
"access_token": "eyJ...",
"refresh_token": "eyJ...",
"token_type": "bearer"
}-
Console Google Cloud :
- Allez sur console.cloud.google.com
- Créez un projet OAuth 2.0
- Ajoutez l'URL de callback :
https://votre-backend.railway.app/api/v1/auth/google/callback
-
Variables Railway :
OAUTH_GOOGLE_CLIENT_ID=votre-client-id OAUTH_GOOGLE_CLIENT_SECRET=votre-secret
-
GitHub Settings :
- Allez sur github.com/settings/developers
- Créez une OAuth App
- Authorization callback URL :
https://votre-backend.railway.app/api/v1/auth/github/callback
-
Variables Railway :
OAUTH_GITHUB_CLIENT_ID=votre-client-id OAUTH_GITHUB_CLIENT_SECRET=votre-secret
-
Azure Portal :
- Allez sur portal.azure.com
- Azure Active Directory > App registrations
- Créez une application
- Ajoutez Redirect URI :
https://votre-backend.railway.app/api/v1/auth/microsoft/callback
-
Variables Railway :
OAUTH_MICROSOFT_CLIENT_ID=votre-client-id OAUTH_MICROSOFT_CLIENT_SECRET=votre-secret
-
Configuration via Azure CLI :
az login az ad app update --id VOTRE_APP_ID \ --web-redirect-uris "https://votre-backend.railway.app/api/v1/auth/microsoft/callback"
# URLs
OAUTH_REDIRECT_BASE_URL=https://votre-frontend.vercel.app
OAUTH_CALLBACK_BASE_URL=https://votre-backend.railway.app
# Google
OAUTH_GOOGLE_CLIENT_ID=...
OAUTH_GOOGLE_CLIENT_SECRET=...
# GitHub
OAUTH_GITHUB_CLIENT_ID=...
OAUTH_GITHUB_CLIENT_SECRET=...
# Microsoft
OAUTH_MICROSOFT_CLIENT_ID=...
OAUTH_MICROSOFT_CLIENT_SECRET=...Inscription d'un nouvel utilisateur
Body :
{
"email": "user@example.com",
"username": "username",
"password": "password123",
"full_name": "John Doe"
}Connexion utilisateur
Body :
{
"username": "username",
"password": "password123"
}Response :
{
"access_token": "eyJ...",
"refresh_token": "eyJ...",
"token_type": "bearer"
}Initie le flux OAuth2 (Google, GitHub, Microsoft)
Redirection : Vers le provider OAuth
Callback OAuth2 (géré automatiquement)
Liste des fichiers
Query Parameters :
folder_id(optional) : ID du dossier parentskip(optional) : Pagination offsetlimit(optional) : Nombre de résultats (max 1000)
Upload d'un fichier
Body : FormData avec champ file et folder_id (optionnel)
Response :
{
"id": 1,
"filename": "document.pdf",
"original_filename": "document.pdf",
"file_size": 1024,
"content_type": "application/pdf",
"created_at": "2024-01-01T00:00:00",
"upload_region": "eastus"
}Téléchargement d'un fichier
Headers : Authorization: Bearer {token}
URL de prévisualisation (SAS URL Azure)
Suppression (soft delete - corbeille)
Restauration depuis la corbeille
Suppression définitive
Liste des fichiers dans la corbeille
Recherche de fichiers
Query Parameters :
q: Terme de recherchecontent_type(optional) : Filtrer par typefolder_id(optional) : Filtrer par dossier
Liste des dossiers
Query Parameters :
parent_id(optional) : ID du dossier parentskip,limit: Pagination
Création d'un dossier
Body :
{
"name": "Mon Dossier",
"parent_id": null
}Renommage d'un dossier
Body :
{
"name": "Nouveau Nom"
}Déplacement d'un dossier
Body :
{
"parent_id": 2
}Suppression d'un dossier (soft delete)
Liste des dossiers dans la corbeille
Création d'un lien de partage
Body :
{
"file_id": 1,
"expires_at": "2024-12-31T23:59:59",
"password": "optional_password"
}Response :
{
"token": "uuid-token",
"url": "https://app.com/share/uuid-token"
}Accès à un fichier partagé
Query Parameters :
password(optional) : Mot de passe si requis
Statistiques du dashboard
Response :
{
"total_files": 100,
"total_size": 1073741824,
"storage_used": 536870912,
"storage_available": 107374182400,
"storage_percentage": 0.5
}-
Authentification :
- JWT tokens sécurisés avec expiration
- Refresh tokens pour renouvellement
- Hachage bcrypt (12 rounds)
-
Autorisation :
- Contrôle d'accès par utilisateur
- Vérification des permissions sur chaque requête
- Middleware d'authentification
-
Validation :
- Validation des entrées (Pydantic)
- Validation des fichiers (taille, extension)
- Protection injection SQL (SQLAlchemy)
-
Réseau :
- HTTPS (en production)
- CORS configuré
- Headers de sécurité
-
Stockage :
- Secrets dans variables d'environnement
- Pas de secrets en clair dans le code
- Azure Blob Storage sécurisé
- ✅ Aucun secret en clair dans le code
- ✅ Validation de toutes les entrées
- ✅ Protection contre injection SQL
- ✅ HTTPS partout en production
- ✅ CORS restreint aux domaines autorisés
Solutions :
- Vérifier
VITE_API_URLdans Vercel - Vérifier
CORS_ORIGINSdans Railway - Vérifier que le backend est accessible
Solutions :
- Vérifier
DATABASE_URLdans Railway - Exécuter les migrations :
alembic upgrade head - Vérifier les logs Railway
Solutions :
- Vérifier toutes les variables Azure
- Vérifier que le conteneur existe
- Vérifier les permissions du Storage Account
Solutions :
- Vérifier les URLs de callback dans les providers
- Vérifier les variables d'environnement OAuth
- Vérifier les logs backend pour les erreurs
Solutions :
- Vider le cache du navigateur (Ctrl+Shift+R)
- Vérifier le Service Worker (DevTools > Application)
- Désinscrire le Service Worker si nécessaire
- Authentification JWT
- Upload/téléchargement
- Gestion fichiers de base
- Gestion dossiers
- Navigation breadcrumbs
- Recherche
- Liens publics
- Partage sécurisé
- Thème clair/sombre
- Animations
- Responsive design
- Historique modifications
- Commentaires
- OAuth2 (Google, GitHub, Microsoft)
- Corbeille avec restauration
- Application mobile (React Native)
- Chiffrement fichiers
- Versioning complet
- Synchronisation temps réel (WebSocket)
- Collaboration en temps réel
Dernière mise à jour : Janvier 2026















