I have a Django 3.0.7 app using the default template for sending password reset emails.
For some of our users, the link to reset is badly formed, e.g.:
https://foo.bar/accounts/reset/McU4Mw/5no-9cd52590f0943503=
fa3a/
/>
While it should be:
https://foo.bar/accounts/reset/McU4Mw/5no-9cd52590f0943503fa3a/
This second one is whats actually being sent. But, as I said, some users are receiving the first one.
I assume some of my users' email clients are wrecking the text, but what could I do?
I've considered adding a plaintext url to the email, but it's already plaintext.
EDIT: This is a solution I came up with, and it works. Can anyone think of a reason not to do this?
urls.py
...
path('accounts/reset/<uidb64>/<token>/<str:extra_chars>/', PasswordResetConfirmView.as_view(), name='password_reset_confirm'),
path('accounts/reset/<uidb64>/<token>/', PasswordResetConfirmView.as_view(), name='password_reset_confirm'),
...
EDIT:
Here's the default template:
/site-packages/django/contrib/admin/templates/registration/password_reset_email.html
{% load i18n %}{% autoescape off %}
{% blocktrans %}You're receiving this email because you requested a password reset for your user account at {{ site_name }}.{% endblocktrans %}
{% trans "Please go to the following page and choose a new password:" %}
{% block reset_link %}
{{ protocol }}://{{ domain }}{% url 'password_reset_confirm' uidb64=uid token=token %}
{% endblock %}
{% trans 'Your username, in case you’ve forgotten:' %} {{ user.get_username }}
{% trans "Thanks for using our site!" %}
{% blocktrans %}The {{ site_name }} team{% endblocktrans %}
{% endautoescape %}
Related
The application is using Django backend and ReactJS frontend. I created user accounts using the standard rest-auth package in Django, calling the endpoints from the ReactJS frontend forms.
Sign up and login works fine, but when it comes to e-mail confirmation, I haven't been able to find where confirmation keys are stored and how this is accessed. I've overridden get_email_confirmation_url from DefaultAccountAdapter to change the URL confirmation link that is being sent out from [backend]/rest-auth/registration/account-confirm-email/[KEY] to [frontend]/registration/confirm-email/[KEY].
I'm able to read out [KEY] at the frontend. However, how do I retrieve the e-mailaddress and name of the user that's trying to confirm their address? In the standard Django template this is possible (email_confirm.html):
{% extends "account/base.html" %}
{% load i18n %}
{% load account %}
{% block head_title %}{% trans "Confirm E-mail Address" %}{% endblock %}
{% block content %}
<h1>{% trans "Confirm E-mail Address" %}</h1>
{% if confirmation %}
{% user_display confirmation.email_address.user as user_display %}
<p>{% blocktrans with confirmation.email_address.email as email %}Please confirm that {{ email }} is an e-mail address for user {{ user_display }}.{% endblocktrans %}</p>
<form method="post" action="{% url 'account_confirm_email' confirmation.key %}">
{% csrf_token %}
<button type="submit">{% trans 'Confirm' %}</button>
</form>
{% else %}
{% url 'account_email' as email_url %}
<p>{% blocktrans %}This e-mail confirmation link expired or is invalid. Please issue a new e-mail confirmation request.{% endblocktrans %}</p>
{% endif %}
{% endblock %}
Where does the information from confirmation.email_address.user and confirmation.email_address.email come from? The account_emailconfirmation table is empty and account_emailaddress only contains a boolean saying whether the emailaccount is verified or not, but no confirmation key.
Keys are no longer stored
https://stackoverflow.com/a/41364419/3241374
I use url confirmation:
I grab the key on the front end
Post it to the backend confirmation url
Check the response / login user
Good starting point is this answer:
https://stackoverflow.com/a/59327408/3241374
I have an error with password reset. If I attempt to reset using an invalid email I get the password reset sent notice. If I use a valid email I get NoReverseMatch error message
from django.conf.urls import url
from django.contrib import admin
from . import views
from django.contrib.auth import views as auth_views
from django.urls import reverse, reverse_lazy, resolve
# Password URL's ###################################################################################################
url(r'^change-password/$', views.change_password, name='change_password'),
url(
r'^password_reset/$',
auth_views.PasswordResetView.as_view(
template_name="registration/password_reset.html",
email_template_name="registration/password_reset_email.html",
success_url=reverse_lazy("partners:password_reset_done"), # might be required
),
name='password_reset'
),
url(r'^password_reset_done/',
auth_views.PasswordResetDoneView.as_view(
),
name='password_reset_done'
),
url(r'^password_reset_confirm/(?P<uidb64>[0-9A-Za-z]+)-(?P<token>.+)/$',
auth_views.PasswordResetConfirmView.as_view(
template_name="registration/password_reset_confirm.html",
success_url=reverse_lazy("partners:password_reset_complete"), # might be required
),
name='password_reset_confirm'
),
url(r'^password_reset_complete/$',auth_views.PasswordResetCompleteView.as_view(), name="password_reset_complete"),
]
Please see my screen grabs for my project structure and the error message
project structure
error message received
{% block head %}
<meta charset="UTF-8">
<title>Welcome ! You can login here !</title>
{% endblock head %}
{% block body %}
{% block content %}
<div class="container">
<div class="row">
<div class="col-sm-6 col-md-3">
<h3>Password Reset Email</h3>
<p>Provide your registered email address </p>
{% autoescape off %}
To initiate the password reset process for your {{ user.get_username }} TestSite Account,
click the link below:
{{ protocol }}://{{ domain }}{% url 'partners:password_reset_confirm' uidb64=uid token=token %}
If clicking the link above doesn't work, please copy and paste the URL in a new browser
window instead.
Sincerely,
The AV's BlogTeam
{% endautoescape %}
</div>
</div>
</div>
{% endblock content %}
{% endblock body %}
I am building this in a "partners app" where I have templates/registration with the above password_reset_confirm.html
Password reset email is as below
{% load i18n %}{% autoescape off %}
{% blocktrans %}You're receiving this email because you requested a password reset for your user account at {{ site_name }}.{% endblocktrans %}
{% trans "Please go to the following page and choose a new password:" %}
{% block reset_link %}
{{ protocol }}://{{ domain }}{% url 'partners:password_reset_confirm' uidb64=uid token=token %}
{% endblock %}
{% trans "Your username, in case you've forgotten:" %} {{ user.get_username }}
{% trans "Thanks for using our site!" %}
{% blocktrans %}The {{ site_name }} team{% endblocktrans %}
{% endautoescape %}
PLEASE HELP
If you want Django to use the template from your partners app, you need to move partners above django.contrib.admin in your INSTALLED_APPS setting.
I would suggest that you move the password reset urls into a urls.py that does not use the partners namespace. Using {% url 'partners:password_reset_confirm' ... %} will fix this specific error, but there are several other places that you will have to make changes to use the namespace, and I don't think it's worth the effort.
I know it's well asked, but somehow none of the other answers seemed to solve my problem.
I get an error with the ReverseMatch, here is the relevant urls.py section:
# for password reset
url(r'^reset-password$','django.contrib.auth.views.password_reset', {'post_reset_redirect' : 'user_details/reset_password.html', 'template_name': 'user_details/reset_password.html'}, name="password_reset"),
url(r'^reset/(?P<uidb64>[0-9A-Za-z]+)-(?P<token>.+)/$', 'django.contrib.auth.views.password_reset_confirm', {'post_reset_redirect' : 'user_details/reset_password.html'}, name="password_reset_confirm"),
I think the name is adequately defined?
The problem is in the template /usr/lib/python2.7/dist-packages/django/contrib/admin/templates/registration/password_reset_email.html, error at line 6:
{{ protocol }}://{{ domain }}{% url 'password_reset_confirm' uidb64=uid token=token %}
where the {% url ...} is highlighted in red.
Why?
I assume that Django would then use the default template for that view?
Thanks!
Chris
Right, I had to resolve to overwriting the Django default email, because the reverse URL lookup doesn't want to behave properly.
So I created a copy of the original Django email file (/usr/lib/python2.7/dist-packages/django/contrib/admin/templates/registration/password_reset_email.html):
{% load i18n %}{% autoescape off %}
{% blocktrans %}You're receiving this email because you requested a password reset for your user account at {{ site_name }}.{% endblocktrans %}
{% trans "Please go to the following page and choose a new password:" %}
{% block reset_link %}
{{ protocol }}://{{ domain }}{% url 'password_reset_confirm' uidb64=uid token=token %}
{% endblock %}
{% trans "Your username, in case you've forgotten:" %} {{ user.get_username }}
{% trans "Thanks for using our site!" %}
{% blocktrans %}The {{ site_name }} team{% endblocktrans %}
{% endautoescape %}
and replaced line 6 with the following:
{{ protocol }}://{{ domain }}/user_details/reset/{{uid}}/{{token}}
which matches my urls.py.
This does indeed work now...
You have defined a URL which accepts a "uidb36" parameter, but the reverse call is passing "uidb64".
I am using Django 1.6.
I have the following file in myApp/templates/registration/password_reset_email.html.
However, when I enter my email address in the form to send a reset password email, I get the following error:
TemplateSyntaxError at /auth/password_reset/
Could not parse the remainder: ',' from 'uid,'
What is wrong with the template below that causes the {% url %} tag to fail?
{% autoescape off %}
You're receiving this e-mail because you requested a password reset for your user account at {{ site_name }}.
Please go to the following page and choose a new password:
{% block reset_link %}
{{ protocol }}://{{ domain }}{% url django.contrib.auth.views.password_reset_confirm uidb36=uid, token=token %}
{% endblock %}
Your username, in case you've forgotten: {{ user.username }}
Thanks for using our site!
The {{ site_name }} team.
{% endautoescape %}
When you are using templatetags with several parameters, separate them by space.
Like {{ protocol }}://{{ domain }}{% url 'django.contrib.auth.views.password_reset_confirm' uidb36=uid token=token %} (notice that there is no , after "uid".
I think that is the solution.
See https://docs.djangoproject.com/en/dev/howto/custom-template-tags/ for more info about custom templatetags and how they work.
in my server I have a lot of apps installed like, facebook_connect, userena, guardian and so on...
For example, I realized that if I customize the:
django-userena / userena / templates / userena / emails / activation_email_message.txt
{% load i18n %}{% autoescape off %}{% load url from future %}
{% if not without_usernames %}{% blocktrans with user.username as username %}Dear {{ username }},{% endblocktrans %}
{% endif %}
{% blocktrans with site.name as site %}Thank you for signing up at {{ site }}.{% endblocktrans %}
{% trans "To activate your account you should click on the link below:" %}
{{ protocol }}://{{ site.domain }}{% url 'userena_activate' activation_key %}
{% trans "Thanks for using our site!" %}
{% trans "Sincerely" %},
{{ site.name }}
{% endautoescape %}
For specified website, and I have more than 4 in the same server, I will make a complete mess in my django_site.
My question is:
How to customize the templates or models in some installed apps without completely change the original django_site?
Thanks in advance,
You cannot change the models, but you can override templates.
In the same directory as manage.py, you would have a directory called templates, there, you can create the following folder hierarchy, and put your custom template.
templates/userena/emails/activation_email_message.txt