implement challenge verification flow with altcha integration and add challenge page

This commit is contained in:
Eduardo Silva
2026-03-18 08:56:48 -03:00
parent 0bd4136b5f
commit 5c5375cb9a
10 changed files with 325 additions and 2 deletions

File diff suppressed because one or more lines are too long

View File

@@ -0,0 +1,35 @@
document.addEventListener("DOMContentLoaded", function () {
var widget = document.getElementById("altcha-widget");
var progressFill = document.getElementById("progress-fill");
var statusText = document.getElementById("challenge-status");
var challengeIcon = document.getElementById("challenge-icon");
if (!widget) return;
var fakeProgress = 0;
var progressInterval = setInterval(function () {
fakeProgress = Math.min(fakeProgress + Math.random() * 2.5, 88);
progressFill.style.width = fakeProgress + "%";
}, 150);
widget.addEventListener("statechange", function (ev) {
if (ev.detail.state === "verified") {
clearInterval(progressInterval);
progressFill.style.width = "100%";
progressFill.classList.add("progress-done");
challengeIcon.textContent = "✓";
challengeIcon.classList.add("challenge-icon-done");
statusText.textContent = "Verification complete. Redirecting...";
document.getElementById("altcha-payload").value = ev.detail.payload;
setTimeout(function () {
document.getElementById("challenge-form").submit();
}, 500);
} else if (ev.detail.state === "error") {
clearInterval(progressInterval);
challengeIcon.textContent = "✕";
challengeIcon.classList.add("challenge-icon-error");
statusText.textContent = "Verification failed. Please reload the page.";
progressFill.classList.add("progress-error");
}
});
});

View File

@@ -238,6 +238,78 @@ input:focus {
margin: 2px 2px 2px 0;
}
/* ── Challenge page ── */
.challenge-wrapper {
text-align: center;
padding: 8px 0 4px;
}
.challenge-icon-wrap {
margin-bottom: 16px;
}
.challenge-icon {
font-size: 44px;
line-height: 1;
display: inline-block;
transition: transform 300ms ease;
}
.challenge-icon-done {
color: #22c55e;
font-style: normal;
font-size: 40px;
font-weight: 700;
}
.challenge-icon-error {
color: var(--danger);
font-style: normal;
font-size: 40px;
font-weight: 700;
}
.challenge-error-text {
color: var(--danger);
}
.challenge-progress {
margin-top: 24px;
}
.altcha-wrapper {
position: absolute;
left: -9999px;
top: -9999px;
width: 0;
height: 0;
overflow: hidden;
}
.progress-bar {
width: 100%;
height: 5px;
background: var(--line);
border-radius: 99px;
overflow: hidden;
}
.progress-fill {
height: 100%;
width: 0%;
background: var(--accent);
border-radius: 99px;
transition: width 200ms ease, background 300ms ease;
}
.progress-done {
background: #22c55e !important;
}
.progress-error {
background: var(--danger) !important;
}
/* ── Dark mode toggle ── */
#dark-mode-toggle {
position: fixed;