feat: Implement initial schema and add various API, service, and management command enhancements across the application.

This commit is contained in:
pacnpal
2026-01-01 15:13:01 -05:00
parent c95f99ca10
commit b243b17af7
413 changed files with 11164 additions and 17433 deletions

View File

@@ -61,11 +61,7 @@ class CustomLoginView(TurnstileMixin, LoginView):
context={"user_id": user.id, "username": user.username},
request=self.request,
)
return (
HttpResponseClientRefresh()
if getattr(self.request, "htmx", False)
else response
)
return HttpResponseClientRefresh() if getattr(self.request, "htmx", False) else response
def form_invalid(self, form):
log_security_event(
@@ -116,11 +112,7 @@ class CustomSignupView(TurnstileMixin, SignupView):
},
request=self.request,
)
return (
HttpResponseClientRefresh()
if getattr(self.request, "htmx", False)
else response
)
return HttpResponseClientRefresh() if getattr(self.request, "htmx", False) else response
def form_invalid(self, form):
if getattr(self.request, "htmx", False):
@@ -260,9 +252,7 @@ class SettingsView(LoginRequiredMixin, TemplateView):
and bool(re.search(r"[0-9]", password))
)
def _send_password_change_confirmation(
self, request: HttpRequest, user: User
) -> None:
def _send_password_change_confirmation(self, request: HttpRequest, user: User) -> None:
"""Send password change confirmation email."""
site = get_current_site(request)
context = {
@@ -270,9 +260,7 @@ class SettingsView(LoginRequiredMixin, TemplateView):
"site_name": site.name,
}
email_html = render_to_string(
"accounts/email/password_change_confirmation.html", context
)
email_html = render_to_string("accounts/email/password_change_confirmation.html", context)
EmailService.send_email(
to=user.email,
@@ -282,9 +270,7 @@ class SettingsView(LoginRequiredMixin, TemplateView):
html=email_html,
)
def _handle_password_change(
self, request: HttpRequest
) -> HttpResponseRedirect | None:
def _handle_password_change(self, request: HttpRequest) -> HttpResponseRedirect | None:
user = cast(User, request.user)
old_password = request.POST.get("old_password", "")
new_password = request.POST.get("new_password", "")
@@ -327,9 +313,7 @@ class SettingsView(LoginRequiredMixin, TemplateView):
def _handle_email_change(self, request: HttpRequest) -> None:
if new_email := request.POST.get("new_email"):
self._send_email_verification(request, new_email)
messages.success(
request, "Verification email sent to your new email address"
)
messages.success(request, "Verification email sent to your new email address")
else:
messages.error(request, "New email is required")
@@ -385,9 +369,7 @@ def create_password_reset_token(user: User) -> str:
return token
def send_password_reset_email(
user: User, site: Site | RequestSite, token: str
) -> None:
def send_password_reset_email(user: User, site: Site | RequestSite, token: str) -> None:
reset_url = reverse("password_reset_confirm", kwargs={"token": token})
context = {
"user": user,
@@ -457,16 +439,12 @@ def handle_password_reset(
messages.success(request, "Password reset successfully")
def send_password_reset_confirmation(
user: User, site: Site | RequestSite
) -> None:
def send_password_reset_confirmation(user: User, site: Site | RequestSite) -> None:
context = {
"user": user,
"site_name": site.name,
}
email_html = render_to_string(
"accounts/email/password_reset_complete.html", context
)
email_html = render_to_string("accounts/email/password_reset_complete.html", context)
EmailService.send_email(
to=user.email,
@@ -479,9 +457,7 @@ def send_password_reset_confirmation(
def reset_password(request: HttpRequest, token: str) -> HttpResponse:
try:
reset = PasswordReset.objects.select_related("user").get(
token=token, expires_at__gt=timezone.now(), used=False
)
reset = PasswordReset.objects.select_related("user").get(token=token, expires_at__gt=timezone.now(), used=False)
if request.method == "POST":
if new_password := request.POST.get("new_password"):