Commit graph

8 commits

Author SHA1 Message Date
jedarden
386820e7b7 test: implement acceptance scenario integration tests (AS-1 through AS-6)
Implemented all 6 acceptance scenarios as verifiable integration tests:
- AS-1: First-time setup in under 5 minutes
- AS-2: Person detected while walking
- AS-3: Fall alert fires correctly
- AS-4: BLE identity resolves to person name
- AS-5: OTA update succeeds / rollback on bad firmware
- AS-6: Replay shows recorded history

Each scenario includes multiple test cases covering pass/fail criteria.
Tests use spaxel-sim as the test harness for simulating CSI data without
hardware. The integration test entry point runs all scenarios sequentially
for CI/CD verification.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-05-05 07:38:16 -04:00
jedarden
77a2fbc9c0 test: implement acceptance scenario integration tests (AS-1 through AS-6)
- Added comprehensive integration tests in test/acceptance/ covering all 6 acceptance scenarios from plan.md
- AS-1: First-time setup in under 5 minutes - verifies PIN setup and node auto-discovery
- AS-2: Person detected while walking - verifies blob detection during walker simulation
- AS-3: Fall alert fires correctly - verifies fall detection with webhook integration
- AS-4: BLE identity resolves to person name - verifies BLE device registration and identity matching
- AS-5: OTA update succeeds / rollback on bad firmware - verifies OTA workflow and rollback
- AS-6: Replay shows recorded history - verifies replay session creation, seeking, and playback

Tests use spaxel-sim CLI as the test harness and verify:
- API endpoint responses (/api/auth/setup, /api/nodes, /api/blobs, /api/events, /api/ble/devices, /api/replay/*)
- Detection accuracy thresholds (>60% blob presence during walking)
- Alert generation and webhook delivery
- Firmware version updates and rollback behavior
- Replay session lifecycle management

All tests skip by default unless ACCEPTANCE_TEST=1 or SPAXEL_INTEGRATION_TEST=1 is set.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-05-05 05:45:15 -04:00
jedarden
d67ec45d15 fix(auth): serve minimal login page for unauthenticated page requests
Instead of serving the full dashboard HTML (which exposes the UI shell
when the auth overlay is deleted), serve a minimal page that only loads
the auth JS and CSS. Deleting the overlay now reveals a blank page.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-13 12:28:16 -04:00
jedarden
3cd10f6f07 fix(auth): enforce PIN authentication server-side on all API/WS routes
The PIN overlay was client-side only — deleting the DOM element bypassed
auth entirely. Add global chi middleware that returns 401 on protected
endpoints when no valid session cookie is present. Static files pass
through so the login page renders. During onboarding (no PIN set), all
routes remain open.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-13 10:50:18 -04:00
jedarden
f99dc15a2d feat: complete crowd flow visualization implementation
- Fix Viz3D exports to include flow visualization functions
- Export setFlowLayerVisible, setDwellLayerVisible, setCorridorLayerVisible
- Export setFlowTimeFilter, setFlowData, setDwellData, setCorridorData
- Remove duplicate setDwellLayerVisible function definition

This completes the crowd flow visualization feature that was
already implemented in the backend (flow.go) and frontend
(crowdflow.js, viz3d.js) but had missing exports in the Viz3D module.
2026-04-11 07:27:21 -04:00
jedarden
3da0c32ba3 feat: dashboard PIN change flow
- Backend: Add POST /api/auth/change-pin endpoint
  - Requires valid session; body: {old_pin, new_pin}
  - Verifies old PIN against bcrypt hash; returns 403 on mismatch
  - Hashes new PIN with bcrypt cost=12
  - Existing sessions remain valid after PIN change
  - Returns {ok:true} on success

- Dashboard: Security section in settings panel
  - Add "Security" section with Change PIN button
  - Modal form: old PIN → new PIN → confirm new PIN → Submit
  - Inline error display for incorrect current PIN (403)
  - Success toast notification on PIN change
  - Validation: 4-8 digits, numeric only, PINs must match, new ≠ old

- Tests: Add comprehensive tests for change PIN endpoint
  - Success case: old PIN verified, new PIN works
  - Wrong old PIN: returns 403, original PIN still works
  - Unauthenticated: returns 401
  - Invalid new PIN: validation for length, digits, etc.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-04-09 08:05:35 -04:00
jedarden
4595eafab0 feat: implement install secret generation with one-time print
Auto-generate 256-bit installation secret on first run using crypto/rand,
print it exactly once to stdout, and store in SQLite for subsequent startups.
Support SPAXEL_INSTALL_SECRET env var override. Expose via GET /api/auth/install-secret
endpoint (admin session or first-run state). Derive per-node provisioning tokens
via HMAC-SHA256(install_secret, node_mac).

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-04-06 18:06:33 -04:00
jedarden
e83b54a9ec feat: implement dashboard PIN authentication and session management
Backend (mothership/internal/auth/):
- SQLite auth table with pin_bcrypt and install_secret (singleton row)
- GET /api/auth/status — return {pin_configured: bool}
- POST /api/auth/setup — sets PIN (bcrypt cost 12) on first run only
- POST /api/auth/login — verifies PIN, issues session cookie (7-day expiry)
- POST /api/auth/logout — clears cookie and deletes session from SQLite
- Session middleware: all /api/* and /ws/* require valid session
- Rolling window: extends session by 7 days if within 24h of expiry
- Install secret generation for node token derivation

Dashboard (dashboard/js/auth.js):
- On load: GET /api/auth/status check
- First-run setup page: enter PIN + confirm PIN → POST /api/auth/setup → reload
- Login page: shown on 401; PIN entry → POST /api/auth/login → reload
- Logout button in settings panel → POST /api/auth/logout → redirect

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-04-06 13:16:04 -04:00