<?php /** * FavMasToKey - Test d'URL * Ce script permet de tester manuellement une URL pour voir comment Misskey la traite */ // Définir la constante pour inclure les fichiers define('FAVMASTOKEY', true); // Inclure les fichiers requis require_once 'includes/config.php'; require_once 'includes/functions.php'; // Initialiser les variables $url = ''; $test_results = []; $detailed_results = []; $misskey_instance = isset($_SESSION['misskey_instance']) ? $_SESSION['misskey_instance'] : ''; $token = isset($_SESSION['misskey_token']) ? $_SESSION['misskey_token'] : ''; $connected = !empty($misskey_instance) && !empty($token); // Si non connecté, permettre de saisir les informations d'authentification if ($_SERVER['REQUEST_METHOD'] === 'POST' && isset($_POST['action']) && $_POST['action'] === 'connect') { if (isset($_POST['misskey_instance']) && isset($_POST['misskey_token'])) { $misskey_instance = trim($_POST['misskey_instance']); $token = trim($_POST['misskey_token']); // Valider le format de l'instance $misskey_instance = preg_replace('/^https?:\/\//', '', $misskey_instance); $misskey_instance = rtrim($misskey_instance, '/'); if (!empty($misskey_instance) && !empty($token)) { // Vérifier la validité du token en effectuant une requête test $validate_result = validate_misskey_token($misskey_instance, $token); if ($validate_result['success']) { // Connecté avec succès $connected = true; // Stockage temporaire pour cette session uniquement $_SESSION['misskey_token_temp'] = $token; $_SESSION['misskey_instance_temp'] = $misskey_instance; $success_message = "Connecté temporairement à {$misskey_instance} pour les tests."; } else { $error_message = "Impossible de se connecter à l'instance avec ce token."; } } else { $error_message = "Veuillez renseigner à la fois l'instance et le token."; } } } // Récupérer les valeurs temporaires si disponibles if (!$connected && isset($_SESSION['misskey_token_temp']) && isset($_SESSION['misskey_instance_temp'])) { $token = $_SESSION['misskey_token_temp']; $misskey_instance = $_SESSION['misskey_instance_temp']; $connected = true; } // Traiter le test d'URL if ($_SERVER['REQUEST_METHOD'] === 'POST' && isset($_POST['action']) && $_POST['action'] === 'test' && $connected) { if (isset($_POST['url'])) { $url = trim($_POST['url']); if (!empty($url)) { // Méthode 1: search-by-url $test_results[] = [ 'method' => 'search-by-url', 'endpoint' => '/api/notes/search-by-url', 'result' => misskey_api_request($misskey_instance, '/api/notes/search-by-url', ['url' => $url], $token) ]; // Méthode 2: ap/show $test_results[] = [ 'method' => 'ap/show', 'endpoint' => '/api/ap/show', 'result' => misskey_api_request($misskey_instance, '/api/ap/show', ['uri' => $url], $token) ]; // Méthode 3: Extraction et recherche par ID distant $urlParts = parse_url($url); $pathParts = isset($urlParts['path']) ? explode('/', trim($urlParts['path'], '/')) : []; if (count($pathParts) >= 4 && $pathParts[count($pathParts) - 2] === 'statuses') { $statusId = end($pathParts); $username = $pathParts[count($pathParts) - 3]; $acctDomain = isset($urlParts['host']) ? $urlParts['host'] : ''; if ($statusId && $username && $acctDomain) { $remoteId = "https://{$acctDomain}/users/{$username}/statuses/{$statusId}"; $test_results[] = [ 'method' => 'notes/show (uri)', 'endpoint' => '/api/notes/show', 'params' => ['uri' => $remoteId], 'result' => misskey_api_request($misskey_instance, '/api/notes/show', ['uri' => $remoteId], $token) ]; } } // Méthode 4: Forcer la fédération if (curl_init()) { $ch = curl_init($url); curl_setopt($ch, CURLOPT_RETURNTRANSFER, true); curl_setopt($ch, CURLOPT_HEADER, false); curl_setopt($ch, CURLOPT_HTTPHEADER, [ 'Accept: application/activity+json' ]); curl_setopt($ch, CURLOPT_TIMEOUT, 5); $response = curl_exec($ch); $info = curl_getinfo($ch); curl_close($ch); $detailed_results['direct_request'] = [ 'url' => $url, 'http_code' => $info['http_code'], 'content_type' => $info['content_type'], 'response_size' => strlen($response), 'response_preview' => substr($response, 0, 500) . (strlen($response) > 500 ? '...' : '') ]; // Attendre un moment pour que l'instance ait le temps de fédérer sleep(2); // Réessayer avec search-by-url après avoir forcé la fédération $test_results[] = [ 'method' => 'search-by-url (après tentative de fédération)', 'endpoint' => '/api/notes/search-by-url', 'result' => misskey_api_request($misskey_instance, '/api/notes/search-by-url', ['url' => $url], $token) ]; } // Essayer la recherche par contenu // Cette méthode est moins précise mais peut aider dans certains cas if (curl_init()) { $ch = curl_init($url); curl_setopt($ch, CURLOPT_RETURNTRANSFER, true); curl_setopt($ch, CURLOPT_HEADER, false); curl_setopt($ch, CURLOPT_TIMEOUT, 10); $html = curl_exec($ch); curl_close($ch); // Extraction simple du contenu (très basique) $content = ''; if (preg_match('/<article[^>]*>(.*?)<\/article>/is', $html, $matches)) { $content = strip_tags($matches[1]); $content = preg_replace('/\s+/', ' ', $content); $content = trim($content); if (strlen($content) > 5) { $detailed_results['content_search'] = [ 'extracted_content' => substr($content, 0, 200) . (strlen($content) > 200 ? '...' : ''), 'content_length' => strlen($content) ]; // Rechercher par les premiers mots du contenu $searchWords = implode(' ', array_slice(explode(' ', $content), 0, 10)); $test_results[] = [ 'method' => 'notes/search (par contenu)', 'endpoint' => '/api/notes/search', 'params' => ['query' => $searchWords, 'limit' => 5], 'result' => misskey_api_request($misskey_instance, '/api/notes/search', ['query' => $searchWords, 'limit' => 5], $token) ]; } } } } else { $error_message = "Veuillez entrer une URL à tester."; } } } ?> <!DOCTYPE html> <html lang="fr" data-bs-theme="dark"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <meta name="theme-color" content="#7e57c2"> <link rel="icon" href="images/favicon.svg" type="image/svg+xml"> <title>Test d'URL - FavMasToKey</title> <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.0/dist/css/bootstrap.min.css"> <link rel="stylesheet" href="css/styles.css"> </head> <body> <div class="container py-5"> <header class="text-center mb-4"> <h1>FavMasToKey - Test d'URL</h1> <p class="lead">Outil de diagnostic pour tester la résolution d'URL Mastodon</p> <p><a href="index.php" class="btn btn-primary">Retour à l'application</a></p> </header> <?php if (isset($error_message)): ?> <div class="alert alert-danger alert-dismissible fade show" role="alert"> <?php echo $error_message; ?> <button type="button" class="btn-close" data-bs-dismiss="alert" aria-label="Fermer"></button> </div> <?php endif; ?> <?php if (isset($success_message)): ?> <div class="alert alert-success alert-dismissible fade show" role="alert"> <?php echo $success_message; ?> <button type="button" class="btn-close" data-bs-dismiss="alert" aria-label="Fermer"></button> </div> <?php endif; ?> <?php if (!$connected): ?> <div class="card mb-4"> <div class="card-header"> <h2 class="card-title h5 mb-0">Connexion à Misskey pour les tests</h2> </div> <div class="card-body"> <div class="alert alert-info"> <strong>Information:</strong> Vous devez vous connecter à votre instance Misskey pour tester les URLs. <p class="mb-0">Cette connexion est temporaire et utilisée uniquement pour cette page de test.</p> </div> <form method="post" action=""> <input type="hidden" name="action" value="connect"> <div class="mb-3"> <label for="misskey-instance" class="form-label">Instance Misskey</label> <input type="text" class="form-control" id="misskey-instance" name="misskey_instance" placeholder="misskey.io" required> <div class="form-text">Entrez le nom de domaine de votre instance Misskey (ex: misskey.io)</div> </div> <div class="mb-3"> <label for="misskey-token" class="form-label">Jeton d'accès</label> <input type="password" class="form-control" id="misskey-token" name="misskey_token" placeholder="Votre jeton d'accès Misskey" required> <div class="form-text">Collez le jeton d'accès généré dans les paramètres de votre compte Misskey</div> </div> <button type="submit" class="btn btn-primary">Se connecter pour les tests</button> </form> </div> </div> <?php else: ?> <div class="card mb-4"> <div class="card-header d-flex justify-content-between align-items-center"> <h2 class="card-title h5 mb-0">Tester une URL</h2> <span class="badge bg-success">Connecté à <?php echo htmlspecialchars($misskey_instance); ?></span> </div> <div class="card-body"> <form method="post" action=""> <input type="hidden" name="action" value="test"> <div class="mb-3"> <label for="url" class="form-label">URL d'une publication Mastodon</label> <input type="url" class="form-control" id="url" name="url" placeholder="https://instance.tld/users/username/statuses/123456" value="<?php echo htmlspecialchars($url); ?>" required> <div class="form-text"> Entrez l'URL complète d'une publication Mastodon que vous souhaitez tester. </div> </div> <button type="submit" class="btn btn-primary">Tester cette URL</button> </form> </div> </div> <?php if (!empty($test_results)): ?> <div class="card mb-4"> <div class="card-header"> <h2 class="card-title h5 mb-0">Résultats de la recherche pour <?php echo htmlspecialchars($url); ?></h2> </div> <div class="card-body"> <div class="mb-4"> <h3 class="h6">Structure de l'URL</h3> <?php $urlParts = parse_url($url); $pathParts = isset($urlParts['path']) ? explode('/', trim($urlParts['path'], '/')) : []; ?> <pre class="bg-dark text-light p-3"><?php echo "Schema: " . (isset($urlParts['scheme']) ? $urlParts['scheme'] : 'non défini') . "\n"; echo "Host: " . (isset($urlParts['host']) ? $urlParts['host'] : 'non défini') . "\n"; echo "Path: " . (isset($urlParts['path']) ? $urlParts['path'] : 'non défini') . "\n"; if (count($pathParts) >= 4 && $pathParts[count($pathParts) - 2] === 'statuses') { $statusId = end($pathParts); $username = $pathParts[count($pathParts) - 3]; echo "\nFormat reconnu comme URL Mastodon: Oui\n"; echo "Username: {$username}\n"; echo "Status ID: {$statusId}\n"; echo "ActivityPub URI: https://{$urlParts['host']}/users/{$username}/statuses/{$statusId}\n"; } else { echo "\nFormat reconnu comme URL Mastodon: Non\n"; echo "Segments du chemin: " . implode(', ', $pathParts); } ?></pre> </div> <?php foreach ($test_results as $index => $result): ?> <div class="mb-4"> <h3 class="h6 mb-2">Méthode <?php echo $index + 1; ?>: <?php echo htmlspecialchars($result['method']); ?></h3> <div class="card bg-dark"> <div class="card-header d-flex justify-content-between align-items-center"> <span>Endpoint: <?php echo htmlspecialchars($result['endpoint']); ?></span> <span class="badge <?php echo $result['result']['success'] ? 'bg-success' : 'bg-danger'; ?>"> <?php echo $result['result']['success'] ? 'Succès' : 'Échec'; ?> </span> </div> <div class="card-body"> <?php if (isset($result['params'])): ?> <h4 class="h6">Paramètres</h4> <pre class="text-light"><?php print_r($result['params']); ?></pre> <?php endif; ?> <h4 class="h6">Code HTTP: <?php echo $result['result']['http_code']; ?></h4> <?php if ($result['result']['success'] && isset($result['result']['data']) && !empty($result['result']['data'])): ?> <h4 class="h6 text-success">Publication trouvée!</h4> <pre class="text-light"><?php print_r($result['result']['data']); ?></pre> <?php else: ?> <h4 class="h6 text-danger">Publication non trouvée</h4> <pre class="text-light"><?php if (isset($result['result']['message'])) { echo "Message: " . print_r($result['result']['message'], true); } if (isset($result['result']['data'])) { echo "\nDonnées: " . print_r($result['result']['data'], true); } ?></pre> <?php endif; ?> </div> </div> </div> <?php endforeach; ?> <?php if (!empty($detailed_results)): ?> <div class="mb-4"> <h3 class="h6">Détails supplémentaires</h3> <pre class="bg-dark text-light p-3"><?php print_r($detailed_results); ?></pre> </div> <?php endif; ?> <div class="mt-4"> <h3 class="h6">Recommandations</h3> <ul> <?php $successFound = false; $bestMethod = ''; foreach ($test_results as $result) { if ($result['result']['success'] && isset($result['result']['data']) && !empty($result['result']['data'])) { $successFound = true; $bestMethod = $result['method']; break; } } if ($successFound): ?> <li class="text-success"> <strong>Bonne nouvelle!</strong> Publication trouvée avec la méthode "<?php echo htmlspecialchars($bestMethod); ?>". <p class="mt-2">Vous devriez modifier la fonction <code>search_federated_note</code> pour utiliser cette méthode en priorité.</p> <div class="alert alert-info"> <p class="mb-1"><strong>Suggestion pour la fonction search_federated_note:</strong></p> <pre class="text-dark mb-0"> function search_federated_note($instance, $url, $token) { // Pour cette publication spécifique, utiliser la méthode qui fonctionne if ($url === "<?php echo htmlspecialchars($url); ?>") { return misskey_api_request($instance, "<?php echo $result['endpoint']; ?>", <?php echo isset($result['params']) ? var_export($result['params'], true) : "['url' => \$url]"; ?>, $token); } // Pour les autres publications, essayer les différentes méthodes... // [reste du code actuel] }</pre> </div> </li> <?php else: ?> <li class="text-warning"> <strong>Publication non trouvée</strong> avec aucune des méthodes testées. Voici quelques suggestions: <ul class="mt-2"> <li>Vérifiez que la publication existe toujours et est publique</li> <li>Assurez-vous que votre instance Misskey peut se fédérer avec l'instance d'origine</li> <li>Visitez manuellement l'URL depuis votre instance Misskey pour forcer la fédération</li> <li>Si c'est un problème récurrent, ajustez les délais entre les requêtes dans config.php</li> </ul> </li> <?php endif; ?> </ul> </div> </div> </div> <?php endif; ?> <?php endif; ?> </div> <script src="https://cdn.jsdelivr.net/npm/bootstrap@5.3.0/dist/js/bootstrap.bundle.min.js"></script> </body> </html>