VerifiCapcha / index.html
tuhbooh's picture
Update index.html
651d2da verified
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Micro Verify Widget - Auto Retry</title>
<style>
@import url('https://fonts.googleapis.com/css2?family=Inter:wght@400;500&family=JetBrains+Mono&display=swap');
:root {
--bg: #18181b;
--border: #27272a;
--primary: #3b82f6;
--text: #f4f4f5;
--muted: #71717a;
--success: #10b981;
}
body {
margin: 0; padding: 0; background: transparent;
font-family: 'Inter', sans-serif;
display: flex; justify-content: center; align-items: center;
height: 100vh; overflow: hidden;
}
.widget {
width: 320px; height: 70px;
background: var(--bg);
border: 1px solid var(--border);
border-radius: 12px;
display: flex; align-items: center;
padding: 0 16px; box-sizing: border-box;
transition: all 0.3s cubic-bezier(0.4, 0, 0.2, 1);
box-shadow: 0 4px 6px -1px rgba(0, 0, 0, 0.1);
}
.widget:hover { border-color: var(--primary); }
.check-area {
width: 32px; height: 32px;
display: flex; justify-content: center; align-items: center;
margin-right: 12px; cursor: pointer;
}
.spinner {
width: 20px; height: 20px;
border: 2px solid rgba(59, 130, 246, 0.2);
border-top-color: var(--primary);
border-radius: 50%;
display: none;
animation: spin 0.8s linear infinite;
}
.checkbox-dummy {
width: 20px; height: 20px;
border: 2px solid var(--muted);
border-radius: 6px;
transition: all 0.2s;
}
.content {
flex-grow: 1; display: flex;
flex-direction: column; justify-content: center;
overflow: hidden;
}
.title { font-size: 13px; font-weight: 500; color: var(--text); margin: 0; }
.email-display {
font-family: 'JetBrains Mono', monospace;
font-size: 11px; color: var(--primary);
cursor: pointer; margin-top: 2px;
white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}
.brand { display: flex; flex-direction: column; align-items: flex-end; opacity: 0.3; }
.brand svg { width: 18px; fill: var(--muted); }
.brand-text { font-size: 7px; color: var(--muted); text-transform: uppercase; margin-top: 2px; }
@keyframes spin { to { transform: rotate(360deg); } }
/* Verified State */
.verified { border-color: var(--success) !important; }
.verified .checkbox-dummy {
background: var(--success);
border-color: var(--success);
display: flex; justify-content: center; align-items: center;
}
.verified .checkbox-dummy::after {
content: ''; width: 4px; height: 8px;
border: solid white; border-width: 0 2px 2px 0;
transform: rotate(45deg); margin-bottom: 2px;
}
.verified .title { color: var(--success); }
.verified .email-display { color: var(--muted); cursor: default; }
/* Loading/Polling State */
.loading .spinner { display: block; }
.loading .checkbox-dummy { display: none; }
.loading .title { color: var(--primary); }
</style>
</head>
<body>
<div class="widget" id="widget">
<div class="check-area" onclick="handleVerify()">
<div class="checkbox-dummy"></div>
<div class="spinner"></div>
</div>
<div class="content">
<div class="title" id="status-text">Click email to send verify</div>
<div class="email-display" id="email-val" onclick="openGmail()" title="Click to copy & open Gmail">Generating...</div>
</div>
<div class="brand">
<svg viewBox="0 0 24 24"><path d="M12 1L3 5v6c0 5.55 3.84 10.74 9 12 5.16-1.26 9-6.45 9-12V5l-9-4z"/></svg>
<div class="brand-text">Verified AI</div>
</div>
</div>
<script>
let token = "";
let checkInterval = null;
async function init() {
const emailEl = document.getElementById('email-val');
try {
// 1. Lấy Domain khả dụng
const domainRes = await fetch('https://api.mail.tm/domains');
const domainData = await domainRes.json();
const domain = domainData['hydra:member'][0].domain;
// 2. Tạo Account ngẫu nhiên
const user = Math.random().toString(36).substring(2, 10);
const address = `${user}@${domain}`;
const password = "pass_" + user;
await fetch('https://api.mail.tm/accounts', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({ address, password })
});
// 3. Lấy Token để truy cập hòm thư
const tokenRes = await fetch('https://api.mail.tm/token', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({ address, password })
});
const tokenData = await tokenRes.json();
token = tokenData.token;
emailEl.innerText = address;
} catch (e) {
emailEl.innerText = "Connection Error";
console.error("Init failed:", e);
}
}
function openGmail() {
const addr = document.getElementById('email-val').innerText;
if (addr.includes('@')) {
// Copy vào clipboard
navigator.clipboard.writeText(addr);
// Mở Gmail compose
const gmailUrl = `https://mail.google.com/mail/?view=cm&fs=1&to=${addr}&su=Verify%20Me&body=Just%20click%20send%20to%20verify%20your%20account.`;
window.open(gmailUrl, '_blank');
// Tự động kích hoạt polling ngay khi user bấm mở mail
handleVerify();
}
}
async function checkMail() {
if (!token) return;
try {
const res = await fetch('https://api.mail.tm/messages', {
headers: { 'Authorization': `Bearer ${token}` }
});
const data = await res.json();
// Nếu tìm thấy ít nhất 1 email trong hòm thư
if (data['hydra:member'] && data['hydra:member'].length > 0) {
stopPolling();
markAsVerified();
}
} catch (e) {
console.error("Polling error:", e);
}
}
function handleVerify() {
const widget = document.getElementById('widget');
// Chống click trùng lặp hoặc khi đã xong
if (widget.classList.contains('verified') || checkInterval || !token) return;
widget.classList.add('loading');
document.getElementById('status-text').innerText = "Waiting for email...";
// Bắt đầu quét mỗi 3 giây
checkInterval = setInterval(checkMail, 3000);
checkMail(); // Chạy phát đầu tiên luôn
}
function stopPolling() {
if (checkInterval) {
clearInterval(checkInterval);
checkInterval = null;
}
}
function markAsVerified() {
const widget = document.getElementById('widget');
widget.classList.remove('loading');
widget.classList.add('verified');
document.getElementById('status-text').innerText = "Identity Verified";
// Gửi tín hiệu ra cho trang web cha nếu dùng <iframe>
window.parent.postMessage("verified", "*");
}
window.onload = init;
</script>
</body>
</html>