(()=>{ 'use strict'; const VERSION='17.7.3-auth-security-v1'; const PENDING_REGISTRATION_KEY='sunPendingRegistrationV23'; let busy=false; const $=id=>document.getElementById(id); const cloud=()=>window.SunCloudV2||null; const client=()=>cloud()?.getClient?.()||null; const esc=value=>window.SunSafe?.escapeHTML?window.SunSafe.escapeHTML(String(value??'')):String(value??''); function redirectUrl(){ try{ const u=new URL(location.href); u.hash=''; return u.toString(); }catch(_){return location.href.split('#')[0];} } function savePendingRegistration(email,companyName){ try{ localStorage.setItem(PENDING_REGISTRATION_KEY,JSON.stringify({ email:String(email||'').trim().toLowerCase(), companyName:String(companyName||'').trim()||'Новая компания', createdAt:new Date().toISOString() })); }catch(_){} } function clearPendingRegistration(){ try{localStorage.removeItem(PENDING_REGISTRATION_KEY)}catch(_){} } function setError(root,message){ const node=root?.querySelector?.('#sunGateErrorV3'); if(node)node.textContent=String(message||''); } function friendlySignupError(error){ const message=String(error?.message||error||'Не удалось создать аккаунт.'); if(/email address not authorized/i.test(message)){ return 'Не удалось отправить письмо подтверждения. Обратитесь к администратору Caterium.'; } if(/rate limit|rate_limit|too many/i.test(message)){ return 'Слишком много попыток регистрации. Попробуйте немного позже.'; } return message; } async function signOutUnsafeSession(c){ try{await c?.auth?.signOut?.()}catch(_){} } function showPublicConfirmation(gate,email){ if(!gate)return; gate.innerHTML=`
Caterium

Подтвердите email

Безопасная регистрация Caterium

Мы отправили письмо на ${esc(email)}. Откройте письмо и нажмите ссылку подтверждения. После подтверждения Caterium откроется автоматически.

`; gate.querySelector('#sunAuthGoLoginV1774')?.addEventListener('click',()=>{gate.remove();document.body.classList.remove('sun-cloud-auth-required');setTimeout(()=>window.SunEnterprise?.ensureAuthGate?.(),30);location.reload();},{once:true}); } function showInviteConfirmation(gate,email){ if(!gate)return; gate.innerHTML=`
Caterium

Подтвердите email

Приглашение сохранено

Письмо подтверждения отправлено на ${esc(email)}. Подтвердите адрес по ссылке в письме. После возврата в Caterium приглашение останется доступно.

`; gate.querySelector('#sunInviteReloadV1774')?.addEventListener('click',()=>location.reload(),{once:true}); } async function publicSignup(gate){ if(busy)return; const c=client(); if(!c){setError(gate,'Облачный сервис не подключён.');return;} const email=String($('sunGateEmailV3')?.value||'').trim().toLowerCase(); const password=String($('sunGatePasswordV3')?.value||''); const password2=String($('sunGatePassword2V27')?.value||''); const companyName=String($('sunGateCompanyV3')?.value||'').trim(); if(!companyName){setError(gate,'Введите название компании.');return;} if(!email||password.length<6){setError(gate,'Введите email и пароль минимум из 6 символов.');return;} if(password!==password2){setError(gate,'Пароли не совпадают.');return;} busy=true; const button=$('sunGateSubmitV3');if(button)button.disabled=true; setError(gate,'Создаю безопасный аккаунт…'); savePendingRegistration(email,companyName); try{ const existing=await c.auth.signInWithPassword({email,password}); if(!existing.error&&existing.data?.session){ location.reload(); return; } const result=await c.auth.signUp({ email, password, options:{ emailRedirectTo:redirectUrl(), data:{company_name:companyName} } }); if(result.error)throw result.error; if(result.data?.session){ await signOutUnsafeSession(c); throw new Error('Защита email ещё не активирована на сервере. Регистрация остановлена, чтобы не создавать неподтверждённый аккаунт.'); } showPublicConfirmation(gate,email); }catch(error){ clearPendingRegistration(); setError(gate,friendlySignupError(error)); if(button)button.disabled=false; }finally{busy=false;} } async function acceptInviteAfterLogin(token,gate){ const api=cloud(); const ws=await api?.acceptInvite?.(token); if(!ws)throw new Error('Не удалось присоединиться к компании.'); try{const u=new URL(location.href);u.searchParams.delete('invite');history.replaceState(null,'',u.toString())}catch(_){} location.reload(); } async function inviteSignup(gate){ if(busy)return; const c=client(); if(!c){setError(gate,'Облачный сервис не подключён.');return;} const email=String($('sunInviteEmailV27')?.value||'').trim().toLowerCase(); const name=String($('sunInviteNameV27')?.value||'').trim(); const password=String($('sunInvitePasswordV27')?.value||''); const password2=String($('sunInvitePassword2V27')?.value||''); let token='';try{token=String(new URL(location.href).searchParams.get('invite')||'').trim()}catch(_){} if(!token){setError(gate,'Ссылка приглашения повреждена.');return;} if(!email||password.length<6){setError(gate,'Пароль должен содержать минимум 6 символов.');return;} if(password!==password2){setError(gate,'Пароли не совпадают.');return;} busy=true; const button=$('sunInviteJoinV27');if(button)button.disabled=true; setError(gate,'Проверяю аккаунт…'); try{ const existing=await c.auth.signInWithPassword({email,password}); if(!existing.error&&existing.data?.session){ await acceptInviteAfterLogin(token,gate); return; } const result=await c.auth.signUp({ email, password, options:{ emailRedirectTo:redirectUrl(), data:{name} } }); if(result.error)throw result.error; if(result.data?.session){ await signOutUnsafeSession(c); throw new Error('Защита email ещё не активирована на сервере. Приглашение остановлено, чтобы не создавать неподтверждённый аккаунт.'); } showInviteConfirmation(gate,email); }catch(error){ setError(gate,friendlySignupError(error)); if(button)button.disabled=false; }finally{busy=false;} } function publicRegistrationMode(){ const fields=$('sunGateRegisterFieldsV27'); return Boolean(fields&&!fields.hidden); } document.addEventListener('click',event=>{ const target=event.target instanceof Element?event.target:null; if(!target)return; if(target.closest('#sunGateSubmitV3')&&publicRegistrationMode()){ event.preventDefault();event.stopImmediatePropagation(); publicSignup($('sunCloudAuthGateV3')).catch(error=>setError($('sunCloudAuthGateV3'),friendlySignupError(error))); return; } if(target.closest('#sunInviteJoinV27')){ event.preventDefault();event.stopImmediatePropagation(); inviteSignup($('sunCloudAuthGateV3')).catch(error=>setError($('sunCloudAuthGateV3'),friendlySignupError(error))); } },true); document.addEventListener('keydown',event=>{ if(event.key!=='Enter')return; const target=event.target instanceof Element?event.target:null; if(target?.id==='sunGatePassword2V27'&&publicRegistrationMode()){ event.preventDefault();event.stopImmediatePropagation(); publicSignup($('sunCloudAuthGateV3')).catch(error=>setError($('sunCloudAuthGateV3'),friendlySignupError(error))); }else if(target?.id==='sunInvitePassword2V27'){ event.preventDefault();event.stopImmediatePropagation(); inviteSignup($('sunCloudAuthGateV3')).catch(error=>setError($('sunCloudAuthGateV3'),friendlySignupError(error))); } },true); window.CateriumAuthSecurityV1774=Object.freeze({VERSION,redirectUrl}); })();