server+ui: detect card removal passively and reflect it within 2s

The UI only noticed a removed card when some user action ran a real card
command (e.g. Check status); /api/status is a cached-state read that kept
returning the old card, and _handle_card_disconnect() did not clear
app.card/rs.

- start_card_monitor() registers a pyscard CardObserver for our reader;
  it only polls SCardGetStatusChange (no APDU, no connection, no extra
  process), and on removal sets server.card_present=False and calls
  _handle_card_disconnect() under _CARD_LOCK
- /api/status now exposes connected (session usable) and card_present
  (physically inserted) and masks card/profile/atr/selection when not
  connected; _CARD_CONNECTED is initialized from card presence instead of
  being unconditionally True
- the 2s UI poll includes /api/status; on disconnect it switches to the
  existing 'No card detected. Insert card and click Equip' state, or the
  new 'Card inserted — press Equip' hint when the card is back; the old
  _hadData heuristic is gone

Tests for the observer (filtering, removal, insertion) and the UI state
transitions. SW cache v90 -> v91.
This commit is contained in:
2026-09-12 13:21:33 +03:00
parent 7288c22830
commit 57eb412b6d
6 changed files with 228 additions and 16 deletions
+1 -1
View File
@@ -1,4 +1,4 @@
const CACHE = 'otaman-v90';
const CACHE = 'otaman-v91';
const URLS = [
'index.html',
'help.html',