diff --git a/app/api/views/auth.py b/app/api/views/auth.py index 61d27365..d186b23f 100644 --- a/app/api/views/auth.py +++ b/app/api/views/auth.py @@ -92,6 +92,7 @@ def auth_register(): return jsonify(error="request body cannot be empty"), 400 email = canonicalize_email(data.get("email")) + dirty_email = sanitize_email(data.get("email")) password = data.get("password") if DISABLE_REGISTRATION: @@ -112,7 +113,7 @@ def auth_register(): return jsonify(error="password too long"), 400 LOG.d("create user %s", email) - user = User.create(email=email, name="", password=password) + user = User.create(email=email, dirty_email=dirty_email, name="", password=password) Session.flush() # create activation code diff --git a/app/auth/views/change_email.py b/app/auth/views/change_email.py index 9e70c882..85ed879c 100644 --- a/app/auth/views/change_email.py +++ b/app/auth/views/change_email.py @@ -23,6 +23,7 @@ def change_email(): user = email_change.user user.email = email_change.new_email + user.dirty_email = email_change.dirty_email or email_change.new_email EmailChange.delete(email_change.id) ResetPasswordCode.filter_by(user_id=user.id).delete() diff --git a/app/auth/views/register.py b/app/auth/views/register.py index a5c3c966..47629242 100644 --- a/app/auth/views/register.py +++ b/app/auth/views/register.py @@ -85,6 +85,7 @@ def register(): LOG.d("create user %s", email) user = User.create( email=email, + dirty_email=sanitized_email, name="", password=form.password.data, referral=get_referral(), diff --git a/app/dashboard/views/setting.py b/app/dashboard/views/setting.py index 480fd6cf..cf45e616 100644 --- a/app/dashboard/views/setting.py +++ b/app/dashboard/views/setting.py @@ -57,6 +57,7 @@ from app.utils import ( random_string, CSRFValidationForm, canonicalize_email, + sanitize_email, ) @@ -170,6 +171,7 @@ def setting(): 60 ), # todo: make sure the code is unique new_email=new_email, + dirty_email=sanitize_email(change_email_form.email.data), ) Session.commit() send_change_email_confirmation(current_user, email_change) diff --git a/app/fake_data.py b/app/fake_data.py index b5b0d0b9..a419a371 100644 --- a/app/fake_data.py +++ b/app/fake_data.py @@ -43,6 +43,7 @@ def fake_data(): # Create a user user = User.create( email="john@wick.com", + dirty_email="john@wick.com", name="John Wick", password="password", activated=True, @@ -234,6 +235,7 @@ def fake_data(): user2 = User.create( email="winston@continental.com", + dirty_email="winston@continental.com", password="password", activated=True, referral_id=referral.id, diff --git a/app/models.py b/app/models.py index bf475e3f..12487c6f 100644 --- a/app/models.py +++ b/app/models.py @@ -320,6 +320,7 @@ class User(Base, ModelMixin, UserMixin, PasswordOracle): FLAG_FREE_OLD_ALIAS_LIMIT = 1 << 2 email = sa.Column(sa.String(256), unique=True, nullable=False) + dirty_email = sa.Column(sa.String(256), unique=False, nullable=True) name = sa.Column(sa.String(128), nullable=True) is_admin = sa.Column(sa.Boolean, nullable=False, default=False) @@ -2064,6 +2065,7 @@ class EmailChange(Base, ModelMixin): index=True, ) new_email = sa.Column(sa.String(256), unique=True, nullable=False) + dirty_email = sa.Column(sa.String(256), unique=False, nullable=True) code = sa.Column(sa.String(128), unique=True, nullable=False) expired = sa.Column(ArrowType, nullable=False, default=_expiration_12h) diff --git a/migrations/versions/2022_113018_74fe25b66e9b_.py b/migrations/versions/2022_113018_74fe25b66e9b_.py new file mode 100644 index 00000000..7036baa6 --- /dev/null +++ b/migrations/versions/2022_113018_74fe25b66e9b_.py @@ -0,0 +1,31 @@ +"""empty message + +Revision ID: 74fe25b66e9b +Revises: 2c2093c82bc0 +Create Date: 2022-11-30 18:21:44.235063 + +""" +import sqlalchemy_utils +from alembic import op +import sqlalchemy as sa + + +# revision identifiers, used by Alembic. +revision = '74fe25b66e9b' +down_revision = '2c2093c82bc0' +branch_labels = None +depends_on = None + + +def upgrade(): + # ### commands auto generated by Alembic - please adjust! ### + op.add_column('email_change', sa.Column('dirty_email', sa.String(length=256), nullable=True)) + op.add_column('users', sa.Column('dirty_email', sa.String(length=256), nullable=True)) + # ### end Alembic commands ### + + +def downgrade(): + # ### commands auto generated by Alembic - please adjust! ### + op.drop_column('users', 'dirty_email') + op.drop_column('email_change', 'dirty_email') + # ### end Alembic commands ###