fix: improve OS version detefix: improve OS version detection for Windows 11 (#6949)ction for Windows 11 (#6949)#8357
Conversation
Windows 11 reports as "Windows NT 10.0" in User-Agent string, same as Windows 10, causing incorrect OS detection. This commit: - Add Windows NT version-to-friendly-name mapping (e.g., NT 10.0 → Windows 10) - Support Sec-CH-UA-Platform-Version Client Hints header to distinguish Windows 11 (platform version >= 13) from Windows 10 - Display user-friendly OS names (e.g., "Windows 10" instead of "Windows NT 10.0") - Add unit tests for Windows 10/11 detection with and without Client Hints
|
[APPROVALNOTIFIER] This PR is NOT APPROVED This pull-request has been approved by: The full list of commands accepted by this bot can be found here. DetailsNeeds approval from an approver in each of these files:Approvers can indicate their approval by writing |
|
There was a problem hiding this comment.
Pull request overview
Improves device fingerprint OS detection for Windows by mapping Windows NT versions to user-friendly Windows names and using the Sec-CH-UA-Platform-Version Client Hints header to distinguish Windows 11 from Windows 10.
Changes:
- Add Windows NT version → friendly Windows version mapping and Windows 11 detection via
Sec-CH-UA-Platform-Version. - Add a new
DeviceInfo.parse(String userAgent, HttpHeaders headers)overload while keeping the originalparse(String userAgent)for compatibility. - Expand unit tests to cover Windows 10/11 detection with/without Client Hints and older Windows versions.
Reviewed changes
Copilot reviewed 2 out of 2 changed files in this pull request and generated 2 comments.
| File | Description |
|---|---|
| application/src/main/java/run/halo/app/security/device/DeviceServiceImpl.java | Enhance OS parsing to output friendly Windows names and leverage Client Hints to detect Windows 11. |
| application/src/test/java/run/halo/app/security/device/DeviceServiceImplTest.java | Add unit tests for Windows 10/11 and older Windows version parsing scenarios. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
| public static DeviceInfo parse(String userAgent, | ||
| org.springframework.http.HttpHeaders headers) { | ||
| return new DeviceInfo(concat(parseBrowser(userAgent).name(), | ||
| parseBrowser(userAgent).version()), | ||
| concat(parseOperatingSystem(userAgent).name(), | ||
| parseOperatingSystem(userAgent).version()) | ||
| concat(parseOperatingSystem(userAgent, headers).name(), | ||
| parseOperatingSystem(userAgent, headers).version()) | ||
| ); |
There was a problem hiding this comment.
DeviceInfo.parse(userAgent, headers) calls parseBrowser(userAgent) and parseOperatingSystem(userAgent, headers) twice each, which repeats regex matching and does unnecessary work. Store the parsed browser/OS Pair in local variables and reuse them when building the DeviceInfo result.
| public static DeviceInfo parse(String userAgent, | ||
| org.springframework.http.HttpHeaders headers) { |
There was a problem hiding this comment.
HttpHeaders is imported at the top of this file, but the new overload uses the fully-qualified org.springframework.http.HttpHeaders in its signature. For consistency/readability, prefer using the imported HttpHeaders type here (or drop the import if fully-qualifying is intentional).
| public static DeviceInfo parse(String userAgent, | |
| org.springframework.http.HttpHeaders headers) { | |
| public static DeviceInfo parse(String userAgent, HttpHeaders headers) { |
Codecov Report❌ Patch coverage is
Additional details and impacted files@@ Coverage Diff @@
## main #8357 +/- ##
============================================
+ Coverage 59.55% 60.84% +1.29%
- Complexity 3812 3999 +187
============================================
Files 677 698 +21
Lines 23248 23872 +624
Branches 1500 1559 +59
============================================
+ Hits 13846 14526 +680
+ Misses 8764 8614 -150
- Partials 638 732 +94 ☔ View full report in Codecov by Sentry. 🚀 New features to boost your workflow:
|
|
PR needs rebase. DetailsInstructions for interacting with me using PR comments are available here. If you have questions or suggestions related to my behavior, please file an issue against the kubernetes-sigs/prow repository. |



What type of PR is this?
/kind bug
/kind improvement
What this PR does / why we need it:
Windows 11 is incorrectly detected as Windows 10 in device fingerprint info,
because both Windows 10 and 11 report as "Windows NT 10.0" in User-Agent string.
This PR:
"NT 6.1" → "Windows 7") so the OS info is more user-friendly
Sec-CH-UA-Platform-VersionClient Hints header to distinguishWindows 11 (platform version >= 13) from Windows 10
and tests for older Windows versions (7, 8.1)
Which issue(s) this PR fixes:
Fixes #6949
Special notes for your reviewer:
parse(String userAgent)method is preserved for backward compatibility.A new overload
parse(String userAgent, HttpHeaders headers)is added.Sec-CH-UA-Platform-Versionheader.If the header is not present, it falls back to "Windows 10" (safe default).
Microsoft's official documentation.
Does this PR introduce a user-facing change?