Fixes Sign out of company on the production-signed APK. On the physical Zebra MC9400 (QQQ Mobile 1.0.1, real Authentik fixture over trusted HTTPS) company sign-out never opened the browser and reported "Company sign-out did not complete".
MC9400 finding.QViewModel.performLogout ran the host beforeLogout hook before the provider logout request. The scanner host's hook ends the device session (POST /qbit/mobile-scanners/sessions/current/end), and on the server that runs the core logout and removes the QQQ session. By the time the client sent POST /qqq/v1/logout with nativeLogout, there was no session left to describe, so nativeLogoutData was never returned and AppAuth's end-session browser never opened.
Change.
Company sign-out now sends the provider logout request first, then ends the host session (a 401 from the device-session end is tolerated because the login already ended), then clears local state and opens the browser. Ordinary sign-out is unchanged: host hook first, then core logout.
Browser (OAuth) login now adopts the server-reported values.user.name (ManageSessionResponse.userName), so the Account dialog no longer shows a blank current user after a browser sign-in.
mobileapp unit tests get unitTests.isReturnDefaultValues = true so the ViewModel test can run on the JVM.
Docs: docs/AUTHENTICATION.md (ordering note) and docs/SESSION-STATE.md (finding and status).
Validation
Shared-library and scanner JVM tests passed: core 52, mobileapp 62 (includes new QViewModelLogoutTest: provider-before-host ordering, failing host end keeps the hint and clears locally, ordinary order unchanged, browser login adopts user name, userName parsing tolerates missing/non-object/blank user), scanner-host 125
Hardware: the fix is not yet installed on the MC9400; it ships in the planned 1.0.2 build. The remaining hardware check is a company sign-out on the production APK against the real Authentik server.
Compatibility and rollout
No API or metadata change. Uses the existing POST /qqq/v1/logout request and existing values.user.name. No server upgrade required. No credentials, cookies, tokens or barcodes included.
## Summary
Fixes **Sign out of company** on the production-signed APK. On the physical Zebra MC9400 (QQQ Mobile 1.0.1, real Authentik fixture over trusted HTTPS) company sign-out never opened the browser and reported "Company sign-out did not complete".
**MC9400 finding.** `QViewModel.performLogout` ran the host `beforeLogout` hook before the provider logout request. The scanner host's hook ends the device session (`POST /qbit/mobile-scanners/sessions/current/end`), and on the server that runs the core logout and removes the QQQ session. By the time the client sent `POST /qqq/v1/logout` with `nativeLogout`, there was no session left to describe, so `nativeLogoutData` was never returned and AppAuth's end-session browser never opened.
**Change.**
- Company sign-out now sends the provider logout request first, then ends the host session (a 401 from the device-session end is tolerated because the login already ended), then clears local state and opens the browser. Ordinary sign-out is unchanged: host hook first, then core logout.
- Browser (OAuth) login now adopts the server-reported `values.user.name` (`ManageSessionResponse.userName`), so the Account dialog no longer shows a blank current user after a browser sign-in.
- `mobileapp` unit tests get `unitTests.isReturnDefaultValues = true` so the ViewModel test can run on the JVM.
- Docs: `docs/AUTHENTICATION.md` (ordering note) and `docs/SESSION-STATE.md` (finding and status).
## Validation
- [x] Shared-library and scanner JVM tests passed: core 52, mobileapp 62 (includes new `QViewModelLogoutTest`: provider-before-host ordering, failing host end keeps the hint and clears locally, ordinary order unchanged, browser login adopts user name, `userName` parsing tolerates missing/non-object/blank user), scanner-host 125
- [x] Scanner lint clean (`lintRelease`: 0 errors, 0 warnings)
- [ ] Native emulator tests: not run for this change
- [ ] Hardware: the fix is not yet installed on the MC9400; it ships in the planned 1.0.2 build. The remaining hardware check is a company sign-out on the production APK against the real Authentik server.
## Compatibility and rollout
No API or metadata change. Uses the existing `POST /qqq/v1/logout` request and existing `values.user.name`. No server upgrade required. No credentials, cookies, tokens or barcodes included.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Company sign-out on the MC9400 (production APK, real Authentik) never opened
the browser: QViewModel.performLogout ran the host beforeLogout hook (scanner
device-session end, which runs the core logout server-side) before the
provider logout request, so POST /qqq/v1/logout found no session and returned
no nativeLogoutData. Company sign-out now requests the provider material
first, then ends the host session (401 tolerated), then clears local state.
Ordinary sign-out keeps the host-hook-first order.
Browser login now adopts the server-reported values.user.name so Account no
longer shows a blank current user.
Adds QViewModelLogoutTest (ordering, failing host end, ordinary order, user
name adoption, ManageSessionResponse.userName parsing) and documents the
finding in AUTHENTICATION.md and SESSION-STATE.md.
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Blocking a user prevents them from interacting with repositories, such as opening or commenting on pull requests or issues. Learn more about blocking a user.
Summary
Fixes Sign out of company on the production-signed APK. On the physical Zebra MC9400 (QQQ Mobile 1.0.1, real Authentik fixture over trusted HTTPS) company sign-out never opened the browser and reported "Company sign-out did not complete".
MC9400 finding.
QViewModel.performLogoutran the hostbeforeLogouthook before the provider logout request. The scanner host's hook ends the device session (POST /qbit/mobile-scanners/sessions/current/end), and on the server that runs the core logout and removes the QQQ session. By the time the client sentPOST /qqq/v1/logoutwithnativeLogout, there was no session left to describe, sonativeLogoutDatawas never returned and AppAuth's end-session browser never opened.Change.
values.user.name(ManageSessionResponse.userName), so the Account dialog no longer shows a blank current user after a browser sign-in.mobileappunit tests getunitTests.isReturnDefaultValues = trueso the ViewModel test can run on the JVM.docs/AUTHENTICATION.md(ordering note) anddocs/SESSION-STATE.md(finding and status).Validation
QViewModelLogoutTest: provider-before-host ordering, failing host end keeps the hint and clears locally, ordinary order unchanged, browser login adopts user name,userNameparsing tolerates missing/non-object/blank user), scanner-host 125lintRelease: 0 errors, 0 warnings)Compatibility and rollout
No API or metadata change. Uses the existing
POST /qqq/v1/logoutrequest and existingvalues.user.name. No server upgrade required. No credentials, cookies, tokens or barcodes included.🤖 Generated with Claude Code