Captcha improvements
This commit is contained in:
12
action.php
12
action.php
@@ -208,14 +208,16 @@ class action_plugin_botmon extends DokuWiki_Action_Plugin {
|
|||||||
|
|
||||||
private function checkCaptchaCookie() {
|
private function checkCaptchaCookie() {
|
||||||
|
|
||||||
$cookieVal = isset($_COOKIE['captcha']) ? $_COOKIE['captcha'] : null;
|
$cookieVal = isset($_COOKIE['DWConfirm']) ? $_COOKIE['DWConfirm'] : null;
|
||||||
|
|
||||||
$today = new DateTime();
|
$today = substr((new DateTime())->format('c'), 0, 10);
|
||||||
$isodate = substr((new DateTime())->format('c'), 0, 10);
|
|
||||||
|
|
||||||
$raw = $this->getConf('captchaSeed') . '|' . $_SERVER['SERVER_NAME'] . '|' . $_SERVER['REMOTE_ADDR'] . '|' . $isodate;
|
$raw = $this->getConf('captchaSeed') . '|' . $_SERVER['SERVER_NAME'] . '|' . $_SERVER['REMOTE_ADDR'] . '|' . $today;
|
||||||
|
$expected = hash('sha256', $raw);
|
||||||
|
|
||||||
return $cookieVal !== hash('sha256', $raw);
|
//echo '<ul><li>cookie: ' . $cookieVal . '</li><li>expected: ' . $expected . '</li><li>matches: ' .($cookieVal == $expected ? 'true' : 'false') . '</li></ul>';
|
||||||
|
|
||||||
|
return $cookieVal !== $expected;
|
||||||
}
|
}
|
||||||
|
|
||||||
private function insertCaptchaLoader() {
|
private function insertCaptchaLoader() {
|
||||||
|
|||||||
54
captcha.js
54
captcha.js
@@ -1,6 +1,6 @@
|
|||||||
"use strict";
|
"use strict";
|
||||||
/* DokuWiki BotMon Captcha JavaScript */
|
/* DokuWiki BotMon Captcha JavaScript */
|
||||||
/* 22.10.2025 - 0.1.0 - pre-release */
|
/* 23.10.2025 - 0.1.2 - pre-release */
|
||||||
/* Author: Sascha Leib <ad@hominem.info> */
|
/* Author: Sascha Leib <ad@hominem.info> */
|
||||||
|
|
||||||
const $BMCaptcha = {
|
const $BMCaptcha = {
|
||||||
@@ -20,20 +20,25 @@ const $BMCaptcha = {
|
|||||||
const dlg = document.createElement('dialog');
|
const dlg = document.createElement('dialog');
|
||||||
dlg.setAttribute('closedby', 'none');
|
dlg.setAttribute('closedby', 'none');
|
||||||
dlg.setAttribute('open', 'open');
|
dlg.setAttribute('open', 'open');
|
||||||
|
dlg.classList.add('checking');
|
||||||
dlg.id = 'botmon_captcha_box';
|
dlg.id = 'botmon_captcha_box';
|
||||||
dlg.innerHTML = '<h2>Captcha box</h2><p>Checking if you are a human …</p><p></p>';
|
dlg.innerHTML = '<h2>Captcha box</h2><p>Making sure you are a human:</p>';
|
||||||
|
|
||||||
// Checkbox:
|
// Checkbox:
|
||||||
const lbl = document.createElement('label');
|
const lbl = document.createElement('label');
|
||||||
|
lbl.innerHTML = '<span class="confirm">Click to confirm.</span><span class="busy"></span><span class="checking">Checking …</span><span class="loading">Loading …</span>';
|
||||||
const cb = document.createElement('input');
|
const cb = document.createElement('input');
|
||||||
cb.setAttribute('type', 'checkbox');
|
cb.setAttribute('type', 'checkbox');
|
||||||
|
cb.setAttribute('disabled', 'disabled');
|
||||||
cb.addEventListener('click', $BMCaptcha._cbCallback);
|
cb.addEventListener('click', $BMCaptcha._cbCallback);
|
||||||
lbl.appendChild(cb);
|
lbl.prepend(cb);
|
||||||
lbl.appendChild(document.createTextNode('I am a human.'));
|
|
||||||
|
|
||||||
dlg.appendChild(lbl);
|
dlg.appendChild(lbl);
|
||||||
|
|
||||||
bm_parent.appendChild(dlg);
|
bm_parent.appendChild(dlg);
|
||||||
|
|
||||||
|
// call the delayed callback in a couple of seconds:
|
||||||
|
setTimeout($BMCaptcha._delayedCallback, 1500);
|
||||||
},
|
},
|
||||||
|
|
||||||
/* creates a digest hash for the cookie function */
|
/* creates a digest hash for the cookie function */
|
||||||
@@ -147,19 +152,42 @@ const $BMCaptcha = {
|
|||||||
if (e.target.checked) {
|
if (e.target.checked) {
|
||||||
//document.getElementById('botmon_captcha_box').close();
|
//document.getElementById('botmon_captcha_box').close();
|
||||||
|
|
||||||
// make a hash for the cookie:
|
const dat = [ // the data to encode
|
||||||
const seed = document._botmon.seed || '';
|
document._botmon.seed || '',
|
||||||
const extIp = document._botmon.ip || '0.0.0.0';
|
location.hostname,
|
||||||
const d = new Date(document._botmon.t0);
|
document._botmon.ip || '0.0.0.0',
|
||||||
const raw = seed + '|' + location.hostname + '|' + extIp + '|' + d.toISOString().substring(0, 10);
|
(document._botmon.t0 ? new Date(document._botmon.t0) : new Date()).toISOString().substring(0, 10)
|
||||||
|
];
|
||||||
|
const hash = $BMCaptcha.digest.hash(dat.join('|'));
|
||||||
|
|
||||||
const hash = $BMCaptcha.digest.hash(raw);
|
// set the cookie:
|
||||||
console.log('Setting cookie to:', raw, ' --> ', hash);
|
document.cookie = "DWConfirm=" + hash + ';path=/;';
|
||||||
document.cookie = "captcha=" + hash + ';';
|
|
||||||
|
|
||||||
|
// change the interface:
|
||||||
|
const dlg = document.getElementById('botmon_captcha_box');
|
||||||
|
if (dlg) {
|
||||||
|
dlg.classList.remove('ready');
|
||||||
|
dlg.classList.add('loading');
|
||||||
|
}
|
||||||
|
|
||||||
|
// reload the page:
|
||||||
window.location.reload(true);
|
window.location.reload(true);
|
||||||
}
|
}
|
||||||
}
|
},
|
||||||
|
|
||||||
|
_delayedCallback: function() {
|
||||||
|
const dlg = document.getElementById('botmon_captcha_box');
|
||||||
|
if (dlg) {
|
||||||
|
dlg.classList.remove('checking');
|
||||||
|
dlg.classList.add('ready');
|
||||||
|
|
||||||
|
const input = dlg.getElementsByTagName('input')[0];
|
||||||
|
if (input) {
|
||||||
|
input.removeAttribute('disabled');
|
||||||
|
input.focus();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
}
|
}
|
||||||
// initialise the captcha module:
|
// initialise the captcha module:
|
||||||
|
|||||||
139
img/busy-light.svg
Normal file
139
img/busy-light.svg
Normal file
@@ -0,0 +1,139 @@
|
|||||||
|
<svg version="1.1" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 36 36">
|
||||||
|
<style>.box{fill:#00CADB;transform-origin: 50% 50%}
|
||||||
|
@keyframes box-1 {
|
||||||
|
9% {transform: translate(-12px,0)}
|
||||||
|
18% {transform: translate(0px,0)}
|
||||||
|
27% {transform: translate(0px,0)}
|
||||||
|
36% {transform: translate(12px,0)}
|
||||||
|
45% {transform: translate(12px,12px)}
|
||||||
|
55% {transform: translate(12px,12px)}
|
||||||
|
64% {transform: translate(12px,12px)}
|
||||||
|
73% {transform: translate(12px,0px)}
|
||||||
|
82% {transform: translate(0px,0px)}
|
||||||
|
91% {transform: translate(-12px,0px)}
|
||||||
|
100% {transform: translate(0px,0px)}
|
||||||
|
}
|
||||||
|
.box:nth-child(1){animation: box-1 4s infinite}
|
||||||
|
@keyframes box-2 {
|
||||||
|
9% {transform: translate(0,0)}
|
||||||
|
18% {transform: translate(12px,0)}
|
||||||
|
27% {transform: translate(0px,0)}
|
||||||
|
36% {transform: translate(12px,0)}
|
||||||
|
45% {transform: translate(12px,12px)}
|
||||||
|
55% {transform: translate(12px,12px)}
|
||||||
|
64% {transform: translate(12px,12px)}
|
||||||
|
73% {transform: translate(12px,12px)}
|
||||||
|
82% {transform: translate(0px,12px)}
|
||||||
|
91% {transform: translate(0px,12px)}
|
||||||
|
100% {transform: translate(0px,0px)}
|
||||||
|
}
|
||||||
|
.box:nth-child(2){animation: box-2 4s infinite}
|
||||||
|
@keyframes box-3 {
|
||||||
|
9% {transform: translate(-12px,0)}
|
||||||
|
18% {transform: translate(-12px,0)}
|
||||||
|
27% {transform: translate(0px,0)}
|
||||||
|
36% {transform: translate(-12px,0)}
|
||||||
|
45% {transform: translate(-12px,0)}
|
||||||
|
55% {transform: translate(-12px,0)}
|
||||||
|
64% {transform: translate(-12px,0)}
|
||||||
|
73% {transform: translate(-12px,0)}
|
||||||
|
82% {transform: translate(-12px,-12px)}
|
||||||
|
91% {transform: translate(0px,-12px)}
|
||||||
|
100% {transform: translate(0px,0px)}
|
||||||
|
}
|
||||||
|
.box:nth-child(3) {animation: box-3 4s infinite}
|
||||||
|
@keyframes box-4 {
|
||||||
|
9% {transform: translate(-12px,0)}
|
||||||
|
18% {transform: translate(-12px,0)}
|
||||||
|
27% {transform: translate(-12px,-12px)}
|
||||||
|
36% {transform: translate(0px,-12px)}
|
||||||
|
45% {transform: translate(0px,0px)}
|
||||||
|
55% {transform: translate(0px,-12px)}
|
||||||
|
64% {transform: translate(0px,-12px)}
|
||||||
|
73% {transform: translate(0px,-12px)}
|
||||||
|
82% {transform: translate(-12px,-12px)}
|
||||||
|
91% {transform: translate(-12px,0px)}
|
||||||
|
100% {transform: translate(0px,0px)}
|
||||||
|
}
|
||||||
|
.box:nth-child(4) {animation: box-4 4s infinite}
|
||||||
|
@keyframes box-5 {
|
||||||
|
9% {transform: translate(0,0)}
|
||||||
|
18% {transform: translate(0,0)}
|
||||||
|
27% {transform: translate(0,0)}
|
||||||
|
36% {transform: translate(12px,0)}
|
||||||
|
45% {transform: translate(12px,0)}
|
||||||
|
55% {transform: translate(12px,0)}
|
||||||
|
64% {transform: translate(12px,0)}
|
||||||
|
73% {transform: translate(12px,0)}
|
||||||
|
82% {transform: translate(12px,-12px)}
|
||||||
|
91% {transform: translate(0px,-12px)}
|
||||||
|
100% {transform: translate(0px,0px)}
|
||||||
|
}
|
||||||
|
.box:nth-child(5) {animation: box-5 4s infinite}
|
||||||
|
@keyframes box-6 {
|
||||||
|
9% {transform: translate(0,0)}
|
||||||
|
18% {transform: translate(-12px,0)}
|
||||||
|
27% {transform: translate(-12px,0)}
|
||||||
|
36% {transform: translate(0px,0)}
|
||||||
|
45% {transform: translate(0px,0)}
|
||||||
|
55% {transform: translate(0px,0)}
|
||||||
|
64% {transform: translate(0px,0)}
|
||||||
|
73% {transform: translate(0px,12px)}
|
||||||
|
82% {transform: translate(-12px,12px)}
|
||||||
|
91% {transform: translate(-12px,0px)}
|
||||||
|
100% {transform: translate(0px,0px)}
|
||||||
|
}
|
||||||
|
.box:nth-child(6) {animation: box-6 4s infinite}
|
||||||
|
@keyframes box-7 {
|
||||||
|
9% {transform: translate(12px,0)}
|
||||||
|
18% {transform: translate(12px,0)}
|
||||||
|
27% {transform: translate(12px,0)}
|
||||||
|
36% {transform: translate(0px,0)}
|
||||||
|
45% {transform: translate(0px,-12px)}
|
||||||
|
55% {transform: translate(12px,-12px)}
|
||||||
|
64% {transform: translate(0px,-12px)}
|
||||||
|
73% {transform: translate(0px,-12px)}
|
||||||
|
82% {transform: translate(0px,0px)}
|
||||||
|
91% {transform: translate(12px,0px)}
|
||||||
|
100% {transform: translate(0px,0px)}
|
||||||
|
}
|
||||||
|
.box:nth-child(7) {animation: box-7 4s infinite}
|
||||||
|
@keyframes box-8 {
|
||||||
|
9% {transform: translate(0,0)}
|
||||||
|
18% {transform: translate(-12px,0)}
|
||||||
|
27% {transform: translate(-12px,-12px)}
|
||||||
|
36% {transform: translate(0px,-12px)}
|
||||||
|
45% {transform: translate(0px,-12px)}
|
||||||
|
55% {transform: translate(0px,-12px)}
|
||||||
|
64% {transform: translate(0px,-12px)}
|
||||||
|
73% {transform: translate(0px,-12px)}
|
||||||
|
82% {transform: translate(12px,-12px)}
|
||||||
|
91% {transform: translate(12px,0px)}
|
||||||
|
100% {transform: translate(0px,0px)}
|
||||||
|
}
|
||||||
|
.box:nth-child(8){animation: box-8 4s infinite}
|
||||||
|
@keyframes box-9{
|
||||||
|
9% {transform: translate(-12px,0)}
|
||||||
|
18% {transform: translate(-12px,0)}
|
||||||
|
27% {transform: translate(0px,0)}
|
||||||
|
36% {transform: translate(-12px,0)}
|
||||||
|
45% {transform: translate(0px,0)}
|
||||||
|
55% {transform: translate(0px,0)}
|
||||||
|
64% {transform: translate(-12px,0)}
|
||||||
|
73% {transform: translate(-12px,0)}
|
||||||
|
82% {transform: translate(-24px,0)}
|
||||||
|
91% {transform: translate(-12px,0)}
|
||||||
|
100% {transform: translate(0px,0)}
|
||||||
|
}
|
||||||
|
.box:nth-child(9) {animation: box-9 4s infinite}
|
||||||
|
</style>
|
||||||
|
<g><rect class="box" x="13" y="1" rx="1" width="10" height="10"/>
|
||||||
|
<rect class="box" x="13" y="1" rx="1" width="10" height="10"/>
|
||||||
|
<rect class="box" x="25" y="25" rx="1" width="10" height="10"/>
|
||||||
|
<rect class="box" x="13" y="13" rx="1" width="10" height="10"/>
|
||||||
|
<rect class="box" x="13" y="13" rx="1" width="10" height="10"/>
|
||||||
|
<rect class="box" x="25" y="13" rx="1" width="10" height="10"/>
|
||||||
|
<rect class="box" x="1" y="25" rx="1" width="10" height="10"/>
|
||||||
|
<rect class="box" x="13" y="25" rx="1" width="10" height="10"/>
|
||||||
|
<rect class="box" x="25" y="25" rx="1" width="10" height="10"/></g>
|
||||||
|
</svg>
|
||||||
|
After Width: | Height: | Size: 4.9 KiB |
@@ -520,7 +520,6 @@ road 8
|
|||||||
late 8
|
late 8
|
||||||
stand 8
|
stand 8
|
||||||
suppose 8
|
suppose 8
|
||||||
la 8
|
|
||||||
daughter 8
|
daughter 8
|
||||||
real 8
|
real 8
|
||||||
nearly 8
|
nearly 8
|
||||||
@@ -1955,7 +1954,6 @@ ends 2
|
|||||||
shop 2
|
shop 2
|
||||||
stairs 2
|
stairs 2
|
||||||
pardon 2
|
pardon 2
|
||||||
gay 2
|
|
||||||
beg 2
|
beg 2
|
||||||
seldom 2
|
seldom 2
|
||||||
kinds 2
|
kinds 2
|
||||||
|
|||||||
104
style.less
104
style.less
@@ -11,15 +11,95 @@ body.botmon_captcha {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
#botmon_captcha_box {
|
#botmon_captcha_box {
|
||||||
border: red dotted 2pt;
|
& {
|
||||||
position: fixed;
|
position: fixed;
|
||||||
width: 400px;
|
width: 400px;
|
||||||
height: 400px;
|
height: 220px;
|
||||||
top: ~"calc(50vh - 200px)";
|
top: ~"calc(50vh - 110px)";
|
||||||
left: ~"calc(50vw - 200px)";
|
left: ~"calc(50vw - 200px)";
|
||||||
border-radius: .5rem;
|
background: #1C1B22 none;
|
||||||
margin: 0; padding: .5rem;
|
border: #7C7B82 solid 1pt;
|
||||||
|
border-radius: 12px;
|
||||||
|
margin: 0; padding: 18px;
|
||||||
|
font-family: system-ui, sans-serif;
|
||||||
|
box-shadow: .25rem .25rem .5rem rgba(0,0,0,.5);
|
||||||
|
box-sizing: border-box;
|
||||||
}
|
}
|
||||||
|
& * {
|
||||||
|
color: #EDEDF5;
|
||||||
|
margin: 0;
|
||||||
|
}
|
||||||
|
h2 {
|
||||||
|
font-size: 24px;
|
||||||
|
line-height: 32px;
|
||||||
|
padding: 0 0 12px 0;
|
||||||
|
}
|
||||||
|
p {
|
||||||
|
font-size: 16px;
|
||||||
|
line-height: 20px;
|
||||||
|
padding: 6px 0;
|
||||||
|
}
|
||||||
|
label {
|
||||||
|
& {
|
||||||
|
display: grid;
|
||||||
|
grid-template-columns: 32px auto;
|
||||||
|
column-gap: 8px;
|
||||||
|
align-items: center;
|
||||||
|
padding: 24px;
|
||||||
|
margin: 16px 0 0 0;
|
||||||
|
background-color: #32313A;
|
||||||
|
border: #7C7B82 solid 1px;
|
||||||
|
border-radius: 3px;
|
||||||
|
font-size: 16px;
|
||||||
|
}
|
||||||
|
span.busy {
|
||||||
|
display: inline-block;
|
||||||
|
width: 24px; height: 24px;
|
||||||
|
background: transparent url('img/busy-light.svg') center no-repeat;
|
||||||
|
background-size: 24px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
input[type="checkbox"] {
|
||||||
|
width: 24px; height: 24px;
|
||||||
|
border: 2px solid #00CADB;
|
||||||
|
border-radius: 4px;
|
||||||
|
appearance: none;
|
||||||
|
}
|
||||||
|
input[type="checkbox"]:focus {
|
||||||
|
outline: none;
|
||||||
|
box-shadow: 0 0 6px rgba(0, 202, 219, .8);
|
||||||
|
}
|
||||||
|
|
||||||
|
input[type="checkbox"]:disabled {
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
&.checking {
|
||||||
|
input[type="checkbox"], span.confirm, span.loading { display: none;}
|
||||||
|
span.busy, span.checking { display: initial; }
|
||||||
|
label, input[type="checkbox"] { cursor: none; }
|
||||||
|
}
|
||||||
|
&.ready {
|
||||||
|
input[type="checkbox"], span.confirm { display: initial;}
|
||||||
|
span.busy, span.checking, span.loading { display: none; }
|
||||||
|
label, input[type="checkbox"] { cursor: pointer; }
|
||||||
|
}
|
||||||
|
&.loading {
|
||||||
|
span.busy, span.loading { display: initial; }
|
||||||
|
input[type="checkbox"], span.confirm, span.checking { display: none;}
|
||||||
|
label { cursor: busy; }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// smaller screens:
|
||||||
|
@media (max-width: 480px) {
|
||||||
|
body.botmon_captcha #botmon_captcha_box {
|
||||||
|
width: 100vw;
|
||||||
|
height: auto;
|
||||||
|
left: 0; top: 80px;
|
||||||
|
border-radius: 2px;
|
||||||
|
z-index: 10001;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* dark mode overrides */
|
/* dark mode overrides */
|
||||||
@@ -33,5 +113,19 @@ body.botmon_captcha {
|
|||||||
text-shadow: 0 0 .35em rgba(170,170,170,.75);
|
text-shadow: 0 0 .35em rgba(170,170,170,.75);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
#botmon_captcha_box {
|
||||||
|
& {
|
||||||
|
background-color: #FFF;
|
||||||
|
border-color: #9F9EA1;
|
||||||
|
box-shadow: .25rem .25rem .5rem rgba(0,0,0,.25);
|
||||||
|
}
|
||||||
|
& * {
|
||||||
|
color: #15141A;
|
||||||
|
}
|
||||||
|
label {
|
||||||
|
background-color: #EEE;
|
||||||
|
border-color: #9F9EA1;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Reference in New Issue
Block a user