1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
|
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>4gCAPTCHA</title>
<style>
body { font-family: sans-serif; display: flex; flex-direction: column; align-items: center; margin-top: 50px; background: #f4f4f4;}
#captcha-container { position: relative; width: 400px; height: 427px; border: 1px solid #ccc; margin-bottom: 20px; background: #fff; box-shadow: 0 4px 6px rgba(0,0,0,0.1); }
#captcha-image { width: 100%; height: 100%; pointer-events: none; }
#grid { position: absolute; top: 27px; left: 0; width: 400px; height: 400px; display: grid; grid-template-columns: repeat(4, 100px); grid-template-rows: repeat(4, 100px); }
.cell { width: 100px; height: 100px; box-sizing: border-box; cursor: pointer; border: 2px solid transparent; transition: all 0.1s; }
.cell:hover { border: 2px solid rgba(255, 255, 255, 0.5); }
.cell.selected { border: 3px solid #00ff00; background: rgba(0, 255, 0, 0.25); }
#controls { display: flex; gap: 10px; }
button { padding: 10px 20px; cursor: pointer; font-size: 16px; border: none; border-radius: 4px; background: #007bff; color: white; }
button:hover { background: #0056b3; }
#result { margin-top: 20px; font-weight: bold; font-size: 18px; }
p { max-width: 600px; text-align: center; line-height: 1.5; color: #444; margin-bottom: 25px; }
a { color: #007bff; text-decoration: none; }
a:hover { text-decoration: underline; }
</style>
</head>
<body>
<h2>4gCAPTCHA</h2>
<p>4gcaptcha is a captcha server based on the one used in <a href="https://git.lolcat.ca/lolcat/4get">4get</a><br/>
The module below demonstrates what a captcha could look like.
<br/>Please refer to the <a href="https://git.moekyun.me/4captcha/about">README on the repo for more info</a>
</p>
<div id="captcha-container">
<img id="captcha-image" src="" alt="Loading captcha..." />
<div id="grid"></div>
</div>
<div id="controls">
<button onclick="loadCaptcha()" style="background: #6c757d;">Reload</button>
<button onclick="verifyCaptcha()">Verify</button>
</div>
<div id="result"></div>
<script>
let currentToken = '';
let selectedCells = new Set();
const grid = document.getElementById('grid');
for (let i = 0; i < 16; i++) {
const cell = document.createElement('div');
cell.className = 'cell';
cell.dataset.index = i;
cell.onclick = () => toggleCell(cell, i);
grid.appendChild(cell);
}
function toggleCell(cell, index) {
if (selectedCells.has(index)) {
selectedCells.delete(index);
cell.classList.remove('selected');
} else {
selectedCells.add(index);
cell.classList.add('selected');
}
}
async function loadCaptcha() {
selectedCells.clear();
document.querySelectorAll('.cell').forEach(c => c.classList.remove('selected'));
document.getElementById('result').innerText = 'Loading...';
document.getElementById('result').style.color = '#333';
try {
const res = await fetch('/generate');
const data = await res.json();
if (data.error) throw new Error(data.error);
currentToken = data.token;
document.getElementById('captcha-image').src = data.image;
document.getElementById('result').innerText = '';
} catch (err) {
document.getElementById('result').innerText = 'Error: ' + err.message;
document.getElementById('result').style.color = 'red';
}
}
async function verifyCaptcha() {
if (!currentToken) return;
try {
const res = await fetch('/verify', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({ token: currentToken, answers: Array.from(selectedCells) })
});
const data = await res.json();
if (data.success) {
document.getElementById('result').style.color = 'green';
document.getElementById('result').innerText = 'Success! You passed the captcha.';
} else {
document.getElementById('result').style.color = 'red';
document.getElementById('result').innerText = 'Failed: ' + (data.error || 'Incorrect answers') + '. Reloading...';
setTimeout(loadCaptcha, 1500);
}
} catch (err) {
document.getElementById('result').innerText = 'Error: ' + err.message;
document.getElementById('result').style.color = 'red';
}
}
loadCaptcha();
</script>
</body>
</html>
|