feat: fix registration 500, add forgot-password flow, frontend validation
Some checks failed
Some checks failed
- Fix MissingGreenlet: sync_engine now uses psycopg2 instead of asyncpg - Fix bcrypt/passlib compat: pin bcrypt<4.1 in requirements - Fix legacy password_hash NOT NULL: alter column to nullable in migration - Add frontend password validation (uppercase + lowercase + digit) - Add forgot-password and reset-password backend endpoints - Add forgot-password and reset-password frontend pages - Add email_service.py (SMTP via admin settings) - Add reset_token/reset_token_expires columns to User model - Migrate legacy JSON-only users to DB on password reset request - Mount data/ volume in docker-compose.local.yml for persistence - Add production deployment config (Dockerfile, nginx, deploy.sh) Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
31
alembic/versions/005_add_reset_token_to_users.py
Normal file
31
alembic/versions/005_add_reset_token_to_users.py
Normal file
@@ -0,0 +1,31 @@
|
||||
"""add reset_token and reset_token_expires to users
|
||||
|
||||
Revision ID: a1b2c3d4e5f6
|
||||
Revises: 5206607942a2
|
||||
Create Date: 2026-05-01 10:00:00.000000
|
||||
"""
|
||||
|
||||
from typing import Sequence, Union
|
||||
|
||||
from alembic import op
|
||||
import sqlalchemy as sa
|
||||
|
||||
|
||||
# revision identifiers, used by Alembic.
|
||||
revision: str = "a1b2c3d4e5f6"
|
||||
down_revision: Union[str, None] = "004_rename_account_tier"
|
||||
branch_labels: Union[str, Sequence[str], None] = None
|
||||
depends_on: Union[str, Sequence[str], None] = None
|
||||
|
||||
|
||||
def upgrade() -> None:
|
||||
op.add_column("users", sa.Column("reset_token", sa.String(length=255), nullable=True))
|
||||
op.add_column("users", sa.Column("reset_token_expires", sa.DateTime(), nullable=True))
|
||||
# Make legacy password_hash column nullable (ORM uses hashed_password now)
|
||||
op.alter_column("users", "password_hash", nullable=True)
|
||||
|
||||
|
||||
def downgrade() -> None:
|
||||
op.drop_column("users", "reset_token_expires")
|
||||
op.drop_column("users", "reset_token")
|
||||
op.alter_column("users", "password_hash", nullable=False)
|
||||
Reference in New Issue
Block a user