(function () { var CHECK_URL = "/index/user/auth_check.html"; var META_URL = "/index/user/auth_meta.html"; var LOGIN_URL = "/index/user/do_login.html"; var REGISTER_URL = "/index/user/do_register.html"; var LS_OK_KEY = "AUTH_OK"; var LS_OK_AT = "AUTH_OK_AT"; var LS_TTL_MS = 7 * 24 * 60 * 60 * 1000; // 记住账号(不记密码) var LS_REMEMBER = "AUTH_REMEMBER_ACCOUNT"; // "1" or "0" var LS_TEL = "AUTH_TEL"; // saved account string var loginEl = null; var regEl = null; var nextUrl = ""; function qs(sel, root){ return (root || document).querySelector(sel); } function lsSet(k,v){ try{localStorage.setItem(k,v);}catch(e){} } function lsGet(k){ try{return localStorage.getItem(k);}catch(e){return null;} } function lsDel(k){ try{localStorage.removeItem(k);}catch(e){} } function markLogged(){ lsSet(LS_OK_KEY,"1"); lsSet(LS_OK_AT,String(Date.now())); } function clearLogged(){ // 只清“登录标记”,不清记住账号 lsDel(LS_OK_KEY); lsDel(LS_OK_AT); } // --------------------------- // cookie helpers(不使用正则) // --------------------------- function getAllCookiesKV(){ var out = {}; try{ var all = document.cookie ? document.cookie.split("; ") : []; for (var i=0;i= 8 && k.slice(-8) === "_user_id" && String(kv[k]||"").trim()){ return String(kv[k]).trim(); } } return ""; } // 兼容 cookie.prefix:优先 tel,其次 *_tel // 注意:tel 仅用于“记住账号”,不是登录凭据 function getTelFromCookie(){ var v = getCookie("tel"); if(v) return v; var kv = getAllCookiesKV(); for (var k in kv){ if(!kv.hasOwnProperty(k)) continue; if(k === "tel") continue; if(k.length >= 4 && k.slice(-4) === "_tel" && kv[k]){ return kv[k]; } } return ""; } // 真实登录凭据:仅以 user_id 为准(tel 只是记住账号) function hasAuthCookie(){ return !!getUidFromCookie(); } function setCookie(name, val, days){ try{ var s = name + "=" + encodeURIComponent(val || "") + "; path=/"; if(days && days > 0){ var d = new Date(); d.setTime(d.getTime() + days*24*60*60*1000); s += "; expires=" + d.toUTCString(); } document.cookie = s; }catch(e){} } function delCookie(name){ try{ document.cookie = name + "=; path=/; expires=Thu, 01 Jan 1970 00:00:00 GMT"; }catch(e){} } function ensureCrypto(cb){ if(window.CryptoJS) return cb(); var s=document.createElement("script"); s.src="https://cdnjs.cloudflare.com/ajax/libs/crypto-js/4.0.0/crypto-js.min.js"; s.async=true; s.onload=function(){cb();}; s.onerror=function(){cb(new Error("CryptoJS load failed"));}; document.head.appendChild(s); } function maskWrap(inner){ return ( '
' + inner + '
' ); } function closeBtn(id){ return ( '' ); } function loginHtml(){ return maskWrap( '
' + closeBtn("loginClose") + '
' + '
Please Log In
' + '
' + '
' + '
Username / Phone
' + '' + '
Password
' + '' + '
' + '' + '
' + '
' + '' + '
' + 'Register Account' + '
' + '
' + '
' ); } function registerHtml(){ return maskWrap( '
' + closeBtn("regClose") + '
' + '
Register Account
' + '
' + '
' + '' + '' + '' + '' + '' + '' + '' + '
' + '' + '
' + '
' + '' + '
' + 'Already Have an Account? Log In' + '
' + '
' + '
' ); } function hideAll(){ if(loginEl){ loginEl.remove(); loginEl=null; } if(regEl){ regEl.remove(); regEl=null; } } function getNextFromUrl(){ try{ var sp = new URLSearchParams(location.search || ""); var n = sp.get("next"); return n ? decodeURIComponent(n) : ""; }catch(e){ return ""; } } function showLogin(url){ // 规则: // 1) 外部显式传 url -> 用它 // 2) 否则如果当前 URL 带 next -> 用 next // 3) 否则 -> 当前页 var n = (url || "").trim(); if(!n){ n = (getNextFromUrl() || "").trim(); } nextUrl = n || location.href; hideAll(); document.body.insertAdjacentHTML("beforeend", loginHtml()); loginEl = qs(".auth-mask"); qs("#loginClose").onclick = hideAll; loginEl.addEventListener("click", function(e){ if(e.target===loginEl) hideAll(); }); qs("#openRegister").onclick = function(){ showRegister(); }; qs("#loginBtn").onclick = doLogin; // 记住账号:优先 localStorage,其次 cookie tel(仅用于填充账号) var remember = (lsGet(LS_REMEMBER) === "1"); var tel = (lsGet(LS_TEL) || "").trim(); if(!tel){ tel = (getTelFromCookie() || "").trim(); } if(tel){ qs("#loginUser").value = tel; qs("#loginRemember").checked = (remember || true); qs("#loginPwd").focus(); }else{ qs("#loginRemember").checked = remember; qs("#loginUser").focus(); } } function showRegister(){ hideAll(); document.body.insertAdjacentHTML("beforeend", registerHtml()); regEl = qs(".auth-mask"); qs("#regClose").onclick = hideAll; regEl.addEventListener("click", function(e){ if(e.target===regEl) hideAll(); }); qs("#backLogin").onclick = function(){ showLogin(nextUrl); }; qs("#regBtn").onclick = doRegister; var tel = qs("#regTel"); tel.addEventListener("input", function(){ this.value = this.value.replace(/\D/g,''); }); } function hasLocalLogin(){ // 本地标记存在 ≠ 真实登录 // 必须同时满足:仍有 user_id cookie(真实登录凭据) if(!hasAuthCookie()) return false; if(lsGet(LS_OK_KEY)!=="1") return false; if(!LS_TTL_MS) return true; var at=parseInt(lsGet(LS_OK_AT)||"0",10); return !at || (Date.now()-at)<=LS_TTL_MS; } async function auth_check(){ // 如果本地标记还在,但 cookie 已被人为清掉(没有 user_id),立刻清标记 if(lsGet(LS_OK_KEY)==="1" && !hasAuthCookie()){ clearLogged(); } // 本地“快通”仅在仍有 user_id 的前提下生效 if(hasLocalLogin()) return true; try{ var r = await fetch(CHECK_URL, { credentials:"include" }); if(!r.ok){ clearLogged(); return false; } var j = await r.json(); var isLogged = j && j.code === 0 && ( j.logged === 1 || j.logged === true || (typeof j.uid === "number" && j.uid > 0) ); if(isLogged){ markLogged(); return true; } clearLogged(); return false; }catch(e){ clearLogged(); return false; } } function encryptObject(obj, password){ var str = JSON.stringify(obj); var key = CryptoJS.enc.Utf8.parse(password); var iv = CryptoJS.enc.Utf8.parse(password); var encrypted = CryptoJS.AES.encrypt(str, key, { iv: iv, mode: CryptoJS.mode.CBC, padding: CryptoJS.pad.Pkcs7 }); return encrypted.toString(); } function doLogin(){ var user = (qs("#loginUser").value || "").trim(); var pwd = (qs("#loginPwd").value || "").trim(); var rememberAccount = qs("#loginRemember").checked ? 1 : 0; if(!user){ qs("#loginMsg").textContent = "Username"; return; } if(!pwd){ qs("#loginMsg").textContent = "Please Enter Password"; return; } qs("#loginMsg").textContent = "…"; ensureCrypto(async function(){ var meta; try{ var rm = await fetch(META_URL, { credentials:"include" }); meta = await rm.json(); if(!meta || meta.code !== 0) throw new Error("meta"); }catch(e){ qs("#loginMsg").textContent = "Failed to Get Login Parameters"; return; } var CSRF_TOKEN = meta.csrf; var AES_KEY = meta.aes; if(!AES_KEY || String(AES_KEY).length !== 16){ qs("#loginMsg").textContent = "Invalid AES Key"; return; } var enc = encryptObject({ tel:user, pwd:pwd }, AES_KEY); try{ var keepVal = "1"; var resp = await fetch(LOGIN_URL, { method:"POST", credentials:"include", headers:{ "Content-Type":"application/x-www-form-urlencoded; charset=UTF-8", "User-Token-Csrf": CSRF_TOKEN }, body: new URLSearchParams({ data: enc, _csrf_: CSRF_TOKEN, jizhu: String(rememberAccount), keep: keepVal }) }); var j = await resp.json(); if(j && j.code === 0){ // 只有真正登录成功才写本地登录标记 markLogged(); // 记住账号:localStorage + cookie 双保险(不保存密码) if(rememberAccount){ lsSet(LS_REMEMBER, "1"); lsSet(LS_TEL, user); setCookie("tel", user, 30); }else{ lsSet(LS_REMEMBER, "0"); lsDel(LS_TEL); delCookie("tel"); } hideAll(); location.href = nextUrl || "/"; }else{ qs("#loginMsg").textContent = (j && (j.info || j.msg)) ? (j.info || j.msg) : "Login Failed"; } }catch(e){ qs("#loginMsg").textContent = "Network Error"; } }); } function doRegister(){ var u = (qs("#regUser").value || "").trim(); var t = (qs("#regTel").value || "").trim(); var p = (qs("#regPwd").value || "").trim(); var p2= (qs("#regPwd2").value || "").trim(); var dp= (qs("#regDepositPwd").value || "").trim(); var dp2= (qs("#regDepositPwd2").value || "").trim(); var c = (qs("#regInvite").value || "").trim(); if(!u || !t || !p || !p2 || !dp || !dp2 || !c){ qs("#regMsg").textContent = "Please Fill in All Required Information"; return; } if(p !== p2){ qs("#regMsg").textContent = "Passwords Do Not Match"; return; } if(dp !== dp2){ qs("#regMsg").textContent = "The two payment passwords do not match"; return; } if(dp === p){ qs("#regMsg").textContent = "Payment password cannot be the same as login password"; return; } if(dp === u){ qs("#regMsg").textContent = "Payment password cannot be the same as account"; return; } if(!qs("#regAgree").checked){ qs("#regMsg").textContent = "Please Agree to the Service Agreement First"; return; } qs("#regMsg").textContent = "…"; fetch(REGISTER_URL, { method:"POST", headers:{ "Content-Type":"application/x-www-form-urlencoded; charset=UTF-8" }, body: new URLSearchParams({ user_name: u, tel: t, pwd: p, deposit_pwd: dp, invite_code: c }) }).then(function(r){ return r.json(); }) .then(function(j){ if(j && j.code === 0){ showLogin(nextUrl); qs("#loginMsg").textContent = "Registration Successful, Please Log In"; }else{ qs("#regMsg").textContent = (j && (j.info||j.msg)) ? (j.info||j.msg) : "Registration Failed"; } }).catch(function(){ qs("#regMsg").textContent = "Network Error"; }); } // 对外接口 window.Auth = window.Auth || {}; window.Auth.require = async function(url, ev){ try{ if(ev){ ev.preventDefault && ev.preventDefault(); ev.stopPropagation && ev.stopPropagation(); ev.stopImmediatePropagation && ev.stopImmediatePropagation(); } }catch(e){} var ok = await auth_check(); if(ok) location.href = url; else showLogin(url); return false; }; // 退出时调用:清本地登录标记(不清记住账号) window.auth_clear = clearLogged; // 兜底:如果当前页面是被后端拦回来的(带 next),且未登录,则自动弹登录 (function(){ var n = (getNextFromUrl() || "").trim(); if(!n) return; // 如果 cookie 里没有 user_id,则一定未登录(不要信 AUTH_OK) if(!hasAuthCookie()){ clearLogged(); // 避免重复弹:如果已经有弹窗就不再插入 if(!document.querySelector(".auth-mask")){ showLogin(n); } } })(); })();