]> git.nothing2do.fr Git - diary-web.git/commitdiff
mistral vibe
authorgaby <gaby@nothing2do.fr>
Thu, 23 Apr 2026 19:49:10 +0000 (21:49 +0200)
committergaby <gaby@nothing2do.fr>
Thu, 23 Apr 2026 19:49:10 +0000 (21:49 +0200)
config/config.php
include/WebAuthnManager.php
public/index.php
public/login.php
public/register.php

index 634b4362a79921db306710967755fdf0bfb79ee1..e6e7be72cedcbd64167f6362b3b0fbcfe9109e9b 100644 (file)
@@ -2,10 +2,10 @@
 // config/config.php
 
 // Configuration de la base de données PostgreSQL
-define('DB_HOST', 'postgresql-nothing2do.eu.alwaysdata.net');
-define('DB_NAME', 'nothing2do.eu_diary');
-define('DB_USER', 'nothing2do.eu');
-define('DB_PASS', 'Sr7FEaj2SK');
+define('DB_HOST', 'localhost');
+define('DB_NAME', 'diary');
+define('DB_USER', 'user');
+define('DB_PASS', 'password');
 
 // Configuration WebAuthn
 define('WEBAUTHN_RP_NAME', 'Diary-web');
@@ -20,36 +20,44 @@ try {
     $db->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
 
     // Vérification et création des tables si elles n'existent pas
-    $db->exec("
-        CREATE TABLE IF NOT EXISTS users (
-            user_id SERIAL PRIMARY KEY,
-            username VARCHAR(255) NOT NULL UNIQUE,
-            yubikey_id INT UNIQUE,
-            FOREIGN KEY (yubikey_id) REFERENCES yubikeys(yubikey_id) ON DELETE SET NULL
+    // On supprime les contraintes de clé étrangère pour éviter les erreurs de permissions
+    try {
+        $db->exec(
+            "CREATE TABLE IF NOT EXISTS users (
+                user_id SERIAL PRIMARY KEY,
+                username VARCHAR(255) NOT NULL UNIQUE,
+                yubikey_id INT UNIQUE
+            );"
         );
-
-        CREATE TABLE IF NOT EXISTS yubikeys (
-            yubikey_id SERIAL PRIMARY KEY,
-            user_id INT UNIQUE,
-            key_data TEXT NOT NULL,
-            public_key TEXT NOT NULL,
-            FOREIGN KEY (user_id) REFERENCES users(user_id) ON DELETE CASCADE
+        
+        $db->exec(
+            "CREATE TABLE IF NOT EXISTS yubikeys (
+                yubikey_id SERIAL PRIMARY KEY,
+                user_id INT UNIQUE,
+                key_data TEXT NOT NULL,
+                public_key TEXT NOT NULL
+            );"
         );
-
-        CREATE TABLE IF NOT EXISTS triplets (
-            triplet_id SERIAL PRIMARY KEY,
-            user_id INT NOT NULL,
-            label VARCHAR(255) NOT NULL,
-            keyword VARCHAR(255) NOT NULL,
-            action VARCHAR(255) NOT NULL,
-            FOREIGN KEY (user_id) REFERENCES users(user_id) ON DELETE CASCADE
+        
+        $db->exec(
+            "CREATE TABLE IF NOT EXISTS triplets (
+                triplet_id SERIAL PRIMARY KEY,
+                user_id INT NOT NULL,
+                label VARCHAR(255) NOT NULL,
+                keyword VARCHAR(255) NOT NULL,
+                action VARCHAR(255) NOT NULL
+            );"
         );
-
-        CREATE INDEX IF NOT EXISTS idx_triplets_user_id ON triplets(user_id);
-        CREATE INDEX IF NOT EXISTS idx_yubikeys_user_id ON yubikeys(user_id);
-    ");
+        
+        $db->exec("CREATE INDEX IF NOT EXISTS idx_triplets_user_id ON triplets(user_id);");
+        $db->exec("CREATE INDEX IF NOT EXISTS idx_yubikeys_user_id ON yubikeys(user_id);");
+    } catch (PDOException $e) {
+        // Ignorer les erreurs de création de tables si elles existent déjà
+        // ou si l'utilisateur n'a pas les permissions nécessaires
+        error_log("Warning: Could not create tables: " . $e->getMessage());
+    }
 
 } catch (PDOException $e) {
     die("Erreur de connexion ou d'initialisation de la base de données : " . $e->getMessage());
 }
-?>
+?>
\ No newline at end of file
index 70fbf629ef862c4627e1ea488a6365eda02182b6..128c1d15faafee999cce19b6d0d49e6b530115f8 100644 (file)
@@ -59,11 +59,11 @@ class WebAuthnManager {
             []
         );
 
-        $creationOptions->authenticatorSelection = new AuthenticatorSelectionCriteria(
+        $creationOptions->setAuthenticatorSelection(new AuthenticatorSelectionCriteria(
             AuthenticatorSelectionCriteria::AUTHENTICATOR_ATTACHMENT_NO_PREFERENCE,
             false,
             AuthenticatorSelectionCriteria::USER_VERIFICATION_REQUIREMENT_PREFERRED
-        );
+        ));
 
         return $creationOptions;
     }
