Files
bionickatana 0826d267f2
CI / scan_ruby (push) Failing after 1m5s
CI / scan_js (push) Failing after 6s
CI / lint (push) Failing after 1m29s
Finished phase005
2026-09-16 15:34:50 -06:00

52 lines
3.4 KiB
Markdown

# Phase 005 Execution
## Scope
- Added lightweight internal authentication without passwords.
- Added database-backed monthly access keys with lazy auto-rotation.
- Added random browser tokens stored in encrypted cookies and mapped to users through server-side session records.
- Required identification for all application pages except the identify flow and Rails health check.
- Replaced temporary `Unknown User` event attribution with the active identified user.
- Added request and model specs for authenticated and unauthenticated flows.
## Changes
- Added `AccessKey` model and migration.
- Added `UserSession` model and migration.
- Added `Current` for request-local user/session access.
- Added `SessionsController` with identify, create session, and logout behavior.
- Added `/identify`, `POST /identify`, and `DELETE /session` routes.
- Added `app/views/sessions/new.html.erb` for the “Identify yourself” page.
- Updated the application layout to show the identified user and a logout button on authenticated pages.
- Updated `ApplicationController` to lazily rotate access keys, load the encrypted-cookie auth token, and require identification by default.
- Updated fuel and maintenance entry creation to set `updated_by_user` from `Current.user`.
- Removed the temporary `Unknown User` seed and replaced it with initial `AccessKey.current` creation.
- Updated vehicle, home, and session request/system specs for the new authentication requirements.
## Decisions
- Access keys are stored in plaintext in the database so the server manager can retrieve the current key with `AccessKey.current.raw_key` from Rails console.
- Browser clients store only a random auth token in an encrypted cookie.
- The database stores only token digests, not raw session tokens.
- `AccessKey.rotate!` invalidates all active sessions by deleting `UserSession` records.
- Auto-rotation is lazy and runs during normal requests when enabled and expired.
- Default auto-rotation frequency is 30 days.
- Auto-rotation can be disabled and re-enabled with `AccessKey.current.disable_auto_rotation!` and `AccessKey.current.enable_auto_rotation!`.
- The rotation frequency can be changed with `AccessKey.current.update!(auto_rotation_frequency_days: days)`.
- Existing users are matched by normalized email and require an exact stored-name match.
- `/up` remains publicly accessible for health checks.
- `DELETE /session` uses the `logout_path` helper because `session_path` is already used for `POST /identify`.
## Console API
```ruby
AccessKey.current.raw_key
AccessKey.rotate!
AccessKey.current.disable_auto_rotation!
AccessKey.current.enable_auto_rotation!
AccessKey.current.auto_rotation_frequency_days
AccessKey.current.update!(auto_rotation_frequency_days: 60)
```
## Verification
- Passed: `bundle exec rspec spec/models/access_key_spec.rb spec/models/user_session_spec.rb spec/requests/sessions_spec.rb spec/requests/vehicles_spec.rb`
- Passed: `bundle exec rspec`
- Passed: `bin/rubocop app/models/access_key.rb app/models/user_session.rb app/models/current.rb app/models/user.rb app/controllers/application_controller.rb app/controllers/sessions_controller.rb app/controllers/fuel_entries_controller.rb app/controllers/maintenance_entries_controller.rb spec/models/access_key_spec.rb spec/models/user_session_spec.rb spec/requests/sessions_spec.rb spec/requests/vehicles_spec.rb spec/requests/home_spec.rb spec/system/home_spec.rb db/seeds.rb`
- Passed after lint cleanup: `bundle exec rspec`