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
+3 -2
View File
@@ -9604,7 +9604,7 @@
"tags": [
"Clients"
],
"summary": "List registered HWID devices for a client. Hashes are not exposed.",
"summary": "List registered HWID devices for a client with a short fingerprint. Full hashes are not exposed.",
"operationId": "post_panel_api_clients_hwids_email",
"parameters": [
{
@@ -9644,7 +9644,8 @@
"userAgent": "Happ/1.0",
"deviceOs": "android",
"osVersion": "15",
"deviceModel": "Pixel 9"
"deviceModel": "Pixel 9",
"fingerprint": "6ad17c93e821"
}
]
}
@@ -101,6 +101,14 @@ export default function ClientHwidListModal({
</Typography.Text>
</>
)}
{entry.fingerprint && (
<>
<br />
<Typography.Text type="secondary" code>
{t('pages.clients.hwidFingerprint')}: {entry.fingerprint}
</Typography.Text>
</>
)}
</div>
<Popconfirm
title={t('pages.clients.deleteHwidConfirm')}
+1
View File
@@ -8,6 +8,7 @@ export type ClientHwidInfo = {
deviceOs: string;
osVersion: string;
deviceModel: string;
fingerprint: string;
};
// normalizeClientHwids accepts the API payload and returns typed entries,
+3 -2
View File
@@ -1483,10 +1483,11 @@ export const sections: readonly Section[] = [
{
method: 'POST',
path: '/panel/api/clients/hwids/:email',
summary: 'List registered HWID devices for a client. Hashes are not exposed.',
summary:
'List registered HWID devices for a client with a short fingerprint. Full hashes are not exposed.',
params: [{ name: 'email', in: 'path', type: 'string', desc: 'Client email.' }],
response:
'{\n "success": true,\n "obj": [\n {\n "id": 1,\n "firstSeen": 1735000000000,\n "lastSeen": 1735100000000,\n "userAgent": "Happ/1.0",\n "deviceOs": "android",\n "osVersion": "15",\n "deviceModel": "Pixel 9"\n }\n ]\n}',
'{\n "success": true,\n "obj": [\n {\n "id": 1,\n "firstSeen": 1735000000000,\n "lastSeen": 1735100000000,\n "userAgent": "Happ/1.0",\n "deviceOs": "android",\n "osVersion": "15",\n "deviceModel": "Pixel 9",\n "fingerprint": "6ad17c93e821"\n }\n ]\n}',
},
{
method: 'DELETE',