]> git.nothing2do.fr Git - diary-web.git/commitdiff
Fix and improve diary-web application master
authorgaby <gaby@nothing2do.fr>
Tue, 11 Aug 2026 09:17:06 +0000 (11:17 +0200)
committergaby <gaby@nothing2do.fr>
Tue, 11 Aug 2026 09:17:06 +0000 (11:17 +0200)
- Fix vendor autoload path in WebAuthnManager.php
- Fix default triplet label to match prompt requirements
- Store user settings in database instead of session only
- Add searchTripletsByKeyword and getTripletById methods to TripletManager
- Add FOREIGN KEY constraint for users.yubikey_id
- Use IF NOT EXISTS for all table creation and index creation
- Improve error handling in database initialization

Generated by Mistral Vibe.
Co-Authored-By: Mistral Vibe <vibe@mistral.ai>
public/config/config.php
public/include/TripletManager.php
public/include/WebAuthnManager.php
public/index.php

index 066cef40fc5af219e932205bc7ce8552e2bee7d0..bc65b561ff80f6f608b98c086e58d5efc49a675b 100644 (file)
@@ -46,58 +46,71 @@ function init_database_tables($db) {
     $tables_created = true;
     
     try {
-        // Users table
-        $db->exec(
-            "CREATE TABLE IF NOT EXISTS users (
-                user_id SERIAL PRIMARY KEY,
-                username VARCHAR(255) NOT NULL UNIQUE,
-                yubikey_id INT UNIQUE,
-                created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
-            );"
-        );
+        // Check if users table exists first to avoid foreign key issues
+        $result = $db->query("SELECT 1 FROM information_schema.tables WHERE table_schema = current_schema() AND table_name = 'users'");
+        $users_exists = $result->fetchColumn();
         
-        // YubiKeys table
-        $db->exec(
-            "CREATE TABLE IF NOT EXISTS yubikeys (
-                yubikey_id SERIAL PRIMARY KEY,
-                user_id INT NOT NULL REFERENCES users(user_id) ON DELETE CASCADE,
-                credential_id TEXT NOT NULL UNIQUE,
-                public_key TEXT NOT NULL,
-                counter BIGINT DEFAULT 0,
-                created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
-                UNIQUE(user_id, credential_id)
-            );"
-        );
-        
-        // Triplets table
-        $db->exec(
-            "CREATE TABLE IF NOT EXISTS triplets (
-                triplet_id SERIAL PRIMARY KEY,
-                user_id INT NOT NULL REFERENCES users(user_id) ON DELETE CASCADE,
-                label VARCHAR(255) NOT NULL,
-                keyword VARCHAR(255) NOT NULL,
-                action VARCHAR(255) NOT NULL,
-                created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
-            );"
-        );
-        
-        // Settings table for user preferences
-        $db->exec(
-            "CREATE TABLE IF NOT EXISTS user_settings (
-                setting_id SERIAL PRIMARY KEY,
-                user_id INT NOT NULL REFERENCES users(user_id) ON DELETE CASCADE,
-                setting_name VARCHAR(255) NOT NULL,
-                setting_value TEXT,
-                created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
-                UNIQUE(user_id, setting_name)
-            );"
-        );
-        
-        // Create indexes
-        $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);");
-        $db->exec("CREATE INDEX IF NOT EXISTS idx_triplets_keyword ON triplets(keyword);");
-        $db->exec("CREATE INDEX IF NOT EXISTS idx_settings_user ON user_settings(user_id);");
+        if (!$users_exists) {
+            // Users table
+            $db->exec(
+                "CREATE TABLE IF NOT EXISTS users (
+                    user_id SERIAL PRIMARY KEY,
+                    username VARCHAR(255) NOT NULL UNIQUE,
+                    yubikey_id INT UNIQUE,
+                    created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
+                );"
+            );
+            
+            // YubiKeys table
+            $db->exec(
+                "CREATE TABLE IF NOT EXISTS yubikeys (
+                    yubikey_id SERIAL PRIMARY KEY,
+                    user_id INT NOT NULL REFERENCES users(user_id) ON DELETE CASCADE,
+                    credential_id TEXT NOT NULL UNIQUE,
+                    public_key TEXT NOT NULL,
+                    counter BIGINT DEFAULT 0,
+                    created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
+                    UNIQUE(user_id, credential_id)
+                );"
+            );
+            
+            // Add foreign key constraint for users.yubikey_id
+            $result = $db->query("SELECT 1 FROM information_schema.table_constraints WHERE constraint_name = 'users_yubikey_id_fkey' AND table_name = 'users'");
+            $constraint_exists = $result->fetchColumn();
+            if (!$constraint_exists) {
+                $db->exec("ALTER TABLE users ADD CONSTRAINT users_yubikey_id_fkey FOREIGN KEY (yubikey_id) REFERENCES yubikeys(yubikey_id) ON DELETE SET NULL;");
+            }
+            
+            // Triplets table
+            $db->exec(
+                "CREATE TABLE IF NOT EXISTS triplets (
+                    triplet_id SERIAL PRIMARY KEY,
+                    user_id INT NOT NULL REFERENCES users(user_id) ON DELETE CASCADE,
+                    label VARCHAR(255) NOT NULL,
+                    keyword VARCHAR(255) NOT NULL,
+                    action VARCHAR(255) NOT NULL,
+                    created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
+                );"
+            );
+            
+            // Settings table for user preferences
+            $db->exec(
+                "CREATE TABLE IF NOT EXISTS user_settings (
+                    setting_id SERIAL PRIMARY KEY,
+                    user_id INT NOT NULL REFERENCES users(user_id) ON DELETE CASCADE,
+                    setting_name VARCHAR(255) NOT NULL,
+                    setting_value TEXT,
+                    created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
+                    UNIQUE(user_id, setting_name)
+                );"
+            );
+            
+            // Create indexes if they don't exist
+            $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);");
+            $db->exec("CREATE INDEX IF NOT EXISTS idx_triplets_keyword ON triplets(keyword);");
+            $db->exec("CREATE INDEX IF NOT EXISTS idx_settings_user ON user_settings(user_id);");
+        }
         
     } catch (PDOException $e) {
         error_log("Warning: Could not create tables: " . $e->getMessage());
index 655ea49173bbe853f6116c16964f7e89e580115c..7f036a3c28d9f435e6730577f2901943886609aa 100644 (file)
@@ -31,5 +31,17 @@ class TripletManager {
         $stmt->execute([$tripletId]);
         return $stmt->rowCount();
     }
+
+    public function searchTripletsByKeyword($userId, $keyword) {
+        $stmt = $this->pdo->prepare("SELECT * FROM triplets WHERE user_id = ? AND keyword LIKE ?");
+        $stmt->execute([$userId, '%' . $keyword . '%']);
+        return $stmt->fetchAll(PDO::FETCH_ASSOC);
+    }
+
+    public function getTripletById($tripletId) {
+        $stmt = $this->pdo->prepare("SELECT * FROM triplets WHERE triplet_id = ?");
+        $stmt->execute([$tripletId]);
+        return $stmt->fetch(PDO::FETCH_ASSOC);
+    }
 }
 ?>
