mirror of
https://github.com/HamzaSha1/zod-backend.git
synced 2025-11-26 08:34:55 +00:00
forgot password and email verification
This commit is contained in:
@ -13,6 +13,38 @@ from rest_framework.decorators import action
|
|||||||
from django.contrib.auth import authenticate, login
|
from django.contrib.auth import authenticate, login
|
||||||
from rest_framework_simplejwt.tokens import RefreshToken
|
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
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
class ForgotPasswordSerializer(serializers.Serializer):
|
||||||
|
"""Forget password serializer"""
|
||||||
|
email = serializers.EmailField()
|
||||||
|
|
||||||
class SuperUserSerializer(serializers.ModelSerializer):
|
class SuperUserSerializer(serializers.ModelSerializer):
|
||||||
user_type = serializers.SerializerMethodField('get_user_type')
|
user_type = serializers.SerializerMethodField('get_user_type')
|
||||||
|
|
||||||
|
|||||||
54
zod_bank/account/templates/templated_email/email_base.email
Normal file
54
zod_bank/account/templates/templated_email/email_base.email
Normal file
@ -0,0 +1,54 @@
|
|||||||
|
<!DOCTYPE HTML>
|
||||||
|
{% block subject %}DinDin{% endblock %}
|
||||||
|
{% load static %}
|
||||||
|
|
||||||
|
{% block html %}
|
||||||
|
<html lang="en" style="height: 100%;">
|
||||||
|
<head>
|
||||||
|
<meta http-equiv="Content-Type"
|
||||||
|
content="text/html; charset=UTF-8">
|
||||||
|
<meta name="viewport"
|
||||||
|
content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=0">
|
||||||
|
<title>Zod Bank | OTP</title>
|
||||||
|
<style type="text/css">
|
||||||
|
@media all and (max-width: 599px) {
|
||||||
|
.block {
|
||||||
|
display: block !important;
|
||||||
|
width: 100%;
|
||||||
|
}
|
||||||
|
.top-space {
|
||||||
|
padding: 15px 0 0 !important;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
</head>
|
||||||
|
|
||||||
|
<body style="margin: 0; padding: 0; background: #f7f8f9; height: 100%;">
|
||||||
|
<!-- begin template body -->
|
||||||
|
<table style="background:#f7f8f9; border: 0; border-collapse: separate; border-spacing: 0px; margin: auto; width: 100%; font-family: Arial, Helvetica, sans-serif; height: 100%;" aria-describedby="email-data-wrapper">
|
||||||
|
<tr>
|
||||||
|
<td style="padding: 0;">
|
||||||
|
<table style="background-color: white; border-collapse: separate; border-spacing: 0px; border: 1px solid #e4e8eb; width: 100%; max-width: 600px; margin-right:auto; margin-left: auto;
|
||||||
|
font-family: Arial, Helvetica, sans-serif;" aria-describedby="email-data-wrapper">
|
||||||
|
<tr>
|
||||||
|
<td style="padding: 41px 30px 40px; height: 39px; background: url({% static 'images/backgrounds/email_template.png' %}) left center no-repeat; background-size: cover;">
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
{% block plain %}
|
||||||
|
{% endblock %}
|
||||||
|
<tr>
|
||||||
|
<td style="padding: 0 27px;">
|
||||||
|
<p style="margin: 0; font-size: 14px; line-height: 20px; color: #505050; font-weight: 400;">-</p>
|
||||||
|
<p style="margin: 0; font-size: 14px; line-height: 20px; color: #505050; font-weight: 400;">Cheers!</p>
|
||||||
|
<p style="margin: 0 0 30px; font-size: 14px; line-height: 20px; color: #505050; font-weight: 700;">Zod Bank Team</p>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
</table>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
</tbody>
|
||||||
|
</table>
|
||||||
|
<!-- end template body -->
|
||||||
|
</body>
|
||||||
|
</html>
|
||||||
|
{% endblock %}
|
||||||
@ -0,0 +1,23 @@
|
|||||||
|
{% extends "templated_email/email_base.email" %}
|
||||||
|
|
||||||
|
{% block subject %}
|
||||||
|
OTP Verification
|
||||||
|
{% endblock %}
|
||||||
|
|
||||||
|
{% block plain %}
|
||||||
|
<tr>
|
||||||
|
<td style="padding: 0 27px 15px;">
|
||||||
|
<p style="margin: 0; font-size: 16px; line-height: 20px; padding: 36px 0 0; font-weight: 500; color: #1f2532;">
|
||||||
|
Hi User,
|
||||||
|
</p>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td style="padding: 0 27px 22px;">
|
||||||
|
<p style="margin: 0;font-size: 14px; font-weight: 400; line-height: 21px; color: #1f2532;">
|
||||||
|
You are receiving this email for email verification. Please use <b>{{ otp }} </b>as the verification code for your email address & username.
|
||||||
|
|
||||||
|
</p>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
{% endblock %}
|
||||||
@ -0,0 +1,23 @@
|
|||||||
|
{% extends "templated_email/email_base.email" %}
|
||||||
|
|
||||||
|
{% block subject %}
|
||||||
|
Reset Password Verification
|
||||||
|
{% endblock %}
|
||||||
|
|
||||||
|
{% block plain %}
|
||||||
|
<tr>
|
||||||
|
<td style="padding: 0 27px 15px;">
|
||||||
|
<p style="margin: 0; font-size: 16px; line-height: 20px; padding: 36px 0 0; font-weight: 500; color: #1f2532;">
|
||||||
|
Hi User,
|
||||||
|
</p>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td style="padding: 0 27px 22px;">
|
||||||
|
<p style="margin: 0;font-size: 14px; font-weight: 400; line-height: 21px; color: #1f2532;">
|
||||||
|
You are receiving this email for reset password verification. Please use <b>{{ verification_code }} </b>as the verification code.
|
||||||
|
|
||||||
|
</p>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
{% endblock %}
|
||||||
@ -4,7 +4,8 @@ from django.urls import path, include
|
|||||||
from rest_framework.decorators import api_view
|
from rest_framework.decorators import api_view
|
||||||
"""Third party import"""
|
"""Third party import"""
|
||||||
from rest_framework import routers
|
from rest_framework import routers
|
||||||
from .views import UserLogin, SendPhoneOtp, UserPhoneVerification, UserEmailVerification, ReSendEmailOtp
|
from .views import (UserLogin, SendPhoneOtp, UserPhoneVerification, UserEmailVerification, ReSendEmailOtp,
|
||||||
|
ForgotPasswordAPIView, ResetPasswordAPIView)
|
||||||
"""Router"""
|
"""Router"""
|
||||||
router = routers.SimpleRouter()
|
router = routers.SimpleRouter()
|
||||||
|
|
||||||
@ -15,6 +16,9 @@ router.register('send-phone-otp', SendPhoneOtp, basename='send-phone-otp')
|
|||||||
router.register('user-phone-verification', UserPhoneVerification, basename='user-phone-verification')
|
router.register('user-phone-verification', UserPhoneVerification, basename='user-phone-verification')
|
||||||
router.register('user-email-verification', UserEmailVerification, basename='user-email-verification')
|
router.register('user-email-verification', UserEmailVerification, basename='user-email-verification')
|
||||||
router.register('resend-email-otp', ReSendEmailOtp, basename='resend-email-otp')
|
router.register('resend-email-otp', ReSendEmailOtp, basename='resend-email-otp')
|
||||||
|
|
||||||
urlpatterns = [
|
urlpatterns = [
|
||||||
path('api/v1/', include(router.urls)),
|
path('api/v1/', include(router.urls)),
|
||||||
|
path('api/v1/forgot-password/', ForgotPasswordAPIView.as_view()),
|
||||||
|
path('api/v1/reset-password/', ResetPasswordAPIView.as_view())
|
||||||
]
|
]
|
||||||
|
|||||||
@ -3,12 +3,19 @@ from django.conf import settings
|
|||||||
import random
|
import random
|
||||||
from rest_framework import viewsets, status
|
from rest_framework import viewsets, status
|
||||||
from rest_framework.response import Response
|
from rest_framework.response import Response
|
||||||
|
|
||||||
|
from templated_email import send_templated_mail
|
||||||
def send_otp_email(recipient_email, otp):
|
def send_otp_email(recipient_email, otp):
|
||||||
subject = 'One-Time Password'
|
from_email = settings.EMAIL_HOST_USER
|
||||||
message = f'Your OTP is: {otp}'
|
|
||||||
from_email = settings.DEFAULT_FROM_EMAIL
|
|
||||||
recipient_list = [recipient_email]
|
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
|
return otp
|
||||||
|
|
||||||
def custom_response(detail, data=None, response_status=status.HTTP_200_OK):
|
def custom_response(detail, data=None, response_status=status.HTTP_200_OK):
|
||||||
|
|||||||
@ -1,12 +1,13 @@
|
|||||||
from rest_framework import viewsets, status
|
from rest_framework import viewsets, status, views
|
||||||
from rest_framework.decorators import action
|
from rest_framework.decorators import action
|
||||||
from rest_framework.response import Response
|
import random
|
||||||
from django.contrib.auth import authenticate, login
|
from django.contrib.auth import authenticate, login
|
||||||
from guardian.models import Guardian
|
from guardian.models import Guardian
|
||||||
from junior.models import Junior
|
from junior.models import Junior
|
||||||
from account.models import UserProfile, UserPhoneOtp, UserEmailOtp
|
from account.models import UserProfile, UserPhoneOtp, UserEmailOtp
|
||||||
from django.contrib.auth.models import User
|
from django.contrib.auth.models import User
|
||||||
from .serializers import SuperUserSerializer, GuardianSerializer, JuniorSerializer, EmailVerificationSerializer
|
from .serializers import (SuperUserSerializer, GuardianSerializer, JuniorSerializer, EmailVerificationSerializer,
|
||||||
|
ForgotPasswordSerializer, ResetPasswordSerializer)
|
||||||
from django.views.decorators.csrf import csrf_exempt
|
from django.views.decorators.csrf import csrf_exempt
|
||||||
from rest_framework_simplejwt.serializers import TokenObtainPairSerializer
|
from rest_framework_simplejwt.serializers import TokenObtainPairSerializer
|
||||||
from rest_framework_simplejwt.views import TokenObtainPairView
|
from rest_framework_simplejwt.views import TokenObtainPairView
|
||||||
@ -15,6 +16,49 @@ from base.messages import ERROR_CODE, SUCCESS_CODE
|
|||||||
from guardian.tasks import generate_otp
|
from guardian.tasks import generate_otp
|
||||||
|
|
||||||
from account.utils import custom_response, custom_error_response
|
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 templated_email import send_templated_mail
|
||||||
|
import secrets
|
||||||
|
|
||||||
|
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
|
||||||
|
subject = 'Password Reset Verification Code'
|
||||||
|
message = f'Your verification code is: {verification_code}'
|
||||||
|
from_email = 'infozodbank@gmail.com'
|
||||||
|
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):
|
class SendPhoneOtp(viewsets.ModelViewSet):
|
||||||
"""Send otp on phone"""
|
"""Send otp on phone"""
|
||||||
def create(self, request, *args, **kwargs):
|
def create(self, request, *args, **kwargs):
|
||||||
|
|||||||
@ -27,7 +27,7 @@ ERROR_CODE = {
|
|||||||
"2001": "Your account has not been verified. Please check your email and verify it.",
|
"2001": "Your account has not been verified. Please check your email and verify it.",
|
||||||
"2002": "Invalid login credentials.",
|
"2002": "Invalid login credentials.",
|
||||||
"2003": "An account already exists with this email address.",
|
"2003": "An account already exists with this email address.",
|
||||||
"2004": "User doesn't exist.",
|
"2004": "User not found.",
|
||||||
"2005": "Your account has been activated.",
|
"2005": "Your account has been activated.",
|
||||||
"2006": "Your account is not activated.",
|
"2006": "Your account is not activated.",
|
||||||
"2007": "Your account already activated.",
|
"2007": "Your account already activated.",
|
||||||
@ -73,7 +73,8 @@ SUCCESS_CODE = {
|
|||||||
"3011": "Email OTP Verified successfully",
|
"3011": "Email OTP Verified successfully",
|
||||||
"3012": "Phone OTP Verified successfully",
|
"3012": "Phone OTP Verified successfully",
|
||||||
"3013": "Valid Guardian code",
|
"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 = {
|
STATUS_CODE_ERROR = {
|
||||||
|
|||||||
@ -17,6 +17,7 @@ from .tasks import generate_otp
|
|||||||
from account.utils import send_otp_email
|
from account.utils import send_otp_email
|
||||||
from account.utils import custom_response, custom_error_response
|
from account.utils import custom_response, custom_error_response
|
||||||
from base.messages import ERROR_CODE, SUCCESS_CODE
|
from base.messages import ERROR_CODE, SUCCESS_CODE
|
||||||
|
|
||||||
class SignupViewset(viewsets.ModelViewSet):
|
class SignupViewset(viewsets.ModelViewSet):
|
||||||
serializer_class = UserSerializer
|
serializer_class = UserSerializer
|
||||||
|
|
||||||
@ -26,7 +27,7 @@ class SignupViewset(viewsets.ModelViewSet):
|
|||||||
serializer.save()
|
serializer.save()
|
||||||
otp = generate_otp()
|
otp = generate_otp()
|
||||||
UserEmailOtp.objects.create(email=request.data['email'], otp=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},
|
return custom_response(SUCCESS_CODE['3001'], {"email_otp": otp},
|
||||||
response_status=status.HTTP_200_OK)
|
response_status=status.HTTP_200_OK)
|
||||||
return custom_error_response(serializer.errors, response_status=status.HTTP_400_BAD_REQUEST)
|
return custom_error_response(serializer.errors, response_status=status.HTTP_400_BAD_REQUEST)
|
||||||
|
|||||||
@ -171,6 +171,32 @@ CORS_ALLOW_HEADERS = (
|
|||||||
# Static files (CSS, JavaScript, Images)
|
# Static files (CSS, JavaScript, Images)
|
||||||
# https://docs.djangoproject.com/en/3.0/howto/static-files/
|
# 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/'
|
STATIC_URL = '/static/'
|
||||||
|
|||||||
Reference in New Issue
Block a user