Sep 15 - Update the check-in pages, employee id field limited to 4 digits/characters

This commit is contained in:
2026-09-15 12:53:06 -04:00
parent e5410d5141
commit b33ed8d6c8
4 changed files with 94 additions and 11 deletions
+21 -2
View File
@@ -586,8 +586,19 @@ source of the bilingual labels echoed back to the page.
**Employee ID is numeric only**`inputmode="numeric"`, `pattern="[0-9]*"`, an `input`
listener stripping non-digits (paste / autofill), a re-strip at submit, and a
digits-only guard before the POST. A `localStorage` value stored before this rule
(e.g. `1234SP`) is cleaned to `1234` on auto-fill. There is **no** `maxlength` cap —
capping at 4 would break any 5-digit employee ID.
(e.g. `1234SP`) is cleaned to `1234` on auto-fill.
**Employee ID is at most 4 digits (Sept 15, 2026, user decision)**`maxlength="4"`, plus
`.slice(0, 4)` in both `input` listeners (script-set values ignore `maxlength`), a bilingual
guard on both submit paths, and an HTTP 400 in `qr_checkin` when the base ID has more than
4 digits; `last-work-type` stays quiet for longer IDs. Shorter IDs are still accepted. Longer
IDs are **refused, never truncated** (a cut-down ID is a different employee), and a stored ID
longer than 4 digits is **not** auto-filled. **An employee with a 5+ digit ID cannot check in**
if that changes, raise all four together: the `maxlength` attribute, `EMPLOYEE_ID_MAX_DIGITS`
(`qr_destination.html`), `QR_EMPLOYEE_ID_MAX_DIGITS` (`qr_destination.js`) and
`CHECKIN_EMPLOYEE_ID_MAX_DIGITS` (`routes/qr_codes.py`). The two JS constants have different
names on purpose: both scripts share the page's global scope, and a duplicate top-level
`const` is a SyntaxError that would break the whole page.
### Type of Work — Anti-Mistake Measures (Sept 2026)
@@ -1246,6 +1257,14 @@ it (the workers share no pub/sub).
| `static/js/attendance_report.js` | **Security:** `createTableRow()` put raw device / address / name text into `innerHTML`. Device comes from the check-in User-Agent, so a crafted UA could inject markup into the report — every value is now escaped |
| — | Verified: filter helper produces identical SQL + params to the previous inline block for 180 input combinations; `_live_record_payload()` matches what `loadTableData()` reads from the Jinja-rendered `<tbody>` for 20 row variants; the real `attendance_report.js` driven with a fake DOM/timers/fetch passes 26 checks (insert, de-dup, page + sort kept, hidden-tab pause, no overlap, backoff + cap, stop on logout, escaping). Not yet exercised against a live MySQL server or a real browser |
### Set 21 — Check-In Employee ID Limited to 4 Digits (Sept 15, 2026)
| File | Change |
|---|---|
| `templates/qr_destination.html` | `maxlength="4"`; `EMPLOYEE_ID_MAX_DIGITS`; input listener cuts to 4 digits; stored IDs over 4 digits not auto-filled; submit guard with bilingual message |
| `static/js/qr_destination.js` | `QR_EMPLOYEE_ID_MAX_DIGITS`; same cut in `initializeForm()`; `loadLastStaffId()` ignores longer IDs; guards in `handleFormSubmit()` and `submitCheckin()` |
| `routes/qr_codes.py` | `CHECKIN_EMPLOYEE_ID_MAX_DIGITS`; `qr_checkin` rejects a base ID over 4 digits (HTTP 400, bilingual); `qr_last_work_type` returns no suggestion for longer IDs |
| — | "Up to 4 digits" chosen over "exactly 4": 13 digit IDs still check in. Supersedes the earlier "no `maxlength` cap" note in §11 |
---
## 21. Infrastructure & Deployment