Skip to content

Commit

Permalink
fix(headless): FRONTEND_URLS were not used unless HEADLESS_ONLY
Browse files Browse the repository at this point in the history
  • Loading branch information
pennersr committed May 12, 2024
1 parent 8281bd7 commit dc21e54
Show file tree
Hide file tree
Showing 3 changed files with 65 additions and 37 deletions.
44 changes: 8 additions & 36 deletions allauth/account/adapter.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
import json
import string
import warnings
from urllib.parse import quote, urlparse
from urllib.parse import urlparse

from django.conf import settings
from django.contrib import messages
Expand Down Expand Up @@ -41,12 +41,7 @@
from allauth.account.app_settings import AuthenticationMethod
from allauth.core import context, ratelimit
from allauth.core.internal.adapter import BaseAdapter
from allauth.core.internal.httpkit import render_url
from allauth.utils import (
build_absolute_uri,
generate_unique_username,
import_attribute,
)
from allauth.utils import generate_unique_username, import_attribute

from . import app_settings

Expand Down Expand Up @@ -538,7 +533,7 @@ def confirm_email(self, request, email_address):
"""
from allauth.account.internal.flows import manage_email

return manage_email.confirm_email(request, email_address)
return manage_email.verify_email(request, email_address)

def set_password(self, user, password):
user.set_password(password)
Expand Down Expand Up @@ -577,25 +572,11 @@ def is_safe_url(self, url):
def get_reset_password_from_key_url(self, key):
"""
Method intented to be overriden in case the password reset email
needs to point to your frontend/SPA.
needs to be adjusted.
"""
if allauth_app_settings.HEADLESS_ONLY:
from allauth.headless import app_settings as headless_settings

return render_url(
self.request,
headless_settings.FRONTEND_URLS["account_reset_password_from_key"],
key=key,
)
from allauth.account.internal import flows

# We intentionally accept an opaque `key` on the interface here, and not
# implementation details such as a separate `uidb36` and `key. Ideally,
# this should have done on `urls` level as well.
path = reverse(
"account_reset_password_from_key", kwargs={"uidb36": "UID", "key": "KEY"}
)
path = path.replace("UID-KEY", quote(key))
return build_absolute_uri(self.request, path)
return flows.password_reset.get_reset_password_from_key_url(self.request, key)

def get_email_confirmation_url(self, request, emailconfirmation):
"""Constructs the email confirmation (activation) url.
Expand All @@ -604,18 +585,9 @@ def get_email_confirmation_url(self, request, emailconfirmation):
confirmations are sent outside of the request context `request`
can be `None` here.
"""
if allauth_app_settings.HEADLESS_ONLY:
from allauth.headless import app_settings as headless_settings

return render_url(
request,
headless_settings.FRONTEND_URLS["account_confirm_email"],
key=emailconfirmation.key,
)
from allauth.account.internal import flows

url = reverse("account_confirm_email", args=[emailconfirmation.key])
ret = build_absolute_uri(request, url)
return ret
return flows.manage_email.get_email_verification_url(request, emailconfirmation)

def should_send_confirmation_mail(self, request, email_address, signup):
send_email = ratelimit.consume(
Expand Down
30 changes: 29 additions & 1 deletion allauth/account/internal/flows/manage_email.py
Original file line number Diff line number Diff line change
@@ -1,9 +1,14 @@
from django.contrib import messages
from django.core.exceptions import ImproperlyConfigured
from django.urls import reverse

from allauth import app_settings as allauth_settings
from allauth.account import app_settings, signals
from allauth.account.adapter import get_adapter
from allauth.account.models import EmailAddress
from allauth.account.reauthentication import raise_if_reauthentication_required
from allauth.core.internal.httpkit import render_url
from allauth.utils import build_absolute_uri


def can_delete_email(email_address):
Expand Down Expand Up @@ -109,7 +114,7 @@ def mark_as_primary(request, email_address):
return success


def confirm_email(request, email_address):
def verify_email(request, email_address):
"""
Marks the email address as confirmed on the db
"""
Expand All @@ -132,3 +137,26 @@ def confirm_email(request, email_address):
instance.remove()
emit_email_changed(request, from_email_address, email_address)
return True


def get_email_verification_url(request, emailconfirmation):
"""Constructs the email confirmation (activation) url.
Note that if you have architected your system such that email
confirmations are sent outside of the request context `request`
can be `None` here.
"""
if allauth_settings.HEADLESS_ENABLED:
from allauth.headless import app_settings as headless_settings

url = headless_settings.FRONTEND_URLS.get("account_confirm_email")
if allauth_settings.HEADLESS_ONLY and not url:
raise ImproperlyConfigured(
"settings.HEADLESS_FRONTEND_URLS['account_confirm_email']"
)
if url:
return render_url(request, url, key=emailconfirmation.key)

url = reverse("account_confirm_email", args=[emailconfirmation.key])
ret = build_absolute_uri(request, url)
return ret
28 changes: 28 additions & 0 deletions allauth/account/internal/flows/password_reset.py
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
from urllib.parse import quote

from django.contrib import messages
from django.core.exceptions import ImproperlyConfigured
from django.urls import reverse
Expand Down Expand Up @@ -46,3 +48,29 @@ def get_reset_password_url(request):
if url:
return render_url(request, url)
return build_absolute_uri(request, reverse("account_reset_password"))


def get_reset_password_from_key_url(request, key):
"""
Method intented to be overriden in case the password reset email
needs to point to your frontend/SPA.
"""
if allauth_settings.HEADLESS_ENABLED:
from allauth.headless import app_settings as headless_settings

url = headless_settings.FRONTEND_URLS.get("account_reset_password_from_key")
if allauth_settings.HEADLESS_ONLY and not url:
raise ImproperlyConfigured(
"settings.HEADLESS_FRONTEND_URLS['account_reset_password_from_key']"
)
if url:
return render_url(request, url, key=key)

# We intentionally accept an opaque `key` on the interface here, and not
# implementation details such as a separate `uidb36` and `key. Ideally,
# this should have done on `urls` level as well.
path = reverse(
"account_reset_password_from_key", kwargs={"uidb36": "UID", "key": "KEY"}
)
path = path.replace("UID-KEY", quote(key))
return build_absolute_uri(request, path)

0 comments on commit dc21e54

Please sign in to comment.