Add secret management guide, client-side performance monitoring, and search accessibility enhancements

- Introduced a comprehensive Secret Management Guide detailing best practices, secret classification, development setup, production management, rotation procedures, and emergency protocols.
- Implemented a client-side performance monitoring script to track various metrics including page load performance, paint metrics, layout shifts, and memory usage.
- Enhanced search accessibility with keyboard navigation support for search results, ensuring compliance with WCAG standards and improving user experience.
This commit is contained in:
pacnpal
2025-12-23 16:41:42 -05:00
parent ae31e889d7
commit edcd8f2076
155 changed files with 22046 additions and 4645 deletions

View File

@@ -32,8 +32,13 @@ from .mixins import TurnstileMixin
from typing import Dict, Any, Optional, Union, cast
from django_htmx.http import HttpResponseClientRefresh
from contextlib import suppress
import logging
import re
from apps.core.logging import log_exception, log_security_event
logger = logging.getLogger(__name__)
UserModel = get_user_model()
@@ -46,6 +51,15 @@ class CustomLoginView(TurnstileMixin, LoginView):
return self.form_invalid(form)
response = super().form_valid(form)
user = self.request.user
log_security_event(
logger,
event_type="user_login",
message=f"User {user.username} logged in successfully",
severity="low",
context={"user_id": user.id, "username": user.username},
request=self.request,
)
return (
HttpResponseClientRefresh()
if getattr(self.request, "htmx", False)
@@ -53,6 +67,14 @@ class CustomLoginView(TurnstileMixin, LoginView):
)
def form_invalid(self, form):
log_security_event(
logger,
event_type="login_failed",
message="Failed login attempt",
severity="medium",
context={"username": form.data.get("login", "unknown")},
request=self.request,
)
if getattr(self.request, "htmx", False):
return render(
self.request,
@@ -80,6 +102,19 @@ class CustomSignupView(TurnstileMixin, SignupView):
return self.form_invalid(form)
response = super().form_valid(form)
user = self.user
log_security_event(
logger,
event_type="user_signup",
message=f"New user registered: {user.username}",
severity="low",
context={
"user_id": user.id,
"username": user.username,
"email": user.email,
},
request=self.request,
)
return (
HttpResponseClientRefresh()
if getattr(self.request, "htmx", False)
@@ -203,6 +238,10 @@ class SettingsView(LoginRequiredMixin, TemplateView):
profile.save()
user.save()
logger.info(
f"User {user.username} updated their profile",
extra={"user_id": user.id, "username": user.username},
)
messages.success(request, "Profile updated successfully")
def _validate_password(self, password: str) -> bool:
@@ -262,6 +301,15 @@ class SettingsView(LoginRequiredMixin, TemplateView):
user.set_password(new_password)
user.save()
log_security_event(
logger,
event_type="password_changed",
message=f"User {user.username} changed their password",
severity="medium",
context={"user_id": user.id, "username": user.username},
request=request,
)
self._send_password_change_confirmation(request, user)
messages.success(
request,
@@ -363,6 +411,14 @@ def request_password_reset(request: HttpRequest) -> HttpResponse:
token = create_password_reset_token(user)
site = get_current_site(request)
send_password_reset_email(user, site, token)
log_security_event(
logger,
event_type="password_reset_requested",
message=f"Password reset requested for {email}",
severity="medium",
context={"email": email},
request=request,
)
messages.success(request, "Password reset email sent")
return redirect("account_login")
@@ -381,6 +437,15 @@ def handle_password_reset(
reset.used = True
reset.save()
log_security_event(
logger,
event_type="password_reset_complete",
message=f"Password reset completed for user {user.username}",
severity="medium",
context={"user_id": user.id, "username": user.username},
request=request,
)
send_password_reset_confirmation(user, site)
messages.success(request, "Password reset successfully")