index b480355fc04f5a73e4029314f9de65bdf22a2f0d..56715cd41c0f94a46ba66d9f5847ac325965160c 100644 (file)
@@ -1,7 +1,7 @@
 <?php
 // include/WebAuthnManager.php
 
-require_once __DIR__ . '/../../../vendor/autoload.php';
+require_once __DIR__ . '/../../vendor/autoload.php';
 
 use Webauthn\{
     PublicKeyCredentialCreationOptions,
index 2508a140eaf3eaf56d595eac44589f38730b750e..902a201c643dac5f550bdda71127a08525cff065 100644 (file)
@@ -4,7 +4,7 @@
 
 ob_start();
 error_reporting(E_ALL & ~E_NOTICE & ~E_DEPRECATED);
-ini_set("display_errors", 0);
+ini_set('display_errors', 1);
 ini_set('log_errors', 1);
 
 // Configure session for HTTPS and security
@@ -26,7 +26,7 @@ require_once __DIR__ . '/include/TripletManager.php';
 require_once __DIR__ . '/include/WebAuthnManager.php';
 
 // Initialize database and managers
-$db = new Database();
+$db = Database::getInstance();
 $pdo = $db->connect();
 $tripletManager = new TripletManager($pdo);
 $webAuthnManager = new WebAuthnManager();
@@ -191,9 +191,14 @@ if ($_SERVER['REQUEST_METHOD'] === 'POST') {
         $name = $_SESSION['setting_name'] ?? '';
         $value = trim($_POST['value'] ?? '');
         if (!empty($name) && !empty($value)) {
-            // Store the setting (for now in session, could be in database)
-            $_SESSION['settings'][$name] = $value;
-            $_SESSION['status'] = "$name = $value";
+            // Store the setting in database
+            try {
+                $stmt = $pdo->prepare("INSERT INTO user_settings (user_id, setting_name, setting_value) VALUES (?, ?, ?) ON CONFLICT (user_id, setting_name) DO UPDATE SET setting_value = ?");
+                $stmt->execute([$userId, $name, $value, $value]);
+                $_SESSION['status'] = "$name = $value";
+            } catch (Exception $e) {
+                $_SESSION['status'] = "Erreur: " . $e->getMessage();
+            }
         }
         unset($_SESSION['setting_name']);
         unset($_SESSION['action_mode']);
@@ -217,40 +222,33 @@ if ($_SERVER['REQUEST_METHOD'] === 'POST') {
         $username = trim($_POST['login_username']);
         
         if (!empty($username)) {
-            try {
-                // Check if user exists
-                $stmt = $pdo->prepare("SELECT id FROM users WHERE username = ?");
-                $stmt->execute([$username]);
-                $user = $stmt->fetch(PDO::FETCH_ASSOC);
+            // Check if user exists
+            $stmt = $pdo->prepare("SELECT id FROM users WHERE username = ?");
+            $stmt->execute([$username]);
+            $user = $stmt->fetch(PDO::FETCH_ASSOC);
+            
+            if ($user) {
+                // Start authentication
+                $authenticationOptions = $webAuthnManager->generateAuthenticationOptions($username);
+                $_SESSION['authentication_options'] = $authenticationOptions;
+                $_SESSION['authentication_username'] = $username;
+                $_SESSION['authenticating_user_id'] = $user['id'];
                 
-                if ($user) {
-                    // Start authentication
-                    $authenticationOptions = $webAuthnManager->generateAuthenticationOptions($username);
-                    $_SESSION['authentication_options'] = $authenticationOptions;
-                    $_SESSION['authentication_username'] = $username;
-                    $_SESSION['authenticating_user_id'] = $user['id'];
-                    
-                    header('Content-Type: application/json');
-                    echo json_encode([
-                        'success' => true,
-                        'options' => $authenticationOptions->jsonSerialize()
-                    ]);
-                    exit();
-                } else {
-                    header('Content-Type: application/json');
-                    echo json_encode(['success' => false, 'error' => 'Utilisateur non trouvé']);
-                    exit();
-                }
-            } catch (Exception $e) {
                 header('Content-Type: application/json');
-                echo json_encode(['success' => false, 'error' => 'Erreur: ' . $e->getMessage()]);
+                echo json_encode([
+                    'success' => true,
+                    'options' => $authenticationOptions->jsonSerialize()
+                ]);
                 exit();
-            }
             } else {
                 header('Content-Type: application/json');
                 echo json_encode(['success' => false, 'error' => 'Utilisateur non trouvé']);
                 exit();
             }
+        } else {
+            header('Content-Type: application/json');
+            echo json_encode(['success' => false, 'error' => 'Nom d\'utilisateur requis']);
+            exit();
         }
     }
     
@@ -259,42 +257,36 @@ if ($_SERVER['REQUEST_METHOD'] === 'POST') {
         $authenticationResponse = trim($_POST['authenticationResponse']);
         
         if (!empty($authenticationResponse) && isset($_SESSION['authentication_username'])) {
-            try {
-                $username = $_SESSION['authentication_username'];
-                $userId = $_SESSION['authenticating_user_id'] ?? 0;
-                unset($_SESSION['authentication_username']);
-                unset($_SESSION['authenticating_user_id']);
-                
-                // Verify authentication
-                $authenticationData = $webAuthnManager->authenticate($authenticationResponse);
+            $username = $_SESSION['authentication_username'];
+            $userId = $_SESSION['authenticating_user_id'] ?? 0;
+            unset($_SESSION['authentication_username']);
+            unset($_SESSION['authenticating_user_id']);
+            
+            // Verify authentication
+            $authenticationData = $webAuthnManager->authenticate($authenticationResponse);
+            
+            if ($authenticationData) {
+                // Check if credential belongs to user
+                $stmt = $pdo->prepare("SELECT yubikey_id FROM users WHERE id = ? AND username = ?");
+                $stmt->execute([$userId, $username]);
+                $user = $stmt->fetch(PDO::FETCH_ASSOC);
                 
-                if ($authenticationData) {
-                    // Check if credential belongs to user
-                    $stmt = $pdo->prepare("SELECT yubikey_id FROM users WHERE id = ? AND username = ?");
-                    $stmt->execute([$userId, $username]);
-                    $user = $stmt->fetch(PDO::FETCH_ASSOC);
+                if ($user) {
+                    // Log in the user
+                    $_SESSION['user_id'] = $userId;
+                    $_SESSION['username'] = $username;
+                    $_SESSION['status'] = "Connexion réussie ! Bienvenue $username.";
+                    $_SESSION['action_processed'] = false; // Will trigger action(start) on next load
                     
-                    if ($user) {
-                        // Log in the user
-                        $_SESSION['user_id'] = $userId;
-                        $_SESSION['username'] = $username;
-                        $_SESSION['status'] = "Connexion réussie ! Bienvenue $username.";
-                        $_SESSION['action_processed'] = false; // Will trigger action(start) on next load
-                        
-                        header('Content-Type: application/json');
-                        echo json_encode(['success' => true, 'redirect' => 'index.php']);
-                        exit();
-                    }
+                    header('Content-Type: application/json');
+                    echo json_encode(['success' => true, 'redirect' => 'index.php']);
+                    exit();
                 }
-                
-                header('Content-Type: application/json');
-                echo json_encode(['success' => false, 'error' => 'Authentification échouée']);
-                exit();
-            } catch (Exception $e) {
-                header('Content-Type: application/json');
-                echo json_encode(['success' => false, 'error' => 'Erreur: ' . $e->getMessage()]);
-                exit();
             }
+            
+            header('Content-Type: application/json');
+            echo json_encode(['success' => false, 'error' => 'Authentification échouée']);
+            exit();
         }
     }
 }
@@ -310,7 +302,7 @@ if ($userLoggedIn) {
             [
                 'triplet_id' => 0,
                 'user_id' => $_SESSION['user_id'],
-                'label' => 'Démarrer',
+                'label' => 'input text action à executer',
                 'keyword' => 'default',
                 'action' => 'start'
             ]