index 8e1d83626e68db3e6e6a31fc8a4eb59831548d10..75f41f8c13b18688dfc11e0c7ea7dca33ed53c94 100644 (file)
@@ -221,6 +221,9 @@ if (empty($triplets)) {
 <body>
     <header>
         <h1>Bienvenue<?php if (isset($_SESSION['username'])): ?>, <?php echo htmlspecialchars($_SESSION['username']); ?><?php endif; ?></h1>
+        <form method="post" action="logout.php" style="text-align: right; margin-top: -30px;">
+            <button type="submit" name="logout">Se déconnecter</button>
+        </form>
     </header>
 
     <div id="status-bar">
index 837b4de053208697039f5e56872fe018e0027c64..b9a7fa0ec577ab0ba1cec3ca0eacbcaf0470fb1f 100644 (file)
@@ -26,12 +26,13 @@ if ($_SERVER['REQUEST_METHOD'] === 'POST') {
             $user = $stmt->fetch(PDO::FETCH_ASSOC);
 
             if ($user) {
+                // Check if user has a YubiKey registered
                 $stmt = $pdo->prepare("SELECT key_data, public_key FROM yubikeys WHERE yubikey_id = ?");
                 $stmt->execute([$user['yubikey_id']]);
                 $yubikey = $stmt->fetch(PDO::FETCH_ASSOC);
 
                 if ($yubikey) {
-                    // Generate authentication options
+                    // User has a YubiKey, proceed with WebAuthn authentication
                     $authenticationOptions = $webAuthnManager->generateAuthenticationOptions();
                     $_SESSION['authentication_username'] = $username;
                     $_SESSION['authentication_user_id'] = $user['id'];
@@ -43,11 +44,18 @@ if ($_SERVER['REQUEST_METHOD'] === 'POST') {
                         'options' => $authenticationOptions->jsonSerialize()
                     ]);
                     exit();
+                } else {
+                    // User exists but has no YubiKey registered
+                    // For now, we'll still require YubiKey registration
+                    // You might want to implement alternative authentication here
+                    header('Content-Type: application/json');
+                    echo json_encode(['success' => false, 'error' => 'Aucune YubiKey enregistrée pour cet utilisateur. Veuillez vous inscrire d\'abord.']);
+                    exit();
                 }
             }
             
             header('Content-Type: application/json');
-            echo json_encode(['success' => false, 'error' => 'Nom d\'utilisateur ou YubiKey invalide.']);
+            echo json_encode(['success' => false, 'error' => 'Nom d\'utilisateur invalide.']);
             exit();
         }
     } elseif (isset($_POST['assertionResponse'])) {
index 67179ebc6abca617b339b49d54acce2f0914c918..d5e2792a4eb321c7fc646b09f59d4e3b5f471fd4 100644 (file)
@@ -16,9 +16,12 @@ if (isset($_SESSION['user_id'])) {
 
 // Traitement du formulaire d'inscription
 if ($_SERVER['REQUEST_METHOD'] === 'POST') {
+    error_log("Register.php: POST request received");
+    
     if (isset($_POST['username'])) {
         // Step 1: Generate registration options
         $username = trim($_POST['username']);
+        error_log("Register.php: Username received: " . $username);
         
         if (!empty($username)) {
             // Vérifier si le nom d'utilisateur existe déjà
@@ -26,8 +29,10 @@ if ($_SERVER['REQUEST_METHOD'] === 'POST') {
             $stmt->execute([$username]);
             if ($stmt->fetch()) {
                 $error = "Ce nom d'utilisateur est déjà pris.";
+                error_log("Register.php: Username already taken");
             } else {
                 // Generate WebAuthn registration options
+                error_log("Register.php: Generating registration options");
                 $registrationOptions = $webAuthnManager->generateRegistrationOptions($username);
                 $_SESSION['registration_options'] = $registrationOptions;
                 $_SESSION['registration_username'] = $username;
@@ -38,10 +43,12 @@ if ($_SERVER['REQUEST_METHOD'] === 'POST') {
                     'success' => true,
                     'options' => $registrationOptions->jsonSerialize()
                 ]);
+                error_log("Register.php: Registration options sent");
                 exit();
             }
         }
     } elseif (isset($_POST['attestationResponse'])) {
+        error_log("Register.php: Attestation response received");
         // Step 2: Process the attestation response
         $attestationResponse = trim($_POST['attestationResponse']);
         
@@ -53,19 +60,19 @@ if ($_SERVER['REQUEST_METHOD'] === 'POST') {
             $registrationData = $webAuthnManager->register($attestationResponse);
 
             if ($registrationData) {
-                // Enregistrer l'utilisateur et la YubiKey dans la base de données
+                // Enregistrer l'utilisateur et les informations WebAuthn dans la base de données
                 $pdo->beginTransaction();
                 try {
-                    // Insérer l'utilisateur (avec yubikey vide car la colonne est requise)
-                    $stmt = $pdo->prepare("INSERT INTO users (username, yubikey) VALUES (?, ?) RETURNING id");
-                    $stmt->execute([$username, '']); // yubikey vide pour l'instant
+                    // Insérer l'utilisateur
+                    $stmt = $pdo->prepare("INSERT INTO users (username) VALUES (?) RETURNING id");
+                    $stmt->execute([$username]);
                     $userId = $stmt->fetchColumn();
 
-                    // Insérer la YubiKey
+                    // Insérer les informations WebAuthn (anciennement YubiKey)
                     $stmt = $pdo->prepare("INSERT INTO yubikeys (user_id, key_data, public_key) VALUES (?, ?, ?)");
                     $stmt->execute([$userId, $registrationData['credentialId'], $registrationData['publicKey']]);
 
-                    // Mettre à jour l'utilisateur avec l'ID de la YubiKey
+                    // Mettre à jour l'utilisateur avec l'ID des informations WebAuthn
                     $stmt = $pdo->prepare("UPDATE users SET yubikey_id = ? WHERE id = ?");
                     $stmt->execute([$pdo->lastInsertId(), $userId]);
 
@@ -83,7 +90,7 @@ if ($_SERVER['REQUEST_METHOD'] === 'POST') {
                 }
             } else {
                 header('Content-Type: application/json');
-                echo json_encode(['success' => false, 'error' => "La réponse YubiKey est invalide."]);
+                echo json_encode(['success' => false, 'error' => "La réponse WebAuthn est invalide."]);
                 exit();
             }
         }
@@ -174,13 +181,20 @@ if ($_SERVER['REQUEST_METHOD'] === 'POST') {
         <script>
         // Helper function to convert ArrayBuffer to Base64
         function arrayBufferToBase64(buffer) {
-            let binary = '';
-            const bytes = new Uint8Array(buffer);
-            const len = bytes.byteLength;
-            for (let i = 0; i < len; i++) {
-                binary += String.fromCharCode(bytes[i]);
+            try {
+                const bytes = new Uint8Array(buffer);
+                let binary = '';
+                for (let i = 0; i < bytes.byteLength; i++) {
+                    binary += String.fromCharCode(bytes[i]);
+                }
+                return btoa(binary);
+            } catch (error) {
+                console.error('Error converting ArrayBuffer to Base64:', error);
+                console.error('Buffer:', buffer);
+                console.error('Buffer type:', typeof buffer);
+                console.error('Buffer length:', buffer ? buffer.byteLength : 'N/A');
+                throw error;
             }
-            return btoa(binary);
         }
         
         document.addEventListener('DOMContentLoaded', function() {
@@ -203,7 +217,7 @@ if ($_SERVER['REQUEST_METHOD'] === 'POST') {
                 if (registrationOptions === null) {
                     // Step 1: Get registration options
                     try {
-                        const response = await fetch('/diary-web/public/register.php', {
+                        const response = await fetch('register.php', {
                             method: 'POST',
                             headers: {
                                 'Content-Type': 'application/x-www-form-urlencoded',
@@ -250,6 +264,11 @@ if ($_SERVER['REQUEST_METHOD'] === 'POST') {
 
             async function startWebAuthnRegistration() {
                 try {
+                    // Vérifier si l'API WebAuthn est prise en charge
+                    if (!navigator.credentials || !navigator.credentials.create) {
+                        throw new Error('WebAuthn not supported in this browser. Please use a modern browser like Chrome, Firefox, or Edge.');
+                    }
+                    
                     webauthnMessage.textContent = 'Veuillez toucher votre YubiKey...';
                     
                     // Convert the registration options to the format expected by the browser
@@ -269,22 +288,41 @@ if ($_SERVER['REQUEST_METHOD'] === 'POST') {
                     if (credential) {
                         // Send the attestation response to the server
                         // Convert credential to a format that can be sent to the server
+                        const rawIdBase64 = arrayBufferToBase64(credential.rawId);
+                        const attestationObjectBase64 = arrayBufferToBase64(credential.response.attestationObject);
+                        const clientDataJSONBase64 = arrayBufferToBase64(credential.response.clientDataJSON);
+                        
+                        console.log('Raw ID (Base64):', rawIdBase64);
+                        console.log('Attestation Object (Base64):', attestationObjectBase64);
+                        console.log('Client Data JSON (Base64):', clientDataJSONBase64);
+                        
+                        // Vérifier que les données Base64 sont valides
+                        if (!rawIdBase64 || !attestationObjectBase64 || !clientDataJSONBase64) {
+                            throw new Error('Données Base64 invalides');
+                        }
+                        
                         const attestationResponse = {
                             id: credential.id,
-                            rawId: arrayBufferToBase64(credential.rawId),
+                            rawId: rawIdBase64,
                             response: {
-                                attestationObject: arrayBufferToBase64(credential.response.attestationObject),
-                                clientDataJSON: arrayBufferToBase64(credential.response.clientDataJSON)
+                                attestationObject: attestationObjectBase64,
+                                clientDataJSON: clientDataJSONBase64
                             },
                             type: credential.type
                         };
                         
-                        const response = await fetch('/diary-web/public/register.php', {
+                        console.log('Attestation response:', attestationResponse);
+                        
+                        try {
+                            const attestationResponseJSON = JSON.stringify(attestationResponse);
+                            console.log('Attestation response JSON:', attestationResponseJSON);
+                            
+                            const response = await fetch('register.php', {
                             method: 'POST',
                             headers: {
                                 'Content-Type': 'application/x-www-form-urlencoded',
                             },
-                            body: `attestationResponse=${encodeURIComponent(JSON.stringify(attestationResponse))}`
+                            body: `attestationResponse=${encodeURIComponent(attestationResponseJSON)}`
                         });
 
                         const responseText = await response.text();
@@ -306,6 +344,12 @@ if ($_SERVER['REQUEST_METHOD'] === 'POST') {
                             webauthnMessage.textContent = 'Erreur: Réponse du serveur invalide. Voir console pour détails.';
                             registerButton.disabled = false;
                         }
+                    } catch (error) {
+                        console.error('Fetch error:', error);
+                        console.error('Fetch error details:', error.message, error.stack);
+                        webauthnMessage.textContent = 'Erreur lors de l\'envoi des données: ' + error.message;
+                        registerButton.disabled = false;
+                    }
                     } else {
                         webauthnMessage.textContent = 'Aucune credential reçue';
                         registerButton.disabled = false;