Files
chore/.github/specs/active/feat-hashed-passwords.md
Ryan Kegel 401c21ad82
All checks were successful
Gitea Actions Demo / build-and-push (push) Successful in 25s
feat: add PendingRewardDialog, RewardConfirmDialog, and TaskConfirmDialog components
- Implemented PendingRewardDialog for handling pending reward requests.
- Created RewardConfirmDialog for confirming reward redemption.
- Developed TaskConfirmDialog for task confirmation with child name display.

test: add unit tests for ChildView and ParentView components

- Added comprehensive tests for ChildView including task triggering and SSE event handling.
- Implemented tests for ParentView focusing on override modal and SSE event management.

test: add ScrollingList component tests

- Created tests for ScrollingList to verify item fetching, loading states, and custom item classes.
- Included tests for two-step click interactions and edit button display logic.
- Moved toward hashed passwords.
2026-02-10 20:21:05 -05:00

88 lines
3.4 KiB
Markdown

# Feature: Hash passwords in database
## Overview
**Goal:** Currently passwords for users are stored in the database as plain text. They need to be hashed using a secure algorithm to prevent exposure in case of a data breach.
**User Story:**
As a user, when I create an account with a password, the password needs to be hashed in the database.
As an admin, I would like a script that will convert the current user database passwords into a hash.
---
## Data Model Changes
### Backend Model (`backend/models/user.py`)
No changes required to the `User` dataclass fields. Passwords will remain as strings, but they will now be hashed values instead of plain text.
### Frontend Model (`frontend/vue-app/src/common/models.ts`)
No changes required. The `User` interface does not expose passwords.
---
## Backend Implementation
### Password Hashing
- Use `werkzeug.security.generate_password_hash()` with default settings (PBKDF2 with SHA256, salt, and iterations) for hashing new passwords.
- Use `werkzeug.security.check_password_hash()` for verification during login and password reset.
- Update the following endpoints to hash passwords on input and verify hashes on output:
- `POST /signup` (hash password before storing; existing length/complexity checks apply).
- `POST /login` (verify hash against input).
- `POST /reset-password` (hash new password before storing; existing length/complexity checks apply).
### Migration Script (`backend/scripts/hash_passwords.py`)
Create a new script to hash existing plain text passwords in the database:
- Read all users from `users_db`.
- For each user, check if the password is already hashed (starts with `scrypt:` or `$pbkdf2-sha256$`); if so, skip.
- For plain text passwords, hash using `generate_password_hash()`.
- Update the user record in the database.
- Log the number of users updated.
- Run this script once after deployment to migrate existing data.
**Usage:** `python backend/scripts/hash_passwords.py`
**Security Notes:**
- The script should only be run in a secure environment (e.g., admin access).
- After migration, verify a few users can log in.
- Delete or secure the script post-migration to avoid reuse.
### Error Handling
No new error codes needed. Existing authentication errors (e.g., invalid credentials) remain unchanged.
---
### Backend Tests (`backend/tests/test_auth_api.py`)
- [x] Test signup with password hashing: Verify stored password is hashed (starts with `scrypt:`).
- [x] Test login with correct password: Succeeds.
- [x] Test login with incorrect password: Fails with appropriate error.
- [x] Test password reset: New password is hashed.
- [x] Test migration script: Hashes existing plain text passwords without data loss; skips already-hashed passwords.
---
## Future Considerations
- Monitor for deprecated hashing algorithms and plan upgrades (e.g., to Argon2 if needed).
- Implement password strength requirements on signup/reset if not already present.
- Consider rate limiting on login attempts to prevent brute-force attacks.
---
## Acceptance Criteria (Definition of Done)
### Backend
- [x] Update `/signup` to hash passwords using `werkzeug.security.generate_password_hash()`.
- [x] Update `/login` to verify passwords using `werkzeug.security.check_password_hash()`.
- [x] Update `/reset-password` to hash new passwords.
- [x] Create `backend/scripts/hash_passwords.py` script for migrating existing plain text passwords.
- [x] All backend tests pass, including new hashing tests.