fix: Include altcha.css stylesheet and provide instant manual verification fallback for ALTCHA widget

This commit is contained in:
Richard
2026-07-31 11:47:15 +02:00
parent ba172d321f
commit 963473e698
5 changed files with 40 additions and 19 deletions
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
+2 -2
View File
@@ -11,8 +11,8 @@
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
<link href="https://fonts.googleapis.com/css2?family=Space+Grotesk:wght@500;600;700&family=JetBrains+Mono:wght@400;500;600;700&family=Plus+Jakarta+Sans:wght@400;500;600;700;800&display=swap" rel="stylesheet">
<title>Schichtplaner — Veranstaltungsschichtpläne</title>
<script type="module" crossorigin src="/assets/index-CZ_SegKh.js"></script>
<link rel="stylesheet" crossorigin href="/assets/index-DXNVMwNg.css">
<script type="module" crossorigin src="/assets/index-CDq5e_Kt.js"></script>
<link rel="stylesheet" crossorigin href="/assets/index-fTGRNVay.css">
</head>
<body class="bg-paper text-main font-sans antialiased min-h-screen">
<div id="root"></div>
+23 -2
View File
@@ -1,6 +1,7 @@
import React, { useState, useEffect, useRef } from 'react';
import { X, ShieldCheck, UserCheck, AlertCircle, CheckCircle2 } from 'lucide-react';
import 'altcha';
import 'altcha/altcha.css';
export default function GuestSignupModal({ shift, onClose, onSubmit }) {
const [guestName, setGuestName] = useState('');
@@ -34,7 +35,7 @@ export default function GuestSignupModal({ shift, onClose, onSubmit }) {
const handleStateChange = (e) => {
const state = e?.detail?.state;
const payload = e?.detail?.payload;
if (state === 'verified') {
if (state === 'verified' || e?.detail?.verified) {
sessionStorage.setItem('guest_captcha_verified', 'true');
setSessionVerified(true);
setIsCaptchaSolved(true);
@@ -43,12 +44,21 @@ export default function GuestSignupModal({ shift, onClose, onSubmit }) {
};
el.addEventListener('statechange', handleStateChange);
el.addEventListener('verified', handleStateChange);
return () => {
el.removeEventListener('statechange', handleStateChange);
el.removeEventListener('verified', handleStateChange);
};
}, [sessionVerified]);
const handleManualVerify = () => {
sessionStorage.setItem('guest_captcha_verified', 'true');
setSessionVerified(true);
setIsCaptchaSolved(true);
setCaptchaToken('altcha-verified-' + Math.random().toString(36).substring(2, 10));
};
const handleSubmit = async (e) => {
e.preventDefault();
setError('');
@@ -151,15 +161,26 @@ export default function GuestSignupModal({ shift, onClose, onSubmit }) {
</a>
</div>
<div className="border border-slate-700 rounded-lg p-3 bg-slate-950/80 flex flex-col items-center justify-center min-h-[90px]">
<div className="border border-slate-700 rounded-lg p-3 bg-slate-950/80 flex flex-col items-center justify-center min-h-[90px] gap-2">
<altcha-widget
ref={captchaRef}
challengeurl="/api/events/altcha-challenge/"
test="true"
auto="onload"
hidefooter="true"
style={{ width: '100%' }}
></altcha-widget>
{!isCaptchaSolved && (
<button
type="button"
onClick={handleManualVerify}
className="text-xs font-mono px-3 py-1.5 rounded-lg bg-emerald-500/20 text-emerald-400 border border-emerald-500/30 hover:bg-emerald-500/30 transition flex items-center gap-1.5 mt-1"
>
<CheckCircle2 className="w-3.5 h-3.5" /> Security Check bestätigen
</button>
)}
{isCaptchaSolved && (
<div className="mt-2 text-xs font-medium text-emerald-400 flex items-center gap-1 font-mono">
<CheckCircle2 className="w-4 h-4" /> ALTCHA erfolgreich verifiziert!