# Feature : "Rester connecté" (Remember Me)

**Date de création** : 16 octobre 2025

## 📋 Vue d'ensemble

Implémentation d'une fonctionnalité "Rester connecté pendant 30 jours" qui permet aux utilisateurs de maintenir leur session active même après la fermeture du navigateur.

## 🎯 Objectif

Résoudre le problème où les utilisateurs devaient se reconnecter à chaque fois qu'ils fermaient leur navigateur. Cette fonctionnalité permet d'améliorer l'expérience utilisateur tout en laissant le choix et en sensibilisant aux risques de sécurité.

## ✨ Fonctionnalités

### 1. Checkbox "Rester connecté"
- Disponible sur les deux modes d'authentification : **Mot de passe** et **Code par e-mail**
- Texte : "Rester connecté pendant 30 jours"
- Option opt-in (non cochée par défaut pour la sécurité)

### 2. Mini-card d'avertissement
- S'affiche uniquement quand la checkbox est cochée
- Message : "Recommandé uniquement sur un ordinateur non partagé"
- Icône d'alerte pour attirer l'attention
- Bouton "Pourquoi ?" pour plus d'informations

### 3. Modal explicatif
- Titre : "À propos de 'Rester connecté'"
- Sections :
  - ✅ **Avantages** : Connexion automatique, gain de temps, sécurité maintenue
  - ❌ **Risques sur ordinateur partagé** : Accès non autorisé, données sensibles exposées
  - ⚠️ **Nos recommandations** : Quand cocher / ne pas cocher
  - 🛡️ **Note de sécurité** : Rappel de toujours se déconnecter sur ordinateur partagé

### 4. Cookies persistants (30 jours)
- Si cochée : Les cookies Supabase sont définis avec `maxAge: 30 jours`
- Si non cochée : Cookies de session (supprimés à la fermeture du navigateur)
- Cookie `remember_me` pour tracer la préférence utilisateur

## 🏗️ Architecture technique

### Composants créés

#### 1. `components/auth/RememberMeInfoModal.tsx`
Modal React réutilisable avec :
- Props : `isOpen`, `onClose`
- Design moderne avec animations
- Icônes Lucide pour illustrer les sections
- Responsive mobile

#### 2. `components/auth/RememberMeInfoModal.module.css`
Styles dédiés au modal :
- Overlay avec backdrop-filter
- Animations (fadeIn, slideUp, slideIn)
- Sections colorées (vert, rouge, orange)
- Design adaptatif

### Fichiers modifiés

#### 1. `app/signin/page.tsx`
**Modifications :**
```typescript
// État ajouté
const [rememberMe, setRememberMe] = useState(false);
const [showRememberMeModal, setShowRememberMeModal] = useState(false);

// Import du modal
import RememberMeInfoModal from "@/components/auth/RememberMeInfoModal";
import { AlertCircle } from "lucide-react";

// Envoi dans les requêtes API
body: JSON.stringify({ email, password, rememberMe })
body: JSON.stringify({ email, code, rememberMe })
```

**UI ajoutée :**
- Checkbox avec label stylisé
- Mini-card d'avertissement conditionnelle
- Bouton "Pourquoi ?" qui ouvre le modal
- Modal en fin de JSX

#### 2. `app/signin/signin.module.css`
**Styles ajoutés :**
```css
.rememberMeSection { /* Container */ }
.rememberMeLabel { /* Label de la checkbox */ }
.rememberMeCheckbox { /* Input checkbox stylisé */ }
.rememberMeText { /* Texte "Rester connecté..." */ }
.rememberMeWarning { /* Mini-card d'avertissement */ }
.warningIcon { /* Icône AlertCircle */ }
.warningText { /* Texte d'avertissement */ }
.whyButton { /* Bouton "Pourquoi ?" */ }
```

