Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

overriding restauth password reset email issues

Good day, I am trying to override the password_reset_email of Django allauth. the issue is that it successfully overrides but I get the html code just sent to the user instead of the html representation.

I was expecting a styled email just like I got for my confirmation email, but this does not seem to be the case.

In my templates/registration/password_reset_email.html

{% load i18n %}
{% autoescape off %}

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <title>Confirm Your E-mail</title>
    <style>
        .body {
            background-color: #f6f6f6;
            padding: 30px;
            display: flex;
            flex-direction: row;
            justify-content: center; 
            align-items: center;
        }
        
        .content {
            background-color: #FFFFFF;
            color: #4d4d4d;
            max-width: 400px;
            padding: 20px;
            margin: auto;
        }
        
        .title {
            font-size: 20px;
            font-weight: 600;
            margin: 10px 0;
            text-align: center
        }
        
        .intro {
            font-size: 15px;
            align-self: flex-start;
            color: #4d4d4d;
            margin-bottom: 15px;
        }
        
        .main-body {
            font-size: 15px;
            color: #4d4d4d;
            margin-bottom: 15px;
        }
        
        .alt-body {
            width: 100%;
            display: flex;
            flex-direction: row !important;
            justify-content: center !important;
        }

        .alt-body>a {
            font-size: 17px;
            font-weight: 500;
            text-decoration: none;
            color: #FFFFFF;
            margin: auto;
            margin-bottom: 15px;
        }
        
        .cta-button {
            background-color: #525659;
            padding: 9px 100px;
            border: 2px solid #525659;
            border-radius: 35px;
            align-self: center;
        }

        .cta-button:hover {
            background-color: #000000;
            border: 2px solid #000000;
        }
        
        .sub-body {
            font-size: 15px;
            color: #4d4d4d;
            margin-bottom: 15px;
            margin-top: 0;
            align-self: flex-start;
        }

        .sub-body a {
            text-decoration: none;
            color: #4d4d4d;
            font-size: 15px;
        }

        .sub-body a:hover {
            text-decoration: none;
            color: #4d4d4d;
        }

        .outro {
            margin: 20px 0;
        }

        .outro > p {
            font-size: 15px;
            margin-top: 3px;
            margin-bottom: 3px;
        }

        .outro a {
            text-decoration: none;
            color: #4d4d4d;
            font-size: 15px;
            margin-top: 3px;
            margin-bottom: 3px;
        }

        .outro a:hover {
            text-decoration: none;
            color: #4d4d4d;
        }
    </style>
</head>
<body class="body">
    <div class="content">
        {% blocktrans with site_name=current_site.name site_domain=current_site.domain %}

        <p class="title">Email Verification</p>

        <p class="intro">Hello there,</p>

        <p class="main-body">
            Simply click on the button to verify your cre8ive-mart email.
        </p>

        <div class="alt-body">
            <a href="{{ activate_url }}" class="cta-button">Verify Email</a>
        </div>
        
        <p class="sub-body">
            if you have any questions, please contact <a href="mailto:[email protected]">[email protected]</a>
        </p>

        <div class="outro">
            <p class="outro-greeting">Sincerely,</p>
            <p class="outro-main">cre8ive-mart</p>
            <a href="#" class="outro-website">cre8ivemart.com</a>
        </div>

        {% endblocktrans %}
    </div>
</body>
</html>
{% endautoescape %}

but the email I get is like this

but the email I get is just the html code back

it is just the html representation i get back. instead of a styled component.

like image 703
Opeyemi Odedeyi Avatar asked Feb 02 '20 13:02

Opeyemi Odedeyi


2 Answers

I can't see the code you used but here is what works for me with django rest auth.

create a custom password reset serializer

from django.contrib.auth.forms import PasswordResetForm
from django.conf import settings
from django.utils.translation import gettext as _
from rest_framework import serializers

###### IMPORT YOUR USER MODEL ######
from .models import User


class PasswordResetSerializer(serializers.Serializer):
    email = serializers.EmailField()
    password_reset_form_class = PasswordResetForm

    def validate_email(self, value):
        self.reset_form = self.password_reset_form_class(data=self.initial_data)

        if not self.reset_form.is_valid():
            raise serializers.ValidationError(_('Error'))

        ###### FILTER YOUR USER MODEL ######
        if not User.objects.filter(email=value).exists():

            raise serializers.ValidationError(_('Invalid e-mail address'))
        return value

    def save(self):
        request = self.context.get('request')
        opts = {
            'use_https': request.is_secure(),
            'from_email': getattr(settings, 'DEFAULT_FROM_EMAIL'),

            ###### USE YOUR TEXT FILE ######
            'email_template_name': 'account/email/password_reset_key.html',
            'html_email_template_name': 'account/email/password_reset_key.html',
            'request': request,
        }
        self.reset_form.save(**opts)

Then have the password reset email template as account/email/password_reset_key.html

Then in the settings, update your password reset serializer to point to the custom password reset serializer.

REST_AUTH_SERIALIZERS = {
    'PASSWORD_RESET_SERIALIZER': '<path to >password_serializer.PasswordResetSerializer'
}

This should work, if it doesn't you will have to provide more context on how you setup this particular password reset flow so we can determine why it's sending it as text instead of the html representation

like image 164
Bernard 'Beta Berlin' Parah Avatar answered Oct 10 '22 20:10

Bernard 'Beta Berlin' Parah


With newer versions of django-rest-auth, we need less code to achieve what the OP wants:

Settings.py

REST_AUTH_SERIALIZERS = {
    'PASSWORD_RESET_SERIALIZER': 'users.serializer.PasswordResetSerializer'
}

Serializer.py

from rest_auth.serializers import PasswordResetSerializer

class PasswordResetSerializer(PasswordResetSerializer):

    def get_email_options(self):
        return {
            'subject_template_name': 'account/email/password_reset_key_subject.txt',
            'email_template_name': 'account/email/password_reset_key.txt',
            # 'html_email_template_name': 'account/password_reset_key.html',
        }
like image 3
Xen_mar Avatar answered Oct 10 '22 20:10

Xen_mar