fix: allow public search routes and prevent js redeclaration

This commit is contained in:
2026-04-07 05:14:43 +02:00
parent db235c5d96
commit aff336c15f
2 changed files with 64 additions and 57 deletions

View File

@@ -61,8 +61,10 @@ func RequireAuth(next http.Handler) http.Handler {
// RequireGlobalAuth ensures that a valid user is in the context for all routes except login and static // RequireGlobalAuth ensures that a valid user is in the context for all routes except login and static
func RequireGlobalAuth(next http.Handler) http.Handler { func RequireGlobalAuth(next http.Handler) http.Handler {
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
// Allow unauthenticated access to login and static files // Allow unauthenticated access to login, search, and static files
if r.URL.Path == "/login" || strings.HasPrefix(r.URL.Path, "/static/") { if r.URL.Path == "/login" || strings.HasPrefix(r.URL.Path, "/static/") ||
r.URL.Path == "/search" || r.URL.Path == "/api/search" || r.URL.Path == "/api/search-quick" ||
r.URL.Path == "/" {
next.ServeHTTP(w, r) next.ServeHTTP(w, r)
return return
} }

View File

@@ -1,15 +1,19 @@
let searchTimeout; (function() {
const searchInput = document.getElementById('search-input'); if (window.searchInitialized) return
const searchDropdown = document.getElementById('search-dropdown'); window.searchInitialized = true
let searchTimeout
const searchInput = document.getElementById('search-input')
const searchDropdown = document.getElementById('search-dropdown')
if (searchInput) { if (searchInput) {
searchInput.addEventListener('input', function(e) { searchInput.addEventListener('input', function(e) {
clearTimeout(searchTimeout); clearTimeout(searchTimeout)
const query = e.target.value.trim(); const query = e.target.value.trim()
if (query.length < 2) { if (query.length < 2) {
searchDropdown.innerHTML = ''; searchDropdown.innerHTML = ''
return; return
} }
searchTimeout = setTimeout(() => { searchTimeout = setTimeout(() => {
@@ -17,12 +21,12 @@ if (searchInput) {
.then(res => res.json()) .then(res => res.json())
.then(results => { .then(results => {
if (!results || results.length === 0) { if (!results || results.length === 0) {
searchDropdown.innerHTML = ''; searchDropdown.innerHTML = ''
return; return
} }
let html = '<div class="search-results">'; let html = '<div class="search-results">'
html += '<div class="search-results-title">Anime</div>'; html += '<div class="search-results-title">Anime</div>'
results.forEach(r => { results.forEach(r => {
html += ` html += `
<a href="/anime/${r.id}" class="search-result-item"> <a href="/anime/${r.id}" class="search-result-item">
@@ -32,31 +36,32 @@ if (searchInput) {
<div class="search-result-type">${r.type}</div> <div class="search-result-type">${r.type}</div>
</div> </div>
</a> </a>
`; `
}); })
html += `<a href="/search?q=${encodeURIComponent(query)}" class="search-result-view-all">View all results for ${escapeHtml(query)}</a>`; html += `<a href="/search?q=${encodeURIComponent(query)}" class="search-result-view-all">View all results for ${escapeHtml(query)}</a>`
html += '</div>'; html += '</div>'
searchDropdown.innerHTML = html; searchDropdown.innerHTML = html
})
.catch(err => console.error('Search error:', err))
}, 300)
}) })
.catch(err => console.error('Search error:', err));
}, 300);
});
searchInput.addEventListener('blur', () => { searchInput.addEventListener('blur', () => {
setTimeout(() => { setTimeout(() => {
searchDropdown.innerHTML = ''; searchDropdown.innerHTML = ''
}, 200); }, 200)
}); })
document.addEventListener('click', (e) => { document.addEventListener('click', (e) => {
if (!e.target.closest('.header-search-wrapper')) { if (!e.target.closest('.header-search-wrapper')) {
searchDropdown.innerHTML = ''; searchDropdown.innerHTML = ''
} }
}); })
} }
function escapeHtml(text) { function escapeHtml(text) {
const div = document.createElement('div'); const div = document.createElement('div')
div.textContent = text; div.textContent = text
return div.innerHTML; return div.innerHTML
} }
})()