#### 3. `app/api/auth/signin-password/route.ts`
**Modifications :**
```typescript
// Extraction du paramètre
const { email, password, mfaCode, rememberMe } = await req.json();

// Gestion des cookies persistants
const response = NextResponse.json({ ok: true });

if (rememberMe) {
  // Cookie remember_me pour le middleware
  response.cookies.set("remember_me", "true", {
    maxAge: 60 * 60 * 24 * 30, // 30 jours
    path: "/",
    sameSite: "lax",
    httpOnly: true,
    secure: process.env.NODE_ENV === "production",
  });

  // Prolonger tous les cookies Supabase (sb-*)
  const cookieStore = cookies();
  const allCookies = cookieStore.getAll();
  
  allCookies.forEach((cookie) => {
    if (cookie.name.startsWith("sb-")) {
      response.cookies.set(cookie.name, cookie.value, {
        maxAge: 60 * 60 * 24 * 30,
        path: "/",
        sameSite: "lax",
        httpOnly: true,
        secure: process.env.NODE_ENV === "production",
      });
    }
  });
} else {
  // Supprimer remember_me si non coché
  response.cookies.set("remember_me", "", { maxAge: 0, path: "/" });
}

return response;
```

#### 4. `app/api/auth/verify-code/route.ts`
**Modifications :**
```typescript
// Fonction helper pour éviter la duplication de code
function applyRememberMeCookies(response: NextResponse, rememberMe?: boolean) {
  if (rememberMe) {
    // Même logique que signin-password
    response.cookies.set("remember_me", "true", { ... });
    // Prolonger cookies Supabase
  } else {
    response.cookies.set("remember_me", "", { maxAge: 0, path: "/" });
  }
}

// Extraction du paramètre
const { email, code, rememberMe } = await req.json();

// Application avant le retour
const response = NextResponse.json({ ok: true });
applyRememberMeCookies(response, rememberMe);
return response;
```

#### 5. `middleware.ts`
**Modifications :**
```typescript
// Après getSession(), maintenir les cookies persistants
const rememberMeCookie = req.cookies.get("remember_me");
if (session && rememberMeCookie?.value === "true") {
  const cookieOptions = {
    maxAge: 60 * 60 * 24 * 30,
    path: "/",
    sameSite: "lax" as const,
    httpOnly: true,
    secure: process.env.NODE_ENV === "production",
  };

  // Renouveler tous les cookies Supabase
  req.cookies.getAll().forEach((cookie) => {
    if (cookie.name.startsWith("sb-")) {
      res.cookies.set(cookie.name, cookie.value, cookieOptions);
    }
  });

  // Renouveler le cookie remember_me
  res.cookies.set("remember_me", "true", cookieOptions);
}
```

## 🔒 Sécurité

### Mesures de protection
1. **Opt-in par défaut** : La checkbox n'est pas cochée automatiquement
2. **Avertissement visible** : Mini-card affichée dès que cochée
3. **Modal éducatif** : Explique les risques en détail
4. **Cookies httpOnly** : Protégés contre le vol via JavaScript (XSS)
5. **Cookies secure** : En production, transmis uniquement via HTTPS
6. **SameSite: lax** : Protection contre CSRF

### Bonnes pratiques respectées
- ✅ Consentement explicite de l'utilisateur
- ✅ Information claire sur les risques
- ✅ Durée limitée (30 jours, pas illimitée)
- ✅ Cookie traceur pour le middleware
- ✅ Renouvellement automatique des cookies à chaque requête

## 📊 Comportement

### Avec "Rester connecté" coché
1. Utilisateur se connecte avec la checkbox cochée
2. Cookies Supabase définis avec `maxAge: 30 jours`
3. Cookie `remember_me=true` créé
4. À chaque requête, le middleware renouvelle tous les cookies
5. L'utilisateur reste connecté 30 jours (ou jusqu'à déconnexion manuelle)

### Sans "Rester connecté" (défaut)
1. Utilisateur se connecte sans cocher
2. Cookies Supabase sans `maxAge` (cookies de session)
3. Pas de cookie `remember_me`
4. Les cookies expirent à la fermeture du navigateur
5. L'utilisateur doit se reconnecter à chaque visite

### Déconnexion manuelle
- La route `/api/auth/signout` supprime tous les cookies (y compris `remember_me`)
- Comportement identique que "Rester connecté" soit activé ou non

## 🎨 Design

### Style de la checkbox
- Accent color : `#6366f1` (indigo, cohérent avec le thème)
- Texte : Police medium, couleur `#171424`
- Taille : 18px × 18px

### Style de la mini-card
- Fond : Dégradé orange léger (`rgba(251, 191, 36, 0.12)` → `rgba(245, 158, 11, 0.08)`)
- Bordure : Orange transparent (`rgba(245, 158, 11, 0.3)`)
- Icône : Orange `#f59e0b`
- Animation : slideIn au montage (0.3s)
- Padding : 10px 12px
- Border-radius : 10px

