Harden login and make personal-best records self-correct

Login: add an in-memory per-IP throttle (8 failed attempts -> 15-min lockout, 429 + Retry-After), raise the change-password minimum to 8 with a 72-char cap, and apply the same minimum on the StartOS Set Login Password action.

Records: add a record_floor column for manually-pinned bests plus recomputeRecord(); the live record is now the direction-aware best of the best logged value and the floor, recomputed on entry edit/delete so it can drop again (never below the floor). Settings exposes the floor as an override and shows the live best as a placeholder.

Bump package 0.1.6:0 -> 0.1.7:0 and the service-worker cache to v7.
This commit is contained in:
Keysat
2026-06-15 13:22:41 -05:00
parent bbddebc3d6
commit fe66575ffe
13 changed files with 125 additions and 28 deletions
+6 -2
View File
@@ -386,8 +386,12 @@ function openSettings() {
const mKind = h('select', {}, kindOptions()); mKind.value = m.kind;
const stepIn = h('input', { type: 'number', min: '1', value: String(m.step || 1), style: 'max-width:64px' });
const trackChk = h('input', { type: 'checkbox', ...(m.track_record ? { checked: true } : {}) });
const recordIn = h('input', { type: 'number', placeholder: 'record', value: m.record != null ? String(m.record) : '',
style: 'max-width:90px', ...(m.track_record ? {} : { disabled: true }) });
// Manual personal-best override. Blank = follow logged data; the live record
// shows as the placeholder so a plain save never re-pins the current best.
const recordIn = h('input', { type: 'number',
placeholder: m.record != null ? `best: ${m.record}` : 'set best',
value: m.record_floor != null ? String(m.record_floor) : '',
style: 'max-width:110px', ...(m.track_record ? {} : { disabled: true }) });
trackChk.addEventListener('change', () => { recordIn.disabled = !trackChk.checked; });
const mSave = h('button', { class: 'btn-ghost', onclick: async () => {