Skip to content

Commit 05a9ec0

Browse files
email token as URL
Signed-off-by: firstTimeCaller
1 parent ac1f6c6 commit 05a9ec0

File tree

6 files changed

+56
-11
lines changed

6 files changed

+56
-11
lines changed

README.md

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -233,7 +233,7 @@ DEFAULTS = {
233233
234234
# URL Prefix for Authentication Endpoints
235235
'PASSWORDLESS_AUTH_PREFIX': 'auth/',
236-
236+
237237
# URL Prefix for Verification Endpoints
238238
'PASSWORDLESS_VERIFY_PREFIX': 'auth/verify/',
239239
@@ -268,6 +268,15 @@ DEFAULTS = {
268268
# The email template name.
269269
'PASSWORDLESS_EMAIL_TOKEN_HTML_TEMPLATE_NAME': "passwordless_default_token_email.html",
270270
271+
# Providing a domain name will email token within a URL
272+
'PASSWORDLESS_LOGIN_URL_DOMAIN': False,
273+
274+
# The email template name for URL
275+
'PASSWORDLESS_EMAIL_URL_HTML_TEMPLATE_NAME': "passwordless_default_url_email.html",
276+
277+
# A plaintext email URL message overridden by the html message. Takes one string.
278+
'PASSWORDLESS_EMAIL_URL_PLAINTEXT_MESSAGE': "Click here to login %s",
279+
271280
# Your twilio number that sends the callback tokens.
272281
'PASSWORDLESS_MOBILE_NOREPLY_NUMBER': None,
273282
@@ -304,7 +313,7 @@ DEFAULTS = {
304313
# the token itself, the second is a boolean value representating whether
305314
# the token was newly created.
306315
'PASSWORDLESS_AUTH_TOKEN_CREATOR': 'drfpasswordless.utils.create_authentication_token',
307-
316+
308317
# What function is called to construct a serializer for drf tokens when
309318
# exchanging a passwordless token for a real user auth token.
310319
'PASSWORDLESS_AUTH_TOKEN_SERIALIZER': 'drfpasswordless.serializers.TokenResponseSerializer'

drfpasswordless/settings.py

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,15 @@
4545
# The email template name.
4646
'PASSWORDLESS_EMAIL_TOKEN_HTML_TEMPLATE_NAME': "passwordless_default_token_email.html",
4747

48+
# Providing a domain name will email token within a URL
49+
'PASSWORDLESS_LOGIN_URL_DOMAIN': False,
50+
51+
# The email template name for URL
52+
'PASSWORDLESS_EMAIL_URL_HTML_TEMPLATE_NAME': "passwordless_default_url_email.html",
53+
54+
# A plaintext email URL message overridden by the html message. Takes one string.
55+
'PASSWORDLESS_EMAIL_URL_PLAINTEXT_MESSAGE': "Click here to login %s",
56+
4857
# Your twilio number that sends the callback tokens.
4958
'PASSWORDLESS_MOBILE_NOREPLY_NUMBER': None,
5059

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
<!DOCTYPE html>
2+
<html lang="en">
3+
<head>
4+
<meta charset="UTF-8">
5+
<title>Your Login Token</title>
6+
</head>
7+
<body>
8+
<h2> <a href="{{ callback_token }}">Click here to login</a> </h2>
9+
</body>
10+
</html>

drfpasswordless/utils.py

Lines changed: 9 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -119,17 +119,20 @@ def send_email_with_callback_token(user, email_token, **kwargs):
119119
# Get email subject and message
120120
email_subject = kwargs.get('email_subject',
121121
api_settings.PASSWORDLESS_EMAIL_SUBJECT)
122-
email_plaintext = kwargs.get('email_plaintext',
123-
api_settings.PASSWORDLESS_EMAIL_PLAINTEXT_MESSAGE)
124-
email_html = kwargs.get('email_html',
125-
api_settings.PASSWORDLESS_EMAIL_TOKEN_HTML_TEMPLATE_NAME)
126122

127123
# Inject context if user specifies.
128-
context = inject_template_context({'callback_token': email_token.key, })
124+
if api_settings.PASSWORDLESS_LOGIN_URL_DOMAIN:
125+
context['callback_token'] = api_settings.PASSWORDLESS_LOGIN_URL_DOMAIN + api_settings.PASSWORDLESS_AUTH_PREFIX + 'login/' + user.email + '/' + email_token.key
126+
else:
127+
context = inject_template_context({'callback_token': email_token.key, })
128+
129+
email_html = kwargs.get('email_html')
130+
email_plaintext = kwargs.get('email_plaintext')
131+
129132
html_message = loader.render_to_string(email_html, context,)
130133
send_mail(
131134
email_subject,
132-
email_plaintext % email_token.key,
135+
email_plaintext % context['callback_token'],
133136
api_settings.PASSWORDLESS_EMAIL_NOREPLY_ADDRESS,
134137
[getattr(user, api_settings.PASSWORDLESS_USER_EMAIL_FIELD_NAME)],
135138
fail_silently=False,

drfpasswordless/views.py

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
from django.utils.module_loading import import_string
33
from rest_framework import parsers, renderers, status
44
from rest_framework.response import Response
5-
from rest_framework.permissions import AllowAny, IsAuthenticated
5+
from rest_framework.permissions import AllowAny, IsAuthenticated
66
from rest_framework.views import APIView
77
from drfpasswordless.models import CallbackToken
88
from drfpasswordless.settings import api_settings
@@ -77,8 +77,14 @@ class ObtainEmailCallbackToken(AbstractBaseObtainCallbackToken):
7777
token_type = CallbackToken.TOKEN_TYPE_AUTH
7878

7979
email_subject = api_settings.PASSWORDLESS_EMAIL_SUBJECT
80-
email_plaintext = api_settings.PASSWORDLESS_EMAIL_PLAINTEXT_MESSAGE
81-
email_html = api_settings.PASSWORDLESS_EMAIL_TOKEN_HTML_TEMPLATE_NAME
80+
81+
if api_settings.PASSWORDLESS_LOGIN_URL_DOMAIN:
82+
email_plaintext = api_settings.PASSWORDLESS_EMAIL_URL_PLAINTEXT_MESSAGE
83+
email_html = api_settings.PASSWORDLESS_EMAIL_URL_HTML_TEMPLATE_NAME
84+
else:
85+
email_plaintext = api_settings.PASSWORDLESS_EMAIL_PLAINTEXT_MESSAGE
86+
email_html = api_settings.PASSWORDLESS_EMAIL_TOKEN_HTML_TEMPLATE_NAME
87+
8288
message_payload = {'email_subject': email_subject,
8389
'email_plaintext': email_plaintext,
8490
'email_html': email_html}

tests/test_settings.py

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -55,6 +55,14 @@ def test_mobile_sender_required(self):
5555
email_response = self.client.post(self.mobile_url, self.mobile_data)
5656
self.assertEqual(email_response.status_code, status.HTTP_400_BAD_REQUEST)
5757

58+
def test_tokon_as_url(self):
59+
"""
60+
Check to make sure user has a send address if mobile is selected.
61+
"""
62+
api_settings.PASSWORDLESS_AUTH_TYPES = ['MOBILE']
63+
email_response = self.client.post(self.mobile_url, self.mobile_data)
64+
self.assertEqual(email_response.status_code, status.HTTP_400_BAD_REQUEST)
65+
5866
def test_email_only_auth_enabled(self):
5967
api_settings.PASSWORDLESS_AUTH_TYPES = ['EMAIL']
6068
api_settings.PASSWORDLESS_EMAIL_NOREPLY_ADDRESS = 'email@example.com'

0 commit comments

Comments
 (0)