dograh/api/alembic/versions/384be6596b36_make_email_case_insensitive.py
developer603 acc2ef9e96
fix: make email lookup case-insensitive in get_user_by_email (#397)
* fix: make email lookup case-insensitive in get_user_by_email

Email addresses are case-insensitive in practice, but get_user_by_email
compared with an exact `UserModel.email == email` predicate. A user who
signed up as "User@example.com" could not be found when logging in as
"user@example.com" (and vice-versa), so the same person could fail to log
in — or be treated as a brand-new account — depending only on how their
client capitalized the address.

Compare on `func.lower(UserModel.email) == func.lower(email)` so lookups
are robust to capitalization. Minimal and backwards-compatible: it works
with existing mixed-case rows immediately, with no migration required.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>

* fix: enforce case-insensitive user emails

---------

Co-authored-by: developer603 <vrramsolutions@gmail.com>
Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Co-authored-by: Abhishek Kumar <abhishek@a6k.me>
2026-06-02 13:43:20 +05:30

32 lines
1.1 KiB
Python

"""make email case insensitive
Revision ID: 384be6596b36
Revises: 6bd9f67ec994
Create Date: 2026-06-02 07:58:00.002359
"""
from typing import Sequence, Union
from alembic import op
import sqlalchemy as sa
# revision identifiers, used by Alembic.
revision: str = '384be6596b36'
down_revision: Union[str, None] = '6bd9f67ec994'
branch_labels: Union[str, Sequence[str], None] = None
depends_on: Union[str, Sequence[str], None] = None
def upgrade() -> None:
# ### commands auto generated by Alembic - please adjust! ###
op.drop_index(op.f('ix_users_email'), table_name='users')
op.create_index('ix_users_email_lower', 'users', [sa.literal_column('lower(email)')], unique=True, postgresql_where=sa.text('email IS NOT NULL'))
# ### end Alembic commands ###
def downgrade() -> None:
# ### commands auto generated by Alembic - please adjust! ###
op.drop_index('ix_users_email_lower', table_name='users', postgresql_where=sa.text('email IS NOT NULL'))
op.create_index(op.f('ix_users_email'), 'users', ['email'], unique=True)
# ### end Alembic commands ###