From 377fdf6fec045234f4ffc37acc16d6d050973050 Mon Sep 17 00:00:00 2001 From: mortezaei Date: Tue, 23 Sep 2025 12:02:02 +0330 Subject: [PATCH] feat(account): enhance user serializers with email normalization and device_id handling - Updated UserRegisterSerializer to make device_id write-only and handle its assignment during user creation. - Implemented email normalization in UserRegisterSerializer, UserVerifySerializer, and UserLoginSerializer to ensure case-insensitive uniqueness. - Refactored UserRecoverPasswordSerializer to validate email format without checking for database uniqueness. --- apps/account/serializers/user.py | 58 +++++++++++++++++++++++++------- 1 file changed, 45 insertions(+), 13 deletions(-) diff --git a/apps/account/serializers/user.py b/apps/account/serializers/user.py index b86eba4..df34944 100644 --- a/apps/account/serializers/user.py +++ b/apps/account/serializers/user.py @@ -42,7 +42,7 @@ class UserProfileSerializer(serializers.ModelSerializer): class UserRegisterSerializer(serializers.ModelSerializer): fcm = serializers.CharField(required=False, allow_blank=True, allow_null=True) - device_id = serializers.CharField(required=False, allow_blank=True, allow_null=True) + device_id = serializers.CharField(required=False, allow_blank=True, allow_null=True, write_only=True) email = serializers.EmailField() class Meta: @@ -52,11 +52,20 @@ class UserRegisterSerializer(serializers.ModelSerializer): 'fullname': {'required': True,}, 'email': {'required': True,}, } + + def create(self, validated_data): + device_id = validated_data.pop('device_id', None) + user = super().create(validated_data) + if device_id: + user.device_id = device_id + user.save() + return user def validate_email(self, value): - if User.objects.filter(email=value).exists(): + normalized_email = User.objects.normalize_email(value) + if User.objects.filter(email=normalized_email).exists(): raise serializers.ValidationError("This email is already registered.") - return value + return normalized_email @@ -65,7 +74,12 @@ class UserVerifySerializer(serializers.Serializer): email = serializers.EmailField() device_id = serializers.CharField(max_length=255, required=False) - + def validate_email(self, value): + """ + Normalize the email to ensure the Redis key matches correctly. + """ + return User.objects.normalize_email(value) + class UserLoginSerializer(serializers.Serializer): password = serializers.CharField(write_only=True) @@ -83,6 +97,12 @@ class UserLoginSerializer(serializers.Serializer): # data.pop('fcm', None) # data.pop('device_id', None) return data + def validate_email(self, value): + """ + Normalize email for case-insensitive login. + """ + return User.objects.normalize_email(value) + # class UserLoginSerializer(serializers.Serializer): # password = serializers.CharField(write_only=True) @@ -98,17 +118,29 @@ class UserLoginSerializer(serializers.Serializer): -class UserRecoverPasswordSerializer(serializers.ModelSerializer): - email = serializers.EmailField() +# class UserRecoverPasswordSerializer(serializers.ModelSerializer): +# email = serializers.EmailField() - class Meta: - model = User - fields = ['email',] - extra_kwargs = { - 'email': {'required': True,}, - } - +# class Meta: +# model = User +# fields = ['email',] +# extra_kwargs = { +# 'email': {'required': True,}, +# } + +class UserRecoverPasswordSerializer(serializers.Serializer): + """ + Validates that an email is provided and is in a valid format + without checking for database uniqueness. + """ + email = serializers.EmailField(required=True) + def validate_email(self, value): + """ + Normalize the email address to ensure case-insensitive lookups. + """ + return User.objects.normalize_email(value) + class UserResetPasswordSerializer(serializers.ModelSerializer): password = serializers.CharField(write_only=True)