feat: implement password reset for shop customers

Add complete password reset functionality:

Database:
- Add password_reset_tokens migration with token hash, expiry, used_at
- Create PasswordResetToken model with secure token hashing (SHA256)
- One active token per customer (old tokens invalidated on new request)
- 1-hour token expiry for security

API:
- Implement forgot_password endpoint with email lookup
- Implement reset_password endpoint with token validation
- No email enumeration (same response for all requests)
- Password minimum 8 characters validation

Frontend:
- Add reset-password.html template with Alpine.js
- Support for invalid/expired token states
- Success state with login redirect
- Dark mode support

Email:
- Add password_reset email templates (en, fr, de, lb)
- Uses existing EmailService with template rendering

Testing:
- Add comprehensive pytest tests (19 tests)
- Test token creation, validation, expiry, reuse prevention
- Test endpoint success and error cases

Removes critical launch blocker for password reset functionality.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
2026-01-03 17:16:27 +01:00
parent 2c7ac5b6b2
commit 2e1a2fc9fc
8 changed files with 1282 additions and 16 deletions

View File

@@ -18,6 +18,7 @@ from .base import Base
from .company import Company
from .content_page import ContentPage
from .customer import Customer, CustomerAddress
from .password_reset_token import PasswordResetToken
from .email import EmailCategory, EmailLog, EmailStatus, EmailTemplate
from .feature import Feature, FeatureCategory, FeatureCode, FeatureUILocation
from .inventory import Inventory
@@ -102,9 +103,10 @@ __all__ = [
"VendorTheme",
# Content
"ContentPage",
# Customer
# Customer & Auth
"Customer",
"CustomerAddress",
"PasswordResetToken",
# Email
"EmailCategory",
"EmailLog",