An unticked checkbox on registration subscribes the verified address to the listmonk list (preconfirmed) once the account exists. The profile page gets a subscribe/unsubscribe toggle, and verified email changes follow through to listmonk. Newsletter outages never block accounts. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
38 lines
1.7 KiB
Python
Executable File
38 lines
1.7 KiB
Python
Executable File
from django import forms
|
||
from django.conf import settings
|
||
from django.contrib.auth.password_validation import validate_password
|
||
|
||
|
||
NEWSLETTER_LABEL = "Email me when new works premiere (about twice a month). Unsubscribe any time."
|
||
|
||
|
||
class RegistrationForm(forms.Form):
|
||
uid = forms.RegexField(regex=r"^[a-z][a-z0-9._-]{2,47}$", max_length=48, label="Username", help_text="3–48 lowercase letters, numbers, dots, underscores or hyphens. Start with a letter.")
|
||
email = forms.EmailField(max_length=254)
|
||
# Explicit opt-in: unticked by default, and only offered when configured.
|
||
newsletter = forms.BooleanField(required=False, label=NEWSLETTER_LABEL)
|
||
|
||
def __init__(self, *args, **kwargs):
|
||
super().__init__(*args, **kwargs)
|
||
if not settings.LISTMONK_ENABLED:
|
||
del self.fields["newsletter"]
|
||
|
||
def clean_email(self):
|
||
return self.cleaned_data["email"].strip().casefold()
|
||
|
||
|
||
class PasswordForm(forms.Form):
|
||
password = forms.CharField(max_length=1024, widget=forms.PasswordInput(attrs={"autocomplete": "new-password"}), label="Password", help_text="Use at least 12 characters. Choose a strong, unique password for your eom.dev account.")
|
||
confirm_password = forms.CharField(max_length=1024, widget=forms.PasswordInput(attrs={"autocomplete": "new-password"}), label="Confirm password")
|
||
|
||
def clean_password(self):
|
||
password = self.cleaned_data["password"]
|
||
validate_password(password)
|
||
return password
|
||
|
||
def clean(self):
|
||
data = super().clean()
|
||
if data.get("password") != data.get("confirm_password"):
|
||
self.add_error("confirm_password", "Passwords must match.")
|
||
return data
|