opnsense-portal/internal/web/guides.go
2026-08-14 09:25:52 +02:00

97 lines
3.2 KiB
Go

package web
import "strings"
// Guide ist eine Kurzanleitung für eine Plattform.
type Guide struct {
Platform string
Client string
Steps []string
Suggested bool
}
// baseGuides ist die feste Reihenfolge aller Anleitungen.
var baseGuides = []Guide{
{
Platform: "Windows",
Client: "OpenVPN Community Client",
Steps: []string{
"Laden Sie den OpenVPN Community Client von openvpn.net herunter und installieren Sie ihn.",
"Laden Sie hier im Portal Ihre .ovpn-Datei herunter.",
"Klicken Sie mit der rechten Maustaste auf das OpenVPN-Symbol im Infobereich und wählen Sie „Datei importieren“.",
"Wählen Sie die heruntergeladene .ovpn-Datei aus.",
"Klicken Sie erneut auf das Symbol und wählen Sie „Verbinden“.",
},
},
{
Platform: "macOS",
Client: "Tunnelblick oder Viscosity",
Steps: []string{
"Installieren Sie Tunnelblick (kostenfrei) oder Viscosity.",
"Laden Sie hier im Portal Ihre Konfiguration herunter — für Viscosity das Viscosity-Paket, für Tunnelblick die .ovpn-Datei.",
"Öffnen Sie die heruntergeladene Datei per Doppelklick; die Konfiguration wird importiert.",
"Starten Sie die Verbindung über das Symbol in der Menüleiste.",
},
},
{
Platform: "iOS / iPadOS",
Client: "OpenVPN Connect",
Steps: []string{
"Installieren Sie „OpenVPN Connect“ aus dem App Store.",
"Laden Sie hier im Portal Ihre .ovpn-Datei herunter.",
"Öffnen Sie die Datei aus der Dateien-App heraus und wählen Sie „Teilen“ und dann „OpenVPN Connect“.",
"Bestätigen Sie den Import mit „Add“ und erlauben Sie die VPN-Konfiguration.",
},
},
{
Platform: "Android",
Client: "OpenVPN Connect",
Steps: []string{
"Installieren Sie „OpenVPN Connect“ aus dem Google Play Store.",
"Laden Sie hier im Portal Ihre .ovpn-Datei herunter.",
"Öffnen Sie OpenVPN Connect, wählen Sie „Import“, dann „File“ und dann die heruntergeladene Datei.",
"Bestätigen Sie den Import und erlauben Sie die VPN-Verbindung.",
},
},
}
// detectPlatform rät die Plattform aus dem User-Agent.
// Das Ergebnis ist ausdrücklich nur ein Vorschlag, nie ein Filter.
// iOS wird vor macOS geprüft, weil iPad-User-Agents „Mac OS X“ enthalten können.
func detectPlatform(userAgent string) string {
ua := strings.ToLower(userAgent)
switch {
case strings.Contains(ua, "iphone"), strings.Contains(ua, "ipad"), strings.Contains(ua, "ipod"):
return "iOS / iPadOS"
case strings.Contains(ua, "android"):
return "Android"
case strings.Contains(ua, "windows"):
return "Windows"
case strings.Contains(ua, "mac os x"), strings.Contains(ua, "macintosh"):
return "macOS"
default:
return ""
}
}
// Guides liefert alle Anleitungen; die erkannte Plattform steht vorn und ist
// als Vorschlag markiert. Es wird niemals etwas ausgeblendet — die
// User-Agent-Erkennung ist zu unzuverlässig, um Inhalte zu verstecken.
func Guides(userAgent string) []Guide {
detected := detectPlatform(userAgent)
out := make([]Guide, 0, len(baseGuides))
if detected != "" {
for _, g := range baseGuides {
if g.Platform == detected {
g.Suggested = true
out = append(out, g)
}
}
}
for _, g := range baseGuides {
if g.Platform != detected {
out = append(out, g)
}
}
return out
}