fix: v3.8.0 preset-store review findings

- /api/send-ota no longer 500s on a counter-less body: the plain `sp` path
  reports final_cntr only when the counter is usable (_counter_valid, 1-10 hex
  digits) - before, the new plain-path report ran int('') and the request died
  in the generic handler.  The failure path is guarded the same way.
- _decode_por wraps the keyset/SPI construction in the same "never raise" rule
  as the decode: a malformed counter or missing keys return None instead of
  escaping the handler.
- presets.add() never accepts a taken id (a fresh uuid is assigned, like the
  import path), the counter is validated as 1-10 hex digits instead of being
  silently masked/kept, and set_counter() ignores a malformed value with a log
  line instead of writing it.
- the preset endpoints answer a JSON 500 when the store write fails (read-only
  home, disk full) instead of dropping the connection.
- tests: counter-less send-ota, store-write 500, duplicate id, counter
  validation (add/update/set_counter), and the temp-file check no longer
  matches the audit file; docs/api.md documents final_cntr for the plain path
  and preset_id.
This commit is contained in:
2026-09-30 14:42:54 +03:00
parent 795a1fea49
commit 4ab133c266
5 changed files with 129 additions and 9 deletions
+8
View File
@@ -351,6 +351,13 @@ packets consume counters). Without the key the command data is sent
byte-exact: applet-directed payloads (HTTP OTA triggers, §9 push, expanded
scripts) must not be wrapped.
`final_cntr` is reported for the plain `sp` path too (a pre-built packet):
the counter that was sent, advanced by one when the card accepted the packet.
A request without a `cntr` (nothing to advance) simply reports no
`final_cntr` — it never fails the send. With `preset_id` the server persists
the counter into the card preset store (see *Card presets*), so a lost
response or a closed tab cannot lose the increment.
**Request body:**
```json
{
@@ -363,6 +370,7 @@ scripts) must not be wrapped.
"cntr": "0000000001",
"kicKey": "D6FCC023...",
"kidKey": "1B07E7E0...",
"preset_id": "7ee0367f3a444b28988fea5fbc50de9f",
"ram_format": "auto"
}
```