document.addEventListener('DOMContentLoaded', function (){
if(window.__otinoAjaxNothemeBound){
return;
}
const otinoAjaxConfig=(typeof window.otino_ajax==='object'&&window.otino_ajax!==null)
? window.otino_ajax
: null;
const bodyClassList=document.body ? document.body.classList:null;
const configuredLoggedIn=otinoAjaxConfig&&otinoAjaxConfig.is_logged_in;
const isLoggedIn=configuredLoggedIn===true ||
configuredLoggedIn===1 ||
configuredLoggedIn==='1' ||
(bodyClassList&&bodyClassList.contains('logged-in'));
const hasOtinoLoginContext = !!document.querySelector('#otino-login-register-form-mobile, #otino-form-otp, form.otino-login-form, form.otino-legacy-login-form, form[name="otino-form"]'
);
if(isLoggedIn||!hasOtinoLoginContext){
return;
}
window.__otinoAjaxNothemeBound=true;
const hiddenOtpInput=document.getElementById('otino_otp');
const otpForm=document.querySelector('#otino-form-otp');
const otpFormSubmitBtn=document.querySelector('button[name="otino_otp_submit"]');
const phoneInput=document.getElementById('otino_mobile');
const maxPhoneLength=10;
const mobileForm=document.querySelector('#otino-login-register-form-mobile');
const changeMobileOtp=document.querySelector('.change-phone-now-otino');
const mobileFormSubmitBtn=document.querySelector('button[name="otino_mobile_submit"]');
const mobileFormSubmitBaleBtn=document.querySelector('button[name="otino_mobile_submit_bale"]');
const mobileFormSubmitTelegramBtn=document.querySelector('button[name="otino_mobile_submit_telegram"]');
const mobileFormSubmitVoiceBtn=document.querySelector('button[name="otino_mobile_submit_voice"]');
const mobileChannelInput=document.getElementById('otino_mobile_channel');
const responseDiv=document.getElementById('otino-response-box');
const loadingIndicator=document.querySelector('.otino-loading-box');
const firstOtpInput=otpForm ? otpForm.querySelector('#otp-input-0'):null;
const mobileInput=mobileForm ? mobileForm.querySelector('#otino_mobile'):null;
const authModeInput=document.getElementById('otino_auth_mode');
const inboundCodeEl=otpForm ? otpForm.querySelector('.otino-inbound-sms-code'):null;
const inboundNumberEl=otpForm ? otpForm.querySelector('.otino-inbound-sms-number'):null;
const inboundStatusEl=otpForm ? otpForm.querySelector('.otino-inbound-sms-status'):null;
const inboundFallbackRow=otpForm ? otpForm.querySelector('.otino-inbound-fallback-row'):null;
const inboundFallbackBtn=otpForm ? otpForm.querySelector('.otino-inbound-fallback-btn'):null;
const legacyLoginOpenBtn=document.querySelector('.otino-legacy-login-open');
const legacyLoginBackBtn=document.querySelector('.otino-legacy-login-back');
const legacyLoginPanel=document.querySelector('.otino-legacy-login-panel');
const legacyLoginForm=legacyLoginPanel ? legacyLoginPanel.querySelector('.otino-legacy-login-form'):null;
const legacyUsernameInput=legacyLoginPanel ? legacyLoginPanel.querySelector('input[name="username"]'):null;
const legacyPasswordInput=legacyLoginPanel ? legacyLoginPanel.querySelector('input[name="password"]'):null;
const legacyPasswordToggle=legacyLoginPanel ? legacyLoginPanel.querySelector('.otino-password-toggle'):null;
const legacyLoginSubmitBtn=legacyLoginForm ? legacyLoginForm.querySelector('button[type="submit"]'):null;
const otpActivatedDescEl=document.querySelector('.desc-above-form-login-otino.otp-activated, .desc-above-form-login-lobgu.otp-activated');
const otpIntroText=(otino_ajax&&typeof otino_ajax.otp_intro_text==='string'&&otino_ajax.otp_intro_text.trim().length > 0)
? otino_ajax.otp_intro_text.trim()
: 'کد تایید ارسال شده را وارد کنید';
const otpTimeResetEl=otpForm ? otpForm.querySelector('.otp-time-reset-otino'):null;
let mobileRequestInFlight=false;
let otpRequestInFlight=false;
let legacyRequestInFlight=false;
let inboundPollTimerId=null;
let inboundPollInFlight=false;
let inboundPollIntervalSeconds=5;
let lastOtpMobile='';
let smsSendCountForLastMobile=0;
let autoBackupTimerId=null;
let autoBackupTriggered=false;
let backupResendConsumed=false;
let forcedBackupPendingMeta=null;
let switchToInboundPending=false;
const smsBackupEnabled = !!(otino_ajax&&otino_ajax.sms_backup_enabled);
const backupAutoResendEnabled=smsBackupEnabled&&!!(otino_ajax&&otino_ajax.backup_auto_resend_enabled);
const backupSecondManualEnabled=smsBackupEnabled&&!!(otino_ajax&&otino_ajax.backup_second_manual_enabled);
const configuredAutoDelaySeconds=parseInt(otino_ajax&&otino_ajax.backup_auto_resend_delay, 10);
const backupAutoDelayMs=(Number.isFinite(configuredAutoDelaySeconds)&&configuredAutoDelaySeconds > 0 ? configuredAutoDelaySeconds:30) * 1000;
let nonceRefreshPromise=null;
if(!otpForm||!mobileForm){
console.warn('Required form elements not found');
return;
}
const timerOtino=new TimerOtino(otino_ajax.smstime * 1000);
setAuthMode('otp');
if(mobileInput) mobileInput.value='';
function setHiddenFieldValue(name, value){
if(!name||typeof value!=='string'){
return;
}
document.querySelectorAll('input[name="' + name + '"]').forEach(function (input){
input.value=value;
});
}
function applyFreshAuthNonces(nonces){
if(!nonces||typeof nonces!=='object'){
return;
}
if(typeof nonces.security_js==='string'&&nonces.security_js.length > 0){
otino_ajax.nonce=nonces.security_js;
}
if(typeof nonces.otino_mobile_nonce==='string'&&nonces.otino_mobile_nonce.length > 0){
setHiddenFieldValue('otino_mobile_nonce', nonces.otino_mobile_nonce);
}
if(typeof nonces.otino_otp_nonce==='string'&&nonces.otino_otp_nonce.length > 0){
setHiddenFieldValue('otino_otp_nonce', nonces.otino_otp_nonce);
}
if(typeof nonces.woocommerce_login_nonce==='string'&&nonces.woocommerce_login_nonce.length > 0){
setHiddenFieldValue('woocommerce-login-nonce', nonces.woocommerce_login_nonce);
}}
function refreshAuthNonces(){
if(!otino_ajax||!otino_ajax.ajax_url){
return Promise.resolve();
}
if(nonceRefreshPromise){
return nonceRefreshPromise;
}
nonceRefreshPromise=new Promise(function (resolve){
const refreshData=new FormData();
refreshData.append('action', 'otino_auth_refresh');
refreshData.append('_', String(Date.now()));
const xhrRefresh=new XMLHttpRequest();
xhrRefresh.open('POST', otino_ajax.ajax_url, true);
xhrRefresh.onload=function (){
if(xhrRefresh.status >=200&&xhrRefresh.status < 400){
try {
const result=JSON.parse(xhrRefresh.responseText);
if(result&&result.success&&result.data){
applyFreshAuthNonces(result.data);
}} catch (error){
}}
nonceRefreshPromise=null;
resolve();
};
xhrRefresh.onerror=function (){
nonceRefreshPromise=null;
resolve();
};
xhrRefresh.send(refreshData);
});
return nonceRefreshPromise;
}
function isPhoneNumberValidOtino(phone){
return phone.length===maxPhoneLength&&phone.startsWith('9')&&/^9\d{9}$/.test(phone);
}
function clearAutoBackupTimer(){
if(autoBackupTimerId){
clearTimeout(autoBackupTimerId);
autoBackupTimerId=null;
}}
function setResponseMessage(type, text){
if(!responseDiv){
return;
}
responseDiv.innerHTML=text||'';
responseDiv.style.display='flex';
if(type==='success'){
responseDiv.style.backgroundColor='#d4edda';
responseDiv.style.color='#155724';
responseDiv.classList.remove('error-message');
responseDiv.classList.add('success-message');
}else{
responseDiv.style.backgroundColor='#ffe2e2';
responseDiv.style.color='#750404';
responseDiv.classList.remove('success-message');
responseDiv.classList.add('error-message');
}}
function resetLegacySecurityChallenge(){
if(!legacyLoginForm){
return;
}
legacyLoginForm.querySelectorAll('input[name="otino_recaptcha_token"]').forEach(function (input){
input.remove();
});
if(window.jQuery){
window.jQuery(legacyLoginForm)
.removeData('recaptcha-ready')
.removeData('recaptcha-generating')
.removeData('recaptcha-pregenerating');
}
if(window.grecaptcha&&typeof window.grecaptcha.reset==='function'){
for (let index=0; index < 10; index++){
try {
window.grecaptcha.reset(index);
} catch (error){
break;
}}
}
if(window.hcaptcha&&typeof window.hcaptcha.reset==='function'){
for (let index=0; index < 10; index++){
try {
window.hcaptcha.reset(index);
} catch (error){
break;
}}
}}
function activateMobileLogin(){
stopInboundPolling();
setAuthMode('otp');
setInboundFallbackButtonVisible(false);
mobileForm.classList.remove('otp-active');
mobileForm.classList.remove('otino-legacy-active');
responseDiv.style.display='none';
timerOtino.stop();
clearAutoBackupTimer();
if(otpActivatedDescEl){
otpActivatedDescEl.textContent=otpIntroText;
}
if(phoneInput){
phoneInput.focus();
}}
function activateLegacyLogin(){
stopInboundPolling();
setAuthMode('otp');
setInboundFallbackButtonVisible(false);
mobileForm.classList.remove('otp-active');
mobileForm.classList.add('otino-legacy-active');
responseDiv.style.display='none';
timerOtino.stop();
clearAutoBackupTimer();
if(otpActivatedDescEl){
otpActivatedDescEl.textContent='نام کاربری یا ایمیل و رمز عبور حساب خود را وارد کنید.';
}
if(legacyUsernameInput){
legacyUsernameInput.focus();
}}
function setAuthMode(mode){
if(authModeInput){
authModeInput.value=mode;
}
if(!otpForm){
return;
}
if(mode==='inbound_sms'){
otpForm.classList.add('otino-auth-mode-inbound');
if(inboundFallbackRow){
inboundFallbackRow.style.display='none';
}
if(otpActivatedDescEl){
otpActivatedDescEl.innerHTML='کد نمایش‌داده‌شده را به شماره مقصد پیامک کنید.';
}
if(otpTimeResetEl){
otpTimeResetEl.innerHTML='<span class="otp-time-otino"></span> ثانیه مانده تا پایان اعتبار این کد';
}}else{
otpForm.classList.remove('otino-auth-mode-inbound');
if(otpActivatedDescEl){
otpActivatedDescEl.textContent=otpIntroText;
}
if(otpTimeResetEl){
otpTimeResetEl.innerHTML='<span class="otp-time-otino"></span> ثانیه مانده تا پایان اعتبار این کد';
}}
}
function setInboundFallbackButtonVisible(isVisible){
if(!inboundFallbackRow||!inboundFallbackBtn){
return;
}
if(authModeInput&&authModeInput.value==='inbound_sms'){
inboundFallbackRow.style.display='none';
return;
}
inboundFallbackRow.style.display=isVisible ? 'block':'none';
inboundFallbackBtn.disabled=false;
}
function stopInboundPolling(){
if(inboundPollTimerId){
clearTimeout(inboundPollTimerId);
inboundPollTimerId=null;
}
inboundPollInFlight=false;
}
function scheduleInboundPolling(delaySeconds){
stopInboundPolling();
const intervalSeconds=Number.isFinite(delaySeconds)&&delaySeconds > 0 ? delaySeconds:inboundPollIntervalSeconds;
inboundPollTimerId=setTimeout(runInboundPolling, intervalSeconds * 1000);
}
function runInboundPolling(){
if(inboundPollInFlight||!mobileForm.classList.contains('otp-active')){
return;
}
if(!authModeInput||authModeInput.value!=='inbound_sms'){
return;
}
inboundPollInFlight=true;
const pollData=new FormData();
pollData.append('action', 'otino_inbound_sms_poll');
pollData.append('security_js', otino_ajax.nonce);
const mobileHidden=document.getElementById('otino_mobile_hidden');
if(mobileHidden&&mobileHidden.value){
pollData.append('otino_mobile_hidden', mobileHidden.value);
}
const redirectField=otpForm ? otpForm.querySelector('input[name="redirect"]'):null;
if(redirectField&&redirectField.value){
pollData.append('redirect', redirectField.value);
}
const wcNonceField=otpForm ? otpForm.querySelector('input[name="woocommerce-login-nonce"]'):null;
if(wcNonceField&&wcNonceField.value){
pollData.append('woocommerce-login-nonce', wcNonceField.value);
}
const xhrPoll=new XMLHttpRequest();
xhrPoll.open('POST', otino_ajax.ajax_url, true);
xhrPoll.onload=function (){
inboundPollInFlight=false;
if(!(xhrPoll.status >=200&&xhrPoll.status < 400)){
if(inboundStatusEl){
inboundStatusEl.textContent='در حال بررسی مجدد وضعیت ارتباط... قطعی موقت';
}
scheduleInboundPolling(inboundPollIntervalSeconds);
return;
}
let result;
try {
result=JSON.parse(xhrPoll.responseText);
} catch (e){
if(inboundStatusEl){
inboundStatusEl.textContent='در حال هماهنگ‌سازی با سرور... لطفاً شکیبا باشید';
}
scheduleInboundPolling(inboundPollIntervalSeconds);
return;
}
if(result&&result.success&&result.success!=='pending'){
stopInboundPolling();
otpForm.classList.add('loading');
mobileForm.classList.add('loading');
responseDiv.style.display='flex';
responseDiv.innerHTML=result.message||'ورود با موفقیت انجام شد.';
responseDiv.style.backgroundColor='#d4edda';
responseDiv.style.color='#155724';
responseDiv.classList.remove('error-message');
responseDiv.classList.add('success-message');
if(result.data&&result.data.redirect){
window.location.href=result.data.redirect;
}else{
location.reload();
}
return;
}
const state=result&&result.data ? result.data.state:'';
if(state==='expired'||state==='invalid_mode'||(result&&result.data&&result.data.action==='mobileActive')){
stopInboundPolling();
setAuthMode('otp');
setInboundFallbackButtonVisible(false);
mobileForm.classList.remove('otp-active');
timerOtino.stop();
if(mobileInput){
mobileInput.value='';
mobileInput.focus();
}
responseDiv.style.display='flex';
responseDiv.innerHTML=result.error||'زمان ورود به پایان رسیده است.';
responseDiv.style.backgroundColor='#ffe2e2';
responseDiv.style.color='#750404';
responseDiv.classList.remove('success-message');
responseDiv.classList.add('error-message');
return;
}
if(inboundStatusEl){
inboundStatusEl.textContent=(result&&result.data&&result.data.status_text) ? result.data.status_text:'در حال بررسی وضعیت پیامک شما... لطفاً شکیبا باشید';
}
scheduleInboundPolling(inboundPollIntervalSeconds);
};
xhrPoll.onerror=function (){
inboundPollInFlight=false;
if(inboundStatusEl){
inboundStatusEl.textContent='در حال تلاش برای برقراری ارتباط... لطفاً کمی صبر کنید';
}
scheduleInboundPolling(inboundPollIntervalSeconds);
};
xhrPoll.send(pollData);
}
function getVisibleOtpValue(){
if(!otpForm){
return '';
}
const otpInputs=otpForm.querySelectorAll('input[id^="otp-input-"]');
return Array.from(otpInputs).map((input)=> (input&&input.value ? input.value.trim():'')).join('');
}
function isOtpEmpty(){
const hiddenValue=hiddenOtpInput ? hiddenOtpInput.value.trim():'';
const visibleValue=getVisibleOtpValue();
return hiddenValue.length===0&&visibleValue.length===0;
}
function queueForcedBackupResend(mobile, reason){
if(!mobile||mobileRequestInFlight||otpRequestInFlight||backupResendConsumed){
return;
}
backupResendConsumed=true;
forcedBackupPendingMeta={
mobile,
channel: 'sms',
reason,
};
if(mobileChannelInput){
mobileChannelInput.value='sms';
}
if(phoneInput){
phoneInput.value=mobile;
}
if(typeof mobileForm.requestSubmit==='function'){
mobileForm.requestSubmit(mobileFormSubmitBtn||undefined);
}else{
const submitEvent=new Event('submit', { bubbles: true, cancelable: true });
mobileForm.dispatchEvent(submitEvent);
}}
function scheduleAutoBackupResend(mobile, channel, sendSource, forcedBackup){
clearAutoBackupTimer();
if(!backupAutoResendEnabled||channel!=='sms'||!mobile){
return;
}
if(forcedBackup||sendSource==='backup'||autoBackupTriggered){
return;
}
autoBackupTimerId=setTimeout(function (){
autoBackupTimerId=null;
if(autoBackupTriggered){
return;
}
if(!mobileForm.classList.contains('otp-active')){
return;
}
if(!isOtpEmpty()){
return;
}
autoBackupTriggered=true;
queueForcedBackupResend(mobile, 'auto_no_input');
}, backupAutoDelayMs);
}
if(changeMobileOtp){
changeMobileOtp.addEventListener('click', function (event){
activateMobileLogin();
backupResendConsumed=false;
autoBackupTriggered=false;
forcedBackupPendingMeta=null;
const otpInputs=otpForm.querySelectorAll('input[id^="otp-input-"]');
otpInputs.forEach(input=> {
input.value='';
});
hiddenOtpInput.value='';
});
}
if(legacyLoginOpenBtn){
legacyLoginOpenBtn.addEventListener('click', activateLegacyLogin);
}
if(legacyLoginBackBtn){
legacyLoginBackBtn.addEventListener('click', activateMobileLogin);
}
if(legacyPasswordToggle&&legacyPasswordInput){
legacyPasswordToggle.addEventListener('click', function (){
const shouldShowPassword=legacyPasswordInput.type==='password';
legacyPasswordInput.type=shouldShowPassword ? 'text':'password';
legacyPasswordToggle.classList.toggle('is-visible', shouldShowPassword);
legacyPasswordToggle.setAttribute('aria-pressed', shouldShowPassword ? 'true':'false');
legacyPasswordToggle.setAttribute('aria-label', shouldShowPassword ? 'مخفی کردن رمز عبور':'نمایش رمز عبور');
legacyPasswordInput.focus();
});
}
if(legacyLoginForm){
legacyLoginForm.addEventListener('submit', function (event){
event.preventDefault();
if(legacyRequestInFlight){
return;
}
const username=legacyUsernameInput ? legacyUsernameInput.value.trim():'';
const password=legacyPasswordInput ? legacyPasswordInput.value:'';
responseDiv.style.display='none';
if(!username||!password){
setResponseMessage('error', 'نام کاربری یا رمز عبور صحیح نیست.');
return;
}
legacyRequestInFlight=true;
legacyLoginPanel.classList.add('loading');
if(legacyLoginSubmitBtn){
legacyLoginSubmitBtn.disabled=true;
}
if(legacyLoginBackBtn){
legacyLoginBackBtn.disabled=true;
}
refreshAuthNonces().then(function (){
const legacyFormData=new FormData(legacyLoginForm);
legacyFormData.append('action', 'otino_legacy_password_login');
legacyFormData.append('security_js', otino_ajax.nonce);
const xhrLegacy=new XMLHttpRequest();
xhrLegacy.open('POST', otino_ajax.ajax_url, true);
xhrLegacy.onload=function (){
legacyRequestInFlight=false;
legacyLoginPanel.classList.remove('loading');
if(legacyLoginSubmitBtn){
legacyLoginSubmitBtn.disabled=false;
}
if(legacyLoginBackBtn){
legacyLoginBackBtn.disabled=false;
}
if(!(xhrLegacy.status >=200&&xhrLegacy.status < 400)){
resetLegacySecurityChallenge();
setResponseMessage('error', 'An unexpected server error occurred.');
return;
}
let data;
try {
data=JSON.parse(xhrLegacy.responseText);
} catch (error){
resetLegacySecurityChallenge();
setResponseMessage('error', 'An unexpected server error occurred.');
return;
}
if(data.success&&data.success!=='failure'){
setResponseMessage('success', data.message||'با موفقیت وارد شدید! درحال انتقال...');
if(data.data&&data.data.redirect){
window.location.href=data.data.redirect;
}else{
location.reload();
}
return;
}
if(data.data&&data.data.nonces){
applyFreshAuthNonces(data.data.nonces);
}
resetLegacySecurityChallenge();
setResponseMessage('error', data.error||'نام کاربری یا رمز عبور صحیح نیست.');
if(data.data&&data.data.action==='reload'){
setTimeout(function (){
location.reload();
}, 1500);
}};
xhrLegacy.onerror=function (){
legacyRequestInFlight=false;
legacyLoginPanel.classList.remove('loading');
if(legacyLoginSubmitBtn){
legacyLoginSubmitBtn.disabled=false;
}
if(legacyLoginBackBtn){
legacyLoginBackBtn.disabled=false;
}
resetLegacySecurityChallenge();
setResponseMessage('error', 'An error occurred while processing your request.');
};
xhrLegacy.send(legacyFormData);
});
});
}
if(mobileForm&&phoneInput){
if(mobileFormSubmitBtn){
mobileFormSubmitBtn.addEventListener('click', function (){
if(mobileChannelInput){
mobileChannelInput.value='sms';
}});
}
if(mobileFormSubmitBaleBtn){
mobileFormSubmitBaleBtn.addEventListener('click', function (){
if(mobileChannelInput){
mobileChannelInput.value='bale';
}});
}
if(mobileFormSubmitTelegramBtn){
mobileFormSubmitTelegramBtn.addEventListener('click', function (){
if(mobileChannelInput){
mobileChannelInput.value='telegram';
}});
}
if(mobileFormSubmitVoiceBtn){
mobileFormSubmitVoiceBtn.addEventListener('click', function (){
if(mobileChannelInput){
mobileChannelInput.value='voice';
}});
}
mobileForm.addEventListener('submit', function (event){
event.preventDefault();
if(mobileRequestInFlight){
return;
}
const mobileNumber=phoneInput.value.trim();
const submitter=event.submitter||null;
let selectedChannel=mobileChannelInput ? mobileChannelInput.value:'sms';
if(submitter&&submitter.name==='otino_mobile_submit_bale'){
selectedChannel='bale';
}else if(submitter&&submitter.name==='otino_mobile_submit_telegram'){
selectedChannel='telegram';
}else if(submitter&&submitter.name==='otino_mobile_submit_voice'){
selectedChannel='voice';
}
let forceBackup=false;
let switchToInbound=false;
let resendReason='';
if(forcedBackupPendingMeta &&
forcedBackupPendingMeta.mobile===mobileNumber &&
forcedBackupPendingMeta.channel===selectedChannel
){
forceBackup=true;
resendReason=forcedBackupPendingMeta.reason||'';
forcedBackupPendingMeta=null;
}else if(switchToInboundPending&&selectedChannel==='sms'){
switchToInbound=true;
switchToInboundPending=false;
}else if(selectedChannel==='sms' &&
backupSecondManualEnabled &&
!backupResendConsumed &&
lastOtpMobile===mobileNumber &&
smsSendCountForLastMobile >=1 &&
timerOtino.hasExpired()
){
forceBackup=true;
resendReason='manual_after_expire';
backupResendConsumed=true;
}
responseDiv.style.display='none';
if(!isPhoneNumberValidOtino(mobileNumber)){
switchToInboundPending=false;
if(inboundFallbackBtn){
inboundFallbackBtn.disabled=false;
}
phoneInput.style.borderColor='red';
responseDiv.textContent='شماره موبایل وارد شده معتبر نیست';
responseDiv.style.display='flex';
responseDiv.style.backgroundColor='#ffe2e2';
responseDiv.style.color='#750404';
responseDiv.classList.remove('success-message');
responseDiv.classList.add('error-message');
}else{
phoneInput.style.borderColor='';
mobileForm.classList.add('loading');
if(otpForm&&mobileForm.classList.contains('otp-active')){
otpForm.classList.add('loading');
}
mobileRequestInFlight=true;
if(mobileFormSubmitBtn) mobileFormSubmitBtn.disabled=true;
if(mobileFormSubmitBaleBtn) mobileFormSubmitBaleBtn.disabled=true;
if(mobileFormSubmitTelegramBtn) mobileFormSubmitTelegramBtn.disabled=true;
if(mobileFormSubmitVoiceBtn) mobileFormSubmitVoiceBtn.disabled=true;
responseDiv.style.display='none';
const formMobileData=mobileForm;
if(!(formMobileData instanceof HTMLFormElement)){
console.error('Form element not found or invalid');
return;
}
refreshAuthNonces().then(function (){
var formData=new FormData(formMobileData);
formData.append('action', 'otino_mobile');
formData.append('otino_mobile_js', mobileNumber);
formData.set('otino_mobile_channel', ['sms', 'bale', 'telegram', 'voice'].includes(selectedChannel) ? selectedChannel:'sms');
formData.set('otino_force_backup', forceBackup ? '1':'0');
formData.set('otino_switch_to_inbound', switchToInbound ? '1':'0');
formData.set('otino_sms_resend_reason', resendReason);
formData.append('security_js', otino_ajax.nonce);
const xhr=new XMLHttpRequest();
xhr.open('POST', otino_ajax.ajax_url, true);
xhr.onload=function (){
mobileForm.classList.remove('loading');
if(otpForm) otpForm.classList.remove('loading');
mobileRequestInFlight=false;
if(inboundFallbackBtn){
inboundFallbackBtn.disabled=false;
}
if(mobileFormSubmitBtn) mobileFormSubmitBtn.disabled=false;
if(mobileFormSubmitBaleBtn) mobileFormSubmitBaleBtn.disabled=false;
if(mobileFormSubmitTelegramBtn) mobileFormSubmitTelegramBtn.disabled=false;
if(mobileFormSubmitVoiceBtn) mobileFormSubmitVoiceBtn.disabled=false;
responseDiv.style.display='flex';
if(xhr.status >=200&&xhr.status < 400){
const data=JSON.parse(xhr.responseText);
if(data.success&&data.success!=="failure"){
responseDiv.innerHTML=data.message||'Request was successful!';
phoneInput.value="";
responseDiv.style.backgroundColor='#d4edda';
responseDiv.style.color='#155724';
responseDiv.classList.remove('error-message');
responseDiv.classList.add('success-message');
if(data.data.action=='otpActive'){
setAuthMode('otp');
stopInboundPolling();
setInboundFallbackButtonVisible(!!data.data.allow_inbound_fallback_button);
if(data.data.mobile!==''&&otpForm){
const hiddenInput=otpForm.querySelector('#otino_mobile_hidden');
const spanElement=otpForm.querySelector('span.otp-message-end-otino > span');
if(hiddenInput) hiddenInput.value=data.data.mobile;
if(spanElement) spanElement.innerHTML=data.data.mobile;
if(data.data.channel==='sms'){
if(lastOtpMobile!==data.data.mobile){
smsSendCountForLastMobile=0;
autoBackupTriggered=false;
backupResendConsumed=false;
forcedBackupPendingMeta=null;
}
lastOtpMobile=data.data.mobile;
smsSendCountForLastMobile +=1;
const sendSource=data.data.send_source||'primary';
const forcedBackupFlag = !!data.data.forced_backup;
if(forcedBackupFlag){
backupResendConsumed=true;
}
scheduleAutoBackupResend(lastOtpMobile, 'sms', sendSource, forcedBackupFlag);
}else{
clearAutoBackupTimer();
}}
mobileForm.classList.add('otp-active');
if(firstOtpInput) firstOtpInput.focus();
timerOtino.stop();
timerOtino.start();
}else if(data.data.action=='inboundSmsActive'){
setAuthMode('inbound_sms');
stopInboundPolling();
setInboundFallbackButtonVisible(false);
if(data.data.mobile!==''&&otpForm){
const hiddenInput=otpForm.querySelector('#otino_mobile_hidden');
const spanElement=otpForm.querySelector('span.otp-message-end-otino > span');
if(hiddenInput) hiddenInput.value=data.data.mobile;
if(spanElement) spanElement.innerHTML=data.data.mobile;
}
if(inboundCodeEl){
inboundCodeEl.textContent=data.data.inbound_code||'';
}
if(inboundNumberEl){
inboundNumberEl.textContent=data.data.inbound_number||'-';
}
if(inboundStatusEl){
inboundStatusEl.textContent='در حال بررسی وضعیت پیامک شما... لطفاً شکیبا باشید';
}
inboundPollIntervalSeconds=parseInt(data.data.poll_interval, 10);
if(!Number.isFinite(inboundPollIntervalSeconds)||inboundPollIntervalSeconds < 3){
inboundPollIntervalSeconds=5;
}
mobileForm.classList.add('otp-active');
responseDiv.style.display='none';
timerOtino.stop();
timerOtino.start();
scheduleInboundPolling(1);
}}else{
if(data.data&&data.data.nonces){
applyFreshAuthNonces(data.data.nonces);
}
responseDiv.innerHTML=data.error||'An unexpected error occurred.';
responseDiv.style.backgroundColor='#ffe2e2';
responseDiv.style.color='#750404';
responseDiv.classList.remove('success-message');
responseDiv.classList.add('error-message');
if(data.data.action=='reload'){
setTimeout(function(){
location.reload();
}, 1500);
}}
}else{
responseDiv.innerHTML='An unexpected server error occurred.';
responseDiv.style.backgroundColor='#ffe2e2';
responseDiv.style.color='#750404';
responseDiv.classList.remove('success-message');
responseDiv.classList.add('error-message');
}};
xhr.onerror=function (){
mobileForm.classList.remove('loading');
if(otpForm) otpForm.classList.remove('loading');
mobileRequestInFlight=false;
switchToInboundPending=false;
if(inboundFallbackBtn){
inboundFallbackBtn.disabled=false;
}
if(mobileFormSubmitBtn) mobileFormSubmitBtn.disabled=false;
if(mobileFormSubmitBaleBtn) mobileFormSubmitBaleBtn.disabled=false;
if(mobileFormSubmitTelegramBtn) mobileFormSubmitTelegramBtn.disabled=false;
if(mobileFormSubmitVoiceBtn) mobileFormSubmitVoiceBtn.disabled=false;
responseDiv.innerHTML='An error occurred while processing your request.';
responseDiv.style.display='flex';
responseDiv.style.backgroundColor='#750404';
responseDiv.style.color='#ffe2e2';
responseDiv.classList.remove('success-message');
responseDiv.classList.add('error-message');
};
xhr.send(formData);
});
}});
}
if(otpForm&&hiddenOtpInput){
otpForm.addEventListener('submit', function (event){
if(authModeInput&&authModeInput.value==='inbound_sms'){
event.preventDefault();
return;
}
event.preventDefault();
if(otpRequestInFlight){
return;
}
const otpCode=hiddenOtpInput.value.trim();
responseDiv.style.display='none';
otpForm.classList.add('loading');
otpRequestInFlight=true;
if(otpFormSubmitBtn) otpFormSubmitBtn.disabled=true;
const formOtpData=otpForm;
if(!(formOtpData instanceof HTMLFormElement)){
console.error('Form element not found or invalid');
return;
}
refreshAuthNonces().then(function (){
var otpFormData=new FormData(formOtpData);
otpFormData.append('action', 'otino_otp');
otpFormData.append('security_js', otino_ajax.nonce);
const xhrOtp=new XMLHttpRequest();
xhrOtp.open('POST', otino_ajax.ajax_url, true);
xhrOtp.onload=function (){
otpForm.classList.remove('loading');
otpRequestInFlight=false;
if(otpFormSubmitBtn) otpFormSubmitBtn.disabled=false;
responseDiv.style.display='flex';
if(xhrOtp.status >=200&&xhrOtp.status < 400){
const data=JSON.parse(xhrOtp.responseText);
if(data.data.action=='reload'){
location.reload();
}
if(data.data.action=="clearOtp"){
const otpInputs=otpForm.querySelectorAll('input[id^="otp-input-"]');
otpInputs.forEach(input=> {
input.value='';
});
if(firstOtpInput) firstOtpInput.focus();
}
if(data.data.action=="mobileActive"){
stopInboundPolling();
setAuthMode('otp');
setInboundFallbackButtonVisible(false);
if(mobileInput) mobileInput.value='';
mobileForm.classList.remove('otp-active');
timerOtino.stop();
clearAutoBackupTimer();
otpForm.classList.remove('loading');
if(mobileInput) mobileInput.focus();
const otpInputs=otpForm.querySelectorAll('input[id^="otp-input-"]');
otpInputs.forEach(input=> {
input.value='';
});
}
if(data.success&&data.success!=="failure"){
otpForm.classList.add('loading');
responseDiv.innerHTML=data.message||'Request was successful!';
hiddenOtpInput.value="";
responseDiv.style.backgroundColor='#d4edda';
responseDiv.style.color='#155724';
responseDiv.classList.remove('error-message');
responseDiv.classList.add('success-message');
if(data.data.redirect){
window.location.href=data.data.redirect;
}else{
location.reload();
}}else{
if(data.data&&data.data.nonces){
applyFreshAuthNonces(data.data.nonces);
}
responseDiv.innerHTML=data.error||'An unexpected error occurred.';
responseDiv.style.backgroundColor='#ffe2e2';
responseDiv.style.color='#750404';
responseDiv.classList.remove('success-message');
responseDiv.classList.add('error-message');
}}else{
responseDiv.innerHTML='An unexpected server error occurred.';
responseDiv.style.backgroundColor='#ffe2e2';
responseDiv.style.color='#750404';
responseDiv.classList.remove('success-message');
responseDiv.classList.add('error-message');
}};
xhrOtp.onerror=function (){
otpForm.classList.remove('loading');
otpRequestInFlight=false;
if(otpFormSubmitBtn) otpFormSubmitBtn.disabled=false;
responseDiv.innerHTML='An error occurred while processing your request.';
responseDiv.style.display='flex';
responseDiv.style.backgroundColor='#750404';
responseDiv.style.color='#ffe2e2';
responseDiv.classList.remove('success-message');
responseDiv.classList.add('error-message');
};
xhrOtp.send(otpFormData);
});
});
}
if(inboundFallbackBtn){
inboundFallbackBtn.addEventListener('click', function (){
if(mobileRequestInFlight||otpRequestInFlight){
return;
}
const hiddenMobile=document.getElementById('otino_mobile_hidden');
const currentMobile=hiddenMobile&&hiddenMobile.value ? hiddenMobile.value.trim():'';
if(!isPhoneNumberValidOtino(currentMobile)){
responseDiv.textContent='شماره موبایل برای تغییر روش ورود معتبر نیست.';
responseDiv.style.display='flex';
responseDiv.style.backgroundColor='#ffe2e2';
responseDiv.style.color='#750404';
responseDiv.classList.remove('success-message');
responseDiv.classList.add('error-message');
return;
}
if(phoneInput){
phoneInput.value=currentMobile;
}
switchToInboundPending=true;
inboundFallbackBtn.disabled=true;
responseDiv.style.display='none';
if(typeof mobileForm.requestSubmit==='function'){
mobileForm.requestSubmit(mobileFormSubmitBtn||undefined);
}else{
const submitEvent=new Event('submit', { bubbles: true, cancelable: true });
mobileForm.dispatchEvent(submitEvent);
}});
}
function TimerOtino(duration){
this.duration=duration;
this.isRunning=false;
this.expired=false;
this.rafId=null;
this.runId=0;
this.getCountdownEl=()=> (otpForm ? otpForm.querySelector('.otp-time-otino'):null);
this.start=()=> {
const countdownEl=this.getCountdownEl();
if(this.isRunning||!countdownEl) return;
this.isRunning=true;
this.expired=false;
this.runId +=1;
const activeRunId=this.runId;
let start=null;
let remainingSeconds=countdownEl.textContent=this.duration / 1000;
const draw=(now)=> {
const currentCountdownEl=this.getCountdownEl();
if(!this.isRunning||!currentCountdownEl||activeRunId!==this.runId) return;
if(!start) start=now;
const diff=now - start;
const newSeconds=Math.ceil((this.duration - diff) / 1000);
if(diff <=this.duration){
if(newSeconds!==remainingSeconds){
remainingSeconds=newSeconds;
currentCountdownEl.textContent=newSeconds;
}
this.rafId=window.requestAnimationFrame(draw);
}else{
currentCountdownEl.textContent=0;
if(mobileForm) mobileForm.classList.remove('otp-active');
if(responseDiv) responseDiv.style.display='none';
stopInboundPolling();
setAuthMode('otp');
if(inboundStatusEl){
inboundStatusEl.textContent='در حال بررسی وضعیت پیامک شما... لطفاً شکیبا باشید';
}
const hiddenMobile=document.getElementById('otino_mobile_hidden');
if(mobileInput&&hiddenMobile) mobileInput.value=hiddenMobile.value;
clearAutoBackupTimer();
autoBackupTriggered=false;
backupResendConsumed=false;
forcedBackupPendingMeta=null;
this.isRunning=false;
this.expired=true;
this.rafId=null;
}};
this.rafId=window.requestAnimationFrame(draw);
};
this.stop=()=> {
if(this.rafId){
window.cancelAnimationFrame(this.rafId);
this.rafId=null;
}
this.runId +=1;
this.isRunning=false;
this.expired=false;
};
this.hasExpired=()=> {
return this.expired===true;
};}});