feat(clients): show short HWID fingerprint in admin device list (#6464)

* feat(clients): show short HWID fingerprint in admin device list

Expose a 12-char prefix of the stored hwid_hash in the admin HWID list API and UI so admins can distinguish devices without querying the database. Full hashes and raw HWIDs remain unexposed.

Fixes #6359

* ci: retrigger release matrix after 386 dependency download flake

---------

Co-authored-by: mrchatam <mrchatam@users.noreply.github.com>
Co-authored-by: mrchatam <287639636+mrchatam@users.noreply.github.com>
This commit is contained in:
mrchatam
2026-09-12 12:43:22 +03:30
committed by GitHub
parent 0a838563bb
commit 8082ab4d74
21 changed files with 55 additions and 11 deletions
+13 -1
View File
@@ -41,7 +41,10 @@ type HwidSlotStatus struct {
Full bool `json:"full" example:"false"`
}
const minHwidLength = 6
const (
minHwidLength = 6
hwidFingerprintLength = 12
)
type ClientHwidInfo struct {
Id int `json:"id"`
@@ -51,6 +54,7 @@ type ClientHwidInfo struct {
DeviceOS string `json:"deviceOs"`
OsVersion string `json:"osVersion"`
DeviceModel string `json:"deviceModel"`
Fingerprint string `json:"fingerprint"`
}
func hashHwid(raw string) string {
@@ -58,6 +62,13 @@ func hashHwid(raw string) string {
return hex.EncodeToString(sum[:])
}
func shortHwidFingerprint(hash string) string {
if len(hash) <= hwidFingerprintLength {
return hash
}
return hash[:hwidFingerprintLength]
}
func trimHwidMeta(s string) string {
s = strings.TrimSpace(s)
r := []rune(s)
@@ -232,6 +243,7 @@ func (s *ClientService) ListClientHwids(email string) ([]ClientHwidInfo, error)
DeviceOS: r.DeviceOS,
OsVersion: r.OsVersion,
DeviceModel: r.DeviceModel,
Fingerprint: shortHwidFingerprint(r.HwidHash),
})
}
return out, nil
+7
View File
@@ -121,8 +121,15 @@ func TestClientHwidGateRegistersAndBlocks(t *testing.T) {
}
foundUpdated := false
for _, row := range list {
if len(row.Fingerprint) != hwidFingerprintLength {
t.Fatalf("fingerprint length = %d, want %d: %q", len(row.Fingerprint), hwidFingerprintLength, row.Fingerprint)
}
if row.DeviceModel == "updated-model" && row.UserAgent == "Karing/2.0" && row.DeviceOS == "ios" && row.OsVersion == "18" {
foundUpdated = true
want := hashHwid(firstRaw)[:hwidFingerprintLength]
if row.Fingerprint != want {
t.Fatalf("fingerprint = %q, want %q", row.Fingerprint, want)
}
}
}
if !foundUpdated {