mirror of
https://github.com/R0m1k3/noteflow.git
synced 2026-10-20 13:48:20 +02:00
Feature: Ajout du support OAuth2 et Service Account pour Google Calendar
Ajout de deux méthodes d'authentification au choix pour Google Calendar : 1. **OAuth 2.0** (méthode existante améliorée) : - ✅ Prompt de sélection de compte Google ('select_account consent') - ✅ Gestion dynamique du redirect_uri avec APP_URL - ✅ Idéal pour accès au calendrier personnel avec consentement 2. **Service Account** (nouvelle méthode) : - ✅ Authentification via clé JSON sans interaction utilisateur - ✅ Parfait pour calendriers partagés en entreprise - ✅ Synchronisation automatique en arrière-plan - ✅ Configuration de l'email du calendrier à synchroniser ## Backend (routes/calendar.routes.js) : - Ajout des constantes AUTH_TYPES (oauth2, service_account) - Fonction getAuthType() pour récupérer la méthode configurée - Fonction getServiceAccountClient() pour Service Account - Fonction getCalendarClient() unifiée qui choisit la bonne méthode - Route /auth-status mise à jour pour retourner le type d'auth - Route /sync adaptée pour supporter les deux méthodes - Support du calendrier email personnalisé pour Service Account ## Frontend (src/pages/Index.tsx) : - Menu déroulant pour choisir entre OAuth2 et Service Account - Interface conditionnelle selon la méthode choisie - Champ textarea pour la clé JSON du Service Account - Champ email pour spécifier le calendrier à synchroniser - Affichage du type d'authentification dans le statut - Amélioration de l'UI avec descriptions claires ## Documentation : - OAUTH_SETUP.md : Guide complet mis à jour avec les deux méthodes - Section dédiée au choix de la méthode - Guide pas à pas pour Service Account - Dépannage pour les deux méthodes - README_GOOGLE_CALENDAR.md : Guide de démarrage rapide (nouveau) - Comparaison des deux méthodes - Configuration rapide pour chaque méthode - Liens vers la documentation complète Cette implémentation offre une flexibilité maximale pour s'adapter à différents cas d'usage : personnel (OAuth2) ou professionnel (Service Account).
This commit is contained in:
4 files changed
+415
-65
No files matched your search
+124
-44
@@ -1345,52 +1345,129 @@ const Index = () => {
|
||||
<CardHeader>
|
||||
<CardTitle className="flex items-center gap-2">
|
||||
<CalendarIcon className="h-5 w-5" />
|
||||
Configuration Google Calendar OAuth 2.0
|
||||
Configuration Google Calendar
|
||||
</CardTitle>
|
||||
</CardHeader>
|
||||
<CardContent className="space-y-4">
|
||||
{/* Choix du type d'authentification */}
|
||||
<div className="space-y-2">
|
||||
<Label htmlFor="google-client-id">Client ID Google</Label>
|
||||
<Input
|
||||
id="google-client-id"
|
||||
type="text"
|
||||
placeholder="123456789-abcdef.apps.googleusercontent.com"
|
||||
value={settings.google_client_id || ''}
|
||||
onChange={(e) => setSettings({ ...settings, google_client_id: e.target.value })}
|
||||
/>
|
||||
<Label htmlFor="google-auth-type">Méthode d'authentification</Label>
|
||||
<Select
|
||||
value={settings.google_auth_type || 'oauth2'}
|
||||
onValueChange={(value) => setSettings({ ...settings, google_auth_type: value })}
|
||||
>
|
||||
<SelectTrigger id="google-auth-type">
|
||||
<SelectValue placeholder="Sélectionnez une méthode" />
|
||||
</SelectTrigger>
|
||||
<SelectContent>
|
||||
<SelectItem value="oauth2">
|
||||
<div className="flex flex-col">
|
||||
<span className="font-medium">OAuth 2.0</span>
|
||||
<span className="text-xs text-muted-foreground">
|
||||
Calendrier personnel avec consentement utilisateur
|
||||
</span>
|
||||
</div>
|
||||
</SelectItem>
|
||||
<SelectItem value="service_account">
|
||||
<div className="flex flex-col">
|
||||
<span className="font-medium">Service Account</span>
|
||||
<span className="text-xs text-muted-foreground">
|
||||
Clé JSON pour calendriers partagés (sans interaction)
|
||||
</span>
|
||||
</div>
|
||||
</SelectItem>
|
||||
</SelectContent>
|
||||
</Select>
|
||||
<p className="text-xs text-muted-foreground">
|
||||
<strong>OAuth 2.0</strong> : Pour accéder au calendrier personnel avec autorisation de l'utilisateur.<br/>
|
||||
<strong>Service Account</strong> : Pour accéder à des calendriers partagés sans interaction utilisateur.
|
||||
</p>
|
||||
</div>
|
||||
|
||||
<div className="space-y-2">
|
||||
<Label htmlFor="google-client-secret">Client Secret Google</Label>
|
||||
<Input
|
||||
id="google-client-secret"
|
||||
type="password"
|
||||
placeholder="GOCSPX-..."
|
||||
value={settings.google_client_secret || ''}
|
||||
onChange={(e) => setSettings({ ...settings, google_client_secret: e.target.value })}
|
||||
/>
|
||||
<p className="text-sm text-muted-foreground">
|
||||
Créez un projet OAuth 2.0 sur{' '}
|
||||
<a href="https://console.cloud.google.com/apis/credentials" target="_blank" rel="noopener noreferrer" className="text-primary hover:underline">
|
||||
Google Cloud Console
|
||||
</a>
|
||||
{' '}et activez l'API Google Calendar.
|
||||
</p>
|
||||
<div className="p-3 bg-yellow-50 dark:bg-yellow-900/20 border border-yellow-200 dark:border-yellow-800 rounded-lg">
|
||||
<p className="text-sm font-semibold text-yellow-900 dark:text-yellow-200 mb-1">
|
||||
⚠️ IMPORTANT : URI de redirection autorisée
|
||||
</p>
|
||||
<p className="text-xs text-yellow-800 dark:text-yellow-300 mb-2">
|
||||
Ajoutez cette URL exacte dans la console Google Cloud (OAuth 2.0 Client IDs → URIs de redirection autorisées) :
|
||||
</p>
|
||||
<code className="block p-2 bg-white dark:bg-gray-800 border border-yellow-300 dark:border-yellow-700 rounded text-xs font-mono break-all">
|
||||
{window.location.origin}/api/calendar/oauth-callback
|
||||
</code>
|
||||
<p className="text-xs text-yellow-800 dark:text-yellow-300 mt-2">
|
||||
💡 Si vous utilisez un domaine différent, créez un fichier .env avec APP_URL=https://votre-domaine.com
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
{/* Configuration OAuth2 */}
|
||||
{(!settings.google_auth_type || settings.google_auth_type === 'oauth2') && (
|
||||
<>
|
||||
<div className="space-y-2">
|
||||
<Label htmlFor="google-client-id">Client ID Google</Label>
|
||||
<Input
|
||||
id="google-client-id"
|
||||
type="text"
|
||||
placeholder="123456789-abcdef.apps.googleusercontent.com"
|
||||
value={settings.google_client_id || ''}
|
||||
onChange={(e) => setSettings({ ...settings, google_client_id: e.target.value })}
|
||||
/>
|
||||
</div>
|
||||
|
||||
<div className="space-y-2">
|
||||
<Label htmlFor="google-client-secret">Client Secret Google</Label>
|
||||
<Input
|
||||
id="google-client-secret"
|
||||
type="password"
|
||||
placeholder="GOCSPX-..."
|
||||
value={settings.google_client_secret || ''}
|
||||
onChange={(e) => setSettings({ ...settings, google_client_secret: e.target.value })}
|
||||
/>
|
||||
<p className="text-sm text-muted-foreground">
|
||||
Créez un projet OAuth 2.0 sur{' '}
|
||||
<a href="https://console.cloud.google.com/apis/credentials" target="_blank" rel="noopener noreferrer" className="text-primary hover:underline">
|
||||
Google Cloud Console
|
||||
</a>
|
||||
{' '}et activez l'API Google Calendar.
|
||||
</p>
|
||||
<div className="p-3 bg-yellow-50 dark:bg-yellow-900/20 border border-yellow-200 dark:border-yellow-800 rounded-lg">
|
||||
<p className="text-sm font-semibold text-yellow-900 dark:text-yellow-200 mb-1">
|
||||
⚠️ IMPORTANT : URI de redirection autorisée
|
||||
</p>
|
||||
<p className="text-xs text-yellow-800 dark:text-yellow-300 mb-2">
|
||||
Ajoutez cette URL exacte dans la console Google Cloud (OAuth 2.0 Client IDs → URIs de redirection autorisées) :
|
||||
</p>
|
||||
<code className="block p-2 bg-white dark:bg-gray-800 border border-yellow-300 dark:border-yellow-700 rounded text-xs font-mono break-all">
|
||||
{window.location.origin}/api/calendar/oauth-callback
|
||||
</code>
|
||||
<p className="text-xs text-yellow-800 dark:text-yellow-300 mt-2">
|
||||
💡 Si vous utilisez un domaine différent, créez un fichier .env avec APP_URL=https://votre-domaine.com
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
</>
|
||||
)}
|
||||
|
||||
{/* Configuration Service Account */}
|
||||
{settings.google_auth_type === 'service_account' && (
|
||||
<>
|
||||
<div className="space-y-2">
|
||||
<Label htmlFor="google-service-account-key">Clé Service Account (JSON)</Label>
|
||||
<textarea
|
||||
id="google-service-account-key"
|
||||
className="w-full min-h-[200px] p-3 text-xs font-mono border rounded-md"
|
||||
placeholder='Collez ici le contenu du fichier JSON de votre Service Account { "type": "service_account", "project_id": "...", "private_key_id": "...", ... }'
|
||||
value={settings.google_service_account_key || ''}
|
||||
onChange={(e) => setSettings({ ...settings, google_service_account_key: e.target.value })}
|
||||
/>
|
||||
<p className="text-sm text-muted-foreground">
|
||||
Créez un Service Account sur{' '}
|
||||
<a href="https://console.cloud.google.com/iam-admin/serviceaccounts" target="_blank" rel="noopener noreferrer" className="text-primary hover:underline">
|
||||
Google Cloud Console
|
||||
</a>
|
||||
{' '}et téléchargez la clé JSON.
|
||||
</p>
|
||||
</div>
|
||||
|
||||
<div className="space-y-2">
|
||||
<Label htmlFor="google-calendar-email">Email du calendrier à synchroniser</Label>
|
||||
<Input
|
||||
id="google-calendar-email"
|
||||
type="email"
|
||||
placeholder="votre-email@gmail.com"
|
||||
value={settings.google_calendar_email || ''}
|
||||
onChange={(e) => setSettings({ ...settings, google_calendar_email: e.target.value })}
|
||||
/>
|
||||
<p className="text-xs text-muted-foreground">
|
||||
⚠️ Important : Vous devez partager votre calendrier avec l'email du Service Account (visible dans le JSON)
|
||||
</p>
|
||||
</div>
|
||||
</>
|
||||
)}
|
||||
|
||||
<div className="flex gap-2">
|
||||
<Button onClick={handleSaveSettings} className="flex items-center gap-2">
|
||||
@@ -1399,14 +1476,17 @@ const Index = () => {
|
||||
</Button>
|
||||
</div>
|
||||
|
||||
{settings.google_client_id && settings.google_client_secret && (
|
||||
{(
|
||||
((!settings.google_auth_type || settings.google_auth_type === 'oauth2') && settings.google_client_id && settings.google_client_secret) ||
|
||||
(settings.google_auth_type === 'service_account' && settings.google_service_account_key)
|
||||
) && (
|
||||
<>
|
||||
<div className="border-t pt-4">
|
||||
<h3 className="font-semibold mb-2">Statut de connexion</h3>
|
||||
{calendarAuthStatus.isAuthenticated && !calendarAuthStatus.isExpired ? (
|
||||
<div className="flex items-center gap-2 text-green-600">
|
||||
<div className="h-2 w-2 rounded-full bg-green-600"></div>
|
||||
<span>Connecté à Google Calendar</span>
|
||||
<span>Connecté à Google Calendar ({calendarAuthStatus.authType === 'service_account' ? 'Service Account' : 'OAuth 2.0'})</span>
|
||||
</div>
|
||||
) : (
|
||||
<div className="flex items-center gap-2 text-yellow-600">
|
||||
@@ -1417,12 +1497,12 @@ const Index = () => {
|
||||
</div>
|
||||
|
||||
<div className="flex gap-2">
|
||||
{calendarAuthStatus.needsReauth ? (
|
||||
{calendarAuthStatus.needsReauth && (!settings.google_auth_type || settings.google_auth_type === 'oauth2') ? (
|
||||
<Button onClick={handleGoogleConnect} className="flex items-center gap-2">
|
||||
<CalendarIcon className="h-4 w-4" />
|
||||
Se connecter avec Google
|
||||
</Button>
|
||||
) : (
|
||||
) : !calendarAuthStatus.needsReauth && (!settings.google_auth_type || settings.google_auth_type === 'oauth2') ? (
|
||||
<>
|
||||
<Button
|
||||
onClick={async () => {
|
||||
|
||||
Reference in new issue
Block a user