Files
EM2_ERP/em2rp/firestore.rules
ElPoyo beaabceda4 feat: Intégration d'un système complet d'alertes et de notifications par email
Cette mise à jour majeure introduit un système de notifications robuste, centré sur la création d'alertes et l'envoi d'emails via des Cloud Functions. Elle inclut la gestion des préférences utilisateur, la création automatique d'alertes lors d'événements critiques et une nouvelle interface dédiée.

**Backend (Cloud Functions) :**
- **Nouveau service d'alerting (`createAlert`, `processEquipmentValidation`) :**
    - `createAlert` : Nouvelle fonction pour créer une alerte. Elle détermine les utilisateurs à notifier (admins, workforce d'événement) et gère la persistance dans Firestore.
    - `processEquipmentValidation` : Endpoint appelé lors de la validation du matériel (chargement/déchargement). Il analyse l'état de l'équipement (`LOST`, `MISSING`, `DAMAGED`) et crée automatiquement les alertes correspondantes.
- **Système d'envoi d'emails (`sendAlertEmail`, `sendDailyDigest`) :**
    - `sendAlertEmail` : Cloud Function `onCall` pour envoyer un email d'alerte individuel. Elle respecte les préférences de notification de l'utilisateur (canal email, type d'alerte).
    - `sendDailyDigest` : Tâche planifiée (tous les jours à 8h) qui envoie un email récapitulatif des alertes non lues des dernières 24 heures aux utilisateurs concernés.
    - Ajout de templates HTML (`base-template`, `alert-individual`, `alert-digest`) avec `Handlebars` pour des emails riches.
    - Configuration centralisée du SMTP via des variables d'environnement (`.env`).
- **Triggers Firestore (`onEventCreated`, `onEventUpdated`) :**
    - Des triggers créent désormais des alertes d'information lorsqu'un événement est créé ou que de nouveaux membres sont ajoutés à la workforce.
- **Règles Firestore :**
    - Mises à jour pour autoriser les utilisateurs authentifiés à créer et modifier leurs propres alertes (marquer comme lue, supprimer), tout en sécurisant les accès.

**Frontend (Flutter) :**
- **Nouvel `AlertService` et `EmailService` :**
    - `AlertService` : Centralise la logique de création, lecture et gestion des alertes côté client en appelant les nouvelles Cloud Functions.
    - `EmailService` : Service pour déclencher l'envoi d'emails via la fonction `sendAlertEmail`. Il contient la logique pour déterminer si une notification doit être immédiate (critique) ou différée (digest).
- **Nouvelle page de Notifications (`/alerts`) :**
    - Interface dédiée pour lister toutes les alertes de l'utilisateur, avec des onglets pour filtrer par catégorie (Toutes, Événement, Maintenance, Équipement).
    - Permet de marquer les alertes comme lues, de les supprimer et de tout marquer comme lu.
- **Intégration dans l'UI :**
    - Ajout d'un badge de notification dans la `CustomAppBar` affichant le nombre d'alertes non lues en temps réel.
    - Le `AutoLoginWrapper` gère désormais la redirection vers des routes profondes (ex: `/alerts`) depuis une URL.
- **Gestion des Préférences de Notification :**
    - Ajout d'un widget `NotificationPreferencesWidget` dans la page "Mon Compte".
    - Les utilisateurs peuvent désormais activer/désactiver les notifications par email, ainsi que filtrer par type d'alerte (événements, maintenance, etc.).
    - Le `UserModel` et `LocalUserProvider` ont été étendus pour gérer ce nouveau modèle de préférences.
- **Création d'alertes contextuelles :**
    - Le service `EventFormService` crée maintenant automatiquement une alerte lorsqu'un événement est créé ou modifié.
    - La page de préparation d'événement (`EventPreparationPage`) appelle `processEquipmentValidation` à la fin de chaque étape pour une détection automatisée des anomalies.

**Dépendances et CI/CD :**
- Ajout des dépendances `cloud_functions` et `timeago` (Flutter), et `nodemailer`, `handlebars`, `dotenv` (Node.js).
- Ajout de scripts de déploiement PowerShell (`deploy_functions.ps1`, `deploy_firestore_rules.ps1`) pour simplifier les mises en production.
2026-01-15 23:15:25 +01:00

185 lines
7.6 KiB
Plaintext

rules_version = '2';
// ============================================================================
// RÈGLES FIRESTORE SÉCURISÉES - VERSION PRODUCTION
// ============================================================================
// Date de création : 14 janvier 2026
// Objectif : Bloquer tous les accès directs à Firestore depuis les clients
// Seules les Cloud Functions (côté serveur) peuvent lire/écrire les données
// ============================================================================
service cloud.firestore {
match /databases/{database}/documents {
// ========================================================================
// RÈGLE GLOBALE PAR DÉFAUT : TOUT BLOQUER
// ========================================================================
// Cette règle empêche tout accès direct depuis les clients (web/mobile)
// Les Cloud Functions ont un accès admin et ne sont pas affectées
match /{document=**} {
// ❌ REFUSER TOUS LES ACCÈS directs depuis les clients
allow read, write: if false;
}
// ========================================================================
// EXCEPTIONS OPTIONNELLES pour les listeners temps réel
// ========================================================================
// Si vous avez besoin de listeners en temps réel pour certaines collections,
// décommentez les règles ci-dessous.
//
// ⚠️ IMPORTANT : Ces règles permettent UNIQUEMENT la LECTURE.
// Toutes les ÉCRITURES doivent passer par les Cloud Functions.
// ========================================================================
/*
// Événements : Lecture seule pour utilisateurs authentifiés
match /events/{eventId} {
allow read: if request.auth != null;
allow write: if false; // ❌ Écriture interdite
}
// Équipements : Lecture seule pour utilisateurs authentifiés
match /equipments/{equipmentId} {
allow read: if request.auth != null;
allow write: if false; // ❌ Écriture interdite
}
// Conteneurs : Lecture seule pour utilisateurs authentifiés
match /containers/{containerId} {
allow read: if request.auth != null;
allow write: if false; // ❌ Écriture interdite
}
// Maintenances : Lecture seule pour utilisateurs authentifiés
match /maintenances/{maintenanceId} {
allow read: if request.auth != null;
allow write: if false; // ❌ Écriture interdite
}
*/
// Alertes : Lecture et création pour utilisateurs authentifiés
// Le trigger backend (onAlertCreated) s'occupe d'assigner les bonnes personnes
match /alerts/{alertId} {
allow read: if request.auth != null;
allow create: if request.auth != null
&& request.resource.data.createdBy == request.auth.uid; // Vérifier que l'utilisateur crée l'alerte en son nom
allow update: if request.auth != null
&& (
// L'utilisateur peut marquer comme lue uniquement s'il est assigné
(request.auth.uid in resource.data.assignedTo && request.resource.data.diff(resource.data).affectedKeys().hasOnly(['isRead', 'readAt']))
// Ou le backend peut tout modifier (processed, assignedTo, etc.)
|| !('createdBy' in resource.data) // Le trigger backend n'a pas de createdBy
);
allow delete: if request.auth != null && request.auth.uid in resource.data.assignedTo;
}
/*
// Utilisateurs : Lecture de son propre profil uniquement
match /users/{userId} {
allow read: if request.auth != null && request.auth.uid == userId;
allow write: if false; // ❌ Écriture interdite
}
// Types d'événements : Lecture seule
match /eventTypes/{typeId} {
allow read: if request.auth != null;
allow write: if false; // ❌ Écriture interdite
}
// Options : Lecture seule
match /options/{optionId} {
allow read: if request.auth != null;
allow write: if false; // ❌ Écriture interdite
}
// Clients : Lecture seule
match /customers/{customerId} {
allow read: if request.auth != null;
allow write: if false; // ❌ Écriture interdite
}
*/
// ========================================================================
// RÈGLES AVANCÉES avec vérification des permissions (OPTIONNEL)
// ========================================================================
// Décommentez ces règles si vous voulez des permissions basées sur les rôles
// pour la lecture en temps réel
//
// ⚠️ ATTENTION : Ces règles nécessitent une lecture supplémentaire dans
// la collection users, ce qui peut impacter les performances et les coûts.
// ========================================================================
/*
// Fonction helper : Récupérer les permissions de l'utilisateur
function getUserPermissions() {
return get(/databases/$(database)/documents/users/$(request.auth.uid)).data.permissions;
}
// Fonction helper : Vérifier si l'utilisateur a une permission
function hasPermission(permission) {
return request.auth != null && permission in getUserPermissions();
}
// Équipements : Lecture uniquement si permission view_equipment
match /equipments/{equipmentId} {
allow read: if hasPermission('view_equipment') || hasPermission('manage_equipment');
allow write: if false; // ❌ Écriture interdite
}
// Événements : Lecture selon permissions
match /events/{eventId} {
allow read: if hasPermission('view_events') || hasPermission('edit_event');
allow write: if false; // ❌ Écriture interdite
}
// Conteneurs : Lecture uniquement si permission view_equipment
match /containers/{containerId} {
allow read: if hasPermission('view_equipment') || hasPermission('manage_equipment');
allow write: if false; // ❌ Écriture interdite
}
// Maintenances : Lecture uniquement si permission view_equipment
match /maintenances/{maintenanceId} {
allow read: if hasPermission('view_equipment') || hasPermission('manage_equipment');
allow write: if false; // ❌ Écriture interdite
}
*/
}
}
// ============================================================================
// NOTES DE SÉCURITÉ
// ============================================================================
//
// 1. RÈGLE PAR DÉFAUT (allow read, write: if false)
// - Bloque TOUS les accès directs depuis les clients
// - Les Cloud Functions ne sont PAS affectées (elles ont un accès admin)
// - C'est la configuration la PLUS SÉCURISÉE
//
// 2. EXCEPTIONS DE LECTURE (commentées par défaut)
// - Permettent les listeners en temps réel pour certaines collections
// - UNIQUEMENT la LECTURE est autorisée
// - Les ÉCRITURES restent bloquées (doivent passer par Cloud Functions)
//
// 3. RÈGLES BASÉES SUR LES RÔLES (commentées par défaut)
// - Permettent un contrôle plus fin basé sur les permissions utilisateur
// - ⚠️ Impact sur les performances (lecture supplémentaire de la collection users)
// - À utiliser uniquement si nécessaire
//
// 4. TESTS APRÈS DÉPLOIEMENT
// - Vérifier que les Cloud Functions fonctionnent toujours
// - Tester qu'un accès direct depuis la console échoue
// - Surveiller les logs : firebase functions:log
//
// 5. ROLLBACK EN CAS DE PROBLÈME
// - Remplacer temporairement par :
// match /{document=**} {
// allow read, write: if request.auth != null;
// }
// - Déployer rapidement : firebase deploy --only firestore:rules
//
// ============================================================================