diff --git a/concordia/static/js/src/modules/turnstile.js b/concordia/static/js/src/modules/turnstile.js index 78ebd974b..2e49c8b95 100644 --- a/concordia/static/js/src/modules/turnstile.js +++ b/concordia/static/js/src/modules/turnstile.js @@ -3,7 +3,11 @@ function resetTurnstile(widgetId) { // widgetId is optional. If not provided, the latest // turnstile widget is used automatically - if (turnstile && typeof turnstile.reset === 'function') { + if ( + typeof turnstile !== 'undefined' && + turnstile !== null && + typeof turnstile.reset === 'function' + ) { turnstile.reset(widgetId); } else { console.error( diff --git a/concordia/templates/transcriptions/asset_detail.html b/concordia/templates/transcriptions/asset_detail.html index ce7c9746f..9cfc6250b 100644 --- a/concordia/templates/transcriptions/asset_detail.html +++ b/concordia/templates/transcriptions/asset_detail.html @@ -42,7 +42,9 @@ - + {% if anonymous_user_validation_required %} + + {% endif %} diff --git a/concordia/templates/transcriptions/asset_detail/editor.html b/concordia/templates/transcriptions/asset_detail/editor.html index c92d9623e..c68054605 100644 --- a/concordia/templates/transcriptions/asset_detail/editor.html +++ b/concordia/templates/transcriptions/asset_detail/editor.html @@ -117,7 +117,11 @@

{{ turnstile_form.turnstile }} + {% if anonymous_user_validation_required %} + {% if transcription_status == 'not_started' or transcription_status == 'in_progress' %} +
{{ turnstile_form.turnstile }}
+ {% endif %} + {% endif %} {% endspaceless %} diff --git a/concordia/views.py b/concordia/views.py index 0ec986152..50b589c81 100644 --- a/concordia/views.py +++ b/concordia/views.py @@ -150,6 +150,49 @@ def inner(*args, **kwargs): return inner +def validate_anonymous_user(view): + @wraps(view) + @never_cache + def inner(request, *args, **kwargs): + if not request.user.is_authenticated and request.method == "POST": + # First check if the user has already been validated within the time limit + # If so, validation can be skipped + turnstile_last_validated = request.session.get( + "turnstile_last_validated", 0 + ) + age = time() - turnstile_last_validated + if age > settings.ANONYMOUS_USER_VALIDATION_INTERVAL: + form = TurnstileForm(request.POST) + if not form.is_valid(): + return JsonResponse( + {"error": "Unable to validate. " "Please try again or login."}, + status=401, + ) + else: + # User has been validated, so we'll cache the time in their session + request.session["turnstile_last_validated"] = time() + + return view(request, *args, **kwargs) + + return inner + + +class AnonymousUserValidationCheckMixin: + def get_context_data(self, *args, **kwargs): + context = super().get_context_data(**kwargs) + if not self.request.user.is_authenticated: + turnstile_last_validated = self.request.session.get( + "turnstile_last_validated", 0 + ) + age = time() - turnstile_last_validated + context["anonymous_user_validation_required"] = ( + age > settings.ANONYMOUS_USER_VALIDATION_INTERVAL + ) + else: + context["anonymous_user_validation_required"] = False + return context + + @never_cache def healthz(request): status = { @@ -1358,7 +1401,7 @@ def get_context_data(self, **kwargs): @method_decorator(never_cache, name="dispatch") -class AssetDetailView(APIDetailView): +class AssetDetailView(AnonymousUserValidationCheckMixin, APIDetailView): """ Class to handle GET ansd POST requests on route /campaigns//asset/ """ @@ -1513,33 +1556,6 @@ def get_context_data(self, **kwargs): return ctx -def validate_anonymous_user(view): - @wraps(view) - @never_cache - def inner(request, *args, **kwargs): - if not request.user.is_authenticated and request.method == "POST": - # First check if the user has already been validated within the time limit - # If so, validation can be skipped - turnstile_last_validated = request.session.get( - "turnstile_last_validated", 0 - ) - age = time() - turnstile_last_validated - if age > settings.ANONYMOUS_USER_VALIDATION_INTERVAL: - form = TurnstileForm(request.POST) - if not form.is_valid(): - return JsonResponse( - {"error": "Unable to validate. " "Please try again or login."}, - status=401, - ) - else: - # User has been validated, so we'll cache the time in their session - request.session["turnstile_last_validated"] = time() - - return view(request, *args, **kwargs) - - return inner - - def get_transcription_superseded(asset, supersedes_pk): if not supersedes_pk: if asset.transcription_set.filter(supersedes=None).exists():