# SmartAuth SmartAuth est le module d'authentification JWT pour Dolibarr, conçu pour les applications SmartMaker. ## Pourquoi SmartAuth ? Nativement Dolibarr propose une API où chaque utilisateur dispose d'une seule clé d'API donnant accès à tout son périmètre fonctionnel. Ce fonctionnement pose problème : si vous développez une application mobile qui ne devrait avoir accès qu'à l'agenda de l'utilisateur, avec la clé native l'application pourra également accéder aux factures et autres éléments. ### Notre approche Avec SmartAuth, un utilisateur peut avoir **autant de clés d'API qu'il souhaite**, chaque clé ayant ses propres droits. Si une clé est liée à une application, elle ne sera pas réutilisable par une autre. Avantages : * **Cloisonnement des accès** : chaque application a sa propre clé * **Révocation ciblée** : si un appareil est volé, supprimez uniquement sa clé * **Traçabilité** : journaux de connexion par appareil {{.:pasted:20250903-082553.png?direct}} ### Journaux de connexion Accédez aux journaux pour détecter des actions incorrectes et gérer les accès : {{.:pasted:20250903-082923.png?direct}} ## Installation Téléchargez SmartAuth gratuitement sur le DoliStore : https://www.dolistore.com/product.php?id=2509&l=fr ## Flux d'authentification JWT ### Schéma global ``` ┌─────────────┐ ┌─────────────┐ ┌─────────────┐ │ Mobile │ │ api.php │ │ Dolibarr │ │ (React) │ │ (JWT) │ │ (PHP) │ └──────┬──────┘ └──────┬──────┘ └──────┬──────┘ │ │ │ │ 1. POST /login │ │ │ {login, password} │ │ │──────────────────────>│ │ │ │ 2. Vérifier user │ │ │──────────────────────>│ │ │ │ │ │ 3. User valide │ │ │<──────────────────────│ │ 4. {accessToken, │ │ │ refreshToken} │ │ │<──────────────────────│ │ │ │ │ │ 5. GET /items │ │ │ Authorization: Bearer│ │ │──────────────────────>│ │ │ │ 6. Valider token │ │ │ + charger user │ │ │──────────────────────>│ │ │ │ │ 7. Données │ │ │<──────────────────────│ │ ``` ### Tokens JWT SmartAuth utilise deux tokens : ^ Token ^ Durée ^ Usage ^ | ''accessToken'' | 15 minutes | Authentifier les requêtes API | | ''refreshToken'' | 7 jours | Obtenir un nouveau accessToken | ### Endpoints d'authentification ^ Méthode ^ Route ^ Description ^ Protégé ^ | GET | ''/login'' | Récupérer les infos de connexion (logo, etc.) | Non | | POST | ''/login'' | Authentification (login + password) | Non | | GET | ''/refresh'' | Renouveler l'accessToken | Non | | POST | ''/logout'' | Déconnexion (invalide le refreshToken) | Oui | | POST | ''/device'' | Enregistrer un appareil pour les notifications | Oui | ## Configuration côté api.php ### Routes d'authentification ``` Ne modifiez pas ce fichier sauf si vous savez ce que vous faites. ## Utilisation côté React ### Configuration du Provider ``` // appConfig.js export const config = { api: { prefixUrl: import.meta.env.VITE_API_URL, paths: { login: "login", logout: "logout", refresh: "refresh", }, }, }; ``` ### Login avec useApi ``` import { useApi, useGlobalStates } from '@cap-rel/smartcommon'; const LoginPage = () => { const api = useApi(); const gst = useGlobalStates(); const handleLogin = async (data) => { try { const user = await api.login(data); gst.local.set('session', user); } catch (error) { console.error('Login failed:', error); } }; return (
); }; ``` ### Refresh automatique Le hook ''useApi'' gère automatiquement le refresh du token : ``` // Quand l'accessToken expire, useApi : // 1. Intercepte l'erreur 401 // 2. Appelle GET /refresh avec le refreshToken // 3. Met à jour les tokens en session // 4. Rejoue la requête originale ``` ### Logout ``` const handleLogout = async () => { await api.private.post('logout'); setSession(null); navigate('/login'); }; ``` ## Gestion des appareils ### Enregistrer un appareil Pour les notifications push, enregistrez l'appareil après le login : ``` const registerDevice = async (pushToken) => { await api.private.post('device', { json: { token: pushToken, platform: 'android', // ou 'ios', 'web' name: 'Mon téléphone', }, }); }; ``` ### Structure côté Dolibarr SmartAuth stocke les appareils dans une table dédiée : ^ Champ ^ Description ^ | ''fk_user'' | ID de l'utilisateur Dolibarr | | ''token'' | Token push de l'appareil | | ''platform'' | Plateforme (android, ios, web) | | ''name'' | Nom de l'appareil | | ''last_used'' | Date de dernière utilisation | ## Sécurité ### Bonnes pratiques * **HTTPS obligatoire** : Les tokens JWT transitent en clair * **Stockage sécurisé** : Utilisez ''useGlobalStates'' qui persiste en localStorage chiffré * **Rotation des tokens** : Le refreshToken est à usage unique * **Révocation** : Supprimez les clés depuis l'interface Dolibarr ### En cas de vol d'appareil 1. Connectez-vous à Dolibarr 2. Allez dans votre profil utilisateur 3. Supprimez la clé API de l'appareil volé 4. Les tokens associés seront immédiatement invalidés ## Réinitialisation du mot de passe SmartAuth inclut un système complet de réinitialisation de mot de passe par token. ### Endpoints ^ Méthode ^ Route ^ Description ^ Protégé ^ | POST | ''/password/reset'' | Demande de réinitialisation (envoi d'email) | Non | | POST | ''/password/confirm'' | Confirmation avec token | Non | | POST | ''/password/change'' | Changement de mot de passe (utilisateur connecté) | Oui | ### Demander une réinitialisation ``` // Côté React const requestReset = async (email) => { await api.public.post('password/reset', { json: { email } }); }; ``` Le serveur : - Vérifie l'utilisateur (rate limiting : 3 tentatives par 15 minutes) - Génère un token avec expiration (1 heure) - Envoie un email avec le lien de réinitialisation ### Confirmer la réinitialisation ``` const confirmReset = async (token, newPassword) => { await api.public.post('password/confirm', { json: { token, password: newPassword } }); }; ``` ### Changer le mot de passe (utilisateur connecté) ``` const changePassword = async (oldPassword, newPassword) => { await api.private.post('password/change', { json: { current_password: oldPassword, new_password: newPassword } }); }; ``` ## Fichiers temporaires (SmartTempFile) SmartAuth fournit un système de fichiers temporaires pour le téléchargement de binaires (exports Excel, PDF générés, etc.). ### Endpoints ^ Méthode ^ Route ^ Description ^ | GET | ''/temp-file/{token}'' | Téléchargement base64 (JSON) | | GET | ''/temp-file/{token}/binary'' | Téléchargement binaire (stream) | | DELETE | ''/temp-file/{token}'' | Suppression du fichier | ### Utilisation côté PHP (Controller) ``` use SmartAuth\Api\SmartTempFile; public function exportExcel($payload) { // Générer le fichier $filePath = '/tmp/export.xlsx'; // ... génération du fichier ... // Stocker en fichier temporaire (TTL défaut : 1 heure) $tempFile = new SmartTempFile(); $token = $tempFile->store($filePath, [ 'filename' => 'export.xlsx', 'mimetype' => 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet', 'user_id' => $payload['user_id'], 'entity' => $payload['entity'], ]); return [['token' => $token], 200]; } ``` ### Utilisation côté React ``` // Téléchargement binaire const downloadExport = async (token) => { const response = await api.get(`temp-file/${token}/binary`, { raw: true }); const blob = await response.blob(); // Créer un lien de téléchargement const url = URL.createObjectURL(blob); const a = document.createElement('a'); a.href = url; a.download = 'export.xlsx'; a.click(); URL.revokeObjectURL(url); }; ``` ## CORS SmartAuth gère automatiquement les headers CORS pour les requêtes cross-origin. ### Configuration ^ Constante Dolibarr ^ Description ^ Défaut ^ | ''SMARTAUTH_CORS_ORIGIN'' | Origine autorisée | ''*'' | | ''SMARTAUTH_CORS_METHODS'' | Méthodes autorisées | ''GET, POST, PUT, DELETE, PATCH, OPTIONS'' | | ''SMARTAUTH_CORS_HEADERS'' | Headers autorisés | ''Content-Type, Authorization, X-DeviceId'' | Les requêtes OPTIONS (preflight) sont gérées automatiquement.