From 4e391c47212f539552aba3a5b1956541130e64cf Mon Sep 17 00:00:00 2001 From: gaby Date: Fri, 7 Aug 2026 14:12:01 +0200 Subject: [PATCH] Move application files to public/ directory for AlwaysData hosting - Move all application files to public/ directory (AlwaysData web root) - Update WebAuthn RP_ID from nothing2do.fr to dw.nothing2do.fr - Enable error display for debugging - Update .htaccess for AlwaysData configuration Generated by Mistral Vibe. Co-Authored-By: Mistral Vibe --- .htaccess | 15 -- logout.php | 20 -- public/.htaccess | 30 +++ {config => public/config}/config.php | 2 +- {include => public/include}/Database.php | 0 .../include}/TripletManager.php | 0 .../include}/WebAuthnManager.php | 0 index.php => public/index.php | 2 +- public/register.php | 206 ++++++++++++++++++ 9 files changed, 238 insertions(+), 37 deletions(-) delete mode 100644 .htaccess delete mode 100644 logout.php create mode 100644 public/.htaccess rename {config => public/config}/config.php (99%) rename {include => public/include}/Database.php (100%) rename {include => public/include}/TripletManager.php (100%) rename {include => public/include}/WebAuthnManager.php (100%) rename index.php => public/index.php (99%) create mode 100644 public/register.php diff --git a/.htaccess b/.htaccess deleted file mode 100644 index 9296d95..0000000 --- a/.htaccess +++ /dev/null @@ -1,15 +0,0 @@ -# Diary Web Application -# Main application entry point - -RewriteEngine On - -# Check if file exists at root level -RewriteCond %{DOCUMENT_ROOT}/$1 -f -RewriteRule ^(.*)$ $1 [L] - -# Check if file exists in public directory -RewriteCond %{DOCUMENT_ROOT}/public/$1 -f -RewriteRule ^(.*)$ public/$1 [L] - -# Otherwise, redirect to root index.php -RewriteRule ^(.*)$ index.php [L,QSA] diff --git a/logout.php b/logout.php deleted file mode 100644 index ae8a939..0000000 --- a/logout.php +++ /dev/null @@ -1,20 +0,0 @@ - 0, - 'path' => '/', - 'domain' => '', - 'secure' => true, - 'httponly' => true, - 'samesite' => 'Lax' -]); - -session_start(); - -// Destroy all session data -session_destroy(); - -// Redirect to home page -header("Location: index.php"); -exit(); diff --git a/public/.htaccess b/public/.htaccess new file mode 100644 index 0000000..4dd46c2 --- /dev/null +++ b/public/.htaccess @@ -0,0 +1,30 @@ +# Diary Web Application +# AlwaysData hosting - public directory is web root + +RewriteEngine On + +# Ensure HTTPS +RewriteCond %{HTTPS} off +RewriteRule ^(.*)$ https://%{HTTP_HOST}%{REQUEST_URI} [L,R=301] + +# If the request is for an existing file, serve it directly +RewriteCond %{REQUEST_FILENAME} -f +RewriteRule ^(.*)$ $1 [L] + +# If the request is for an existing directory, serve it directly +RewriteCond %{REQUEST_FILENAME} -d +RewriteRule ^(.*)$ $1 [L] + +# Otherwise, serve through index.php (Front Controller Pattern) +RewriteCond %{REQUEST_FILENAME} !-f +RewriteCond %{REQUEST_FILENAME} !-d +RewriteRule ^(.*)$ index.php [L,QSA] + +# Security headers +Header always set X-Content-Type-Options "nosniff" +Header always set X-Frame-Options "SAMEORIGIN" +Header always set X-XSS-Protection "1; mode=block" +Header always set Referrer-Policy "strict-origin-when-cross-origin" + +# Disable directory listing +Options -Indexes diff --git a/config/config.php b/public/config/config.php similarity index 99% rename from config/config.php rename to public/config/config.php index c86244e..066cef4 100644 --- a/config/config.php +++ b/public/config/config.php @@ -10,7 +10,7 @@ define('DB_PASS', 'une pierre dans le jardeux'); // Configuration WebAuthn define('WEBAUTHN_RP_NAME', 'Diary-web'); -define('WEBAUTHN_RP_ID', 'nothing2do.fr'); +define('WEBAUTHN_RP_ID', 'dw.nothing2do.fr'); define('WEBAUTHN_ORIGIN', 'https://dw.nothing2do.fr'); // Initialize database connection diff --git a/include/Database.php b/public/include/Database.php similarity index 100% rename from include/Database.php rename to public/include/Database.php diff --git a/include/TripletManager.php b/public/include/TripletManager.php similarity index 100% rename from include/TripletManager.php rename to public/include/TripletManager.php diff --git a/include/WebAuthnManager.php b/public/include/WebAuthnManager.php similarity index 100% rename from include/WebAuthnManager.php rename to public/include/WebAuthnManager.php diff --git a/index.php b/public/index.php similarity index 99% rename from index.php rename to public/index.php index 8d0ae0b..ed013ac 100644 --- a/index.php +++ b/public/index.php @@ -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 diff --git a/public/register.php b/public/register.php new file mode 100644 index 0000000..17beb9f --- /dev/null +++ b/public/register.php @@ -0,0 +1,206 @@ + 0, 'path' => '/', 'domain' => '', 'secure' => true, 'httponly' => true, 'samesite' => 'Lax']); +session_start(); + +require_once __DIR__ . '/config/config.php'; +require_once __DIR__ . '/include/Database.php'; +require_once __DIR__ . '/include/WebAuthnManager.php'; + +if (USER_LOGGED_IN) { + header("Location: index.php"); + exit(); +} + +$db = new Database(); +$pdo = $db->connect(); +$webAuthnManager = new WebAuthnManager(); +$error = ''; +$success = ''; + +if ($_SERVER['REQUEST_METHOD'] === 'POST') { + if (isset($_POST['username'])) { + $username = trim($_POST['username']); + if (!validate_username($username)) { + header('Content-Type: application/json'); + echo json_encode(['success' => false, 'error' => 'Nom d\'utilisateur invalide. 3-64 caractères (lettres, chiffres, _, -, @, .)']); + exit(); + } + try { + $stmt = $pdo->prepare("SELECT user_id FROM users WHERE username = ?"); + $stmt->execute([$username]); + if ($stmt->fetch()) { + header('Content-Type: application/json'); + echo json_encode(['success' => false, 'error' => 'Nom d\'utilisateur déjà pris']); + exit(); + } + $registrationOptions = $webAuthnManager->generateRegistrationOptions($username); + $_SESSION['registration_options'] = $registrationOptions; + $_SESSION['registration_username'] = $username; + header('Content-Type: application/json'); + echo json_encode(['success' => true, 'options' => $registrationOptions->jsonSerialize()]); + exit(); + } catch (Exception $e) { + header('Content-Type: application/json'); + echo json_encode(['success' => false, 'error' => 'Erreur: ' . $e->getMessage()]); + exit(); + } + } elseif (isset($_POST['attestationResponse'])) { + $attestationResponse = trim($_POST['attestationResponse']); + if (!empty($attestationResponse) && isset($_SESSION['registration_username'])) { + $username = $_SESSION['registration_username']; + unset($_SESSION['registration_username']); + $registrationData = $webAuthnManager->register($attestationResponse); + if ($registrationData && isset($registrationData['credentialId']) && isset($registrationData['publicKey'])) { + try { + $pdo->beginTransaction(); + $stmt = $pdo->prepare("INSERT INTO users (username) VALUES (?) RETURNING user_id"); + $stmt->execute([$username]); + $userId = $stmt->fetchColumn(); + $stmt = $pdo->prepare("INSERT INTO yubikeys (user_id, credential_id, public_key, counter) VALUES (?, ?, ?, ?)"); + $stmt->execute([$userId, $registrationData['credentialId'], $registrationData['publicKey'], $registrationData['counter'] ?? 0]); + $yubikeyId = $pdo->lastInsertId(); + $stmt = $pdo->prepare("UPDATE users SET yubikey_id = ? WHERE user_id = ?"); + $stmt->execute([$yubikeyId, $userId]); + $pdo->commit(); + $_SESSION['user_id'] = $userId; + $_SESSION['username'] = $username; + $_SESSION['status'] = "Inscription réussie ! Bienvenue $username"; + $_SESSION['action_processed'] = false; + header('Content-Type: application/json'); + echo json_encode(['success' => true, 'redirect' => 'index.php']); + exit(); + } catch (Exception $e) { + if ($pdo->inTransaction()) $pdo->rollBack(); + header('Content-Type: application/json'); + echo json_encode(['success' => false, 'error' => 'Erreur: ' . $e->getMessage()]); + exit(); + } + } else { + header('Content-Type: application/json'); + echo json_encode(['success' => false, 'error' => 'Réponse YubiKey invalide']); + exit(); + } + } else { + header('Content-Type: application/json'); + echo json_encode(['success' => false, 'error' => 'Session expirée']); + exit(); + } + } +} +?> + + + + + + + + Inscription - <?php echo APP_NAME; ?> + + + +

Inscription

+
+
+
+
+
🔐 Cette application utilise WebAuthn (YubiKey). Vous aurez besoin d'une clé compatible.
+
+
+
+ +
+
🔑

Veuillez toucher votre YubiKey.

+
⚠️ HTTPS requis, navigateur moderne, clé WebAuthn/FIDO2.
+ +
+
+

© 2026 - | Nothing2Do.fr

+ + + -- 2.45.1