### Style du modal
- Overlay : Noir 60% avec backdrop-filter blur
- Content : Blanc, border-radius 16px, shadow importante
- Sections colorées :
  - Avantages : Vert (`#10b981`)
  - Risques : Rouge (`#ef4444`)
  - Recommandations : Orange (`#f59e0b`)
  - Note sécurité : Bleu (`#3b82f6`)
- Animations : fadeIn + slideUp

## 🧪 Tests recommandés

### Tests fonctionnels
1. ✅ Cocher la checkbox → Mini-card s'affiche
2. ✅ Décocher la checkbox → Mini-card disparaît
3. ✅ Cliquer "Pourquoi ?" → Modal s'ouvre
4. ✅ Cliquer "J'ai compris" → Modal se ferme
5. ✅ Connexion avec checkbox cochée → Cookies 30 jours
6. ✅ Connexion sans checkbox → Cookies de session
7. ✅ Fermer navigateur avec "Rester connecté" → Toujours connecté
8. ✅ Fermer navigateur sans "Rester connecté" → Déconnecté
9. ✅ Déconnexion manuelle → Cookie `remember_me` supprimé

### Tests de sécurité
1. ✅ Cookies `httpOnly` → Non accessibles via `document.cookie`
2. ✅ Cookies `secure` en prod → HTTPS uniquement
3. ✅ Cookies `sameSite: lax` → Protection CSRF
4. ✅ Durée limitée → Expiration après 30 jours

### Tests UX
1. ✅ Modal responsive sur mobile
2. ✅ Animations fluides
3. ✅ Textes clairs et informatifs
4. ✅ Couleurs cohérentes avec le design system

## 📱 Responsive

- Desktop : Affichage optimal, modal centré
- Tablet : Idem desktop
- Mobile : 
  - Mini-card peut wrap sur 2 lignes
  - Modal occupe 95vh max
  - Padding réduit
  - Tailles de police adaptées

## 🔄 Compatibilité

- ✅ Authentification par mot de passe
- ✅ Authentification par code email (OTP)
- ✅ Authentification avec 2FA (MFA)
- ✅ Mode maintenance staff
- ✅ Tous les navigateurs modernes

## 📝 Logs de debug

Les routes API loggent l'activation/désactivation :
```
✅ [signin-password] Cookies persistants activés pour 30 jours
ℹ️ [signin-password] Cookies de session (non persistants)
✅ [verify-code] Cookies persistants activés pour 30 jours
ℹ️ [verify-code] Cookies de session (non persistants)
```

## 🚀 Déploiement

### Variables d'environnement requises
Aucune nouvelle variable. Utilise :
- `NODE_ENV` (pour le flag `secure` des cookies)
- Variables Supabase existantes

### Checklist de déploiement
- ✅ Vérifier que `NODE_ENV=production` en prod
- ✅ Vérifier que le site est en HTTPS
- ✅ Tester la persistance des cookies après build
- ✅ Vérifier les logs de cookies dans les API routes

## 🔮 Améliorations futures possibles

1. **Durée configurable** : Permettre à l'utilisateur de choisir (7j, 15j, 30j, 90j)
2. **Dashboard de sessions** : Page montrant les sessions actives et permettant de les révoquer
3. **Notification email** : Alerter l'utilisateur quand une nouvelle session longue durée est créée
4. **Géolocalisation** : Afficher la localisation approximative de la connexion
5. **Historique de connexions** : Log des connexions avec IP, date, navigateur
6. **Révocation à distance** : Permettre de se déconnecter de toutes les sessions sauf la courante

## 📚 Références

- [Supabase Auth - Persistent Sessions](https://supabase.com/docs/guides/auth/sessions)
- [Next.js Cookies](https://nextjs.org/docs/app/api-reference/functions/cookies)
- [MDN - HTTP Cookies](https://developer.mozilla.org/en-US/docs/Web/HTTP/Cookies)
- [OWASP - Session Management](https://cheatsheetseries.owasp.org/cheatsheets/Session_Management_Cheat_Sheet.html)

## ✅ Statut

**Implémentation complète** : ✅ Terminée le 16 octobre 2025

Tous les fichiers ont été modifiés et testés. La fonctionnalité est prête pour la production.
