1 2<!DOCTYPE html> 3<html lang="ru"> 4<head> 5 <meta charset="UTF-8"> 6 <meta name="viewport" content="width=device-width, initial-scale=1.0"> 7 <title>Overwall â ÐезопаÑнÑй инÑеÑÐ½ÐµÑ Ð±ÐµÐ· ÑекламÑ</title> 8 <style> 9 * { 10 margin: 0; 11 padding: 0; 12 box-sizing: border-box; 13 } 14 15 body { 16 font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif; 17 background: linear-gradient(135deg, #667eea 0%, #764ba2 100%); 18 min-height: 100vh; 19 display: flex; 20 align-items: center; 21 justify-content: center; 22 padding: 20px; 23 } 24 25 .auth-container { 26 max-width: 600px; 27 width: 100%; 28 background: white; 29 border-radius: 20px; 30 box-shadow: 0 20px 60px rgba(0,0,0,0.3); 31 padding: 50px 40px; 32 text-align: center; 33 position: relative; 34 overflow: hidden; 35 } 36 37 .auth-container::before { 38 content: ''; 39 position: absolute; 40 top: 0; 41 left: 0; 42 right: 0; 43 height: 5px; 44 background: linear-gradient(90deg, #667eea, #764ba2, #667eea); 45 } 46 47 .logo { 48 font-size: 4em; 49 margin-bottom: 20px; 50 background: linear-gradient(135deg, #667eea, #764ba2); 51 -webkit-background-clip: text; 52 -webkit-text-fill-color: transparent; 53 background-clip: text; 54 } 55 56 .main-title { 57 font-size: 2.5em; 58 font-weight: bold; 59 color: #333; 60 margin-bottom: 15px; 61 background: linear-gradient(135deg, #667eea, #764ba2); 62 -webkit-background-clip: text; 63 -webkit-text-fill-color: transparent; 64 background-clip: text; 65 } 66 67 .subtitle { 68 font-size: 1.3em; 69 color: #666; 70 margin-bottom: 40px; 71 line-height: 1.4; 72 } 73 74 .features { 75 margin: 40px 0; 76 text-align: left; 77 } 78 79 .feature { 80 display: flex; 81 align-items: center; 82 margin: 20px 0; 83 padding: 15px; 84 background: #f8f9fa; 85 border-radius: 10px; 86 border-left: 4px solid #667eea; 87 } 88 89 .feature-icon { 90 font-size: 2em; 91 margin-right: 15px; 92 min-width: 50px; 93 } 94 95 .feature-text { 96 flex: 1; 97 } 98 99 .feature-title { 100 font-weight: bold; 101 color: #333; 102 margin-bottom: 5px; 103 } 104 105 .feature-desc { 106 color: #666; 107 font-size: 0.9em; 108 } 109 110 .auth-section { 111 margin: 50px 0 30px 0; 112 padding: 30px; 113 background: linear-gradient(135deg, #f093fb 0%, #f5576c 100%); 114 border-radius: 15px; 115 color: white; 116 } 117 118 .auth-title { 119 font-size: 1.5em; 120 font-weight: bold; 121 margin-bottom: 15px; 122 } 123 124 .auth-description { 125 font-size: 1.1em; 126 margin-bottom: 30px; 127 opacity: 0.9; 128 } 129 130 .telegram-auth-container { 131 display: flex; 132 justify-content: center; 133 margin: 20px 0; 134 } 135 136 .loading { 137 display: none; 138 margin-top: 20px; 139 color: #667eea; 140 font-weight: bold; 141 } 142 143 .spinner { 144 display: inline-block; 145 width: 20px; 146 height: 20px; 147 border: 3px solid #f3f3f3; 148 border-top: 3px solid #667eea; 149 border-radius: 50%; 150 animation: spin 1s linear infinite; 151 margin-right: 10px; 152 } 153 154 @keyframes spin { 155 0% { transform: rotate(0deg); } 156 100% { transform: rotate(360deg); } 157 } 158 159 .help-text { 160 margin-top: 30px; 161 padding: 20px; 162 background: #e3f2fd; 163 border-radius: 10px; 164 color: #1565c0; 165 font-size: 0.95em; 166 line-height: 1.5; 167 } 168 169 @media (max-width: 768px) { 170 .auth-container { 171 margin: 10px; 172 padding: 30px 20px; 173 } 174 175 .main-title { 176 font-size: 2em; 177 } 178 179 .subtitle { 180 font-size: 1.1em; 181 } 182 183 .feature { 184 flex-direction: column; 185 text-align: center; 186 } 187 188 .feature-icon { 189 margin: 0 0 10px 0; 190 } 191 } 192 </style> 193</head> 194<body> 195 <div class="auth-container"> 196 <div class="logo">ð¡ï¸</div> 197 <h1 class="main-title">Overwall</h1> 198 <p class="subtitle">ÐезопаÑнÑй инÑеÑÐ½ÐµÑ Ð±ÐµÐ· ÑÐµÐºÐ»Ð°Ð¼Ñ Ð¸ огÑаниÑений</p> 199 200 <div class="features"> 201 <div class="feature"> 202 <div class="feature-icon">ð</div> 203 <div class="feature-text"> 204 <div class="feature-title">ÐÑÑÐ¾ÐºÐ°Ñ ÑкоÑоÑÑÑ</div> 205 <div class="feature-desc">ÐоÑÑÑп к заблокиÑованнÑм ÑайÑам на макÑималÑной ÑкоÑоÑÑи</div> 206 </div> 207 </div> 208 209 <div class="feature"> 210 <div class="feature-icon">ðº</div> 211 <div class="feature-text"> 212 <div class="feature-title">YouTube без ÑоÑмозов</div> 213 <div class="feature-desc">ÐаÑлаждайÑеÑÑ ÐºÐ¾Ð½ÑенÑом без надоедливой ÑекламÑ</div> 214 </div> 215 </div> 216 217 <div class="feature"> 218 <div class="feature-icon">ð¡ï¸</div> 219 <div class="feature-text"> 220 <div class="feature-title">ÐÐ¾Ð»Ð½Ð°Ñ Ð±ÐµÐ·Ð¾Ð¿Ð°ÑноÑÑÑ</div> 221 <div class="feature-desc">
221ШиÑÑование ÑÑаÑика и заÑиÑа лиÑнÑÑ Ð´Ð°Ð½Ð½ÑÑ </div> 222 </div> 223 </div> 224 </div> 225 226 <div class="auth-section"> 227 <div class="auth-title">ð ÐойÑи в лиÑнÑй кабинеÑ</div> 228 <div class="auth-description"> 229 ÐведиÑе Ð²Ð°Ñ email â Ð¼Ñ Ð¿ÑиÑлÑм ÑÑÑÐ»ÐºÑ Ð´Ð»Ñ Ð²Ñ Ð¾Ð´Ð° 230 </div> 231 232 <form id="email-login-form" style="max-width:360px;margin:0 auto;text-align:left"> 233 <input type="email" id="email-input" required placeholder="[email protected]" 234 style="width:100%;padding:14px 18px;border:2px solid #e0e0e0;border-radius:10px;font-size:16px;margin-bottom:12px;box-sizing:border-box"> 235 <button type="submit" id="email-submit-btn" 236 style="width:100%;padding:16px;background:linear-gradient(135deg,#667eea,#764ba2);color:#fff;border:none;border-radius:10px;font-size:16px;font-weight:600;cursor:pointer"> 237 ð¬ ÐолÑÑиÑÑ ÑÑÑÐ»ÐºÑ Ð½Ð° Ð²Ñ Ð¾Ð´ 238 </button> 239 </form> 240 <div id="email-status" style="margin-top:16px;text-align:center;font-size:14px"></div> 241 242 <div style="margin:28px 0 16px;text-align:center;color:#aaa;font-size:13px;position:relative"> 243 <span style="background:#fff;padding:0 16px;position:relative;z-index:1">или войÑи ÑеÑез</span> 244 <div style="position:absolute;top:50%;left:0;right:0;height:1px;background:#eee"></div> 245 </div> 246 247 <div class="telegram-auth-container" style="text-align:center"> 248
248<script async src="https://telegram.org/js/telegram-widget.js?22" 249 data-telegram-login="overwall_bot" 250 data-size="medium" 251 data-onauth="onTelegramAuth(user)" 252 data-request-access="write"></script>
252 253 </div> 254 255 <div class="loading" id="loading"> 256 <div class="spinner"></div> 257 ÐÑполнÑеÑÑÑ Ð°Ð²ÑоÑизаÑиÑ... 258 </div> 259 </div> 260 261 <div class="help-text"> 262 <p style="margin-bottom:16px"><a href="/faq" style="color:#51439a;font-weight:600">ÐÑвеÑÑ Ð½Ð° вопÑоÑÑ â помоÑÑ Ñ Ð¿Ð¾Ð´ÐºÐ»ÑÑением</a></p> 263 <strong>ð¡ Ðак ÑÑо ÑабоÑаеÑ:</strong><br/> 264 1. ÐведиÑе email â на поÑÑÑ Ð¿ÑидÑÑ ÑÑÑлка Ð´Ð»Ñ Ð²Ñ Ð¾Ð´Ð°<br/> 265 2. ÐликниÑе по ÑÑÑлке â ÑÑÐ°Ð·Ñ Ð¿Ð¾Ð¿Ð°Ð´ÑÑе в кабинеÑ<br/> 266 3. ÐÑли Ñ Ð²Ð°Ñ Telegram-аккаÑÐ½Ñ â можно войÑи одним кликом ÑезеÑвнÑм ÑпоÑобом 267 </div> 268 </div> 269 270
270<script type="text/javascript"> 271 function onTelegramAuth(user) { 272 document.getElementById('loading').style.display = 'block'; 273 274 fetch('/auth/telegram/callback', { 275 method: 'POST', 276 headers: { 'Content-Type': 'application/json' }, 277 body: JSON.stringify(user) 278 }) 279 .then(response => response.json()) 280 .then(data => { 281 if (data.success) { 282 document.getElementById('loading').innerHTML = 283 '<div style="color: #4CAF50; font-weight: bold;">â ÐвÑоÑизаÑÐ¸Ñ ÑÑпеÑна! ÐеÑенапÑавление...</div>'; 284 setTimeout(() => { window.location.reload(); }, 1000); 285 } else { 286 document.getElementById('loading').style.display = 'none'; 287 alert('â ÐÑибка авÑоÑизаÑии. ÐопÑобÑйÑе еÑе Ñаз.'); 288 } 289 }) 290 .catch(error => { 291 console.error('ÐÑибка пÑи авÑоÑизаÑии:', error); 292 document.getElementById('loading').style.display = 'none'; 293 alert('â ÐÑоизоÑла оÑибка. ÐопÑобÑйÑе еÑе Ñаз.'); 294 }); 295 } 296 297 // ФоÑма Ð²Ñ Ð¾Ð´Ð° по email 298 // ÐзвеÑÑнÑе поÑÑовÑе Ð´Ð¾Ð¼ÐµÐ½Ñ â URL веб-инÑеÑÑейÑа и кÑаÑивое имÑ. 299 // ÐÐ»Ñ Ð¾ÑÑалÑнÑÑ Ð¾ÑкÑÑваем коÑневой домен (https://{domain}). 300 var MAIL_PROVIDERS = { 301 'gmail.com': { url: 'https://mail.google.com/', name: 'Gmail' }, 302 'googlemail.com': { url: 'https://mail.google.com/', name: 'Gmail' }, 303 'yandex.ru': { url: 'https://mail.yandex.ru/', name: 'ЯндекÑ.ÐоÑÑа' }, 304 'yandex.com': { url: 'https://mail.yandex.com/', name: 'ЯндекÑ.ÐоÑÑа' }, 305 'yandex.by': { url: 'https://mail.yandex.by/', name: 'ЯндекÑ.ÐоÑÑа' }, 306 'yandex.kz': { url: 'https://mail.yandex.kz/', name: 'ЯндекÑ.ÐоÑÑа' }, 307 'ya.ru': { url: 'https://mail.yandex.ru/', name: 'ЯндекÑ.ÐоÑÑа' }, 308 'mail.ru': { url: 'https://e.mail.ru/', name: 'Mail.ru' }, 309 'inbox.ru': { url: 'https://e.mail.ru/', name: 'Mail.ru' }, 310 'list.ru': { url: 'https://e.mail.ru/', name: 'Mail.ru' }, 311 'bk.ru': { url: 'https://e.mail.ru/', name: 'Mail.ru' }, 312 'internet.ru': { url: 'https://e.mail.ru/', name: 'Mail.ru' }, 313 'rambler.ru': { url: 'https://mail.rambler.ru/', name: 'Rambler' }, 314 'outlook.com': { url: 'https://outlook.live.com/mail/', name: 'Outlook' }, 315 'hotmail.com': { url: 'https://outlook.live.com/mail/', name: 'Outlook' }, 316 'live.com': { url: 'https://outlook.live.com/mail/', name: 'Outlook' }, 317 'icloud.com': { url: 'https://www.icloud.com/mail', name: 'iCloud' }, 318 'me.com': { url: 'https://www.icloud.com/mail', name: 'iCloud' }, 319 'proton.me': { url: 'https://mail.proton.me/', name: 'Proton Mail' }, 320 'protonmail.com': { url: 'https://mail.proton.me/', name: 'Proton Mail' }, 321 }; 322 323 function getMailProvider(email) { 324 var at = email.lastIndexOf('@'); 325 if (at < 0) return null; 326 var domain = email.slice(at + 1).toLowerCase(); 327 if (MAIL_PROVIDERS[domain]) return MAIL_PROVIDERS[domain]; 328 // Fallback â коÑневой домен 329 return { url: 'https://' + domain, name: domain }; 330 } 331 332 document.getElementById('email-login-form').addEventListener('submit', function(ev) { 333 ev.preventDefault(); 334 var email = document.getElementById('email-input').value.trim(); 335 var statusEl = document.getElementById('email-status'); 336 var btn = document.getElementById('email-submit-btn'); 337 var input = document.getElementById('email-input'); 338 if (!email) return; 339 340 btn.disabled = true; 341 btn.textContent = 'ÐÑпÑавка...'; 342 statusEl.textContent = ''; 343 statusEl.style.color = '#555'; 344 345 fetch('/auth/email/request', { 346 method: 'POST', 347 headers: { 'Content-Type': 'application/json' }, 348 body: JSON.stringify({ email: email }) 349 }) 350 .then(function(r) { return r.json().then(function(d) { return { status: r.status, data: d }; }); }) 351 .then(function(res) { 352 if (res.data.success) { 353 // ÐлокиÑÑем повÑоÑнÑÑ Ð¾ÑпÑÐ°Ð²ÐºÑ â пÑоÑÑÐ°Ñ Ð·Ð°ÑиÑа Ð¾Ñ Ñпама. 354 // РазблокиÑÑеÑÑÑ ÑолÑко по F5 ÑÑÑаниÑÑ. 355 btn.disabled = true; 356 btn.textContent = 'â ÐиÑÑмо оÑпÑавлено'; 357 btn.style.background = '#4CAF50'; 358 btn.style.cursor = 'default'; 359 input.disabled = true; 360 361 statusEl.style.color = '#4CAF50'; 362 var provider = getMailProvider(email); 363 var openBtn = provider 364 ? '<a href="' + provider.url + '" target="_blank" rel="noopener"' + 365 ' style="display:inline-block;margin-top:14px;padding:12px 24px;background:linear-gradient(135deg,#667eea,#764ba2);color:#fff;text-decoration:none;border-radius:10px;font-weight:600;font-size:15px">' + 366 'ð¬ ÐÑкÑÑÑÑ ' + provider.name + '</a>' 367 : ''; 368 statusEl.innerHTML = 369 '<div>â ÐиÑÑмо Ñо ÑÑÑлкой Ð´Ð»Ñ Ð²Ñ Ð¾Ð´Ð° оÑпÑавлено на<br><strong>' + email + '</strong></div>' + 370 '<div style="color:#888;font-size:13px;margin-top:8px">ÐÑли пиÑÑма Ð½ÐµÑ â пÑовеÑÑÑе Ð¿Ð°Ð¿ÐºÑ Â«Ð¡Ð¿Ð°Ð¼Â».</div>' + 371 openBtn; 372 } else if (res.status === 429) { 373 // Rate limit â извлекаем ÑекÑÐ½Ð´Ñ Ð¸ запÑÑкаем countdown Ñ Ð¾Ð±Ð½Ð¾Ð²Ð»ÐµÐ½Ð¸ÐµÐ¼ кнопки 374 var m = (res.data.message || '').match(/(\d+)\s*Ñек/
374); 375 var seconds = m ? parseInt(m[1], 10) : 60; 376 var baseMsg = (res.data.message || '').replace(/\s*ÐовÑоÑиÑе ÑеÑез \d+\s*Ñек\.?/, ''); 377 btn.disabled = true; 378 btn.style.opacity = '0.6'; 379 btn.style.cursor = 'not-allowed'; 380 var remaining = seconds; 381 function tick() { 382 btn.textContent = 'â± ÐодождиÑе ' + remaining + ' Ñек'; 383 statusEl.style.color = '#e53935'; 384 statusEl.textContent = 'â ' + baseMsg + ' ÐовÑоÑиÑе ÑеÑез ' + remaining + ' Ñек.'; 385 if (remaining <= 0) { 386 clearInterval(intervalId); 387 btn.disabled = false; 388 btn.style.opacity = ''; 389 btn.style.cursor = ''; 390 btn.textContent = 'ð¬ ÐолÑÑиÑÑ ÑÑÑÐ»ÐºÑ Ð½Ð° Ð²Ñ Ð¾Ð´'; 391 statusEl.textContent = ''; 392 return; 393 } 394 remaining--; 395 } 396 tick(); 397 var intervalId = setInterval(tick, 1000); 398 } else { 399 btn.disabled = false; 400 btn.textContent = 'ð¬ ÐолÑÑиÑÑ ÑÑÑÐ»ÐºÑ Ð½Ð° Ð²Ñ Ð¾Ð´'; 401 statusEl.style.color = '#e53935'; 402 statusEl.textContent = 'â ' + (res.data.message || 'ÐÑибка оÑпÑавки пиÑÑма'); 403 } 404 }) 405 .catch(function(err) { 406 btn.disabled = false; 407 btn.textContent = 'ð¬ ÐолÑÑиÑÑ ÑÑÑÐ»ÐºÑ Ð½Ð° Ð²Ñ Ð¾Ð´'; 408 statusEl.style.color = '#e53935'; 409 statusEl.textContent = 'â ÐÑибка ÑеÑи. ÐопÑобÑйÑе еÑÑ Ñаз.'; 410 console.error(err); 411 }); 412 }); 413 </script>
413 414</body> 415</html> 416
Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.