Compare commits

..

No commits in common. "main" and "new-style" have entirely different histories.

12 changed files with 314 additions and 529 deletions

Binary file not shown.

Before

Width:  |  Height:  |  Size: 7.8 KiB

View File

@ -29,8 +29,6 @@ COPY --from=builder /app/ek-suche /app/ek-suche
# Kopiere die index.html und den public-Ordner vom Builder
COPY --from=builder /app/index.html /app/index.html
COPY --from=builder /app/popup.html /app/popup.html
COPY --from=builder /app/public/ /app/public/
# Stelle sicher, dass die Anwendung ausführbar ist

File diff suppressed because one or more lines are too long

96
main.go
View File

@ -14,6 +14,8 @@ var serverConfig = map[string]string{
"serverURL": os.Getenv("SERVER_URL"),
}
var secret = os.Getenv("SECRET")
func main() {
port := os.Getenv("PORT")
if port == "" {
@ -21,38 +23,19 @@ func main() {
}
// Set up routes
mux := http.NewServeMux()
mux.HandleFunc("/", handleRoot)
mux.HandleFunc("/config", handleConfig)
mux.HandleFunc("/popup", handlePopupInstructions)
mux.HandleFunc("/search", handleSearch)
mux.HandleFunc("/favicon.ico", handleFavicon)
http.HandleFunc("/", handleRoot)
http.HandleFunc("/config", handleConfig)
http.HandleFunc("/login", handleLogin)
http.HandleFunc("/search", handleSearch)
http.HandleFunc("/favicon.ico", handleFavicon)
// Serve static files from 'public' directory
fs := http.FileServer(http.Dir("./public"))
mux.Handle("/public/", http.StripPrefix("/public/", fs))
// Wende die Sicherheitsheader-Middleware auf alle Routen an
secureMux := secureHeaders(mux)
http.Handle("/public/", http.StripPrefix("/public/", fs))
// Start the server
log.Printf("Server is running at http://0.0.0.0:%s\n", port)
log.Fatal(http.ListenAndServe("0.0.0.0:"+port, secureMux))
}
// Middleware für Sicherheitsheader
func secureHeaders(next http.Handler) http.Handler {
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
// Setze die Sicherheitsheader
w.Header().Set("Content-Security-Policy", "default-src 'self'; script-src 'self' 'unsafe-inline' 'unsafe-eval'; style-src 'self' 'unsafe-inline'; img-src 'self' data: https:; font-src 'self' data:; connect-src 'self';")
w.Header().Set("Strict-Transport-Security", "max-age=31536000; includeSubDomains; preload")
w.Header().Set("X-Content-Type-Options", "nosniff")
w.Header().Set("X-Frame-Options", "DENY")
w.Header().Set("X-XSS-Protection", "1; mode=block")
// Führe den nächsten Handler aus
next.ServeHTTP(w, r)
})
log.Fatal(http.ListenAndServe("0.0.0.0:"+port, nil))
}
func handleRoot(w http.ResponseWriter, r *http.Request) {
@ -67,6 +50,30 @@ func handleConfig(w http.ResponseWriter, r *http.Request) {
fmt.Fprintf(w, `{"serverIP":"%s","serverURL":"%s"}`, serverConfig["serverIP"], serverConfig["serverURL"])
}
func handleLogin(w http.ResponseWriter, r *http.Request) {
if r.Method == http.MethodPost {
username := r.FormValue("username")
password := r.FormValue("password")
if username == os.Getenv("USER") && password == os.Getenv("PASSWORD") {
http.Redirect(w, r, "/stats", http.StatusSeeOther)
} else {
http.Error(w, "Ungültiges Passwort oder Benutzername", http.StatusForbidden)
}
} else {
// Show login form
tmpl := `
<form action="/login" method="post">
<label for="username">Benutzername:</label><br>
<input type="text" id="username" name="username"><br>
<label for="password">Passwort:</label><br>
<input type="password" id="password" name="password"><br>
<input type="submit" value="Anmelden">
</form>`
fmt.Fprint(w, tmpl)
}
}
func handleSearch(w http.ResponseWriter, r *http.Request) {
query := r.URL.Query().Get("query")
websites := r.URL.Query()["websites"]
@ -94,24 +101,14 @@ func handleFavicon(w http.ResponseWriter, r *http.Request) {
w.WriteHeader(http.StatusNoContent)
}
func handlePopupInstructions(w http.ResponseWriter, r *http.Request) {
tmpl := template.Must(template.ParseFiles("popup.html"))
if err := tmpl.Execute(w, nil); err != nil {
http.Error(w, err.Error(), http.StatusInternalServerError)
}
}
func generateSearchUrl(website, query string) string {
searchUrls := map[string]string{
// ----- Eletronik ----
"conrad": fmt.Sprintf("https://www.conrad.de/de/search.html?search=%s", query),
"reichelt": fmt.Sprintf("https://www.reichelt.de/index.html?ACTION=446&SEARCH=%s", query),
"kosatec": fmt.Sprintf("https://shop.kosatec.de/search?search=%s", query),
"schreiber": fmt.Sprintf("https://www.schreiber-electronics.de/search?sSearch=%s", query),
"conrad": fmt.Sprintf("https://www.conrad.de/de/search.html?search=%s", query),
"reichelt": fmt.Sprintf("https://www.reichelt.de/index.html?ACTION=446&SEARCH=%s", query),
"kosatec": fmt.Sprintf("https://shop.kosatec.de/search?search=%s", query),
// ----- Verpackungen ------
"papstar": fmt.Sprintf("https://www.papstar-shop.de/catalogsearch/result/?q=%s", query),
"pacovis": fmt.Sprintf("https://www.pacovis.com/de-de/suche/1/search=%s", query),
"transpak": fmt.Sprintf("https://www.transpak.de/search/%s", query),
// ----- Baumarkt ------
"hornbach": fmt.Sprintf("https://www.hornbach.de/s/%s", query),
@ -119,9 +116,14 @@ func generateSearchUrl(website, query string) string {
"fkr": fmt.Sprintf("https://shop.fkr-baucentrum.de/suche/?q=%s", query),
"contorion": fmt.Sprintf("https://www.contorion.de/search?q=%s", query),
"esska": fmt.Sprintf("https://www.esska.de/shop/search/%s", query),
"toolineo": fmt.Sprintf("https://toolineo.de/#search:query=%s", query),
"voelkner": fmt.Sprintf("https://www.voelkner.de/search/search.html?keywords=%s", query),
"megabad": fmt.Sprintf("https://www.megabad.com/search/?query=sdyc/#/q/%s", query),
"haefele": fmt.Sprintf("https://www.haefele.de/prod-live/web/WFS/Haefele-HDE-Site/de_DE/-/EUR/ViewParametricSearch-Browse?SearchTerm=%s", query),
//knauss: "https://knauss.info/dksearch?sSearch=${query}"",
"baubeschlag": fmt.Sprintf("https://www.baubeschlagshop.de/fts.php?criteria=%s", query),
"ips": fmt.Sprintf("https://www.ips-kts.com/de/suche?query=%s", query),
"haefele": fmt.Sprintf("https://www.haefele.de/prod-live/web/WFS/Haefele-HDE-Site/de_DE/-/EUR/ViewParametricSearch-Browse?SearchTerm=%s", query),
"delker": fmt.Sprintf("https://www.delker2business.com/nwsearch/execute?query=%s", query),
// ------ Küche --------
"esmeyer": fmt.Sprintf("https://www.esmeyer-shop.de/search?search=%s", query),
@ -141,7 +143,9 @@ func generateSearchUrl(website, query string) string {
"rossmann": fmt.Sprintf("https://www.rossmann.de/de/search/?text=%s", query),
// ----- Schilder ------
"vkfrenzel": fmt.Sprintf("https://www.vkf-renzel.de/index.php?lang=0&cl=rasearch&searchparam=%s", query),
"brewes": fmt.Sprintf("https://www.brewes.de/catalogsearch/result?q=%s", query),
"schildershop24": fmt.Sprintf("https://www.schildershop24.de/?action=Query&-query.&query.stichwort=%s", query),
"vkfrenzel": fmt.Sprintf("https://www.vkf-renzel.de/index.php?lang=0&cl=rasearch&searchparam=%s", query),
// ----- Landwirtschaft -------
"siepmann": fmt.Sprintf("https://www.siepmann.net/siepmann_shop.php?suchfeld=%s", query),
@ -150,10 +154,14 @@ func generateSearchUrl(website, query string) string {
"kox": "https://www.kox-direct.de/?query=${query}&sid=6d0b4366af8bb99af514529b7e61ad&act=search",
// ----- Arbeitsschutz -------
"engelbert": fmt.Sprintf("https://www.engelbert-strauss.de/s/suche?query=%s", query),
"engelbert": fmt.Sprintf("https://www.engelbert-strauss.de/s/suche?query=%s", query),
"arbeitsplatzmattenprofi": fmt.Sprintf("https://arbeitsplatzmatten-profi.com/?s=%s", query),
"ara": fmt.Sprintf("https://ara-arbeitsschutz.de/navi.php?qs=%s", query),
// ------ Med. Artikel -------
"oekonomed": fmt.Sprintf("https://shop.oekonomed.de/de/advanced_search_result.php?keywords=%s&inc_subcat=1", query),
"praxisdienst": fmt.Sprintf("https://www.praxisdienst.de/index.php?stoken=268B7DE4&sid=hf02v2hm41hv6v8j3nttfgej8c&lang=0&cl=search&listorderby=reset&searchparam=%s", query),
"gerl": fmt.Sprintf("https://gerl-dental.de/search?query=%s", query),
// ----- Möbel -------
"ikea": fmt.Sprintf("https://www.ikea.com/de/de/search/?q=%s", query),
@ -176,10 +184,6 @@ func generateSearchUrl(website, query string) string {
// ----- Saatgut ------
"saatgutshop": fmt.Sprintf("https://www.saatgut-shop.de/advanced_search_result.php?categories_id=0&keywords=%s&inc_subcat=1", query),
"saatgutmanufaktur": fmt.Sprintf("https://shop.saatgut-manufaktur.de/advanced_search_result.php?keywords=%s&inc_subcat=1", query),
// ------ Bücher ------
"buchammarkt": fmt.Sprintf("https://bam-mr.buchkatalog.de/search?q=%s", query),
"thalia": fmt.Sprintf("https://www.thalia.de/suche?sq=%s", query),
}
if url, ok := searchUrls[website]; ok {

View File

@ -1,170 +0,0 @@
<!DOCTYPE html>
<html lang="de">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Pop-ups erlauben</title>
<style>
/* Allgemeine Stile */
body {
font-family: 'Arial', sans-serif;
margin: 0;
padding: 0;
background-color: #f0f2f5;
}
header {
background-color: #3498db;
position: relative;
color: white;
text-align: center;
padding: 1vh;
font-size: 1vw;
}
ul {
list-style-type: disc;
margin-left: 20px;
}
.browser-instructions {
background-color: white;
padding: 15px;
border-radius: 10px;
box-shadow: 0 0 10px rgba(0, 0, 0, 0.1);
margin: 1vh;
}
.container {
width: 70%;
margin: 0 auto;
padding: 1vh 0;
}
/* Responsive Bild */
.responsive-image {
max-width: 100%; /* Bild wird nie breiter als sein Container */
height: auto; /* Höhe wird proportional angepasst */
display: block; /* Entfernt unnötigen Abstand unter dem Bild */
margin: 10px 0; /* Optional: Abstand oben und unten */
}
footer {
text-align: center;
padding: 2vh;
background-color: #3498db;
color: white;
font-size: 1.5vw;
margin-top: 5vh;
}
/* Tablet-Layout (Bildschirmbreite bis 1200px) */
@media (max-width: 1200px) {
.container {
width: 80%;
}
header {
font-size: 2vw;
}
.browser-instructions {
padding: 12px;
}
}
/* Mobile-Layout (Bildschirmbreite bis 768px) */
@media (max-width: 768px) {
.container {
width: 90%;
}
header {
font-size: 3vw;
padding: 2vh;
}
.browser-instructions {
padding: 10px;
margin: 2vh;
}
}
/* Sehr kleine Bildschirme (Bildschirmbreite bis 480px) */
@media (max-width: 480px) {
.container {
width: 95%;
}
header {
font-size: 4vw;
padding: 3vh;
}
.browser-instructions {
padding: 8px;
margin: 3vh;
}
}
</style>
</head>
<body>
<header>
<h1>Pop-ups erlauben</h1>
</header>
<div class="browser-instructions">
<p> Wenn du bei der ersten Suche mehrere Webseiten auswählst wird oben in der Adressleiste eine Meldung erscheinen das die Pop-Ups blockiert wurden. Damit alle suchergebnisse angezeigt werden musst du die Pop-Ups erlauben.</p>
<p>Wenn die Pop-Ups erlaubt wurden lade die Seite neu.</p>
</div>
<div class="browser-instructions">
<h2>Google Chrome</h2>
<ul>
<li>Klicke auf das Pop-Up-Symbol in der Adressleiste.</li>
<img src="https://einkauf.diefleckenbuehler.de/public/chrome-popup.jpg" alt="Pop-ups in Firefox erlauben" class="responsive-image">
<li>Hier <strong>Pop-ups und Weiterleitungen</strong> immer zulassen.</li>
<img src="https://einkauf.diefleckenbuehler.de/public/chrome.jpg" alt="Pop-ups in Firefox erlauben" class="responsive-image">
</ul>
</div>
<div class="browser-instructions">
<h2>Mozilla Firefox</h2>
<ul>
<li>Klicke auf das Einstellungen-Symbol in der Adressleiste.</li>
<img src="https://einkauf.diefleckenbuehler.de/public/firefox-popup.jpg" alt="Pop-ups in Firefox erlauben" class="responsive-image">
<li>Scrolle zu <strong>Pop-ups blockieren</strong> und stelle es auf <strong>Erlauben</strong>.</li>
<img src="https://einkauf.diefleckenbuehler.de/public/firefox.jpg" alt="Pop-ups in Firefox erlauben" class="responsive-image">
</ul>
</div>
<div class="browser-instructions">
<h2>Microsoft Edge</h2>
<ul>
<li>Klicke auf das Pop-Up-Symbol in der Adressleiste.</li>
<img src="https://einkauf.diefleckenbuehler.de/public/edge-popup.jpg" alt="Pop-ups in Firefox erlauben" class="responsive-image">
<li>Hier <strong>Pop-ups und Weiterleitungen</strong> immer zulassen.</li>
<img src="https://einkauf.diefleckenbuehler.de/public/edge.jpg" alt="Pop-ups in Firefox erlauben" class="responsive-image">
</ul>
</div>
<div class="browser-instructions">
<h2>Safari (macOS)</h2>
<ul>
<p>Klicke auf das Pop-Up-Symbol in der Adressleiste. Damit werden die Pop-Ups erlaubt</p>
<img src="https://einkauf.diefleckenbuehler.de/public/safari.jpg" alt="Pop-ups in Firefox erlauben" class="responsive-image">
</ul>
</div>
<footer>
<p>&copy; 2025 Einkauf Suche - Alle Rechte vorbehalten</p>
</footer>
</body>
</html>

Binary file not shown.

Before

Width:  |  Height:  |  Size: 8.9 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 30 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 7.7 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 34 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 15 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 26 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 9.3 KiB