/* * iCaptcha * Internet Captcha * version: 2 (20 May 2013) * * Examples at http://www.icaptcha.com * * License: * CREATIVE COMMONS Attribution-NonCommercial 3.0 Unported * * Copyright 2013 David Arroni Castellanos */ /* ========================================================= * GLOBAL * ========================================================= */ var icaptchaXML; var icaptchactx; var icaptchas; var icaptchac; var icaptchat; var icaptchag; var icaptchae; $('#ForgetPwdModal').on('shown.bs.offcanvas', function () { icaptcha(1, '#000000', 'Wrong Code', 10, 'php', "forgot_icaptcha"); $('#forgot_code').val(''); }); /* ========================================================= * SECURE CODE VALIDATION * * Common function for: * 1. Forget Password * 2. Register * * Usage: * * verifySecureCode(function () { * // Secure Code correct * send OTP * }); * ========================================================= */ function verifySecureCode(codeId, captchaId, callback) { var codeElement = document.getElementById(codeId); if (!codeElement) { console.log("Secure Code input not found:", codeId); return; } var code = codeElement.value.trim(); if (code == "") { $("#error_text").html("Please enter Secure Code"); $("#ErrorNotice").offcanvas("show"); return; } if (window.XMLHttpRequest) { icaptchaXML = new XMLHttpRequest(); } else { icaptchaXML = new ActiveXObject("Microsoft.XMLHTTP"); } icaptchaXML.open("POST", "/validate/", true); icaptchaXML.onreadystatechange = function () { if (icaptchaXML.readyState == 4) { var e = icaptchaXML.responseText.trim(); console.log("Secure Code Response:", e); if (e == "ok=True") { /* * Secure Code correct * * Continue with the function */ callback(); } else { /* * Secure Code incorrect */ $("#error_text").html("Secure Code Invalid"); $("#ErrorNotice").offcanvas("show"); loadicaptcha(captchaId); // 清空当前 modal 的 Secure Code codeElement.value = ""; } } }; icaptchaXML.setRequestHeader( "Content-Type", "application/x-www-form-urlencoded", ); icaptchaXML.send("code=" + encodeURIComponent(code)); } /* ========================================================= * FORGET PASSWORD * * User clicks SEND OTP * * First: * verify Secure Code * * Then: * send Forget Password OTP * ========================================================= */ function forget_pw() { /* * First validate Secure Code */ verifySecureCode("forgot_code", "forgot_icaptcha", function () { /* * Secure Code is correct * * Now send Forget Password OTP */ send_forget_pwd_otp(); }); } /* ========================================================= * SEND FORGET PASSWORD OTP * ========================================================= */ function send_forget_pwd_otp() { $("#fgtpwdotp").attr("disabled", true); var country = $("#forgot_country_code").val(); var tel = $("#forgot_tel").val(); var request = "forget password"; /* * Malaysia * * Example: * * country = 60 * tel = 0123456789 * * becomes: * * 60123456789 */ if (country == "60") { if (tel.substring(0, 1) == "0") { tel = tel.substr(1); } } tel = country + tel; var xhr = new XMLHttpRequest(); xhr.onreadystatechange = function () { if (xhr.readyState == 4) { /* * Success */ if (xhr.status == 200) { $("#fgtpwdotp").attr("disabled", false); var str = xhr.responseText.trim(); console.log("Forget Password OTP:", str); if (str == "OK") { $("#success_text").html("OTP Sent Successful"); $("#SuccessNotice").offcanvas("show"); /* * Start 60 seconds countdown */ $("#fgtpwdotp").attr("disabled", true); var encount = 120; var entimer = setInterval(function () { $("#fgtpwdotp").html(encount--); $("#fgtpwdotp").attr("disabled", true); $("#forgot_tel").attr("readonly", true); if (encount == 0) { $("#fgtpwdotp").attr("disabled", false); $("#forgot_tel").attr("readonly", false); clearInterval(entimer); $("#fgtpwdotp").html("SEND"); } }, 1000); } else { $("#fgtpwdotp").attr("disabled", false); $("#info_text").html("Error. Please try again later"); $("#InfoNotice").offcanvas("show"); } } else if (xhr.status >= 300 || xhr.status == 0) { /* * Server / connection error */ $("#fgtpwdotp").attr("disabled", false); $("#info_text").html("Error. Please try again later"); $("#InfoNotice").offcanvas("show"); } } }; xhr.open("POST", "/request_forget_pwd/", true); xhr.setRequestHeader("Content-type", "application/x-www-form-urlencoded"); xhr.send("hpno=" + encodeURIComponent(tel) + "&request=" + encodeURIComponent(request)); } /* ========================================================= * REGISTER OTP * * User clicks SEND OTP * * First: * verify Secure Code * * Then: * send Register OTP * ========================================================= */ function register_otp() { /* * First validate Secure Code */ verifySecureCode("register_code", "register_icaptcha", function () { /* * Secure Code is correct * * Now send Register OTP */ request_code_register(); }); } /* ========================================================= * REQUEST REGISTER OTP * * Register fields: * * #country_code_reg * #reg_tel * * request = register * ========================================================= */ function request_code_register() { $("#regotp").attr("disabled", true); var country = $("#country_code_reg").val(); var tel = $("#reg_tel").val(); var request = "register"; /* * Check phone number */ if (!country || !tel) { $("#regotp").attr("disabled", false); $("#error_text").html("Please enter your phone number"); $("#ErrorNotice").offcanvas("show"); return; } /* * Malaysia * * Example: * * country = 60 * tel = 0123456789 * * becomes: * * 60123456789 */ if (country == "60") { if (tel.substring(0, 1) == "0") { tel = tel.substr(1); } } /* * Full phone number */ tel = country + tel; console.log("Register OTP Phone:", tel); var xhr = new XMLHttpRequest(); xhr.onreadystatechange = function () { if (xhr.readyState == 4) { /* * Success */ if (xhr.status == 200) { $("#regotp").attr("disabled", false); var str = xhr.responseText.trim(); console.log("Register OTP Response:", str); if (str == "OK") { $("#success_text").html("OTP Sent Successful"); $("#SuccessNotice").offcanvas("show"); /* * Start 60 seconds countdown */ $("#regotp").attr("disabled", true); var encount = 120; var entimer = setInterval(function () { $("#regotp").html(encount--); $("#regotp").attr("disabled", true); $("#reg_tel").attr("readonly", true); if (encount == 0) { $("#regotp").attr("disabled", false); $("#reg_tel").attr("readonly", false); clearInterval(entimer); $("#regotp").html("SEND"); } }, 1000); } else { $("#regotp").attr("disabled", false); $("#info_text").html("Error. Please try again later"); $("#InfoNotice").offcanvas("show"); } } else if (xhr.status >= 300 || xhr.status == 0) { $("#regotp").attr("disabled", false); $("#info_text").html("Error. Please try again later"); $("#InfoNotice").offcanvas("show"); } } }; xhr.open("POST", "/request_code/", true); xhr.setRequestHeader("Content-type", "application/x-www-form-urlencoded"); xhr.send( "hpno=" + encodeURIComponent(tel) + "&request=" + encodeURIComponent(request), ); } /* ========================================================= * LOAD CAPTCHA * ========================================================= */ function loadicaptcha(captchaId) { if (!captchaId) { console.log("Captcha ID is missing"); return; } if (window.XMLHttpRequest) { icaptchaXML = new XMLHttpRequest(); } else { icaptchaXML = new ActiveXObject("Microsoft.XMLHTTP"); } icaptchaXML.open("POST", "/icaptcha/", true); icaptchaXML.onreadystatechange = function () { if (icaptchaXML.readyState == 4) { readicaptcha(captchaId); } }; icaptchaXML.send(); } /* ========================================================= * READ CAPTCHA * ========================================================= */ function readicaptcha(captchaId) { if (icaptchaXML.readyState != 4) { return; } var e; var t; var n = new Array(5); var r = document.getElementById(captchaId); if (!r) { return; } var canvas = r.querySelector("canvas"); if (!canvas) { return; } var s = r.offsetWidth; var o = r.offsetHeight; canvas.height = o; canvas.width = s; icaptchactx.clearRect(0, 0, s, o); var u = icaptchaXML.responseText; var a = u.length / 12; for (e = 0; e < a; e++) { icaptchactx.beginPath(); icaptchactx.lineWidth = icaptchas; icaptchactx.strokeStyle = icaptchac; var f = icaptchag - 5; var l = icaptchag - 35; var c = s / (240 + 2 * icaptchag); var h = o / (60 + 2 * icaptchag); for (t = 0; t < 6; t++) { n[t] = parseInt(u.substr(e * 12 + t * 2, 2), 16); } icaptchactx.moveTo((n[0] + f) * c, (n[1] + l) * h); icaptchactx.quadraticCurveTo( (n[4] + f) * c, (n[5] + l) * h, (n[2] + f) * c, (n[3] + l) * h, ); icaptchactx.stroke(); } } /* ========================================================= * INITIALIZE CAPTCHA * ========================================================= */ function icaptcha(e, t, n, r, i, captchaId) { icaptchas = e; icaptchac = t; icaptchat = n; icaptchag = r; icaptchae = i; var captchaContainer = document.getElementById(captchaId); if (!captchaContainer) { console.log("Captcha container not found:", captchaId); return; } // 清除旧 captcha captchaContainer.innerHTML = ""; var canvas = document.createElement("canvas"); canvas.id = captchaId + "_canvas"; captchaContainer.appendChild(canvas); if (typeof G_vmlCanvasManager != "undefined") { G_vmlCanvasManager.initElement(canvas); } icaptchactx = canvas.getContext("2d"); loadicaptcha(captchaId); }