From e00ea42c47be2014e8a8b5f188a05654d27dbe90 Mon Sep 17 00:00:00 2001 From: pacnpal <183241239+pacnpal@users.noreply.github.com> Date: Tue, 29 Oct 2024 13:31:30 -0400 Subject: [PATCH] fixed some thangs, implemented cloudflare turnstile --- accounts/__pycache__/urls.cpython-312.pyc | Bin 1859 -> 1989 bytes accounts/__pycache__/views.cpython-312.pyc | Bin 10705 -> 12130 bytes accounts/mixins.py | 28 ++++++ accounts/templatetags/__init__.py | 0 accounts/templatetags/turnstile_tags.py | 14 +++ accounts/urls.py | 8 +- accounts/views.py | 21 +++++ assets/css/src/input.css | 17 ++++ static/css/tailwind.css | 84 ++++++++++++++++++ templates/account/login.html | 3 + templates/account/signup.html | 3 + templates/accounts/turnstile_widget.html | 2 + templates/base/base.html | 69 ++++++++------ .../__pycache__/settings.cpython-312.pyc | Bin 5330 -> 5562 bytes thrillwiki/__pycache__/urls.cpython-312.pyc | Bin 2650 -> 2651 bytes thrillwiki/settings.py | 7 +- thrillwiki/urls.py | 11 +-- 17 files changed, 234 insertions(+), 33 deletions(-) create mode 100644 accounts/mixins.py create mode 100644 accounts/templatetags/__init__.py create mode 100644 accounts/templatetags/turnstile_tags.py create mode 100644 templates/accounts/turnstile_widget.html diff --git a/accounts/__pycache__/urls.cpython-312.pyc b/accounts/__pycache__/urls.cpython-312.pyc index af5a136910e0a87dd64c68b9a7c58f740fdfd68e..8c87f5675840b6200ae84b277ce424b1b6302657 100644 GIT binary patch delta 870 zcmX@ica&fKG%qg~0}!m0P)wI(Wng#=;=lkul=1o3M0Gh!h7{%;)?BtIHb#aNmK3HO z_FU#DW+0n2ii3$El`(}al{rfYrWHYFiB9|{t;xQIV>L5G5UiLJs8|f42*v^{7Ux1! z%nj7SmL&o-N00|iig$7zqc|hj3O+O`{#2GMDVV_s8sZ)SG{u5I#WDy*Fcw6y5Sn6P zpkg_g5(EuaEG&YiSTvPoas!hH6T~PnG+A+=QA!9SU@WlWKnXO(lE6Syfhj@IDN<y2UVj7wzmkF3>j{L>?$aT2N`yY-?_B7BtIAEn9Mwo zTW+x@7RQ6s-V%Vw1cNQx{ES7Ev0f9X8|2nvUm*E`nURt4E`!Wn2IIR7I(Hd_A8?B{ zaD3!oVCC$Pm|%KcSmUCw#&uzXi^2w%g^hN|Ut#gQ$->bgIl=Y1h}K0Bt?MF27e$ON ziZE|`lrYt0f&Eu6jZmG=6(v+Dqbd6m zq*#;j7E3{5Nd}N+Ez3+TFMbJ%!CM@O$;tVpc_qbFY&rSqnR)tE!Y~niuz+4hNp22M z6K_dsZb43BNossvVs7d!R6SpTB1{sp_>3&Q%Bg+nexCtYDlzRAMTAvwY8x`^gQ5zXr&h8IN)FN+xO Y(73|lJoygWJ#J|}ex^q5B2}O@05#Z_-v9sr diff --git a/accounts/__pycache__/views.cpython-312.pyc b/accounts/__pycache__/views.cpython-312.pyc index a659fdbc1db2691dc8a8117d5bc40ab346c871c0..a44224180523e16086f6b5da1bf386631e315492 100644 GIT binary patch delta 3223 zcmdT`ZERat89wLwCU#QCalRa{`EueUj?>lYSJHG#n?-9fpjk!hcB3BJmFIhs++q7> z=U&%omDU+#S~IBFIG`dJ5Vi>vMMXlHCL|D2e}e>7hq_$^Xn@3r_)#qZD)__uo@={R z#27 zOC=QY6wy0YiQdV^+32QP)*qAlF3@*_eoX2w;D*PTU+-BZRRfRfkyVnKkjr~vc^{*j zp0bhSQX2(rKMOFWYW##g0DC6&LBJ<2#o|Na2lRWv#%I!5Lr>d=nV;s|E8 zr*77qH}cOItmxDyjrn|G5#_&7I3-S~r6viS)A(e;vdvuevlHrK+WjasiU#igHy+mj8>iNR~VoNRe*P(;Ggg`JziN)9eaij+e8S3e2*3 z0FH9%(z>oOq~7s>&hgKgJf|6XxzVYy3X6<8^-?KS8*0>1EtZ{gR8%^YIdz(r$)+t! z(=2o=5{aycA$6w2M__b$?=FH94{Tw8w$lLjSI9j@t=sp3KX}(4z3q>#pZxypcW2-C zAKdYgVB1>pc4O~)|DDFzFMYB5J6;m(`Isnj`Ik?xo&NffcUsoZyd8SqKlDLM``woQ z+b#X;=kDxp8UB@j_}}+xVCBEI_rft>=-5wg)=fR?d2ioT%yX-kf_N)d1GrHm1{()T zcwwiZ>`sPdvzoR+`4P}s7}_WJC?FrG0ECrnHvrsUCI3`vYliL-fNfB?i~iTNJo`{y z23^`7q&_BQ_4ogqmpq2-3?Uo4#gR_jSU4(|ipMo_b;+h&&_~h12 zwaL?U8ckuDI<+}wFPJ(%g_;?JS@COc&oQ*??6J&@k$1Lax4uR3BP19+pUpWumBE1 z{kzdz5PxgvrRTQ-fo9r{5s3TwF+A!qgvSv&#cboL_-9dEK$t)%2ecZ`XHkjpDe?2h z(OMbHXN5QThiOUrJj}#Z>7{D~`Ii?3Epo>52quE8T+;XI;k1mO`O=CdiTGLn6 zQ5n!rSFG@5l&%0cH8Y=_olbHL3%`nR76DrTPl~glzE5DA;T;H=CUKv8zDx)eiFB`W z85hXAub}iYfaL>_GY&z&bymAjyol1ucGu{i7Vm^LP5M7?r@1K zZoL&A_Uw@^Vp{U2#odl>IxGIsk)ShTpmVVCI;f#MkTpoY8IkIIkA7Y>b@i9d;D!h6 zNXOApSr5DuB}^~ghJfwS2^JRNd1so*wG3w<@ery#d9%pdaa9-r8FSQpI>&e`j(c!i zZ?QbQO;{&9i3-1Xx2v^BMpxckGKiPuHxS-HFvXv`y85tBJE8JJr!B(cR5ZB`)rPtH z9hiJ`Yq0xA>KIy>0Uyzb6JSe=P>Yt9wl!_uc2sBw<>JN&or^1O%)TO8qZg?VUySww zEjObl>2>jOw7;|li{fGFw#&kEpx`o%&}aS)ga-`D+rNT3nM7})B+2+DN>v*8n>dvI zO1hB=mu^XXJr2JG5KsDKLvwwpab3lGyO)*>$rAWB=yqirXq;Cg5{=g8$1B%g1wL^TTMsqo|P|7E>tU zt0SKT+4f`!%e0kI;n?up7ft55ZvvbwWZ4P+QvzLt!mRaUF&giqhs62#fsx;lqrV}2 rA9>sEc-vRh9o0*RUeB)^I|PKCW*l8zzbr@hnu!t=ug8z8*mM2^CROy; delta 1929 zcmZ8iO>9(E6rMYs-?lST+L>vYpLS+iN?$vjLSd>=i_=6ThQVq{x-eu;QH}i(` z-V{m@Dpn0)q2{tyRVCTNt=x1kZlM9o~rMa}2QK(HVOv!QF*i_rR zu$j5sF7CNR%kW#s^KPww#kDq{)&^Ew3tQZ-y)JG2ic3pycBy04cdKNR$fkIhyDxcG z`J$G_H8a{E;uA|l3d;ze`;*occNY`40$<0n=%+Bp5BzwOTeih;o)MS5a|x%nX>m}2 zYdY|=>GP+5kBnc9jDNcATBP_}pa`R_ zA0uP#Cz3MR9yN5UiihUJgLSsw@mkFW2XV4@s4tC9u#G%@$8^Ky0Ncgqy_xtN z@dL#B?JAhfN>%Z}thnAAds^<>1Dw)jshCt)vbgO8RkduCEK5}_AFe~;nar}(4*PL_ zDs>P{Jc5fC;xYd&WUL?)wfKNI+IQDCigTq~eBs-`lA;zpP$ZFZofBH!x6BPgRX=0! zBCVxc+|}NFhFl4X;zqP6w}Kg&(_-wGJ@T6NqE+$0KJuhsfNo6QAhNSGexBeUf!v;o z>#_L7?s$%sMI}DNMq3}mFM5iy1g6Me9#E!{hTwST_CK>{9x_C5g3SaWf@x7n=Ju_p zVS<1PO9`~kmnGyWLB(o^QX&Vrb%jP%1S^1mLCFtm;c7C)s;xhh8sjp3ewZiMLj*4o z943%*>oj_q;1z_&lXrwjf>+7Vi*Rqn^+zpxql+BHMzhfTElQ37Rd z)|w2GWTlFPC_xIr>1j5!lFd~U)G}}!L5%2*x_JWPXr?iNZ}>Of{?Og(n$%NAvj5JP~6X@*@#FCr@U_?@lI=Y z_&ZOKT<1`!E$(kj^hrf@QHKFz3 zkpNjuqzm34c$6g>kwKiSrSmkBg3r-tO)9)eQ>md{ZZr)N$mEhxSV2(cSLKpO#|s?0 zR~A@1XsKFu!dqznU(wNuuw0=wu-8wRpuq(sFSq_xmKl3eoSFEZ<;8pXjCegCVqtM5 zzd?MN53>l4wv6}C`Y!FYQoUjp%4Yo-tRtppjR9VuXA*ivYBIHxq&a=7#-^O0^;KOL{yxg>^V%ST025JTBw;CH>~#K_Ar*JZ8v~Ab1k|i zpbxdF6DgI;X0vWv4_C?xO^LrIqh)$Nop}3c$N!Q=z03=%zm}{&`F|oGd-+7kRs$*_ znKqz@soh>9v{PUQ2G=zBQ}8iP>5a24iVq7p@l&DDb;BRK=I>wjT*qW)r*?X%EB^yF C<;Y?H diff --git a/accounts/mixins.py b/accounts/mixins.py new file mode 100644 index 00000000..b2dc7516 --- /dev/null +++ b/accounts/mixins.py @@ -0,0 +1,28 @@ +import requests +from django.conf import settings +from django.core.exceptions import ValidationError + +class TurnstileMixin: + """ + Mixin to handle Cloudflare Turnstile validation. + """ + def validate_turnstile(self, request): + """ + Validate the Turnstile response token. + """ + token = request.POST.get('cf-turnstile-response') + if not token: + raise ValidationError('Please complete the Turnstile challenge.') + + # Verify the token with Cloudflare + data = { + 'secret': settings.TURNSTILE_SECRET_KEY, + 'response': token, + 'remoteip': request.META.get('REMOTE_ADDR'), + } + + response = requests.post(settings.TURNSTILE_VERIFY_URL, data=data) + result = response.json() + + if not result.get('success'): + raise ValidationError('Turnstile validation failed. Please try again.') diff --git a/accounts/templatetags/__init__.py b/accounts/templatetags/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/accounts/templatetags/turnstile_tags.py b/accounts/templatetags/turnstile_tags.py new file mode 100644 index 00000000..6cddcd67 --- /dev/null +++ b/accounts/templatetags/turnstile_tags.py @@ -0,0 +1,14 @@ +from django import template +from django.conf import settings + +register = template.Library() + +@register.inclusion_tag('accounts/turnstile_widget.html') +def turnstile_widget(): + """ + Template tag to render the Cloudflare Turnstile widget. + Usage: {% load turnstile_tags %}{% turnstile_widget %} + """ + return { + 'site_key': settings.TURNSTILE_SITE_KEY + } diff --git a/accounts/urls.py b/accounts/urls.py index 260e7c48..e87938f2 100644 --- a/accounts/urls.py +++ b/accounts/urls.py @@ -1,13 +1,17 @@ from django.urls import path from django.contrib.auth import views as auth_views +from allauth.account.views import LogoutView from . import views app_name = 'accounts' urlpatterns = [ + # Override allauth's login and signup views with our Turnstile-enabled versions + path('login/', views.CustomLoginView.as_view(), name='account_login'), + path('signup/', views.CustomSignupView.as_view(), name='account_signup'), + # Authentication views - path('login/', auth_views.LoginView.as_view(template_name='accounts/login.html'), name='login'), - path('logout/', auth_views.LogoutView.as_view(), name='logout'), + path('logout/', LogoutView.as_view(), name='logout'), path('password_change/', auth_views.PasswordChangeView.as_view(), name='password_change'), path('password_change/done/', auth_views.PasswordChangeDoneView.as_view(), name='password_change_done'), path('password_reset/', auth_views.PasswordResetView.as_view(), name='password_reset'), diff --git a/accounts/views.py b/accounts/views.py index 1703f11c..2bfa22b2 100644 --- a/accounts/views.py +++ b/accounts/views.py @@ -4,6 +4,7 @@ from django.shortcuts import get_object_or_404, redirect, render from django.contrib.auth.decorators import login_required from django.contrib.auth.mixins import LoginRequiredMixin from django.contrib import messages +from django.core.exceptions import ValidationError from allauth.socialaccount.providers.google.views import GoogleOAuth2Adapter from allauth.socialaccount.providers.discord.views import DiscordOAuth2Adapter from allauth.socialaccount.providers.oauth2.client import OAuth2Client @@ -20,9 +21,29 @@ from django.urls import reverse from accounts.models import User, PasswordReset from reviews.models import Review from email_service.services import EmailService +from allauth.account.views import LoginView, SignupView +from .mixins import TurnstileMixin User = get_user_model() +class CustomLoginView(TurnstileMixin, LoginView): + def form_valid(self, form): + try: + self.validate_turnstile(self.request) + except ValidationError as e: + form.add_error(None, str(e)) + return self.form_invalid(form) + return super().form_valid(form) + +class CustomSignupView(TurnstileMixin, SignupView): + def form_valid(self, form): + try: + self.validate_turnstile(self.request) + except ValidationError as e: + form.add_error(None, str(e)) + return self.form_invalid(form) + return super().form_valid(form) + @login_required def user_redirect_view(request): """Redirect /user/ to the logged-in user's profile""" diff --git a/assets/css/src/input.css b/assets/css/src/input.css index ed73972d..2d556322 100644 --- a/assets/css/src/input.css +++ b/assets/css/src/input.css @@ -55,6 +55,23 @@ @apply mt-2 text-sm text-red-600 dark:text-red-400; } + /* Status Badge Styles */ + .status-badge { + @apply inline-flex items-center px-3 py-1 text-sm font-medium rounded-full; + } + + .status-operating { + @apply text-green-800 bg-green-100 dark:bg-green-800/30 dark:text-green-100 dark:ring-1 dark:ring-green-400/30; + } + + .status-closed { + @apply text-red-800 bg-red-100 dark:bg-red-800/30 dark:text-red-100 dark:ring-1 dark:ring-red-400/30; + } + + .status-construction { + @apply text-yellow-800 bg-yellow-100 dark:bg-yellow-800/30 dark:text-yellow-100 dark:ring-1 dark:ring-yellow-400/30; + } + /* Auth Card Styles */ .auth-card { @apply w-full max-w-md p-8 mx-auto border shadow-xl bg-white/90 dark:bg-gray-800/90 rounded-2xl backdrop-blur-sm border-gray-200/50 dark:border-gray-700/50; diff --git a/static/css/tailwind.css b/static/css/tailwind.css index a2739a55..240d5df0 100644 --- a/static/css/tailwind.css +++ b/static/css/tailwind.css @@ -1749,6 +1749,72 @@ select { color: rgb(248 113 113 / var(--tw-text-opacity)); } +/* Status Badge Styles */ + +.status-badge { + display: inline-flex; + align-items: center; + border-radius: 9999px; + padding-left: 0.75rem; + padding-right: 0.75rem; + padding-top: 0.25rem; + padding-bottom: 0.25rem; + font-size: 0.875rem; + line-height: 1.25rem; + font-weight: 500; +} + +.status-operating { + --tw-bg-opacity: 1; + background-color: rgb(220 252 231 / var(--tw-bg-opacity)); + --tw-text-opacity: 1; + color: rgb(22 101 52 / var(--tw-text-opacity)); +} + +.status-operating:is(.dark *) { + background-color: rgb(22 101 52 / 0.3); + --tw-text-opacity: 1; + color: rgb(220 252 231 / var(--tw-text-opacity)); + --tw-ring-offset-shadow: var(--tw-ring-inset) 0 0 0 var(--tw-ring-offset-width) var(--tw-ring-offset-color); + --tw-ring-shadow: var(--tw-ring-inset) 0 0 0 calc(1px + var(--tw-ring-offset-width)) var(--tw-ring-color); + box-shadow: var(--tw-ring-offset-shadow), var(--tw-ring-shadow), var(--tw-shadow, 0 0 #0000); + --tw-ring-color: rgb(74 222 128 / 0.3); +} + +.status-closed { + --tw-bg-opacity: 1; + background-color: rgb(254 226 226 / var(--tw-bg-opacity)); + --tw-text-opacity: 1; + color: rgb(153 27 27 / var(--tw-text-opacity)); +} + +.status-closed:is(.dark *) { + background-color: rgb(153 27 27 / 0.3); + --tw-text-opacity: 1; + color: rgb(254 226 226 / var(--tw-text-opacity)); + --tw-ring-offset-shadow: var(--tw-ring-inset) 0 0 0 var(--tw-ring-offset-width) var(--tw-ring-offset-color); + --tw-ring-shadow: var(--tw-ring-inset) 0 0 0 calc(1px + var(--tw-ring-offset-width)) var(--tw-ring-color); + box-shadow: var(--tw-ring-offset-shadow), var(--tw-ring-shadow), var(--tw-shadow, 0 0 #0000); + --tw-ring-color: rgb(248 113 113 / 0.3); +} + +.status-construction { + --tw-bg-opacity: 1; + background-color: rgb(254 249 195 / var(--tw-bg-opacity)); + --tw-text-opacity: 1; + color: rgb(133 77 14 / var(--tw-text-opacity)); +} + +.status-construction:is(.dark *) { + background-color: rgb(133 77 14 / 0.3); + --tw-text-opacity: 1; + color: rgb(254 249 195 / var(--tw-text-opacity)); + --tw-ring-offset-shadow: var(--tw-ring-inset) 0 0 0 var(--tw-ring-offset-width) var(--tw-ring-offset-color); + --tw-ring-shadow: var(--tw-ring-inset) 0 0 0 calc(1px + var(--tw-ring-offset-width)) var(--tw-ring-color); + box-shadow: var(--tw-ring-offset-shadow), var(--tw-ring-shadow), var(--tw-shadow, 0 0 #0000); + --tw-ring-color: rgb(250 204 21 / 0.3); +} + /* Auth Card Styles */ .auth-card { @@ -2513,6 +2579,10 @@ select { background-color: rgb(254 249 195 / 0.9); } +.bg-white\/80 { + background-color: rgb(255 255 255 / 0.8); +} + .bg-gradient-to-br { background-image: linear-gradient(to bottom right, var(--tw-gradient-stops)); } @@ -2972,6 +3042,11 @@ select { background-color: rgb(79 70 229 / 0.1); } +.hover\:bg-gray-200:hover { + --tw-bg-opacity: 1; + background-color: rgb(229 231 235 / var(--tw-bg-opacity)); +} + .hover\:from-primary\/90:hover { --tw-gradient-from: rgb(79 70 229 / 0.9) var(--tw-gradient-from-position); --tw-gradient-to: rgb(79 70 229 / 0) var(--tw-gradient-to-position); @@ -3125,6 +3200,10 @@ select { background-color: rgb(133 77 14 / 0.3); } +.dark\:bg-gray-700\/80:is(.dark *) { + background-color: rgb(55 65 81 / 0.8); +} + .dark\:from-gray-950:is(.dark *) { --tw-gradient-from: #030712 var(--tw-gradient-from-position); --tw-gradient-to: rgb(3 7 18 / 0) var(--tw-gradient-to-position); @@ -3223,6 +3302,11 @@ select { background-color: rgb(79 70 229 / 0.2); } +.dark\:hover\:bg-gray-600:hover:is(.dark *) { + --tw-bg-opacity: 1; + background-color: rgb(75 85 99 / var(--tw-bg-opacity)); +} + .dark\:hover\:text-blue-300:hover:is(.dark *) { --tw-text-opacity: 1; color: rgb(147 197 253 / var(--tw-text-opacity)); diff --git a/templates/account/login.html b/templates/account/login.html index f3cfde68..8902b71d 100644 --- a/templates/account/login.html +++ b/templates/account/login.html @@ -2,6 +2,7 @@ {% load i18n %} {% load account socialaccount %} {% load static %} +{% load turnstile_tags %} {% block title %}Login - ThrillWiki{% endblock %} @@ -88,6 +89,8 @@ + {% turnstile_widget %} + {% if redirect_field_value %} {% endif %} diff --git a/templates/account/signup.html b/templates/account/signup.html index 08052829..6bc6097a 100644 --- a/templates/account/signup.html +++ b/templates/account/signup.html @@ -2,6 +2,7 @@ {% load i18n %} {% load account socialaccount %} {% load static %} +{% load turnstile_tags %} {% block title %}Register - ThrillWiki{% endblock %} @@ -116,6 +117,8 @@ {% endif %} + {% turnstile_widget %} + {% if redirect_field_value %} {% endif %} diff --git a/templates/accounts/turnstile_widget.html b/templates/accounts/turnstile_widget.html new file mode 100644 index 00000000..25e0fbce --- /dev/null +++ b/templates/accounts/turnstile_widget.html @@ -0,0 +1,2 @@ + +
diff --git a/templates/base/base.html b/templates/base/base.html index 28c262a8..b7e46868 100644 --- a/templates/base/base.html +++ b/templates/base/base.html @@ -1,6 +1,6 @@ {% load static %} - + @@ -11,9 +11,14 @@ @@ -49,30 +54,44 @@ this.setTheme(e.matches ? 'dark' : 'light'); } }); + + // Set initial theme icon state + this.updateThemeIcon(); }); }, setTheme(theme) { - // Force a repaint by temporarily adding a class - document.documentElement.classList.add('theme-transitioning'); - if (theme === 'dark') { document.documentElement.classList.add('dark'); } else { document.documentElement.classList.remove('dark'); } - localStorage.theme = theme; - - // Remove the transition class after a short delay - setTimeout(() => { - document.documentElement.classList.remove('theme-transitioning'); - }, 100); + localStorage.setItem('theme', theme); + this.updateThemeIcon(); }, toggleTheme() { const isDark = document.documentElement.classList.contains('dark'); this.setTheme(isDark ? 'light' : 'dark'); + }, + + updateThemeIcon() { + const isDark = document.documentElement.classList.contains('dark'); + const sunIcon = document.querySelector('#theme-toggle .fa-sun'); + const moonIcon = document.querySelector('#theme-toggle .fa-moon'); + + if (sunIcon && moonIcon) { + // Show sun icon in dark mode (to indicate you can switch to light) + // Show moon icon in light mode (to indicate you can switch to dark) + if (isDark) { + sunIcon.classList.remove('hidden'); + moonIcon.classList.add('hidden'); + } else { + sunIcon.classList.add('hidden'); + moonIcon.classList.remove('hidden'); + } + } } }; @@ -81,24 +100,24 @@ @@ -141,9 +160,9 @@
- diff --git a/thrillwiki/__pycache__/settings.cpython-312.pyc b/thrillwiki/__pycache__/settings.cpython-312.pyc index a039b8a07e7b1312a93133af284a9962556b3b72..ad5cf6158db37eb15be4b790f59266eb633932d3 100644 GIT binary patch delta 430 zcmcblxl5bxG%qg~0}$L5Q%tvzn8+u=sJ2mEnpq&lEy^UtJ<2r2Bg(9jNz-$)8?y{| z{VfTD3KK^Ns4NUCFb>K}PA+n`^sc(4j3QGMn4c3_T;%BH?qzHl5aHn!?-5uPS!J0~ zQc_TCrLUiyk(iT{nwOqhte2dVUz(DZlUS6hmzS6q^rld4~4pkJI>l3JEp zl$lnkX?}~nU~@X3EOWg?h@+=ZxTl{>yt9vIytBWbo2Prco2QTKEfEx%;2`IC=iuO5 zq9~#+p1~ntVWE)FAiv-cpuYHE&k)ymZ`Vkm0SGZy=OEV*bkQ)^Aa+l;$oSA8pUHa! zW4S7ULB|Nh#k)5v3uQ7z$;iz&pJ_hdW~R*wjtfR^m!;h=Fi6}Gmz-Wcv3z>X#F_;j z7xX+Xi+f&R5V;{CHJ^PZ`+T06JPRT&=zCn20E&u!U}F$7xWFKEL)-?WMm*>ugGf<1 G&;|f|t&9r* delta 194 zcmdm`eMyt=G%qg~0}xbZDWrRfPvnzel-j5+&CF8Cr0KRfh*^f4Nz-KWD?SBg3*it) zPoHp4KbLrCAJ2Gae?K=*_gexeg26$~Xd?chA(JNv#d4JZtzZP=;^mva3uQ97iAzpT zpO`*9XJXC*iwnArm&KeeFbLle7M*TB(R{kiM4JU17qnb13%g!m5I_@kzAWr=kwKuS H2xuAr>S;Sz diff --git a/thrillwiki/__pycache__/urls.cpython-312.pyc b/thrillwiki/__pycache__/urls.cpython-312.pyc index 728d08f9a6c2fd3afa4adb7c6edb70e86ff7c5ba..98433dc244f9bfd6fe2579f4ea6329f5fd3a70a0 100644 GIT binary patch delta 309 zcmca5a$7|1G%qg~0}$+$P)xtY&cN^(#DM|PjdILPu5wHasVpf9s~I7}tC=7)P?R}E zF_k+@4W=AHrzoxAS0V~h qyE!?7bEecsHU?JC4x!HQ3GtVCRWGxseK42dXKLX7U^khYD*ymkfIp}J diff --git a/thrillwiki/settings.py b/thrillwiki/settings.py index 14ef6908..594d86b3 100644 --- a/thrillwiki/settings.py +++ b/thrillwiki/settings.py @@ -206,4 +206,9 @@ AUTH_USER_MODEL = 'accounts.User' # Tailwind configuration TAILWIND_CLI_CONFIG_FILE = os.path.join(BASE_DIR, 'tailwind.config.js') TAILWIND_CLI_SRC_CSS = os.path.join(BASE_DIR, 'assets/css/src/input.css') -TAILWIND_CLI_DIST_CSS = os.path.join(BASE_DIR, 'static/css/tailwind.css') \ No newline at end of file +TAILWIND_CLI_DIST_CSS = os.path.join(BASE_DIR, 'static/css/tailwind.css') + +# Cloudflare Turnstile settings +TURNSTILE_SITE_KEY = '0x4AAAAAAAyqVp3RjccrC9Kz' +TURNSTILE_SECRET_KEY = '0x4AAAAAAAyqVrQolYsrAFGJ39PXHJ_HQzY' +TURNSTILE_VERIFY_URL = 'https://challenges.cloudflare.com/turnstile/v0/siteverify' diff --git a/thrillwiki/urls.py b/thrillwiki/urls.py index 6537d3d2..6fb82b0e 100644 --- a/thrillwiki/urls.py +++ b/thrillwiki/urls.py @@ -19,8 +19,12 @@ urlpatterns = [ path('terms/', TemplateView.as_view(template_name='pages/terms.html'), name='terms'), path('privacy/', TemplateView.as_view(template_name='pages/privacy.html'), name='privacy'), - # Authentication URLs - path('accounts/', include('allauth.urls')), # This includes social auth URLs + # Custom authentication URLs first (to override allauth defaults) + path('accounts/', include('accounts.urls')), + + # Default allauth URLs (for social auth and other features) + path('accounts/', include('allauth.urls')), + path('accounts/email-required/', accounts_views.email_required, name='email_required'), # User profile URLs @@ -31,9 +35,6 @@ urlpatterns = [ # Redirect /user/ to the user's profile if logged in path('user/', accounts_views.user_redirect_view, name='user_redirect'), - - # Include remaining accounts URLs - path('', include('accounts.urls')), ] # Serve static files in development