- invalidateOtherSessions() in authService.js: deletes all sessions except current
- Password change (auth.js + profile.js) now invalidates all other sessions
- Password change rotates current session ID (sets new cookie)
- New POST /api/auth/logout-all endpoint (deletes all sessions + clears cookie)
- Audit logging for logout.all and password.change
- Added last_password_change_at to auth.js change-password for consistency
- Hudson security audit: 6/6 PASS
CRITICAL fix: Users upgrading from pre-migration-tracking databases
(now get 'invalid username/password' because schema_migrations table
doesn't exist. Added handleLegacyDatabase() and
reconcileLegacyMigrations() to detect and reconcile legacy DBs.
Security fixes:
- Path traversal: replaced sanitizePath() with ALLOWED_FILES allowlist
- Public /about bypass: added admin route guard in App.jsx
- Sensitive info exposure: expanded redactSensitiveContent() patterns
- Error message path leaks: generic error messages only
- Race condition: wrapped in db.transaction() in server.js
- Password validation: INIT_REGULAR_PASS min 8 chars with process.exit(1)
All verified by Bishop (build + runtime) and Private_Hudson (security).
- Add INIT_REGULAR_USER/INIT_REGULAR_PASS for non-admin test user creation
- Regular user created at startup with role='user', not admin
- Move bill_history_ranges from inline to versioned migration v0.42
- Clean up FUTURE.md: remove completed items, add skip-first-login item