persona-community-1/pkg/auth/useragent.go
jordan 4004f88f4a
Some checks failed
ci/woodpecker/push/woodpecker Pipeline failed
ci/woodpecker/manual/woodpecker Pipeline was successful
Initialize project from skeleton template
2026-02-23 10:20:59 +00:00

69 lines
1.7 KiB
Go

package auth
import "strings"
// ParseDeviceLabel extracts a human-readable device label from a user agent string.
// Returns something like "Chrome on macOS", "Safari on iPhone", "Firefox on Windows".
func ParseDeviceLabel(userAgent string) string {
if userAgent == "" {
return "Unknown device"
}
browser := parseBrowser(userAgent)
os := parseOS(userAgent)
if browser == "" && os == "" {
return "Unknown device"
}
if browser == "" {
return os
}
if os == "" {
return browser
}
return browser + " on " + os
}
func parseBrowser(ua string) string {
// Order matters — check more specific before generic.
switch {
case strings.Contains(ua, "Edg/") || strings.Contains(ua, "Edge/"):
return "Edge"
case strings.Contains(ua, "OPR/") || strings.Contains(ua, "Opera"):
return "Opera"
case strings.Contains(ua, "Brave"):
return "Brave"
case strings.Contains(ua, "Vivaldi"):
return "Vivaldi"
case strings.Contains(ua, "Chrome/") && !strings.Contains(ua, "Chromium"):
return "Chrome"
case strings.Contains(ua, "Firefox/"):
return "Firefox"
case strings.Contains(ua, "Safari/") && !strings.Contains(ua, "Chrome"):
return "Safari"
default:
return ""
}
}
func parseOS(ua string) string {
switch {
case strings.Contains(ua, "iPhone"):
return "iPhone"
case strings.Contains(ua, "iPad"):
return "iPad"
case strings.Contains(ua, "Android"):
return "Android"
case strings.Contains(ua, "Mac OS X") || strings.Contains(ua, "Macintosh"):
return "macOS"
case strings.Contains(ua, "Windows"):
return "Windows"
case strings.Contains(ua, "Linux"):
return "Linux"
case strings.Contains(ua, "CrOS"):
return "ChromeOS"
default:
return ""
}
}