Durcit le formulaire de recherche
This commit is contained in:
@@ -2,6 +2,7 @@
|
|||||||
|
|
||||||
const HIGHLIGHT_START = "__MEILI_HIGHLIGHT_START__";
|
const HIGHLIGHT_START = "__MEILI_HIGHLIGHT_START__";
|
||||||
const HIGHLIGHT_END = "__MEILI_HIGHLIGHT_END__";
|
const HIGHLIGHT_END = "__MEILI_HIGHLIGHT_END__";
|
||||||
|
const MAX_SEARCH_QUERY_LENGTH = 200;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Lit la configuration exposee par le template Hugo.
|
* Lit la configuration exposee par le template Hugo.
|
||||||
@@ -65,6 +66,58 @@ function readSearchQuery(queryParam) {
|
|||||||
return rawValue.trim();
|
return rawValue.trim();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Indique si la requete est acceptable pour le frontend.
|
||||||
|
* @param {string} query Texte recherche.
|
||||||
|
* @returns {boolean}
|
||||||
|
*/
|
||||||
|
function isSearchQueryValid(query) {
|
||||||
|
return query.length > 0 && query.length <= MAX_SEARCH_QUERY_LENGTH;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Valide un chemin interne renvoye par l'index.
|
||||||
|
* @param {unknown} rawPath Chemin brut.
|
||||||
|
* @returns {string}
|
||||||
|
*/
|
||||||
|
function normalizeInternalPath(rawPath) {
|
||||||
|
if (typeof rawPath !== "string") {
|
||||||
|
return "";
|
||||||
|
}
|
||||||
|
|
||||||
|
const trimmedPath = rawPath.trim();
|
||||||
|
if (trimmedPath.length === 0 || trimmedPath.startsWith("/") === false) {
|
||||||
|
return "";
|
||||||
|
}
|
||||||
|
|
||||||
|
if (trimmedPath.startsWith("//") || trimmedPath.includes("\\") || trimmedPath.includes("?") || trimmedPath.includes("#")) {
|
||||||
|
return "";
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
const parsed = new URL(trimmedPath, window.location.origin);
|
||||||
|
if (parsed.origin !== window.location.origin) {
|
||||||
|
return "";
|
||||||
|
}
|
||||||
|
|
||||||
|
if (parsed.username.length > 0 || parsed.password.length > 0) {
|
||||||
|
return "";
|
||||||
|
}
|
||||||
|
|
||||||
|
if (parsed.search.length > 0 || parsed.hash.length > 0) {
|
||||||
|
return "";
|
||||||
|
}
|
||||||
|
|
||||||
|
if (parsed.pathname !== trimmedPath) {
|
||||||
|
return "";
|
||||||
|
}
|
||||||
|
|
||||||
|
return parsed.pathname;
|
||||||
|
} catch (_error) {
|
||||||
|
return "";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Construit le payload envoye a Meilisearch.
|
* Construit le payload envoye a Meilisearch.
|
||||||
* @param {string} query Texte recherche.
|
* @param {string} query Texte recherche.
|
||||||
@@ -202,11 +255,12 @@ function normalizeHit(hit) {
|
|||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (typeof hit.path !== "string" || hit.path.trim().length === 0) {
|
const normalizedPath = normalizeInternalPath(hit.path);
|
||||||
|
if (normalizedPath.length === 0) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
let title = hit.path.trim();
|
let title = normalizedPath;
|
||||||
if (typeof hit.title === "string" && hit.title.trim().length > 0) {
|
if (typeof hit.title === "string" && hit.title.trim().length > 0) {
|
||||||
title = hit.title.trim();
|
title = hit.title.trim();
|
||||||
}
|
}
|
||||||
@@ -230,7 +284,7 @@ function normalizeHit(hit) {
|
|||||||
titleMarkup,
|
titleMarkup,
|
||||||
summary,
|
summary,
|
||||||
summaryMarkup,
|
summaryMarkup,
|
||||||
path: hit.path.trim(),
|
path: normalizedPath,
|
||||||
section,
|
section,
|
||||||
published_at: publishedAt,
|
published_at: publishedAt,
|
||||||
};
|
};
|
||||||
@@ -627,6 +681,13 @@ async function initSearchPage() {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (isSearchQueryValid(query) === false) {
|
||||||
|
updateStatus(status, "Requete trop longue.");
|
||||||
|
setSectionVisibility(listingSection, false);
|
||||||
|
clearNode(results);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
updateStatus(status, "Recherche en cours...");
|
updateStatus(status, "Recherche en cours...");
|
||||||
|
|
||||||
const response = await fetchAllSearchResults(config, query);
|
const response = await fetchAllSearchResults(config, query);
|
||||||
|
|||||||
@@ -16,7 +16,7 @@
|
|||||||
<strong>{{ $site.Title }}</strong>
|
<strong>{{ $site.Title }}</strong>
|
||||||
</a>
|
</a>
|
||||||
<form class="site-search" role="search" method="get" action="{{ $site.Params.search.action | relURL }}" aria-label="Recherche">
|
<form class="site-search" role="search" method="get" action="{{ $site.Params.search.action | relURL }}" aria-label="Recherche">
|
||||||
<input id="header-search-input" type="search" name="{{ $site.Params.search.param }}" required aria-label="Recherche">
|
<input id="header-search-input" type="search" name="{{ $site.Params.search.param }}" required maxlength="200" aria-label="Recherche">
|
||||||
<button type="submit" class="ui-button" aria-label="Lancer la recherche" title="Lancer la recherche">
|
<button type="submit" class="ui-button" aria-label="Lancer la recherche" title="Lancer la recherche">
|
||||||
<svg viewBox="0 0 24 24" aria-hidden="true">
|
<svg viewBox="0 0 24 24" aria-hidden="true">
|
||||||
<path d="M11 4a7 7 0 1 0 4.9 12l4.5 4.5 1.4-1.4-4.5-4.5A7 7 0 0 0 11 4Zm0 2a5 5 0 1 1 0 10 5 5 0 0 1 0-10Z"></path>
|
<path d="M11 4a7 7 0 1 0 4.9 12l4.5 4.5 1.4-1.4-4.5-4.5A7 7 0 0 0 11 4Zm0 2a5 5 0 1 1 0 10 5 5 0 0 1 0-10Z"></path>
|
||||||
|
|||||||
Reference in New Issue
Block a user