Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01NBHF4R9EAejDJUMdwr6C68
97 lines
3.2 KiB
Go
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
|
|
}
|