diff --git a/zod_bank/account/serializers.py b/zod_bank/account/serializers.py
index 03b1012..94c774f 100644
--- a/zod_bank/account/serializers.py
+++ b/zod_bank/account/serializers.py
@@ -13,6 +13,64 @@ from rest_framework.decorators import action
from django.contrib.auth import authenticate, login
from rest_framework_simplejwt.tokens import RefreshToken
+class ResetPasswordSerializer(serializers.Serializer):
+ """Reset Password after verification"""
+ verification_code = serializers.CharField(max_length=10)
+ password = serializers.CharField(required=True)
+ class Meta(object):
+ """Meta info"""
+ model = User
+
+ def create(self, validated_data):
+ verification_code = validated_data.pop('verification_code')
+ password = validated_data.pop('password')
+ print("verification_code===>",verification_code)
+ print("password===>", password)
+ user_opt_details = UserEmailOtp.objects.filter(otp=verification_code, is_verified=True).last()
+ print("user_opt_details===>",user_opt_details)
+ if user_opt_details:
+ print("qqqqqqqqqq")
+ user_details = User.objects.filter(email=user_opt_details.email).last()
+ if user_details:
+ print("333333333==>",user_details.password)
+ user_details.set_password(password)
+ user_details.save()
+ return {'password':password}
+ return user_opt_details
+ return ''
+
+class ChangePasswordSerializer(serializers.Serializer):
+ """Update Password after verification"""
+ current_password = serializers.CharField(max_length=100)
+ new_password = serializers.CharField(required=True)
+ class Meta(object):
+ """Meta info"""
+ model = User
+
+ def validate_current_password(self, value):
+ user = self.context
+ if self.context.password not in ('', None):
+ if user.check_password(value):
+ return value
+ raise serializers.ValidationError({"error":"Invalid Current password"})
+ def create(self, validated_data):
+ new_password = validated_data.pop('new_password')
+ user_details = User.objects.filter(email=self.context).last()
+ print("user_details==>", user_details)
+ if user_details:
+ print("333333333==>",user_details.password)
+ user_details.set_password(new_password)
+ user_details.save()
+ return {'password':new_password}
+ return user_details
+ return ''
+
+
+
+class ForgotPasswordSerializer(serializers.Serializer):
+ """Forget password serializer"""
+ email = serializers.EmailField()
+
class SuperUserSerializer(serializers.ModelSerializer):
user_type = serializers.SerializerMethodField('get_user_type')
diff --git a/zod_bank/account/templates/templated_email/email_base.email b/zod_bank/account/templates/templated_email/email_base.email
new file mode 100644
index 0000000..5721e28
--- /dev/null
+++ b/zod_bank/account/templates/templated_email/email_base.email
@@ -0,0 +1,54 @@
+
+{% block subject %}DinDin{% endblock %}
+{% load static %}
+
+{% block html %}
+
+
+
+
+ Zod Bank | OTP
+
+
+
+
+
+
+
+
+
+
+ |
+ |
+
+ {% block plain %}
+ {% endblock %}
+
+ |
+ -
+ Cheers!
+ Zod Bank Team
+ |
+
+
+ |
+
+
+
+
+
+
+{% endblock %}
diff --git a/zod_bank/account/templates/templated_email/email_otp_verification.email b/zod_bank/account/templates/templated_email/email_otp_verification.email
new file mode 100644
index 0000000..8b3c693
--- /dev/null
+++ b/zod_bank/account/templates/templated_email/email_otp_verification.email
@@ -0,0 +1,23 @@
+{% extends "templated_email/email_base.email" %}
+
+{% block subject %}
+ OTP Verification
+{% endblock %}
+
+{% block plain %}
+
+ |
+
+ Hi User,
+
+ |
+
+
+ |
+
+ You are receiving this email for email verification. Please use {{ otp }} as the verification code for your email address & username.
+
+
+ |
+
+{% endblock %}
diff --git a/zod_bank/account/templates/templated_email/email_reset_verification.email b/zod_bank/account/templates/templated_email/email_reset_verification.email
new file mode 100644
index 0000000..e2f8ebf
--- /dev/null
+++ b/zod_bank/account/templates/templated_email/email_reset_verification.email
@@ -0,0 +1,23 @@
+{% extends "templated_email/email_base.email" %}
+
+{% block subject %}
+ Password Reset Verification Code
+{% endblock %}
+
+{% block plain %}
+
+ |
+
+ Hi User,
+
+ |
+
+
+ |
+
+ You are receiving this email for reset password verification. Please use {{ verification_code }} as the verification code.
+
+
+ |
+
+{% endblock %}
diff --git a/zod_bank/account/urls.py b/zod_bank/account/urls.py
index 1350cea..3c1fc2c 100644
--- a/zod_bank/account/urls.py
+++ b/zod_bank/account/urls.py
@@ -4,7 +4,8 @@ from django.urls import path, include
from rest_framework.decorators import api_view
"""Third party import"""
from rest_framework import routers
-from .views import UserLogin, SendPhoneOtp, UserPhoneVerification, UserEmailVerification, ReSendEmailOtp
+from .views import (UserLogin, SendPhoneOtp, UserPhoneVerification, UserEmailVerification, ReSendEmailOtp,
+ ForgotPasswordAPIView, ResetPasswordAPIView, ChangePasswordAPIView)
"""Router"""
router = routers.SimpleRouter()
@@ -15,6 +16,10 @@ router.register('send-phone-otp', SendPhoneOtp, basename='send-phone-otp')
router.register('user-phone-verification', UserPhoneVerification, basename='user-phone-verification')
router.register('user-email-verification', UserEmailVerification, basename='user-email-verification')
router.register('resend-email-otp', ReSendEmailOtp, basename='resend-email-otp')
+
urlpatterns = [
path('api/v1/', include(router.urls)),
+ path('api/v1/forgot-password/', ForgotPasswordAPIView.as_view()),
+ path('api/v1/reset-password/', ResetPasswordAPIView.as_view()),
+ path('api/v1/change-password/', ChangePasswordAPIView.as_view())
]
diff --git a/zod_bank/account/utils.py b/zod_bank/account/utils.py
index c6ffe7f..2d86106 100644
--- a/zod_bank/account/utils.py
+++ b/zod_bank/account/utils.py
@@ -3,12 +3,19 @@ from django.conf import settings
import random
from rest_framework import viewsets, status
from rest_framework.response import Response
+
+from templated_email import send_templated_mail
def send_otp_email(recipient_email, otp):
- subject = 'One-Time Password'
- message = f'Your OTP is: {otp}'
- from_email = settings.DEFAULT_FROM_EMAIL
+ from_email = settings.EMAIL_HOST_USER
recipient_list = [recipient_email]
- send_mail(subject, message, from_email, recipient_list)
+ send_templated_mail(
+ template_name='email_otp_verification.email',
+ from_email=from_email,
+ recipient_list=recipient_list,
+ context={
+ 'otp': otp
+ }
+ )
return otp
def custom_response(detail, data=None, response_status=status.HTTP_200_OK):
diff --git a/zod_bank/account/views.py b/zod_bank/account/views.py
index 352b834..82039b9 100644
--- a/zod_bank/account/views.py
+++ b/zod_bank/account/views.py
@@ -1,20 +1,75 @@
-from rest_framework import viewsets, status
+from rest_framework import viewsets, status, views
from rest_framework.decorators import action
-from rest_framework.response import Response
+import random
from django.contrib.auth import authenticate, login
from guardian.models import Guardian
from junior.models import Junior
from account.models import UserProfile, UserPhoneOtp, UserEmailOtp
from django.contrib.auth.models import User
-from .serializers import SuperUserSerializer, GuardianSerializer, JuniorSerializer, EmailVerificationSerializer
+from .serializers import (SuperUserSerializer, GuardianSerializer, JuniorSerializer, EmailVerificationSerializer,
+ ForgotPasswordSerializer, ResetPasswordSerializer, ChangePasswordSerializer)
from django.views.decorators.csrf import csrf_exempt
from rest_framework_simplejwt.serializers import TokenObtainPairSerializer
from rest_framework_simplejwt.views import TokenObtainPairView
from rest_framework_simplejwt.tokens import RefreshToken
from base.messages import ERROR_CODE, SUCCESS_CODE
from guardian.tasks import generate_otp
-
+from django.conf import settings
from account.utils import custom_response, custom_error_response
+from django.core.mail import EmailMessage
+from django.core.mail import send_mail
+from rest_framework.response import Response
+from rest_framework.permissions import IsAuthenticated
+from templated_email import send_templated_mail
+import secrets
+
+
+class ChangePasswordAPIView(views.APIView):
+ permission_classes = [IsAuthenticated]
+ def post(self, request):
+ print("request.data====>",request.data)
+ print("request.user====>", request.user)
+ serializer = ChangePasswordSerializer(context=request.user, data=request.data)
+ if serializer.is_valid():
+ serializer.save()
+ return custom_response(SUCCESS_CODE['3006'], response_status=status.HTTP_200_OK)
+ return custom_error_response(serializer.errors, response_status=status.HTTP_400_BAD_REQUEST)
+
+class ResetPasswordAPIView(views.APIView):
+ def post(self, request):
+ print("request.data====>",request.data)
+ serializer = ResetPasswordSerializer(data=request.data)
+ if serializer.is_valid():
+ serializer.save()
+ return custom_response(SUCCESS_CODE['3006'], response_status=status.HTTP_200_OK)
+ return custom_error_response(serializer.errors, response_status=status.HTTP_400_BAD_REQUEST)
+
+class ForgotPasswordAPIView(views.APIView):
+ def post(self, request):
+ serializer = ForgotPasswordSerializer(data=request.data)
+ if serializer.is_valid():
+ email = serializer.validated_data['email']
+ try:
+ User.objects.get(email=email)
+ except User.DoesNotExist:
+ return custom_error_response(ERROR_CODE['2004'], response_status=status.HTTP_404_NOT_FOUND)
+ verification_code = ''.join([str(random.randrange(9)) for _ in range(6)])
+ # Send the verification code to the user's email
+ from_email = settings.EMAIL_HOST_USER
+ recipient_list = [email]
+ send_templated_mail(
+ template_name='email_reset_verification.email',
+ from_email=from_email,
+ recipient_list=recipient_list,
+ context={
+ 'verification_code': verification_code
+ }
+ )
+ UserEmailOtp.objects.create(email=email, otp=verification_code)
+ return custom_response(SUCCESS_CODE['3015'], {'verification_code': verification_code},
+ response_status=status.HTTP_200_OK)
+ return custom_error_response(serializer.errors, response_status=status.HTTP_400_BAD_REQUEST)
+
class SendPhoneOtp(viewsets.ModelViewSet):
"""Send otp on phone"""
def create(self, request, *args, **kwargs):
@@ -58,7 +113,7 @@ class UserLogin(viewsets.ViewSet):
serializer = JuniorSerializer(junior_data)
if user.is_superuser:
serializer = SuperUserSerializer(user)
- return custom_response(None, serializer.data, response_status=status.HTTP_200_OK)
+ return custom_response(SUCCESS_CODE['3003'], serializer.data, response_status=status.HTTP_200_OK)
else:
return custom_error_response(ERROR_CODE["2002"], response_status=status.HTTP_401_UNAUTHORIZED)
except Exception as e:
diff --git a/zod_bank/base/messages.py b/zod_bank/base/messages.py
index 718d6be..39f0282 100644
--- a/zod_bank/base/messages.py
+++ b/zod_bank/base/messages.py
@@ -27,7 +27,7 @@ ERROR_CODE = {
"2001": "Your account has not been verified. Please check your email and verify it.",
"2002": "Invalid login credentials.",
"2003": "An account already exists with this email address.",
- "2004": "User doesn't exist.",
+ "2004": "User not found.",
"2005": "Your account has been activated.",
"2006": "Your account is not activated.",
"2007": "Your account already activated.",
@@ -55,7 +55,7 @@ SUCCESS_CODE = {
# Success code for Thank you
"3002": "Thank you for contacting us! Our Consumer Experience Team will reach out to you shortly.",
# Success code for account activation
- "3003": "Your account has been activated.",
+ "3003": "Log in successfully",
# Success code for password reset
"3004": "Password reset link has been sent to your email address",
# Success code for link verified
@@ -73,7 +73,8 @@ SUCCESS_CODE = {
"3011": "Email OTP Verified successfully",
"3012": "Phone OTP Verified successfully",
"3013": "Valid Guardian code",
- "3014": "Password has been updated successfully."
+ "3014": "Password has been updated successfully.",
+ "3015": "Verification code sent on your email."
}
STATUS_CODE_ERROR = {
diff --git a/zod_bank/guardian/urls.py b/zod_bank/guardian/urls.py
index 64aa80f..0e3f898 100644
--- a/zod_bank/guardian/urls.py
+++ b/zod_bank/guardian/urls.py
@@ -11,7 +11,7 @@ router = routers.SimpleRouter()
"""API End points with router"""
router.register('sign-up', SignupViewset, basename='sign-up')
-router.register('update-guardian-profile', UpdateGuardianProfile, basename='update-guardian-profile')
+router.register('complete-guardian-profile', UpdateGuardianProfile, basename='update-guardian-profile')
urlpatterns = [
path('api/v1/', include(router.urls)),
]
diff --git a/zod_bank/guardian/views.py b/zod_bank/guardian/views.py
index f43e4c8..2b40702 100644
--- a/zod_bank/guardian/views.py
+++ b/zod_bank/guardian/views.py
@@ -17,6 +17,7 @@ from .tasks import generate_otp
from account.utils import send_otp_email
from account.utils import custom_response, custom_error_response
from base.messages import ERROR_CODE, SUCCESS_CODE
+
class SignupViewset(viewsets.ModelViewSet):
serializer_class = UserSerializer
@@ -26,7 +27,7 @@ class SignupViewset(viewsets.ModelViewSet):
serializer.save()
otp = generate_otp()
UserEmailOtp.objects.create(email=request.data['email'], otp=otp)
- # send_otp_email(request.data['email'], otp)
+ send_otp_email(request.data['email'], otp)
return custom_response(SUCCESS_CODE['3001'], {"email_otp": otp},
response_status=status.HTTP_200_OK)
return custom_error_response(serializer.errors, response_status=status.HTTP_400_BAD_REQUEST)
diff --git a/zod_bank/junior/urls.py b/zod_bank/junior/urls.py
index cce385d..27a312e 100644
--- a/zod_bank/junior/urls.py
+++ b/zod_bank/junior/urls.py
@@ -10,7 +10,7 @@ from rest_framework import routers
router = routers.SimpleRouter()
"""API End points with router"""
-router.register('profile-update', UpdateJuniorProfile, basename='profile-update')
+router.register('complete-junior-profile', UpdateJuniorProfile, basename='profile-update')
router.register('validate-guardian-code', ValidateGuardianCode, basename='validate-guardian-code')
urlpatterns = [
path('api/v1/', include(router.urls)),
diff --git a/zod_bank/zod_bank/settings.py b/zod_bank/zod_bank/settings.py
index 0c8da76..9e47b30 100644
--- a/zod_bank/zod_bank/settings.py
+++ b/zod_bank/zod_bank/settings.py
@@ -171,6 +171,32 @@ CORS_ALLOW_HEADERS = (
# Static files (CSS, JavaScript, Images)
# https://docs.djangoproject.com/en/3.0/howto/static-files/
+#
+# MAIL_MAILER='smtp'
+# MAIL_HOST='smtp.gmail.com'
+# MAIL_PORT=587
+# mail_username='infozodbank@gmail.com'
+# MAIL_PASSWORD='ghwdmznwwslvchga'
+# MAIL_ENCRYPTION='tls'
+# mail_from_address='infozodbank@gmail.com'
+# MAIL_FROM_NAME="${APP_NAME}"
+
+# MAIL_MAILER='smtp'
+# MAIL_HOST='smtp.gmail.com'
+# MAIL_PORT=587
+# mail_username='ankita.jain@kiwitech.com'
+# MAIL_PASSWORD='jaijain0912@'
+# MAIL_ENCRYPTION='tls'
+# mail_from_address='infozodbank@gmail.com'
+# MAIL_FROM_NAME="${APP_NAME}"
+
+# Email settings
+EMAIL_BACKEND = 'django.core.mail.backends.smtp.EmailBackend'
+EMAIL_HOST = 'smtp.gmail.com'
+EMAIL_PORT = 587
+EMAIL_USE_TLS = True
+EMAIL_HOST_USER = 'infozodbank@gmail.com'
+EMAIL_HOST_PASSWORD = 'ghwdmznwwslvchga' # Replace with your Gmail email password or App password
STATIC_URL = '/static/'