69 lines
1.7 KiB
Go
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 ""
|
|
}
|
|
}
|