Files
chore/.github/specs/archive/feat-hashed-passwords.md
Ryan Kegel 55e7dc7568
All checks were successful
Chore App Build, Test, and Push Docker Images / build-and-push (push) Successful in 2m6s
feat: remove hashed passwords feature spec and migrate to archive
fix: update login token expiration to 62 days

chore: bump version to 1.0.5RC1

test: add isParentPersistent to LoginButton.spec.ts

refactor: rename Assign Tasks button to Assign Chores in ParentView.vue

refactor: rename Assign Tasks to Assign Chores in TaskAssignView.vue

feat: add stay in parent mode checkbox and badge in LoginButton.vue

test: enhance LoginButton.spec.ts with persistent mode tests

test: add authGuard.spec.ts for logoutParent and enforceParentExpiry

feat: implement parent mode expiry logic in auth.ts

test: add auth.expiry.spec.ts for parent mode expiry tests

chore: create template for feature specs
2026-02-20 16:31:13 -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.