From c4a466e8e26a9642a59aa35bc9e7d0f087f73018 Mon Sep 17 00:00:00 2001 From: AN Date: Sat, 11 Jan 2025 14:55:42 +0000 Subject: [PATCH] u --- config/settings/base.py | 1 + lms/accounts/serializers.py | 20 ++++++++++++++++++-- lms/accounts/signals.py | 10 ++++++++++ lms/accounts/urls.py | 1 + lms/accounts/views.py | 22 ++++++++++++++++++---- 5 files changed, 48 insertions(+), 6 deletions(-) create mode 100644 lms/accounts/signals.py diff --git a/config/settings/base.py b/config/settings/base.py index c411f66..60d9f7e 100644 --- a/config/settings/base.py +++ b/config/settings/base.py @@ -324,6 +324,7 @@ LOGOUT_ON_PASSWORD_CHANGE = False ACCOUNT_CHANGE_EMAIL = True ACCOUNT_EMAIL_CONFIRMATION_HMAC = True ACCOUNT_CONFIRM_EMAIL_ON_GET = True +ACCOUNT_MAX_EMAIL_ADDRESSES = 2 ACCOUNT_EMAIL_CONFIRMATION_ANONYMOUS_REDIRECT_URL = None ACCOUNT_EMAIL_CONFIRMATION_AUTHENTICATED_REDIRECT_URL = None # ACCOUNT_RATE_LIMITS = { diff --git a/lms/accounts/serializers.py b/lms/accounts/serializers.py index 92b0b54..7d16122 100644 --- a/lms/accounts/serializers.py +++ b/lms/accounts/serializers.py @@ -83,9 +83,25 @@ class CustomRegisterSerializer(RegisterSerializer): - class ChangeEmailSerializer(serializers.Serializer): email = serializers.EmailField() + def validate_email(self, value): + if EmailAddress.objects.filter(email=value).exists() or User.objects.filter(email=value).exists(): + raise serializers.ValidationError("This email is already in use.") + return value - + def save(self, user): + email = self.validated_data["email"] + EmailAddress.objects.filter(user=user, verified=False).delete() # حذف الايميلات السابقة + + email_address, created = EmailAddress.objects.get_or_create( + user=user, + email=email, + defaults={"primary": False, "verified": False} + ) + + if created: + send_email_confirmation(self.context["request"], user, email=email) + + return email \ No newline at end of file diff --git a/lms/accounts/signals.py b/lms/accounts/signals.py new file mode 100644 index 0000000..007ef91 --- /dev/null +++ b/lms/accounts/signals.py @@ -0,0 +1,10 @@ +from allauth.account.signals import email_confirmed +from django.dispatch import receiver +from allauth.account.models import EmailAddress + +@receiver(email_confirmed) +def set_primary_email(sender, request, email_address, **kwargs): + user = email_address.user + EmailAddress.objects.filter(user=user).update(primary=False) + email_address.primary = True + email_address.save() diff --git a/lms/accounts/urls.py b/lms/accounts/urls.py index 7f641e6..49ec7ee 100644 --- a/lms/accounts/urls.py +++ b/lms/accounts/urls.py @@ -12,4 +12,5 @@ urlpatterns = [ PasswordResetConfirmView.as_view(), name='password_reset_confirm', ), + path('change-email/', views.ChangeEmailView.as_view(), name='change_email'), ] diff --git a/lms/accounts/views.py b/lms/accounts/views.py index d0d9748..692aeb5 100644 --- a/lms/accounts/views.py +++ b/lms/accounts/views.py @@ -2,10 +2,24 @@ from rest_framework.views import APIView from rest_framework.response import Response from rest_framework import status from django.utils.translation import gettext as _ -from allauth.account.models import EmailConfirmation, EmailConfirmationHMAC -from rest_framework.permissions import AllowAny +from allauth.account.models import EmailConfirmation, EmailConfirmationHMAC, EmailAddress +from rest_framework.permissions import AllowAny, IsAuthenticated from .serializers import ChangeEmailSerializer +from asgiref.sync import sync_to_async +class ChangeEmailView(APIView): + + def post(self, request, *args, **kwargs): + serializer = ChangeEmailSerializer(data=request.data, context={"request": request}) + if serializer.is_valid(): + serializer.save(user=request.user) + return Response({ + "message": "Confirmation email has been sent to the new address.", + }, status=status.HTTP_200_OK) + + return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST) + + class ConfirmEmailAPIView(APIView): permission_classes = [AllowAny] @@ -29,5 +43,5 @@ class ConfirmEmailAPIView(APIView): # Verify the email email_confirmation.confirm(request) - - return Response({"detail": _("Email successfully verified.")}, status=status.HTTP_200_OK) + email = email_confirmation.email_address.email + return Response({"detail": _("Email successfully verified."), "email": email}, status=status.HTTP_200_OK)