From 537519a3ddb63a72859d4bf5af697d173be5afcb Mon Sep 17 00:00:00 2001
From: Chneemann
Date: Mon, 5 Aug 2024 00:05:26 +0200
Subject: [PATCH] update error.service, added register send email for
activation
---
backend/videoflix/auth/views.py | 44 +++++++++++++++-
backend/videoflix/templates/mail.html | 50 +++++++++++++++++++
backend/videoflix/videoflix/settings.py | 11 +++-
backend/videoflix/videoflix/urls.py | 4 +-
.../auth/login/login.component.html | 17 +++++--
.../components/auth/login/login.component.ts | 21 +++++---
.../auth/register/register.component.html | 1 +
.../auth/register/register.component.ts | 10 ++--
frontend/src/app/services/error.service.ts | 27 ++++++++--
9 files changed, 161 insertions(+), 24 deletions(-)
create mode 100644 backend/videoflix/templates/mail.html
diff --git a/backend/videoflix/auth/views.py b/backend/videoflix/auth/views.py
index ac96a84..5700884 100644
--- a/backend/videoflix/auth/views.py
+++ b/backend/videoflix/auth/views.py
@@ -4,6 +4,11 @@ from rest_framework import status
from rest_framework.authtoken.models import Token
from django.contrib.auth import authenticate
from .serializer import LoginSerializer
+from users.serializer import UserSerializer
+from django.utils.html import strip_tags
+from django.core.mail import EmailMultiAlternatives
+from django.template.loader import render_to_string
+from users.models import CustomUser
class LoginView(APIView):
serializer_class = LoginSerializer
@@ -17,11 +22,46 @@ class LoginView(APIView):
user = authenticate(request, email=email, password=password)
if user:
+ if not user.is_active:
+ return Response({'password': 'Account is inactive, please check your mails'}, status=status.HTTP_403_FORBIDDEN)
return self._create_token_response(user)
return Response({'detail': 'Unable to login with provided credentials.'}, status=status.HTTP_401_UNAUTHORIZED)
return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)
def _create_token_response(self, user):
- token, created = Token.objects.get_or_create(user=user)
- return Response({token.key}, status=status.HTTP_200_OK)
\ No newline at end of file
+ token = Token.objects.get_or_create(user=user)
+ return Response({'token': token.key}, status=status.HTTP_200_OK)
+
+class RegisterView(APIView):
+ def post(self, request):
+ email = request.data.get('email')
+ password = request.data.get('password')
+ if CustomUser.objects.filter(email=email).exists():
+ return Response({'detail': 'A user with this email already exists.'}, status=status.HTTP_400_BAD_REQUEST)
+
+ serialized = UserSerializer(data=request.data)
+ if serialized.is_valid():
+ user = serialized.save()
+ user.is_active = False
+ user.set_password(password)
+ user.save()
+ self.send_email(user)
+ return Response(serialized.data, status=status.HTTP_201_CREATED)
+ else:
+ return Response(serialized.errors, status=status.HTTP_400_BAD_REQUEST)
+
+ def send_email(self, user):
+ merge_data = {
+ 'name': user.username
+ }
+ html_body = render_to_string("mail.html", merge_data)
+
+ message = EmailMultiAlternatives(
+ subject='Confirm your email',
+ body=strip_tags(html_body), # Plain text fallback
+ from_email='noreply@videoflix.com',
+ to=['andre.kempf.dev@gmail.com']
+ )
+ message.attach_alternative(html_body, "text/html")
+ message.send(fail_silently=False)
\ No newline at end of file
diff --git a/backend/videoflix/templates/mail.html b/backend/videoflix/templates/mail.html
new file mode 100644
index 0000000..ea3ff02
--- /dev/null
+++ b/backend/videoflix/templates/mail.html
@@ -0,0 +1,50 @@
+
+
+
+
+
+ Dear {{ name }},
+
+ Thank you for registering with Videoflix. To complete your registration
+ and verify your email address, please click the link below:
+
+ Activate account
+
+ If you did not create an account with us, please disregard this email.
+
+ Best regards,
+ Your Videoflix Team.
+
+
diff --git a/backend/videoflix/videoflix/settings.py b/backend/videoflix/videoflix/settings.py
index daeb408..8030a52 100644
--- a/backend/videoflix/videoflix/settings.py
+++ b/backend/videoflix/videoflix/settings.py
@@ -10,6 +10,7 @@ For the full list of settings and their values, see
https://docs.djangoproject.com/en/5.0/ref/settings/
"""
+import os
from pathlib import Path
# Build paths inside the project like this: BASE_DIR / 'subdir'.
@@ -25,6 +26,14 @@ SECRET_KEY = 'django-insecure-*o%q)*3l+9^fs!m0z_h=z9bc)su=%)fv$@ktb#pza-pvi^z*en
# SECURITY WARNING: don't run with debug turned on in production!
DEBUG = True
+# EMAIL
+EMAIL_USE_TLS = True
+EMAIL_HOST = 'smtp.gmail.com'
+EMAIL_PORT = 587
+EMAIL_HOST_USER = 'andre.kempf.dev@gmail.com'
+EMAIL_HOST_PASSWORD = 'oyxwawshudwytgud'
+EMAIL_BACKEND = 'django.core.mail.backends.smtp.EmailBackend'
+
ALLOWED_HOSTS = []
CORS_ALLOWED_ORIGINS = [
@@ -61,7 +70,7 @@ ROOT_URLCONF = 'videoflix.urls'
TEMPLATES = [
{
'BACKEND': 'django.template.backends.django.DjangoTemplates',
- 'DIRS': [],
+ 'DIRS': [os.path.join(BASE_DIR, 'templates')],
'APP_DIRS': True,
'OPTIONS': {
'context_processors': [
diff --git a/backend/videoflix/videoflix/urls.py b/backend/videoflix/videoflix/urls.py
index 29f95c4..6b18d44 100644
--- a/backend/videoflix/videoflix/urls.py
+++ b/backend/videoflix/videoflix/urls.py
@@ -17,12 +17,12 @@ Including another URLconf
from django.contrib import admin
from django.urls import path, include
from users import views
-from auth.views import LoginView
+from auth.views import LoginView, RegisterView
urlpatterns = [
path('admin/', admin.site.urls),
path('users/', views.user_list),
path('users//', views.user_detail),
path('auth/login/', LoginView.as_view()),
-
+ path('auth/register/', RegisterView.as_view()),
]
diff --git a/frontend/src/app/components/auth/login/login.component.html b/frontend/src/app/components/auth/login/login.component.html
index 780f938..955ffd4 100644
--- a/frontend/src/app/components/auth/login/login.component.html
+++ b/frontend/src/app/components/auth/login/login.component.html
@@ -5,6 +5,7 @@
#loginForm="ngForm"
(ngSubmit)="onSubmit(loginForm)"
onsubmit="return false"
+ (input)="this.errorService.clearError()"
>
0 &&
!isUserEmailValid(authData.mail.toLowerCase())) {
This is not a valid email format
- }} @if ((errorService.error$ | async)) {
- {{ errorService.error$ | async }}
- }
+ }}
+
+
Password is too short, min 6 characters
} }
+
+
+
+
{{ errors["password"] }}
+
+