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

3.4 KiB

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)

  • Test signup with password hashing: Verify stored password is hashed (starts with scrypt:).
  • Test login with correct password: Succeeds.
  • Test login with incorrect password: Fails with appropriate error.
  • Test password reset: New password is hashed.
  • 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

  • Update /signup to hash passwords using werkzeug.security.generate_password_hash().
  • Update /login to verify passwords using werkzeug.security.check_password_hash().
  • Update /reset-password to hash new passwords.
  • Create backend/scripts/hash_passwords.py script for migrating existing plain text passwords.
  • All backend tests pass, including new hashing tests.