File manager - Edit - /home/webapp69.cm.in.th/u69319090038/Shop/public/js/auth.js
Back
// ============================================================ // auth.js — Login, Register, OTP flow logic // ============================================================ import { api, Auth, redirectHome } from '../js/api.js'; import { showToast, setButtonLoading, checkPasswordStrength, startOtpCountdown, initOtpInputs, getOtpValue } from '../js/ui.js'; // ─── State ─────────────────────────────────────────────────── let currentStep = 'form'; // 'form' | 'otp' let currentTab = 'login'; // 'login' | 'register' let otpIdentifier = ''; let otpPurpose = ''; let stopCountdown = null; // ─── DOM refs ──────────────────────────────────────────────── const tabLogin = document.getElementById('tab-login'); const tabRegister = document.getElementById('tab-register'); const stepForm = document.getElementById('step-form'); const stepOtp = document.getElementById('step-otp'); // Login form const loginForm = document.getElementById('login-form'); const loginId = document.getElementById('login-identifier'); const loginPass = document.getElementById('login-password'); const loginRemember = document.getElementById('login-remember'); const loginBtn = document.getElementById('login-btn'); const loginPassToggle = document.getElementById('login-pass-toggle'); const loginOtpLink = document.getElementById('login-otp-link'); // Register form const registerForm = document.getElementById('register-form'); const regUsername = document.getElementById('reg-username'); const regEmail = document.getElementById('reg-email'); const regPhone = document.getElementById('reg-phone'); const regPass = document.getElementById('reg-password'); const regPassConfirm = document.getElementById('reg-password-confirm'); const regTos = document.getElementById('reg-tos'); const registerBtn = document.getElementById('register-btn'); const regStrengthBar = document.getElementById('reg-strength-bar'); const regStrengthLabel= document.getElementById('reg-strength-label'); const regPassToggle = document.getElementById('reg-pass-toggle'); // OTP step const otpContextMsg = document.getElementById('otp-context'); const otpTimer = document.getElementById('otp-timer'); const otpResendBtn = document.getElementById('otp-resend'); const verifyOtpBtn = document.getElementById('verify-otp-btn'); const otpBackBtn = document.getElementById('otp-back-btn'); // ─── Init ───────────────────────────────────────────────────── document.addEventListener('DOMContentLoaded', () => { // If already logged in, redirect to home const urlParams = new URLSearchParams(window.location.search); const tab = urlParams.get('tab') || 'login'; const msg = urlParams.get('msg'); if (msg) showToast(msg, 'warning'); switchTab(tab); initOtpInputs('#step-otp'); setupPasswordToggle(loginPass, loginPassToggle); setupPasswordToggle(regPass, regPassToggle); // Real-time password strength regPass?.addEventListener('input', updatePasswordStrength); // Real-time confirm match regPassConfirm?.addEventListener('input', () => { const match = regPassConfirm.value === regPass.value; regPassConfirm.classList.toggle('is-error', !match && regPassConfirm.value.length > 0); regPassConfirm.classList.toggle('is-success', match && regPassConfirm.value.length > 0); }); // Tab buttons tabLogin?.addEventListener('click', () => switchTab('login')); tabRegister?.addEventListener('click', () => switchTab('register')); // Forms loginForm?.addEventListener('submit', handleLogin); registerForm?.addEventListener('submit', handleRegister); loginOtpLink?.addEventListener('click', handleSendLoginOtp); // OTP verifyOtpBtn?.addEventListener('click', handleVerifyOtp); otpBackBtn?.addEventListener('click', goBackToForm); otpResendBtn?.addEventListener('click', handleResendOtp); }); // ─── Tab Switching ──────────────────────────────────────────── function switchTab(tab) { currentTab = tab; document.querySelectorAll('.auth-panel').forEach(p => p.classList.remove('active')); document.getElementById(`panel-${tab}`)?.classList.add('active'); tabLogin?.classList.toggle('active', tab === 'login'); tabRegister?.classList.toggle('active', tab === 'register'); goBackToForm(); } function goBackToForm() { currentStep = 'form'; stepForm?.classList.add('active'); stepOtp?.classList.remove('active'); if (stopCountdown) { stopCountdown(); stopCountdown = null; } } // ─── Password Toggle ────────────────────────────────────────── function setupPasswordToggle(input, toggleBtn) { if (!input || !toggleBtn) return; toggleBtn.addEventListener('click', () => { const isPass = input.type === 'password'; input.type = isPass ? 'text' : 'password'; toggleBtn.textContent = isPass ? '🙈' : '👁'; }); } // ─── Password Strength ───────────────────────────────────────── function updatePasswordStrength() { const val = regPass.value; const result = checkPasswordStrength(val); if (regStrengthBar) { regStrengthBar.style.width = val ? result.width : '0%'; regStrengthBar.style.background = result.color; } if (regStrengthLabel) { regStrengthLabel.textContent = val ? result.label : ''; regStrengthLabel.style.color = result.color; } } // ─── Set OTP Step ───────────────────────────────────────────── function showOtpStep(identifier, purpose, contextText) { otpIdentifier = identifier; otpPurpose = purpose; if (otpContextMsg) otpContextMsg.innerHTML = contextText; // Reset digit inputs document.querySelectorAll('#step-otp .otp-digit').forEach(i => { i.value = ''; i.classList.remove('filled'); }); stepForm?.classList.remove('active'); stepOtp?.classList.add('active'); // Start countdown stopCountdown = startOtpCountdown(otpTimer, otpResendBtn, 300); // 5 mins // Focus first input setTimeout(() => document.querySelector('#step-otp .otp-digit')?.focus(), 100); } // ─── Handle Login ───────────────────────────────────────────── async function handleLogin(e) { e.preventDefault(); const identifier = loginId.value.trim(); const password = loginPass.value; const rememberMe = loginRemember?.checked ?? false; if (!identifier || !password) { showToast('กรุณากรอกข้อมูลให้ครบ', 'warning'); return; } setButtonLoading(loginBtn, true, 'กำลังเข้าสู่ระบบ...'); const result = await api.login({ identifier, password, rememberMe }); setButtonLoading(loginBtn, false); if (!result) return; if (!result.ok) { showToast(result.data.message || 'เข้าสู่ระบบไม่สำเร็จ', 'error'); loginPass.classList.add('is-error'); setTimeout(() => loginPass.classList.remove('is-error'), 2000); return; } Auth.setToken(result.data.accessToken); Auth.setUser(result.data.user); showToast(`ยินดีต้อนรับ, ${result.data.user.username}! 🎉`, 'success'); setTimeout(redirectHome, 1000); } // ─── Handle Send Login OTP ──────────────────────────────────── async function handleSendLoginOtp(e) { e.preventDefault(); const identifier = loginId.value.trim(); if (!identifier) { showToast('กรุณากรอกอีเมลหรือเบอร์โทรก่อน', 'warning'); loginId.focus(); return; } setButtonLoading(loginOtpLink, true, 'กำลังส่ง OTP...'); const result = await api.sendOtp(identifier, 'login'); setButtonLoading(loginOtpLink, false); if (!result || !result.ok) { showToast(result?.data?.message || 'ไม่สามารถส่ง OTP ได้', 'error'); return; } showToast('ส่ง OTP แล้ว! ตรวจสอบอีเมล/SMS ของคุณ', 'success'); showOtpStep(identifier, 'login', `กรอก OTP ที่ส่งไปยัง <strong class="otp-identifier">${identifier}</strong>`); if (result.data.otp_hint) showToast(`[DEV] OTP ของคุณ: ${result.data.otp_hint}`, 'info', 10000); } // ─── Handle Register ────────────────────────────────────────── async function handleRegister(e) { e.preventDefault(); const username = regUsername.value.trim(); const email = regEmail.value.trim(); const phone = regPhone?.value.trim() || null; const password = regPass.value; const confirm = regPassConfirm.value; if (!username || !email || !password) { showToast('กรุณากรอกข้อมูลที่จำเป็น', 'warning'); return; } if (password !== confirm) { showToast('รหัสผ่านไม่ตรงกัน', 'error'); return; } if (!regTos?.checked) { showToast('กรุณายอมรับข้อกำหนดการใช้งาน', 'warning'); return; } setButtonLoading(registerBtn, true, 'กำลังสมัครสมาชิก...'); const result = await api.register({ username, email, phone, password }); setButtonLoading(registerBtn, false); if (!result) return; if (!result.ok) { showToast(result.data.message || 'สมัครสมาชิกไม่สำเร็จ', 'error'); return; } if (result.data.requiresOtp === false) { Auth.setToken(result.data.accessToken); Auth.setUser(result.data.user); showToast('สมัครสมาชิกและเข้าสู่ระบบสำเร็จ! 🎉', 'success'); setTimeout(redirectHome, 1200); return; } showToast('สมัครสมาชิกสำเร็จ! กรุณายืนยัน OTP', 'success'); showOtpStep(email, 'register', `กรอก OTP ที่ส่งไปยัง <strong class="otp-identifier">${email}</strong> เพื่อยืนยันบัญชี`); if (result.data.otp_hint) showToast(`[DEV] OTP ของคุณ: ${result.data.otp_hint}`, 'info', 10000); } // ─── Handle Verify OTP ──────────────────────────────────────── async function handleVerifyOtp() { const code = getOtpValue('#step-otp'); if (code.length < 6) { showToast('กรุณากรอก OTP ให้ครบ 6 หลัก', 'warning'); return; } setButtonLoading(verifyOtpBtn, true, 'กำลังตรวจสอบ...'); const result = await api.verifyOtp({ identifier: otpIdentifier, code, purpose: otpPurpose }); setButtonLoading(verifyOtpBtn, false); if (!result) return; if (!result.ok) { showToast(result.data.message || 'OTP ไม่ถูกต้อง', 'error'); return; } if (otpPurpose === 'login') { Auth.setToken(result.data.accessToken); Auth.setUser(result.data.user); showToast(`เข้าสู่ระบบสำเร็จ! ยินดีต้อนรับ ${result.data.user.username} 🎉`, 'success'); setTimeout(redirectHome, 1200); } else { showToast('ยืนยันบัญชีสำเร็จ! กรุณาเข้าสู่ระบบ 🎉', 'success'); goBackToForm(); switchTab('login'); } } // ─── Handle Resend OTP ──────────────────────────────────────── async function handleResendOtp() { if (stopCountdown) stopCountdown(); const result = await api.sendOtp(otpIdentifier, otpPurpose); if (!result?.ok) { showToast(result?.data?.message || 'ไม่สามารถส่ง OTP ได้', 'error'); return; } showToast('ส่ง OTP ใหม่แล้ว!', 'success'); stopCountdown = startOtpCountdown(otpTimer, otpResendBtn, 300); if (result.data.otp_hint) showToast(`[DEV] OTP ใหม่: ${result.data.otp_hint}`, 'info', 10000); }
| ver. 1.4 |
Github
|
.
| PHP 7.4.33 | Generation time: 0.23 |
proxy
|
phpinfo
|
Settings