fix(auth): run provider logout before host session end; show OAuth user name #17

Merged
james.maes merged 1 commits from fix/company-signout-before-session-end into main 2026-11-06 23:22:52 +00:00
Owner

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

  • 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
  • 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

## 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)
james.maes added 1 commit 2026-11-06 16:40:43 +00:00
fix(auth): run provider logout before host session end; show OAuth user name
QRun-IO/ci-policy: ci / fork-guard (pull_request) Skipped
QRun-IO/ci-policy: native / fork-deny (pull_request) Skipped
QRun-IO/ci-policy: native / dotnet-0 (pull_request) Skipped
QRun-IO/ci-policy: ci / Scoped workflow [workflow 539bec410f7926fec3ef7fabe51934a91e0248be] (pull_request) Successful in 13s
QRun-IO/ci-policy: native / native-result (pull_request) Successful in 11s
QRun-IO/ci-policy: ci / head-profile (pull_request) Skipped
QRun-IO/ci-policy: ci / repository-policy (pull_request) Skipped
QRun-IO/ci-policy: ci / application-template-0 (pull_request) Skipped
QRun-IO/ci-policy: ci / gradle-1 (pull_request) Skipped
QRun-IO/ci-policy: ci / java-core-2-head (pull_request) Skipped
QRun-IO/ci-policy: ci / java-docker-3 (pull_request) Skipped
QRun-IO/ci-policy: ci / java-docker-3-head (pull_request) Skipped
QRun-IO/ci-policy: ci / java-docker-4 (pull_request) Skipped
QRun-IO/ci-policy: ci / java-frontend-browser-5 (pull_request) Skipped
QRun-IO/ci-policy: ci / java-maven-6 (pull_request) Skipped
QRun-IO/ci-policy: ci / java-maven-6-head (pull_request) Skipped
QRun-IO/ci-policy: ci / java-maven-7 (pull_request) Skipped
QRun-IO/ci-policy: ci / java-maven-7-head (pull_request) Skipped
QRun-IO/ci-policy: ci / node-8 (pull_request) Skipped
QRun-IO/ci-policy: ci / node-9 (pull_request) Skipped
QRun-IO/ci-policy: ci / node-10 (pull_request) Skipped
QRun-IO/ci-policy: ci / node-playwright-11 (pull_request) Skipped
QRun-IO/ci-policy: ci / repository-policy-12 (pull_request) Skipped
QRun-IO/ci-policy: ci / source-config-13 (pull_request) Skipped
QRun-IO/ci-policy: ci / source-config-14 (pull_request) Skipped
QRun-IO/ci-policy: ci / original-business (pull_request) Skipped
QRun-IO/ci-policy: ci / original-mcp (pull_request) Skipped
QRun-IO/ci-policy: ci / original-voyage (pull_request) Skipped
QRun-IO/ci-policy: ci / original-cli (pull_request) Skipped
QRun-IO/ci-policy: ci / not-enrolled (pull_request) Skipped
QRun-IO/ci-policy: ci / shared-pipeline (pull_request) Skipped
QRun-IO/ci-policy: Shared Android CI / unit-test (pull_request) Successful in 4m51s
QRun-IO/ci-policy: Shared Android CI / android-test (pull_request) Successful in 10m13s
QRun-IO/ci-policy: Shared Android CI / secrets (pull_request) Successful in 20s
QRun-IO/ci-policy: Shared Android CI / package (pull_request) Successful in 23s
QRun-IO/ci-policy: Shared Android CI / gate (pull_request) Successful in 19s
QRun-IO/ci-policy: ci / android-0 (pull_request) Successful in 1h42m13s
QRun-IO/ci-policy: ci / ci-result (pull_request) Successful in 11s
cf82dd5d78
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>
james.maes merged commit f39f7a37d3 into main 2026-11-06 23:22:52 +00:00
Sign in to join this conversation.