8a08f642d436d87bd46c3617e667e7a35a260dac
6 Commits
| Author | SHA1 | Message | Date | |
|---|---|---|---|---|
|
|
cdd3820064 |
v3.32.1: "Start counter value" in the outfile import
release / release (push) Waiting to run
The import created presets with the store's default counter (1). Cards whose counters are already past it had to be edited preset by preset afterwards. - The outfile preview form gains a "Start counter value" field (default 1, the store's value). The value is written into every created keyset of every imported card - parse_outfile's `start_counter`, 1-10 hex digits, whitespace stripped and uppercased; a bad value raises and the endpoint answers 400. Without it the store's default still applies (the field is omitted), so the API keeps its old behaviour. - The preview shows the counter; an import stores the protocol's 10-digit form (counter_hex). - Docs: api.md (the field), help EN/RU (the form). - Version strings + the PWA cache bumped together (simple-v459). Tests: the parser (every keyset, normalisation, unset, the bad values), the endpoint (the preview's keysets, the 400, the stored padded form), the PWA (the field's default, the controls' normalisation, both bodies). 1008 Python + 953 frontend green. |
||
|
|
9a688207ba |
v3.30.4: the in-app dialogs (native alert/confirm/prompt replaced)
The native browser dialogs block the page and look foreign inside the app. One shared modal (#pysim-dialog-modal) with the promise-based helpers pysimAlert/pysimConfirm/pysimPrompt replaces all 71 call sites (60 alert, 10 confirm, 1 prompt in profilerNew); deferredPrompt.prompt() is the PWA install prompt and is untouched. The helpers serialize through ONE promise queue (overlapping dialogs appear in order, no message is overwritten). Escape cancels; Enter accepts except with the Cancel button focused (native behaviour); key repeats/IME are ignored; a POINTER answer within 500 ms of a dialog opening is dropped (the buttons keep the same position, so a double-click's second click would otherwise answer the next queued dialog - e.g. an alert queued before a destructive confirm). Backdrop clicks are ignored. The dialog is role="dialog" aria-modal="true" and traps Tab (the handler cycles the controls the dialog shows: alert OK; confirm Cancel/OK; prompt Cancel/input/OK), so the focus can neither leave the modal nor reach a background control (Space would activate it). When the modal is absent the helpers fall back to the native dialogs - the Node tests extract single functions without the markup. Alerts are fire-and-forget (a notification, not a decision); the 10 confirms and the prompt are awaited, which made five functions async (scriptsDelete, pysimCustomRemove, profilerNew, profilerDelete, snapshotDelete). Because the modal no longer freezes the page, the delete flows that mutated by index after the confirmation mutate by identity now (profilerDelete/snapshotDelete/pysimCustomRemove/ testSuiteDeleteScript/testSuiteDelete): a list reorder during the open dialog would otherwise delete the wrong entry. The nine dialog messages that were still raw English literals are t()-wrapped - three of them (No secured packet to verify/send, Card reader server is not connected) activated RU entries that had existed unused because they were never wrapped; Import error and Snapshot save failed are new keys. Drive-by: the batch modal's #ram-op-batch-info used whitespace-pre-line, which has no rule in the prebuilt style.css (the v3.30.0 stale-style trap), so its notice never line-broke - now whitespace-pre-wrap. Tests: a new frontend/tests/dialogs.test.js (15 tests: the modal path, the queue, the double-answer guard, the keyboard, the grace, the trap, the fallback, the sweep pin, the stylesheet pin) plus the async/helper updates in 8 existing test files. 945 frontend + 952 Python; sw cache simple-v454. |
||
|
|
94d7cff485 |
v3.29.2: the strict row rule for the outfile import
The format is positional: an empty value drops its token, so the parser now requires every data row to have exactly the header's column count. That catches an empty value anywhere - including a middle one, which would otherwise shift the following columns (a missing ADM made the KIC columns read the KIK values: valid hex, wrong preset) - and a KICn/KIDn pair declared in the header must carry a usable hex value in every row (a placeholder fails). A violation makes the whole file invalid: the report's error names the line, no presets are returned, and an import (mode) answers 400 - it is never partially imported. The PWA disables the Import button while the report carries an error and guards the call. Unchanged per-row reports: a non-hex PIN/PUK/ADM/PSK value (dropped, the card kept), an unsupported key size (that keyset skipped), a card whose remaining keysets are unusable (skipped). All three real samples satisfy the rule exactly (11/11, 18/18, 18/18). Docs: help EN/RU, api.md, the repo AGENTS. Tests: the short/long row and the placeholder-keyset file errors, the valid-file round trip, the endpoint's refusal (nothing stored), the PWA's disabled button. 926 frontend + 945 Python; sw cache simple-v449. |
||
|
|
8a66ea5a0a |
v3.29.1: the per-row keysets in the outfile preview
The import applied one global default keyset to every TAR entry of every imported card. The preview's TAR table (TAR + MSL, the three role rows + "+ TAR") now has a keyset select per row, mirroring the preset editor: an empty "— none —" plus the keysets found in the file with their KIc/KID, the first preselected, and the editor's amber warning when a non-zero MSL has no keyset. Each TAR's packets then use exactly the chosen keyset. - PWA: the global "Default keyset for the TARs" select (and the request's tar_keyset) is gone; cardsOutfileTarsFromDom/FromForm carry each row's keyset; cardsOutfileKeysets() became cardsOutfileKeysetOptions() (the union with the KIc/KID bytes for the labels). - Server: a `tars` entry's own `keyset` (1-15; an unusable value is a 400) wins, then the optional global `tar_keyset` (the API shorthand), then the card's first keyset - parse_outfile no longer clobbers per-entry keysets with the card-level fallback. presets.normalise_keyset_ref() is module-level (one rule for the store and the parser). - Docs: help EN/RU, api.md (the tars entry keyset + the global fallback), the repo AGENTS. Tests: the per-entry/global/card fallbacks, the bad-keyset 400, the options helper, the row select and round-trip, the import body. 925 frontend + 944 Python; sw cache simple-v448. |
||
|
|
21d7f58f61 |
v3.27.0 review: the outfile import hardening
- The endpoint validates algorithm16 (3des2/aes, case-insensitive) and mode (merge/replace or omitted): a misspelled value answers 400 instead of silently picking 3DES2 or turning an import into a dry run. The choices come from outfile.ALGORITHM16_CHOICES, derived from the algorithm map, so the validation and the parser cannot drift apart. - A present but unusable PIN/PUK value is reported with its raw text: a value that strips to nothing (e.g. 'abcd') used to vanish without a report line, contradicting the "nothing is silently dropped" contract. A column absent from a short row stays silent - it is not present. - The column-line detection drops the arbitrary 8-character column-name cap: a candidate header must carry ICCID plus at least one column the import consumes (a fixed name or a numbered KIC/KID), so a long unknown column name next to a real one parses while 'ICCID <value>' and 'ICCID CUSTOMER_NAME' config lines are still rejected. Both real samples are unaffected. - PWA: a chosen default keyset survives an empty or failed preview (it used to reset to null, and the import silently fell back to the card's first keyset); the select renders the preview's keysets plus a remembered value. - PWA: the destructive Replace mode asks for confirmation first, matching the other store-wiping actions. - api.md documents both validations. Tests: the endpoint's 400s and the replace import, the raw-value report, the header guards, the keyset preservation and the declined confirmation. 906 frontend + 904 Python; sw cache simple-v437. |
||
|
|
212bfc24ac |
v3.27.0: the outfile import
Import many card presets at once from a card vendor's plain-text dump. The new pure pysim_simple_server/outfile.py (parse_outfile) plus POST /api/presets/import-outfile: without `mode` the call is a dry-run preview returning the parsed presets and a report (nothing is stored), with `merge`/`replace` the same parse runs and the presets go through the preset store. The parser: the data starts at the first line whose whitespace tokens all look like column names and include ICCID (a leading `word:` prefix is stripped, so a `var_out:IMSI ICCID ...` header line matches while a config line naming a value - `ICCID:897...` or `ICCID 897...` - cannot); one row per card follows. Recognised columns (case-insensitive): ICCID, PIN1/PIN2, PUK1/PUK2, ADM (the ASCII string, hex-encoded), PSK (32 hex; an optional PSKID/PSK_ID names the identity, defaulting to the card's ICCID) and KICn/KIDn - one keyset per numbered pair, up to 15; IMSI*/EKI/KIKn are ignored. The KIc/KID bytes are inferred: the keyset number is the column number, the algorithm nibble follows the key size (8 B DES, 16 B 3DES2 or AES - the preview's choice, 3DES2 default, 24 B 3DES3; anything else skips the keyset with a note), both bytes carrying the same number (TS 102 225 A.2). The TARs never come from the file: the caller's table (default the three role entries) is applied with one global default keyset written into every entry (the card's first keyset when unset). An invalid optional code is dropped with a report line instead of failing the card; the report names the columns, the rows read, the parsed keysets and every skip. The ICCID normaliser fix (both sides, drift-guarded): the trailing F (or Fs) is the odd-nibble padding - when the rest is digits only it is the plain digit form (the vendors print the ICCID as digits+F), otherwise the value is the raw nibble-swapped EF hex; a raw value never ends in F, so the rule is unambiguous. PWA: the Import outfile button in the Cards list, the hidden file input and the preview panel (the common name, the 16-byte algorithm select, the TAR table with the role defaults editable and + TAR / remove for extras, the global default keyset select over the parsed keysets, the merge/replace mode, the parsed cards table, the report, Refresh preview, Import). The panel joins refreshDynamicI18n for the language switch. Docs: help EN/RU (the term outfile stays untranslated in RU), api.md's new section, the repo AGENTS. Tests: the parser (both fixture shapes, the column detection, the key-size inference, the options/TAR table, the PSK identity, the skips, the store round-trip), the endpoint (the preview, the import, the duplicate skip, the 400s), the normaliser on both sides, the PWA helpers/wiring and the algorithm16 drift guard against outfile.py. 904 frontend + 903 Python; sw cache simple-v436. |