fix: remove legacy login flash during session restoration
This commit is contained in:
parent
6472dba7ee
commit
4fe984b584
@ -11,7 +11,7 @@
|
||||
"serverReady": true,
|
||||
"workspaceAutoDiscovery": true,
|
||||
"invitesTemporarilyDisabled": false,
|
||||
"pwaCache": "v95-20260918-proposal-loading",
|
||||
"pwaCache": "v96-20260918-single-login",
|
||||
"fullOfferDescriptions": true,
|
||||
"dynamicOfferRows": true,
|
||||
"pdfOfferDescriptionFix": true,
|
||||
@ -393,6 +393,9 @@
|
||||
"supabaseProjectRef": "usfjwhztqoopzzfmfbis",
|
||||
"recoveryMigration": "20260917150000_fresh_caterium",
|
||||
"anonymousAccessDisabled": true,
|
||||
"singleLoginFirstPaint": true,
|
||||
"loginWaitsForSessionRestore": true,
|
||||
"legacyLocalLoginRemoved": true,
|
||||
"clientCacheTenantIsolation": true,
|
||||
"trialDemo": {
|
||||
"version": 1,
|
||||
|
||||
9
docs/releases/2026-09-18-SINGLE-LOGIN.md
Normal file
9
docs/releases/2026-09-18-SINGLE-LOGIN.md
Normal file
@ -0,0 +1,9 @@
|
||||
# One login screen from the first frame
|
||||
|
||||
Release cache: `v96-20260918-single-login`.
|
||||
|
||||
The older blue/white email/password card could appear before the asynchronously loaded login decoration script. A saved session also initially looked signed out while the SDK restored it. The current cream login stylesheet is now loaded directly by the document and cached with the application. Its title, company mark and fields are created in their final form, independent of optional decoration JavaScript. The obsolete card styles and old local user/PIN popup have been removed.
|
||||
|
||||
An explicit session-restoration state keeps email/password fields absent until the SDK confirms that login is necessary. Startup shows a neutral Caterium loading message instead of imitation input fields. Startup cover cleanup works even if the decorative script fails. SDK loading and session restoration have deadlines, and authentication remains required; the emergency local switch remains disabled.
|
||||
|
||||
Regression coverage delays session restoration, blocks the decorative script, seeds old local-role preferences, switches login/registration modes, and verifies the authenticated app opens without ever mounting a password form. Existing account separation, real SDK login and retry checks remain enabled.
|
||||
@ -2181,6 +2181,7 @@ window.SUN_LEGACY_CATALOG_V175=[];
|
||||
let client = null;
|
||||
let clientSignature = '';
|
||||
let session = null;
|
||||
let authLoading = true;
|
||||
let memberships = [];
|
||||
let workspace = null;
|
||||
let supportMode = null;
|
||||
@ -3181,13 +3182,14 @@ window.SUN_LEGACY_CATALOG_V175=[];
|
||||
const existing=$('sunSupabaseJsV2');
|
||||
if(existing){for(let i=0;i<80&&!window.supabase?.createClient;i++)await sleep(100);if(window.supabase?.createClient)return;}
|
||||
await new Promise((resolve,reject)=>{
|
||||
const script=document.createElement('script');script.id='sunSupabaseJsV2';script.src=SUPABASE_JS;script.async=true;script.onload=resolve;script.onerror=()=>reject(new Error('Не удалось загрузить библиотеку Supabase. Проверьте интернет.'));document.head.appendChild(script);
|
||||
const script=document.createElement('script'),timer=setTimeout(()=>{script.remove();reject(new Error('Не удалось загрузить сервис входа. Обновите страницу и проверьте интернет.'))},12000);script.id='sunSupabaseJsV2';script.src=SUPABASE_JS;script.async=true;script.onload=()=>{clearTimeout(timer);resolve()};script.onerror=()=>{clearTimeout(timer);script.remove();reject(new Error('Не удалось загрузить библиотеку Supabase. Проверьте интернет.'))};document.head.appendChild(script);
|
||||
});
|
||||
if(!window.supabase?.createClient)throw new Error('Supabase SDK не загрузился.');
|
||||
}
|
||||
|
||||
async function connectFromConfig(silent=true) {
|
||||
if(!config.url||!config.key){setStatus('local','Облако не подключено.');return;}
|
||||
if(!config.url||!config.key){finishAuthRestore();setStatus('local','Облако не подключено.');return;}
|
||||
authLoading=true;
|
||||
setStatus('syncing','Подключаю Supabase…');
|
||||
try{
|
||||
await loadSupabaseLibrary();
|
||||
@ -3196,7 +3198,7 @@ window.SUN_LEGACY_CATALOG_V175=[];
|
||||
client=window.supabase.createClient(config.url,config.key,{auth:{persistSession:true,autoRefreshToken:true,detectSessionInUrl:true},global:{fetch:supabaseProxyFetch}});clientSignature=signature;
|
||||
client.auth.onAuthStateChange((_event,next)=>{const changed=session?.user?.id!==next?.user?.id;if(changed)window.CateriumBranding?.resetSidebar();session=next;if(!changed&&(membershipsLoading||(membershipsLoaded&&!membershipError)))return;membershipsLoading=Boolean(next?.user);membershipsLoaded=!next?.user;setTimeout(async()=>{try{if(!next?.user){const sw=await switchTenantLocal('');if(sw.changed){location.reload();return;}}else{const sw=await loadMemberships();if(sw){location.reload();return;}}}finally{renderCloudUI();updatePill();}},0);});
|
||||
}
|
||||
const {data,error}=await client.auth.getSession();if(error)throw error;session=data.session||null;
|
||||
const {data,error}=await sunCloudAwait(client.auth.getSession(),'Проверка входа');if(error)throw error;session=data.session||null;finishAuthRestore();
|
||||
const tenantSwitched=session?await loadMemberships():(await switchTenantLocal('')).changed;
|
||||
if(tenantSwitched){location.reload();return;}
|
||||
if(session&&workspace){
|
||||
@ -3213,7 +3215,12 @@ window.SUN_LEGACY_CATALOG_V175=[];
|
||||
else setStatus('auth','Подключено. Войдите в аккаунт.');
|
||||
if(!silent)toast('Supabase подключён.','success');
|
||||
}catch(error){handleError(error,'Не удалось подключиться к Supabase.');}
|
||||
finally{renderCloudUI();}
|
||||
finally{finishAuthRestore();renderCloudUI();}
|
||||
}
|
||||
|
||||
function finishAuthRestore(){
|
||||
if(!authLoading)return;authLoading=false;
|
||||
window.dispatchEvent(new CustomEvent('sun:cloud-permissions-changed'));
|
||||
}
|
||||
|
||||
async function signIn(signUp) {
|
||||
@ -3468,12 +3475,12 @@ window.SUN_LEGACY_CATALOG_V175=[];
|
||||
setAutoSyncDeveloper,
|
||||
snapshotLocal:()=>collectLocalPayload(),
|
||||
reloadMemberships:async()=>{await loadMemberships();renderCloudUI();return workspace?clone(workspace):null;},
|
||||
status:()=>({connected:Boolean(client),signedIn:Boolean(session),supportMode:supportMode?clone(supportMode):null,workspace:workspace?clone(workspace):null,membershipsLoading,membershipsLoaded,membershipError,membershipCount:memberships.length,dirty,lastStatus,lastError})
|
||||
status:()=>({connected:Boolean(client),signedIn:Boolean(session),authLoading,supportMode:supportMode?clone(supportMode):null,workspace:workspace?clone(workspace):null,membershipsLoading,membershipsLoaded,membershipError,membershipCount:memberships.length,dirty,lastStatus,lastError})
|
||||
};
|
||||
|
||||
async function boot(){
|
||||
injectStyles();disableLegacyCloud();installStorageTracking();hookEnterpriseSchedule();observeSettings();updatePill();
|
||||
if(config.url&&config.key)await connectFromConfig(true);else setStatus('local','Облако не подключено. Откройте Настройки → Облако Supabase.');
|
||||
if(config.url&&config.key)await connectFromConfig(true);else{finishAuthRestore();setStatus('local','Облако не подключено. Откройте Настройки → Облако Supabase.');}
|
||||
}
|
||||
|
||||
if(document.readyState==='loading')document.addEventListener('DOMContentLoaded',boot,{once:true});else boot();
|
||||
@ -3564,7 +3571,7 @@ window.SUN_LEGACY_CATALOG_V175=[];
|
||||
.sun-rbac-toolbar{display:flex;gap:8px;align-items:center;justify-content:space-between;flex-wrap:wrap;margin:8px 0 12px}
|
||||
.sun-rbac-members{display:grid;gap:8px}.sun-rbac-member{display:grid;grid-template-columns:minmax(220px,1.4fr) minmax(150px,.7fr) auto;gap:10px;align-items:center;border:1px solid #dfe5e8;border-radius:10px;padding:10px 12px;background:#fff}
|
||||
.sun-rbac-member small{display:block;color:#75808a;margin-top:3px}.sun-rbac-off{opacity:.58}.sun-rbac-perm-groups{display:grid;grid-template-columns:repeat(2,minmax(0,1fr));gap:10px;margin-top:12px}.sun-rbac-group{border:1px solid #dfe5e8;border-radius:10px;padding:10px;background:#fafcfc}.sun-rbac-group h4{margin:0 0 8px;color:#17384d}.sun-rbac-check{display:flex!important;flex-direction:row!important;align-items:center!important;gap:8px!important;margin:6px 0!important}.sun-rbac-check input{width:17px!important;height:17px!important;flex:0 0 auto}.sun-rbac-role-line{display:grid;grid-template-columns:1.2fr 1fr auto;gap:10px;align-items:end}.sun-rbac-danger{margin-left:auto}.sun-rbac-section-title{display:flex;align-items:center;justify-content:space-between;gap:10px;margin:18px 0 8px}.sun-rbac-section-title h3{margin:0;color:#17384d;font-size:15px}.sun-rbac-invite{display:grid;grid-template-columns:minmax(190px,1.2fr) minmax(130px,.65fr) auto;gap:10px;align-items:center;border:1px dashed #cfd9df;border-radius:10px;padding:10px 12px;background:#fbfcfc}.sun-rbac-invite small{display:block;color:#75808a;margin-top:3px}.sun-rbac-invite-form{border:1px solid #dfe5e8;border-radius:12px;padding:14px;background:#fbfcfc}.sun-rbac-invite-grid{display:grid;grid-template-columns:1.2fr 1.5fr 1fr;gap:10px}.sun-rbac-linkbox{margin-top:12px;padding:10px;border-radius:9px;background:#f1f5f6;word-break:break-all;font:600 12px/1.45 ui-monospace,monospace}.sun-rbac-lock-note{font-size:12px;color:#6e7880;margin-top:6px}.sun-cloud-identity-v3{font-size:12px;color:#adc0cc;padding:3px 7px}.sun-cloud-pin-card{border-top:1px solid #e2e7e9;margin-top:10px;padding-top:10px}
|
||||
body.sun-cloud-auth-required .view,body.sun-cloud-auth-required header{filter:blur(2px);pointer-events:none;user-select:none}.sun-cloud-auth-gate{position:fixed;inset:0;z-index:10000;background:#132f44eb;display:grid;place-items:center;padding:20px}.sun-cloud-auth-card{width:min(430px,100%);background:#fff;border-radius:16px;padding:22px;box-shadow:0 24px 80px #0005}.sun-cloud-auth-brand{display:flex;align-items:center;gap:12px;margin-bottom:16px}.sun-cloud-auth-brand img{width:58px;height:58px;object-fit:contain}.sun-cloud-auth-card h2{margin:0;color:#17384d}.sun-cloud-auth-card label{display:block;margin:10px 0}.sun-cloud-auth-card input{width:100%}.sun-auth-password{position:relative}.sun-auth-password input{padding-right:46px}.sun-auth-eye{position:absolute;right:7px;bottom:6px;width:34px;height:34px;border:0;background:transparent;border-radius:8px;cursor:pointer;font-size:17px;color:#536674}.sun-auth-eye:hover{background:#eef2f3}.sun-auth-switch{margin:14px 0 0;text-align:center;font-size:13px}.sun-auth-switch button{border:0;background:transparent;color:#245c7c;font-weight:800;cursor:pointer;text-decoration:underline;text-underline-offset:3px}.sun-cloud-auth-actions{display:flex;gap:8px;flex-wrap:wrap;margin-top:12px}.sun-cloud-auth-error{color:#9a3838;font-size:12px;margin-top:8px;min-height:18px}.sun-auth-mode-tabs{display:grid;grid-template-columns:1fr 1fr;gap:6px;background:#f2f4f5;border-radius:11px;padding:4px;margin:10px 0 14px}.sun-auth-mode-tabs button{border:0;border-radius:8px;padding:9px 10px;background:transparent;font-weight:800;cursor:pointer}.sun-auth-mode-tabs button.on{background:#fff;box-shadow:0 2px 10px #0001;color:#17384d}.sun-auth-trial{background:#eef8f2;color:#286447;border-radius:10px;padding:10px 11px;font-size:12px;font-weight:700;margin:10px 0}.sun-auth-success{background:#eef8f2;color:#286447;border-radius:10px;padding:10px 11px;font-size:12px;margin-top:10px}
|
||||
body.sun-cloud-auth-required .view,body.sun-cloud-auth-required header{filter:blur(2px);pointer-events:none;user-select:none}.sun-auth-password{position:relative}.sun-auth-password input{padding-right:46px}.sun-auth-eye{position:absolute;right:7px;bottom:6px;width:34px;height:34px;border:0;background:transparent;border-radius:8px;cursor:pointer;font-size:17px;color:#536674}.sun-auth-eye:hover{background:#eef2f3}.sun-auth-switch{margin:14px 0 0;text-align:center;font-size:13px}.sun-auth-switch button{border:0;background:transparent;color:#245c7c;font-weight:800;cursor:pointer;text-decoration:underline;text-underline-offset:3px}.sun-cloud-auth-actions{display:flex;gap:8px;flex-wrap:wrap;margin-top:12px}.sun-cloud-auth-error{color:#9a3838;font-size:12px;margin-top:8px;min-height:18px}.sun-auth-mode-tabs{display:grid;grid-template-columns:1fr 1fr;gap:6px;background:#f2f4f5;border-radius:11px;padding:4px;margin:10px 0 14px}.sun-auth-mode-tabs button{border:0;border-radius:8px;padding:9px 10px;background:transparent;font-weight:800;cursor:pointer}.sun-auth-mode-tabs button.on{background:#fff;box-shadow:0 2px 10px #0001;color:#17384d}.sun-auth-trial{background:#eef8f2;color:#286447;border-radius:10px;padding:10px 11px;font-size:12px;font-weight:700;margin:10px 0}.sun-auth-success{background:#eef8f2;color:#286447;border-radius:10px;padding:10px 11px;font-size:12px;margin-top:10px}
|
||||
@media(max-width:760px){.sun-rbac-perm-groups{grid-template-columns:1fr}.sun-rbac-member,.sun-rbac-invite{grid-template-columns:1fr}.sun-rbac-role-line,.sun-rbac-invite-grid{grid-template-columns:1fr}}
|
||||
`;document.head.appendChild(style);
|
||||
}
|
||||
@ -3829,7 +3836,7 @@ window.SUN_LEGACY_CATALOG_V175=[];
|
||||
function currentInviteToken(){try{return String(new URL(location.href).searchParams.get(INVITE_QUERY_KEY)||'').trim()}catch(_){return ''}}
|
||||
function clearInviteFromUrl(){try{const u=new URL(location.href);u.searchParams.delete(INVITE_QUERY_KEY);history.replaceState(null,'',u.toString())}catch(_){}}
|
||||
function passwordField(id,label,autocomplete='current-password'){
|
||||
return `<label>${esc(label)}<div class="sun-auth-password"><input id="${id}" type="password" autocomplete="${autocomplete}"><button class="sun-auth-eye" type="button" data-toggle-password="${id}" aria-label="Показать пароль">◉</button></div></label>`;
|
||||
return `<label class="caterium-clean-field caterium-password-field">${esc(label)}<div class="sun-auth-password"><input id="${id}" placeholder="${esc(label)}" type="password" autocomplete="${autocomplete}"><button class="sun-auth-eye" type="button" data-toggle-password="${id}" aria-label="Показать пароль">◉</button></div></label>`;
|
||||
}
|
||||
function bindPasswordEyes(root){qa('[data-toggle-password]',root).forEach(b=>b.onclick=()=>{const i=root.querySelector(`#${b.dataset.togglePassword}`);if(!i)return;i.type=i.type==='password'?'text':'password';b.textContent=i.type==='password'?'◉':'×';b.setAttribute('aria-label',i.type==='password'?'Показать пароль':'Скрыть пароль');});}
|
||||
async function getInvitePreview(token){
|
||||
@ -3869,11 +3876,15 @@ window.SUN_LEGACY_CATALOG_V175=[];
|
||||
}
|
||||
if(st.signedIn&&ws){$('sunCloudAuthGateV3')?.remove();document.body.classList.remove('sun-cloud-auth-required');try{localStorage.removeItem(LOCAL_ONLY_KEY)}catch(_){}return;}
|
||||
if(!st.signedIn&&window.CateriumAccessPolicy?.emergencyLocalActive()){$('sunCloudAuthGateV3')?.remove();document.body.classList.remove('sun-cloud-auth-required');return;}
|
||||
const gateState=st.signedIn?(st.membershipsLoading?'loading':st.membershipError?'error':'missing'):'login';
|
||||
const gateState=st.signedIn?(st.membershipsLoading?'loading':st.membershipError?'error':'missing'):st.authLoading?'restoring':'login';
|
||||
const currentGate=$('sunCloudAuthGateV3');
|
||||
if(currentGate){if(st.signedIn&¤tGate.dataset.authState!==gateState)currentGate.remove();else{if(st.signedIn){const e=$('sunGateErrorV3');if(e)e.textContent=st.membershipsLoading?'Загружаю рабочую базу…':st.membershipError||e.textContent;}return;}}
|
||||
if(currentGate){if(currentGate.dataset.authState!==gateState)currentGate.remove();else{if(st.signedIn){const e=$('sunGateErrorV3');if(e)e.textContent=st.membershipsLoading?'Загружаю рабочую базу…':st.membershipError||e.textContent;}return;}}
|
||||
document.body.classList.add('sun-cloud-auth-required');
|
||||
const gate=document.createElement('div');gate.id='sunCloudAuthGateV3';gate.className='sun-cloud-auth-gate';gate.dataset.authState=gateState;
|
||||
if(gateState==='restoring'){
|
||||
gate.innerHTML='<div class="sun-cloud-auth-card"><div class="caterium-signature-brand"><img class="caterium-signature-mark" src="caterium-mark-light.svg" alt=""><span class="caterium-signature-word">Caterium</span></div><div class="sun-cloud-auth-brand"><h2>Открываю Caterium…</h2><p class="hint" role="status">Проверяю сохранённый вход</p></div></div>';
|
||||
document.body.appendChild(gate);return;
|
||||
}
|
||||
if(st.signedIn&&st.membershipError){
|
||||
gate.innerHTML=`<div class="sun-cloud-auth-card"><h2>Не удалось загрузить рабочую базу</h2><p class="hint">${esc(ss?.user?.email||'Аккаунт авторизован')}</p><p class="hint">Вход выполнен, но сервер не вернул данные компании. Повторите загрузку.</p><div class="sun-cloud-auth-error" id="sunGateErrorV3">${esc(st.membershipError)}</div><div class="sun-cloud-auth-actions"><button class="primary" id="sunGateRetryWorkspaceV3" type="button">Повторить загрузку</button><button class="outline" id="sunGateSignOutV3" type="button">Выйти</button></div></div>`;
|
||||
document.body.appendChild(gate);
|
||||
@ -3887,12 +3898,12 @@ window.SUN_LEGACY_CATALOG_V175=[];
|
||||
gate.querySelector('#sunGateRetryWorkspaceV3').onclick=async()=>{const e=gate.querySelector('#sunGateErrorV3');if(getPendingRegistration(ss.user.email||''))return finishPendingRegistration(gate,ss.user.email||'');if(!st.membershipsLoading){const companyName=String(gate.querySelector('#sunGateRecoveryCompanyV25')?.value||'').trim();if(!companyName){e.textContent='Введите название компании.';return;}savePendingRegistration(ss.user.email||'',companyName);return finishPendingRegistration(gate,ss.user.email||'');}e.textContent='Проверяю доступ…';try{const found=await cloud()?.reloadMemberships?.();if(found){gate.remove();document.body.classList.remove('sun-cloud-auth-required');await cloud()?.pull?.();setTimeout(applyNavPermissions,100);}else e.textContent='Рабочая база для этого аккаунта не найдена.';}catch(err){e.textContent=errText(err,'Не удалось проверить доступ.');}};
|
||||
gate.querySelector('#sunGateSignOutV3').onclick=async()=>{if(window.SunCloudV2?.signOut)return window.SunCloudV2.signOut();try{await client()?.auth.signOut();}catch(_){}location.reload();};return;
|
||||
}
|
||||
gate.innerHTML=`<div class="sun-cloud-auth-card"><div class="sun-cloud-auth-brand"><img src="caterium-login-logo.png" alt="Caterium"><div><h2 id="sunGateTitleV3">Вход в Caterium</h2><div class="hint" id="sunGateSubtitleV3">Введите данные своего аккаунта</div></div></div><div id="sunGateRegisterFieldsV27" hidden><label>Название компании<input id="sunGateCompanyV3" autocomplete="organization" placeholder="Например, Мой Кейтеринг"></label></div><label>Email<input id="sunGateEmailV3" type="email" autocomplete="username"></label>${passwordField('sunGatePasswordV3','Пароль','current-password')}<div id="sunGateConfirmWrapV27" hidden>${passwordField('sunGatePassword2V27','Подтвердите пароль','new-password')}</div><div class="sun-cloud-auth-actions"><button class="primary" id="sunGateSubmitV3" type="button">Войти</button></div><div class="sun-cloud-auth-error" id="sunGateErrorV3"></div><p class="sun-auth-switch"><span id="sunGateSwitchTextV27">Нет аккаунта?</span> <button type="button" id="sunGateSwitchV27">Создать аккаунт</button></p><p class="sun-auth-switch"><button type="button" id="sunGateLocalOnlyV1" style="background:none;border:0;padding:0;color:inherit;opacity:.6;text-decoration:underline;cursor:pointer;font:inherit">Работать локально без интернета</button></p></div>`;document.body.appendChild(gate);bindPasswordEyes(gate);
|
||||
gate.innerHTML=`<div class="sun-cloud-auth-card"><div class="caterium-signature-brand"><img class="caterium-signature-mark" src="caterium-mark-light.svg" alt=""><span class="caterium-signature-word">Caterium</span></div><div class="sun-cloud-auth-brand"><div><h2 id="sunGateTitleV3">Войти в рабочее пространство</h2><div class="hint" id="sunGateSubtitleV3">Ваши заказы. Ваша команда. Ваш результат.</div></div></div><div id="sunGateRegisterFieldsV27" hidden><label>Название компании<input id="sunGateCompanyV3" autocomplete="organization" placeholder="Например, Мой Кейтеринг"></label></div><label class="caterium-clean-field caterium-email-field">Email<input id="sunGateEmailV3" placeholder="Email" type="email" autocomplete="username"></label>${passwordField('sunGatePasswordV3','Пароль','current-password')}<div id="sunGateConfirmWrapV27" hidden>${passwordField('sunGatePassword2V27','Подтвердите пароль','new-password')}</div><div class="sun-cloud-auth-actions"><button class="primary" id="sunGateSubmitV3" type="button">Войти</button></div><div class="sun-cloud-auth-error" id="sunGateErrorV3"></div><p class="sun-auth-switch"><span id="sunGateSwitchTextV27">Нет аккаунта?</span> <button type="button" id="sunGateSwitchV27">Создать аккаунт</button></p><p class="sun-auth-switch"><button type="button" id="sunGateLocalOnlyV1" style="background:none;border:0;padding:0;color:inherit;opacity:.6;text-decoration:underline;cursor:pointer;font:inherit">Работать локально без интернета</button></p></div>`;document.body.appendChild(gate);bindPasswordEyes(gate);
|
||||
const localOnlyButton=gate.querySelector('#sunGateLocalOnlyV1');
|
||||
if(window.CateriumAccessPolicy?.emergencyLocalEnabled){localOnlyButton.onclick=()=>{try{localStorage.setItem(LOCAL_ONLY_KEY,'1')}catch(_){}location.reload();};}
|
||||
else localOnlyButton.closest('p').remove();
|
||||
const emailInput=gate.querySelector('#sunGateEmailV3'),passwordInput=gate.querySelector('#sunGatePasswordV3'),password2Input=gate.querySelector('#sunGatePassword2V27'),companyInput=gate.querySelector('#sunGateCompanyV3'),submitBtn=gate.querySelector('#sunGateSubmitV3'),gateError=gate.querySelector('#sunGateErrorV3');let registerMode=false;
|
||||
const setMode=(registration)=>{registerMode=Boolean(registration);gate.querySelector('#sunGateRegisterFieldsV27').hidden=!registerMode;gate.querySelector('#sunGateConfirmWrapV27').hidden=!registerMode;gate.querySelector('#sunGateTitleV3').textContent=registerMode?'Создать аккаунт Caterium':'Вход в Caterium';gate.querySelector('#sunGateSubtitleV3').textContent=registerMode?'Заполните данные — после регистрации Caterium откроется автоматически':'Введите данные своего аккаунта';submitBtn.textContent=registerMode?'Создать аккаунт':'Войти';gate.querySelector('#sunGateSwitchTextV27').textContent=registerMode?'Уже есть аккаунт?':'Нет аккаунта?';gate.querySelector('#sunGateSwitchV27').textContent=registerMode?'Войти':'Создать аккаунт';passwordInput.autocomplete=registerMode?'new-password':'current-password';gateError.textContent='';if(registerMode)setTimeout(()=>companyInput.focus(),30);else setTimeout(()=>emailInput.focus(),30)};
|
||||
const setMode=(registration)=>{registerMode=Boolean(registration);gate.querySelector('#sunGateRegisterFieldsV27').hidden=!registerMode;gate.querySelector('#sunGateConfirmWrapV27').hidden=!registerMode;gate.querySelector('#sunGateTitleV3').textContent=registerMode?'Создать аккаунт Caterium':'Войти в рабочее пространство';gate.querySelector('#sunGateSubtitleV3').textContent=registerMode?'Заполните данные — после регистрации Caterium откроется автоматически':'Ваши заказы. Ваша команда. Ваш результат.';submitBtn.textContent=registerMode?'Создать аккаунт':'Войти';gate.querySelector('#sunGateSwitchTextV27').textContent=registerMode?'Уже есть аккаунт?':'Нет аккаунта?';gate.querySelector('#sunGateSwitchV27').textContent=registerMode?'Войти':'Создать аккаунт';passwordInput.autocomplete=registerMode?'new-password':'current-password';gateError.textContent='';if(registerMode)setTimeout(()=>companyInput.focus(),30);else setTimeout(()=>emailInput.focus(),30)};
|
||||
async function auth(){const c=client(),email=emailInput.value.trim(),password=passwordInput.value,password2=password2Input.value,companyName=String(companyInput.value||'').trim();if(!c){gateError.textContent='Облачный сервис не подключён.';return;}if(registerMode&&!companyName){gateError.textContent='Введите название компании.';return;}if(!email||password.length<6){gateError.textContent='Введите email и пароль минимум из 6 символов.';return;}if(registerMode&&password!==password2){gateError.textContent='Пароли не совпадают.';return;}submitBtn.disabled=true;gateError.textContent=registerMode?'Создаю аккаунт…':'Выполняю вход…';try{let r;if(registerMode){savePendingRegistration(email,companyName);const existing=await c.auth.signInWithPassword({email,password});if(!existing.error&&existing.data.session){r=existing;}else{r=await c.auth.signUp({email,password,options:{data:{company_name:companyName,registration_source:'caterium_public_signup'}}});if(r.error)throw r.error;if(!r.data.session){const retry=await c.auth.signInWithPassword({email,password});if(retry.error){clearPendingRegistration();throw new Error('Этот email уже зарегистрирован. Войдите в аккаунт или восстановите пароль.');}r=retry;}}}else r=await c.auth.signInWithPassword({email,password});if(r.error)throw r.error;const authUser=r.data.user||r.data.session?.user||null;const userId=authUser?.id||'';if(userId)sessionStorage.setItem(`sunCloudQuickPinUnlockedV3:${userId}`,'1');gateError.textContent=registerMode?'Аккаунт готов. Создаю компанию…':'Вход выполнен. Загружаю рабочую базу…';setTimeout(async()=>{await cloud()?.reloadMemberships?.();if(registerMode&&workspace()){clearPendingRegistration();gate.remove();document.body.classList.remove('sun-cloud-auth-required');await cloud()?.pull?.();applyNavPermissions();return;}if(getPendingRegistration(email)&&!workspace()){await finishPendingRegistration(gate,email);return;}if(workspace()){gate.remove();document.body.classList.remove('sun-cloud-auth-required');await cloud()?.pull?.();applyNavPermissions();}else{gate.remove();ensureAuthGate();}},180);}catch(err){gateError.textContent=errText(err,'Не удалось выполнить операцию.')}finally{submitBtn.disabled=false}}
|
||||
gate.querySelector('#sunGateSwitchV27').onclick=()=>setMode(!registerMode);submitBtn.onclick=auth;passwordInput.addEventListener('keydown',e=>{if(e.key==='Enter'&&!registerMode)auth()});password2Input.addEventListener('keydown',e=>{if(e.key==='Enter'&®isterMode)auth()});setMode(false);
|
||||
}
|
||||
|
||||
20
public/core/login-signature-v1776.css
Normal file
20
public/core/login-signature-v1776.css
Normal file
@ -0,0 +1,20 @@
|
||||
|
||||
body.sun-cloud-auth-required{overflow:hidden!important;background:#f5f0e7!important}body.sun-cloud-auth-required>header,body.sun-cloud-auth-required>.view{visibility:hidden!important}
|
||||
#sunCloudAuthGateV3.sun-cloud-auth-gate{position:fixed!important;inset:0!important;z-index:20000!important;overflow:auto!important;display:grid!important;place-items:center!important;padding:clamp(32px,6vh,78px) clamp(24px,8vw,120px)!important;background:radial-gradient(circle at 18% 18%,rgba(255,255,255,.92),transparent 34%),radial-gradient(circle at 77% 22%,rgba(255,255,255,.5),transparent 28%),linear-gradient(135deg,#f8f4ec 0%,#f2ece1 56%,#f7f3eb 100%)!important;color:#282621!important}
|
||||
#sunCloudAuthGateV3.sun-cloud-auth-gate:before{content:'C';position:fixed;z-index:0;left:-7vw;top:49%;transform:translateY(-50%);pointer-events:none;font:400 min(72vw,860px)/.72 Georgia,'Times New Roman',serif;color:rgba(73,67,59,.032)}
|
||||
#sunCloudAuthGateV3.sun-cloud-auth-gate:after{content:'';position:fixed;z-index:0;right:-7vw;bottom:-14vh;width:min(48vw,720px);height:min(70vh,850px);pointer-events:none;background:radial-gradient(ellipse at 58% 20%,rgba(67,64,58,.14) 0 7%,transparent 8%),radial-gradient(ellipse at 36% 35%,rgba(67,64,58,.13) 0 6%,transparent 7%),radial-gradient(ellipse at 68% 47%,rgba(67,64,58,.12) 0 8%,transparent 9%),linear-gradient(106deg,transparent 43%,rgba(67,64,58,.08) 44% 46%,transparent 47%);filter:blur(18px);transform:rotate(-17deg);opacity:.45}
|
||||
#sunCloudAuthGateV3 .sun-cloud-auth-card{position:relative!important;z-index:3!important;width:min(790px,100%)!important;margin:0!important;padding:0 0 58px!important;border:0!important;border-radius:0!important;background:transparent!important;color:#2c2924!important;box-shadow:none!important;backdrop-filter:none!important}
|
||||
#sunCloudAuthGateV3 .caterium-signature-brand{display:flex;align-items:center;gap:13px;margin:0 0 clamp(46px,7vh,88px)!important}.caterium-signature-mark{display:block;width:62px;height:62px;object-fit:contain;flex:0 0 62px}.caterium-signature-word{font:500 36px/1 Georgia,'Times New Roman',serif;color:#26231f;letter-spacing:-.02em}
|
||||
#sunCloudAuthGateV3 .sun-cloud-auth-brand{display:block!important;margin:0 0 35px!important}#sunCloudAuthGateV3 .sun-cloud-auth-brand img{display:none!important}#sunCloudAuthGateV3 .sun-cloud-auth-brand h2{margin:0!important;max-width:720px;color:#24211d!important;font:500 clamp(48px,5.2vw,76px)/.99 Georgia,'Times New Roman',serif!important;letter-spacing:-.045em!important}#sunCloudAuthGateV3 .sun-cloud-auth-brand .hint{margin-top:18px!important;color:#8e887f!important;font-size:clamp(16px,1.55vw,21px)!important;line-height:1.45!important;font-weight:400!important}
|
||||
#sunCloudAuthGateV3 .sun-cloud-auth-card>p.hint{color:#817b72!important}#sunCloudAuthGateV3 .sun-cloud-auth-card label{display:block!important;margin:14px 0 0!important;color:#716b62!important;font-size:12px!important;font-weight:700!important}#sunCloudAuthGateV3 label.caterium-clean-field{font-size:0!important;color:transparent!important;position:relative!important}
|
||||
#sunCloudAuthGateV3 .sun-cloud-auth-card input,#sunCloudAuthGateV3 .sun-cloud-auth-card select,#sunCloudAuthGateV3 .sun-cloud-auth-card textarea{width:100%!important;min-height:58px!important;margin-top:7px!important;padding:0 18px!important;border:1px solid #bdb5aa!important;border-radius:13px!important;background:rgba(255,255,255,.13)!important;color:#312e29!important;box-shadow:none!important;outline:none!important;font-size:16px!important;font-weight:500!important}#sunCloudAuthGateV3 label.caterium-clean-field input{margin-top:0!important;padding-left:58px!important}#sunCloudAuthGateV3 input::placeholder{color:#9c958c!important;opacity:1!important}#sunCloudAuthGateV3 input:focus{border-color:#d7a632!important;box-shadow:0 0 0 4px rgba(216,167,50,.12)!important;background:rgba(255,255,255,.5)!important}
|
||||
#sunCloudAuthGateV3 .caterium-email-field:before{content:'✉';position:absolute;z-index:2;left:20px;top:15px;color:#777168;font-size:25px;font-weight:400}#sunCloudAuthGateV3 .caterium-password-field:before{content:'♙';position:absolute;z-index:2;left:21px;top:14px;color:#777168;font-size:24px;transform:rotate(180deg);opacity:.8}
|
||||
#sunCloudAuthGateV3 .sun-auth-password{display:block!important;position:relative!important}#sunCloudAuthGateV3 .sun-auth-password input{padding-right:58px!important}#sunCloudAuthGateV3 .sun-auth-eye{right:9px!important;bottom:10px!important;width:38px!important;height:38px!important;color:#777168!important;background:transparent!important;border-radius:9px!important}
|
||||
#sunCloudAuthGateV3 .sun-cloud-auth-actions{display:block!important;margin-top:25px!important}#sunCloudAuthGateV3 .sun-cloud-auth-actions .primary,#sunCloudAuthGateV3 #sunGateSubmitV3{width:100%!important;min-height:62px!important;border:0!important;border-radius:13px!important;background:linear-gradient(100deg,#d9aa42,#efca69)!important;color:#171512!important;font-size:18px!important;font-weight:900!important;box-shadow:0 14px 34px rgba(184,135,34,.14)!important}#sunCloudAuthGateV3 #sunGateSubmitV3:after{content:' →';font-size:24px;font-weight:500;margin-left:13px}
|
||||
#sunCloudAuthGateV3 .sun-cloud-auth-actions .outline{width:100%!important;margin-top:9px!important;min-height:48px!important;border:1px solid #c9c1b6!important;border-radius:11px!important;background:rgba(255,255,255,.25)!important;color:#37332d!important}#sunCloudAuthGateV3 .sun-cloud-auth-error{min-height:19px!important;margin-top:10px!important;color:#a64c40!important;font-size:12px!important}#sunCloudAuthGateV3 .sun-auth-switch{margin:26px 0 0!important;padding-top:25px!important;border-top:1px solid #cfc7bc!important;color:#898279!important;font-size:14px!important;text-align:center!important}#sunCloudAuthGateV3 .sun-auth-switch button{border:0!important;background:transparent!important;color:#c18f24!important;text-decoration:none!important;font-weight:900!important}
|
||||
.caterium-signature-caption{position:fixed;left:42px;bottom:31px;z-index:4;color:#9d968d;font-size:9px;letter-spacing:.31em;text-transform:uppercase;pointer-events:none}.caterium-signature-caption:before{content:'';display:block;width:48px;height:2px;margin-bottom:13px;background:#d3a43c}.caterium-signature-manifesto{position:fixed;right:56px;top:44px;z-index:4;width:270px;color:#a19a91;font-size:10px;line-height:1.9;letter-spacing:.28em;text-transform:uppercase;pointer-events:none;white-space:pre-line}.caterium-flow-top{position:fixed;z-index:1;right:5.5vw;top:13vh;width:min(37vw,470px);opacity:.86;pointer-events:none;color:#a7a097}.caterium-flow-top svg{width:100%;height:auto}.caterium-flow-top path{fill:none;stroke:currentColor;stroke-width:1.6}.caterium-flow-top circle{fill:currentColor}.caterium-flow-top circle.gold{fill:#e5a313}
|
||||
@media(max-width:980px){#sunCloudAuthGateV3.sun-cloud-auth-gate{padding:34px 28px 70px!important;place-items:start center!important}#sunCloudAuthGateV3 .sun-cloud-auth-card{width:min(720px,100%)!important;padding-top:12px!important}.caterium-signature-manifesto{display:none!important}.caterium-flow-top{right:-60px;top:125px;width:360px;opacity:.45}}
|
||||
@media(max-width:620px){body.sun-cloud-auth-required{overflow:auto!important}#sunCloudAuthGateV3.sun-cloud-auth-gate{min-height:100dvh!important;padding:25px 18px 50px!important;place-items:start center!important}#sunCloudAuthGateV3 .sun-cloud-auth-card{width:100%!important;padding:0!important}.caterium-signature-brand{margin-bottom:42px!important}.caterium-signature-mark{width:50px;height:50px;flex-basis:50px}.caterium-signature-word{font-size:29px}#sunCloudAuthGateV3 .sun-cloud-auth-brand h2{font-size:clamp(38px,12vw,52px)!important}.caterium-flow-top{right:-125px;top:100px;width:330px;opacity:.25}.caterium-signature-caption{display:none!important}}
|
||||
|
||||
#sunCloudAuthGateV3 .sun-auth-eye{position:absolute;border:0;cursor:pointer;font-size:17px}
|
||||
#sunCloudAuthGateV3 .sun-auth-switch button{cursor:pointer}
|
||||
@ -1,30 +1,12 @@
|
||||
(()=>{
|
||||
'use strict';
|
||||
if(window.CateriumLoginSignatureV1776)return;
|
||||
const VERSION='17.7.7-cream-login-v2';
|
||||
const VERSION='17.7.8-single-login';
|
||||
const $=(s,r=document)=>r.querySelector(s);
|
||||
const boot=()=>$('#cateriumAuthBootV1776');
|
||||
const removeBoot=()=>{const b=boot();if(b){b.classList.add('leave');setTimeout(()=>b.remove(),180)}};
|
||||
const FLOW='<svg viewBox="0 0 430 220" aria-hidden="true"><path d="M18 42H122V108H220V58H318V164H420"/><circle cx="18" cy="42" r="7"/><circle cx="122" cy="42" r="7"/><circle cx="122" cy="108" r="7"/><circle cx="220" cy="108" r="7"/><circle cx="220" cy="58" r="7"/><circle cx="318" cy="58" r="7"/><circle cx="318" cy="164" r="7"/><circle cx="420" cy="164" r="8" class="gold"/></svg>';
|
||||
function styles(){if($('#caterium-login-signature-v1776-style'))return;const s=document.createElement('style');s.id='caterium-login-signature-v1776-style';s.textContent=`
|
||||
body.sun-cloud-auth-required{overflow:hidden!important;background:#f5f0e7!important}body.sun-cloud-auth-required>header,body.sun-cloud-auth-required>.view{visibility:hidden!important}
|
||||
#sunCloudAuthGateV3.sun-cloud-auth-gate{position:fixed!important;inset:0!important;z-index:20000!important;overflow:auto!important;display:grid!important;place-items:center!important;padding:clamp(32px,6vh,78px) clamp(24px,8vw,120px)!important;background:radial-gradient(circle at 18% 18%,rgba(255,255,255,.92),transparent 34%),radial-gradient(circle at 77% 22%,rgba(255,255,255,.5),transparent 28%),linear-gradient(135deg,#f8f4ec 0%,#f2ece1 56%,#f7f3eb 100%)!important;color:#282621!important}
|
||||
#sunCloudAuthGateV3.sun-cloud-auth-gate:before{content:'C';position:fixed;z-index:0;left:-7vw;top:49%;transform:translateY(-50%);pointer-events:none;font:400 min(72vw,860px)/.72 Georgia,'Times New Roman',serif;color:rgba(73,67,59,.032)}
|
||||
#sunCloudAuthGateV3.sun-cloud-auth-gate:after{content:'';position:fixed;z-index:0;right:-7vw;bottom:-14vh;width:min(48vw,720px);height:min(70vh,850px);pointer-events:none;background:radial-gradient(ellipse at 58% 20%,rgba(67,64,58,.14) 0 7%,transparent 8%),radial-gradient(ellipse at 36% 35%,rgba(67,64,58,.13) 0 6%,transparent 7%),radial-gradient(ellipse at 68% 47%,rgba(67,64,58,.12) 0 8%,transparent 9%),linear-gradient(106deg,transparent 43%,rgba(67,64,58,.08) 44% 46%,transparent 47%);filter:blur(18px);transform:rotate(-17deg);opacity:.45}
|
||||
#sunCloudAuthGateV3 .sun-cloud-auth-card{position:relative!important;z-index:3!important;width:min(790px,100%)!important;margin:0!important;padding:0 0 58px!important;border:0!important;border-radius:0!important;background:transparent!important;color:#2c2924!important;box-shadow:none!important;backdrop-filter:none!important}
|
||||
#sunCloudAuthGateV3 .caterium-signature-brand{display:flex;align-items:center;gap:13px;margin:0 0 clamp(46px,7vh,88px)!important}.caterium-signature-mark{display:block;width:62px;height:62px;object-fit:contain;flex:0 0 62px}.caterium-signature-word{font:500 36px/1 Georgia,'Times New Roman',serif;color:#26231f;letter-spacing:-.02em}
|
||||
#sunCloudAuthGateV3 .sun-cloud-auth-brand{display:block!important;margin:0 0 35px!important}#sunCloudAuthGateV3 .sun-cloud-auth-brand img{display:none!important}#sunCloudAuthGateV3 .sun-cloud-auth-brand h2{margin:0!important;max-width:720px;color:#24211d!important;font:500 clamp(48px,5.2vw,76px)/.99 Georgia,'Times New Roman',serif!important;letter-spacing:-.045em!important}#sunCloudAuthGateV3 .sun-cloud-auth-brand .hint{margin-top:18px!important;color:#8e887f!important;font-size:clamp(16px,1.55vw,21px)!important;line-height:1.45!important;font-weight:400!important}
|
||||
#sunCloudAuthGateV3 .sun-cloud-auth-card>p.hint{color:#817b72!important}#sunCloudAuthGateV3 .sun-cloud-auth-card label{display:block!important;margin:14px 0 0!important;color:#716b62!important;font-size:12px!important;font-weight:700!important}#sunCloudAuthGateV3 label.caterium-clean-field{font-size:0!important;color:transparent!important;position:relative!important}
|
||||
#sunCloudAuthGateV3 .sun-cloud-auth-card input,#sunCloudAuthGateV3 .sun-cloud-auth-card select,#sunCloudAuthGateV3 .sun-cloud-auth-card textarea{width:100%!important;min-height:58px!important;margin-top:7px!important;padding:0 18px!important;border:1px solid #bdb5aa!important;border-radius:13px!important;background:rgba(255,255,255,.13)!important;color:#312e29!important;box-shadow:none!important;outline:none!important;font-size:16px!important;font-weight:500!important}#sunCloudAuthGateV3 label.caterium-clean-field input{margin-top:0!important;padding-left:58px!important}#sunCloudAuthGateV3 input::placeholder{color:#9c958c!important;opacity:1!important}#sunCloudAuthGateV3 input:focus{border-color:#d7a632!important;box-shadow:0 0 0 4px rgba(216,167,50,.12)!important;background:rgba(255,255,255,.5)!important}
|
||||
#sunCloudAuthGateV3 .caterium-email-field:before{content:'✉';position:absolute;z-index:2;left:20px;top:15px;color:#777168;font-size:25px;font-weight:400}#sunCloudAuthGateV3 .caterium-password-field:before{content:'♙';position:absolute;z-index:2;left:21px;top:14px;color:#777168;font-size:24px;transform:rotate(180deg);opacity:.8}
|
||||
#sunCloudAuthGateV3 .sun-auth-password{display:block!important;position:relative!important}#sunCloudAuthGateV3 .sun-auth-password input{padding-right:58px!important}#sunCloudAuthGateV3 .sun-auth-eye{right:9px!important;bottom:10px!important;width:38px!important;height:38px!important;color:#777168!important;background:transparent!important;border-radius:9px!important}
|
||||
#sunCloudAuthGateV3 .sun-cloud-auth-actions{display:block!important;margin-top:25px!important}#sunCloudAuthGateV3 .sun-cloud-auth-actions .primary,#sunCloudAuthGateV3 #sunGateSubmitV3{width:100%!important;min-height:62px!important;border:0!important;border-radius:13px!important;background:linear-gradient(100deg,#d9aa42,#efca69)!important;color:#171512!important;font-size:18px!important;font-weight:900!important;box-shadow:0 14px 34px rgba(184,135,34,.14)!important}#sunCloudAuthGateV3 #sunGateSubmitV3:after{content:' →';font-size:24px;font-weight:500;margin-left:13px}
|
||||
#sunCloudAuthGateV3 .sun-cloud-auth-actions .outline{width:100%!important;margin-top:9px!important;min-height:48px!important;border:1px solid #c9c1b6!important;border-radius:11px!important;background:rgba(255,255,255,.25)!important;color:#37332d!important}#sunCloudAuthGateV3 .sun-cloud-auth-error{min-height:19px!important;margin-top:10px!important;color:#a64c40!important;font-size:12px!important}#sunCloudAuthGateV3 .sun-auth-switch{margin:26px 0 0!important;padding-top:25px!important;border-top:1px solid #cfc7bc!important;color:#898279!important;font-size:14px!important;text-align:center!important}#sunCloudAuthGateV3 .sun-auth-switch button{border:0!important;background:transparent!important;color:#c18f24!important;text-decoration:none!important;font-weight:900!important}
|
||||
.caterium-signature-caption{position:fixed;left:42px;bottom:31px;z-index:4;color:#9d968d;font-size:9px;letter-spacing:.31em;text-transform:uppercase;pointer-events:none}.caterium-signature-caption:before{content:'';display:block;width:48px;height:2px;margin-bottom:13px;background:#d3a43c}.caterium-signature-manifesto{position:fixed;right:56px;top:44px;z-index:4;width:270px;color:#a19a91;font-size:10px;line-height:1.9;letter-spacing:.28em;text-transform:uppercase;pointer-events:none;white-space:pre-line}.caterium-flow-top{position:fixed;z-index:1;right:5.5vw;top:13vh;width:min(37vw,470px);opacity:.86;pointer-events:none;color:#a7a097}.caterium-flow-top svg{width:100%;height:auto}.caterium-flow-top path{fill:none;stroke:currentColor;stroke-width:1.6}.caterium-flow-top circle{fill:currentColor}.caterium-flow-top circle.gold{fill:#e5a313}
|
||||
@media(max-width:980px){#sunCloudAuthGateV3.sun-cloud-auth-gate{padding:34px 28px 70px!important;place-items:start center!important}#sunCloudAuthGateV3 .sun-cloud-auth-card{width:min(720px,100%)!important;padding-top:12px!important}.caterium-signature-manifesto{display:none!important}.caterium-flow-top{right:-60px;top:125px;width:360px;opacity:.45}}
|
||||
@media(max-width:620px){body.sun-cloud-auth-required{overflow:auto!important}#sunCloudAuthGateV3.sun-cloud-auth-gate{min-height:100dvh!important;padding:25px 18px 50px!important;place-items:start center!important}#sunCloudAuthGateV3 .sun-cloud-auth-card{width:100%!important;padding:0!important}.caterium-signature-brand{margin-bottom:42px!important}.caterium-signature-mark{width:50px;height:50px;flex-basis:50px}.caterium-signature-word{font-size:29px}#sunCloudAuthGateV3 .sun-cloud-auth-brand h2{font-size:clamp(38px,12vw,52px)!important}.caterium-flow-top{right:-125px;top:100px;width:330px;opacity:.25}.caterium-signature-caption{display:none!important}}
|
||||
`;document.head.appendChild(s)}
|
||||
function field(g,id,ph,type){const i=$('#'+id,g);if(!i)return;i.placeholder=ph;const l=i.closest('label');if(l)l.classList.add('caterium-clean-field',type==='email'?'caterium-email-field':'caterium-password-field')}
|
||||
function decorate(g){if(!g)return false;const c=$('.sun-cloud-auth-card',g);if(!c)return false;if(!$('.caterium-signature-brand',c)){const b=document.createElement('div');b.className='caterium-signature-brand';b.innerHTML='<img class="caterium-signature-mark" src="caterium-mark-light.svg" alt=""><span class="caterium-signature-word">Caterium</span>';c.prepend(b)}if(!$('.caterium-signature-caption',g)){const n=document.createElement('div');n.className='caterium-signature-caption';n.textContent='Caterium · вкус в деталях';g.appendChild(n)}if(!$('.caterium-signature-manifesto',g)){const n=document.createElement('div');n.className='caterium-signature-manifesto';n.textContent='Простые решения\nдля больших событий';g.appendChild(n)}if(!$('.caterium-flow-top',g)){const n=document.createElement('div');n.className='caterium-flow-top';n.innerHTML=FLOW;g.appendChild(n)}const t=$('#sunGateTitleV3',g),sub=$('#sunGateSubtitleV3',g);if(t&&t.textContent.trim()==='Вход в Caterium')t.textContent='Войти в рабочее пространство';if(sub&&sub.textContent.trim()==='Введите данные своего аккаунта')sub.textContent='Ваши заказы. Ваша команда. Ваш результат.';field(g,'sunGateEmailV3','Email','email');field(g,'sunGatePasswordV3','Пароль','password');field(g,'sunGatePassword2V27','Подтвердите пароль','password');removeBoot();return true}
|
||||
function scan(){return decorate($('#sunCloudAuthGateV3'))}styles();scan();const o=new MutationObserver(scan);o.observe(document.documentElement,{childList:true,subtree:true,characterData:true});window.addEventListener('sun:cloud-state-applied',scan);const p=setInterval(()=>{if(scan()||!boot())clearInterval(p)},80);setTimeout(()=>{clearInterval(p);if(boot()&&!$('#sunCloudAuthGateV3'))removeBoot()},10000);window.CateriumLoginSignatureV1776=Object.freeze({VERSION,scan,removeBoot,disconnect:()=>{o.disconnect();clearInterval(p)}})
|
||||
function scan(){return decorate($('#sunCloudAuthGateV3'))}scan();const o=new MutationObserver(scan);o.observe(document.documentElement,{childList:true,subtree:true,characterData:true});window.addEventListener('sun:cloud-state-applied',scan);const p=setInterval(()=>{if(scan()||!boot())clearInterval(p)},80);setTimeout(()=>{clearInterval(p);if(boot()&&!$('#sunCloudAuthGateV3'))removeBoot()},10000);window.CateriumLoginSignatureV1776=Object.freeze({VERSION,scan,removeBoot,disconnect:()=>{o.disconnect();clearInterval(p)}})
|
||||
})();
|
||||
@ -1,7 +1,7 @@
|
||||
(()=>{
|
||||
'use strict';
|
||||
const VERSION='17.7.3';
|
||||
const RELEASE='20260918-proposal-loading';
|
||||
const RELEASE='20260918-single-login';
|
||||
|
||||
const hasStoredSession=()=>{try{return Object.keys(localStorage).some(k=>/^sb-.*-auth-token$/i.test(k)&&String(localStorage.getItem(k)||'').length>20)}catch(_){return false}};
|
||||
function installAuthBoot(){
|
||||
@ -16,16 +16,23 @@
|
||||
#cateriumAuthBootV1776 .cab-word{font:500 36px/1 Georgia,'Times New Roman',serif;color:#26231f;letter-spacing:-.02em}
|
||||
#cateriumAuthBootV1776 h1{margin:0;max-width:720px;color:#24211d;font:500 clamp(48px,5.2vw,76px)/.99 Georgia,'Times New Roman',serif;letter-spacing:-.045em}
|
||||
#cateriumAuthBootV1776 p{margin:18px 0 0;color:#8e887f;font:400 clamp(16px,1.55vw,21px)/1.45 Arial,sans-serif}
|
||||
#cateriumAuthBootV1776 .cab-fields{margin-top:25px;display:grid;gap:14px}.cab-field{height:58px;border:1px solid #bdb5aa;border-radius:13px;background:rgba(255,255,255,.13)}
|
||||
#cateriumAuthBootV1776 .cab-btn{height:62px;margin-top:11px;border-radius:13px;background:linear-gradient(100deg,#d9aa42,#efca69)}
|
||||
#cateriumAuthBootV1776 .cab-note{position:fixed;left:42px;bottom:31px;color:#9d968d;font:9px/1 Arial,sans-serif;letter-spacing:.31em;text-transform:uppercase;text-shadow:none}
|
||||
@media(max-width:900px){#cateriumAuthBootV1776{padding:34px 28px 70px;place-items:start center}#cateriumAuthBootV1776 .cab-wrap{width:min(720px,100%);padding-top:12px}}
|
||||
@media(max-width:620px){#cateriumAuthBootV1776{min-height:100dvh;padding:25px 18px 50px;place-items:start center}#cateriumAuthBootV1776 .cab-wrap{width:100%}#cateriumAuthBootV1776 .cab-brand{margin-bottom:42px}#cateriumAuthBootV1776 .cab-mark{width:50px;height:50px;flex-basis:50px}#cateriumAuthBootV1776 .cab-word{font-size:29px}#cateriumAuthBootV1776 h1{font-size:clamp(38px,12vw,52px)}#cateriumAuthBootV1776 .cab-note{display:none}}
|
||||
`;document.head.appendChild(style);
|
||||
const el=document.createElement('div');el.id='cateriumAuthBootV1776';el.innerHTML='<div class="cab-wrap"><div class="cab-brand"><img class="cab-mark" src="caterium-mark-light.svg" alt=""><span class="cab-word">Caterium</span></div><h1>Войти в рабочее пространство</h1><p>Ваши заказы. Ваша команда. Ваш результат.</p><div class="cab-fields"><div class="cab-field"></div><div class="cab-field"></div><div class="cab-btn"></div></div></div><div class="cab-note">Caterium · вкус в деталях</div>';document.documentElement.appendChild(el);
|
||||
const el=document.createElement('div');el.id='cateriumAuthBootV1776';el.innerHTML='<div class="cab-wrap"><div class="cab-brand"><img class="cab-mark" src="caterium-mark-light.svg" alt=""><span class="cab-word">Caterium</span></div><h1>Открываю Caterium…</h1><p role="status">Проверяю сохранённый вход</p></div><div class="cab-note">Caterium · вкус в деталях</div>';document.documentElement.appendChild(el);
|
||||
}
|
||||
function loadLoginSignatureEarly(){if(window.CateriumLoginSignatureV1776||document.getElementById('cateriumLoginSignatureV1776Script'))return;const s=document.createElement('script');s.id='cateriumLoginSignatureV1776Script';s.src=`core/login-signature-v1776.js?v=${RELEASE}`;s.async=false;document.head.appendChild(s)}
|
||||
installAuthBoot();loadLoginSignatureEarly();
|
||||
// Boot cleanup is independent of the optional decorative script.
|
||||
if(document.getElementById('cateriumAuthBootV1776')){
|
||||
const bootObserver=new MutationObserver(()=>{
|
||||
const boot=document.getElementById('cateriumAuthBootV1776');
|
||||
if(!boot){bootObserver.disconnect();return}
|
||||
if(document.getElementById('sunCloudAuthGateV3')||(window.SunAdminRBACV3&&!document.body?.classList.contains('sun-cloud-auth-required'))){boot.remove();bootObserver.disconnect()}
|
||||
});
|
||||
bootObserver.observe(document.documentElement,{childList:true,subtree:true,attributes:true,attributeFilter:['class']});
|
||||
}
|
||||
|
||||
const critical=img=>img.closest('header,.brand,#sunCloudAuthGate,.sun-auth-gate')||img.id==='sunLoginLogo'||img.classList.contains('sun-live-catalog-logo');
|
||||
const tune=img=>{if(!(img instanceof HTMLImageElement)||critical(img))return;if(!img.hasAttribute('loading'))img.loading='lazy';if(!img.hasAttribute('decoding'))img.decoding='async';if(!img.hasAttribute('fetchpriority'))img.setAttribute('fetchpriority','low');};
|
||||
|
||||
File diff suppressed because one or more lines are too long
@ -1,8 +1,8 @@
|
||||
const CACHE='sun-catering-pwa-v95-20260918-proposal-loading';
|
||||
const VERSION='20260918-proposal-loading';
|
||||
const CACHE='sun-catering-pwa-v96-20260918-single-login';
|
||||
const VERSION='20260918-single-login';
|
||||
const CORE=[
|
||||
'./','./index.html',`./core/proposal-layout.js?v=${VERSION}`,'./fonts/Manrope.ttf','./fonts/PlayfairDisplay.ttf','./fonts/PlayfairDisplay-Italic.ttf',`./core/trial-demo.js?v=${VERSION}`,`./core/cloud-transport.js?v=${VERSION}`,`./core/banquet-menu.js?v=${VERSION}`,`./core/access-policy.js?v=${VERSION}`,`./core/import-archive.js?v=${VERSION}`,`./core/company-branding.js?v=${VERSION}`,`./core/signature-offer-pdf-v18.js?v=${VERSION}`,`./core/brand-theme.js?v=${VERSION}`,
|
||||
`./core/sun-safe.js?v=${VERSION}`,`./core/performance.js?v=${VERSION}`,`./core/account-center-v1780.js?v=${VERSION}`,`./core/login-signature-v1776.js?v=${VERSION}`,`./core/data-layer-v1773.js?v=${VERSION}`,`./core/server-automation-v1770.js?v=${VERSION}`,`./core/hotfix-v1763.js?v=${VERSION}`,`./core/ops-ux-v1762.js?v=${VERSION}`,`./core/ux-fixes-v1764.js?v=${VERSION}`,`./core/pdf-engine.js?v=${VERSION}`,`./core/classic-offer-pdf-v1767.js?v=${VERSION}`,`./core/developer-console-v1768.js?v=${VERSION}`,`./core/offer-workspace-v1769.js?v=${VERSION}`,`./core/auth-security-v1774.js?v=${VERSION}`,`./core/order-enhancements-v1775.js?v=${VERSION}`,`./legacy/bootstrap.js?v=${VERSION}`,`./app-runtime.js?v=${VERSION}`,
|
||||
`./core/sun-safe.js?v=${VERSION}`,`./core/performance.js?v=${VERSION}`,`./core/account-center-v1780.js?v=${VERSION}`,`./core/login-signature-v1776.js?v=${VERSION}`,`./core/login-signature-v1776.css?v=${VERSION}`,`./core/data-layer-v1773.js?v=${VERSION}`,`./core/server-automation-v1770.js?v=${VERSION}`,`./core/hotfix-v1763.js?v=${VERSION}`,`./core/ops-ux-v1762.js?v=${VERSION}`,`./core/ux-fixes-v1764.js?v=${VERSION}`,`./core/pdf-engine.js?v=${VERSION}`,`./core/classic-offer-pdf-v1767.js?v=${VERSION}`,`./core/developer-console-v1768.js?v=${VERSION}`,`./core/offer-workspace-v1769.js?v=${VERSION}`,`./core/auth-security-v1774.js?v=${VERSION}`,`./core/order-enhancements-v1775.js?v=${VERSION}`,`./legacy/bootstrap.js?v=${VERSION}`,`./app-runtime.js?v=${VERSION}`,
|
||||
'./offer-gallery/001.jpg','./offer-gallery/002.jpg',
|
||||
'./catalog/001.jpg','./catalog/002.jpg','./catalog/003.jpg',
|
||||
'./sun-logo.png','./caterium-login-logo.png','./caterium-mark-light.svg','./pwa-icon-192.png','./pwa-icon-512.png','./manifest.webmanifest',
|
||||
@ -10,7 +10,7 @@ const CORE=[
|
||||
];
|
||||
const CRITICAL_FRESH=new Set([
|
||||
'/core/cloud-transport.js','/core/trial-demo.js','/core/proposal-layout.js',
|
||||
'/core/banquet-menu.js','/core/access-policy.js','/core/import-archive.js','/core/company-branding.js','/core/brand-theme.js','/core/sun-safe.js','/core/performance.js','/core/account-center-v1780.js','/core/login-signature-v1776.js','/core/auth-security-v1774.js','/legacy/bootstrap.js','/app-runtime.js'
|
||||
'/core/banquet-menu.js','/core/access-policy.js','/core/import-archive.js','/core/company-branding.js','/core/brand-theme.js','/core/sun-safe.js','/core/performance.js','/core/account-center-v1780.js','/core/login-signature-v1776.js','/core/login-signature-v1776.css','/core/auth-security-v1774.js','/legacy/bootstrap.js','/app-runtime.js'
|
||||
]);
|
||||
self.addEventListener('install',event=>{
|
||||
event.waitUntil(caches.open(CACHE).then(cache=>cache.addAll(CORE)).then(()=>self.skipWaiting()));
|
||||
|
||||
@ -1,6 +1,48 @@
|
||||
import fs from 'node:fs';
|
||||
import {test,expect} from '@playwright/test';
|
||||
|
||||
async function delayedSessionApp(page,signedIn=true){
|
||||
await page.route('https://**',r=>r.abort());
|
||||
await page.addInitScript(signed=>{
|
||||
localStorage.setItem('sunCloudV2Config',JSON.stringify({workspaceId:signed?'startup-company':'',localWorkspaceId:signed?'startup-company':'',tenantStorageReady:true,autoSync:false}));
|
||||
if(signed)localStorage.setItem('sb-startup-auth-token','stored-session-placeholder-without-credentials');
|
||||
localStorage.setItem('sunEnterpriseSettingsV1',JSON.stringify({rolesEnabled:true}));
|
||||
localStorage.setItem('sunUsersV1',JSON.stringify([{id:'legacy-user',name:'Old local user',role:'owner',active:true,pinHash:'old-hash'}]));
|
||||
window.supabase={createClient:()=>({
|
||||
auth:{onAuthStateChange:()=>({data:{subscription:{unsubscribe(){}}}}),getSession:()=>new Promise(resolve=>{window.finishSessionRestore=resolve}),getUser:async()=>({data:{user:null}})},
|
||||
rpc:async name=>({data:name==='sun_my_workspaces'?[{id:'startup-company',name:'Test company',role:'admin',is_active:true}]:null}),
|
||||
channel:()=>({on(){return this},subscribe(){return this}}),removeChannel:()=>{}
|
||||
})};
|
||||
window.loginFormSeen=false;window.legacyFormSeen=false;new MutationObserver(()=>{if(document.getElementById('sunGateEmailV3'))window.loginFormSeen=true;if(document.getElementById('sunLoginOverlay'))window.legacyFormSeen=true}).observe(document,{childList:true,subtree:true});
|
||||
},signedIn);
|
||||
await page.goto('/index.html',{waitUntil:'domcontentloaded'});
|
||||
await page.waitForFunction(()=>Boolean(window.finishSessionRestore));
|
||||
}
|
||||
|
||||
test('restoring an existing session never mounts a password form before opening the app',async({page})=>{
|
||||
await delayedSessionApp(page);
|
||||
await expect(page.locator('#sunCloudAuthGateV3')).toHaveAttribute('data-auth-state','restoring');
|
||||
await expect(page.locator('#sunGateEmailV3')).toHaveCount(0);await expect(page.locator('body > header')).toBeHidden();
|
||||
await page.evaluate(()=>finishSessionRestore({data:{session:{user:{id:'startup-user',email:'test@example.invalid'}}},error:null}));
|
||||
await expect(page.locator('#sunCloudAuthGateV3')).toHaveCount(0);await expect(page.locator('body > header')).toBeVisible();
|
||||
expect(await page.evaluate(()=>window.loginFormSeen)).toBe(false);
|
||||
expect(await page.evaluate(()=>window.legacyFormSeen)).toBe(false);
|
||||
});
|
||||
|
||||
test('the single current login is styled even when its decorative script is unavailable',async({page})=>{
|
||||
await page.route('**/core/login-signature-v1776.js*',r=>r.abort());
|
||||
await delayedSessionApp(page,false);
|
||||
await page.evaluate(()=>finishSessionRestore({data:{session:null},error:null}));
|
||||
await expect(page.locator('#sunGateEmailV3')).toBeVisible();
|
||||
await expect(page.locator('#sunGateTitleV3')).toHaveText('Войти в рабочее пространство');
|
||||
await expect(page.locator('#sunCloudAuthGateV3 .caterium-signature-brand')).toHaveCount(1);
|
||||
await expect(page.locator('#sunCloudAuthGateV3 .sun-cloud-auth-card')).toHaveCSS('background-color','rgba(0, 0, 0, 0)');
|
||||
await expect(page.locator('#sunGateEmailV3')).toHaveCSS('border-radius','13px');
|
||||
await expect(page.locator('#sunLoginOverlay,#cateriumAuthBootV1776')).toHaveCount(0);
|
||||
await page.locator('#sunGateSwitchV27').click();await expect(page.locator('#sunGateTitleV3')).toHaveText('Создать аккаунт Caterium');
|
||||
await page.locator('#sunGateSwitchV27').click();await expect(page.locator('#sunGateTitleV3')).toHaveText('Войти в рабочее пространство');
|
||||
});
|
||||
|
||||
test('slow connections use a healthy route, allow longer saves and preserve caller cancellation',async({page})=>{
|
||||
await page.route('**/index.html',r=>r.fulfill({contentType:'text/html',body:'<html><body></body></html>'}));
|
||||
await page.goto('/index.html');await page.addScriptTag({url:'/core/cloud-transport.js'});
|
||||
|
||||
@ -14,8 +14,8 @@ check(!index.includes('offer-gallery-data.js'),'blocking Base64 gallery absent')
|
||||
check((runtime.match(/\/Type \/Catalog/g)||[]).length===0,'runtime contains no PDF binary writer');
|
||||
check(read('core/pdf-engine.js').includes('595.28')&&read('core/pdf-engine.js').includes('841.89'),'PDF engine uses A4 MediaBox');
|
||||
check([...index.matchAll(/@page\{([^}]*)\}/g)].every(m=>/size:A4/i.test(m[1])),'compact @page rules use A4');
|
||||
check(sw.includes('v95-20260918-proposal-loading')&&sw.includes('data-layer-v1773.js')&&sw.includes('server-automation-v1770.js')&&sw.includes('offer-workspace-v1769.js'),'service worker cache is v17.7.3');
|
||||
check(index.includes('20260918-proposal-loading')&&index.includes('classic-offer-pdf-v1767.js')&&!index.includes('20260907-v17-6-0-stability-security'),'index cache-busting points to v17.7.3');
|
||||
check(sw.includes('v96-20260918-single-login')&&sw.includes('data-layer-v1773.js')&&sw.includes('server-automation-v1770.js')&&sw.includes('offer-workspace-v1769.js'),'service worker cache is v17.7.3');
|
||||
check(index.includes('20260918-single-login')&&index.includes('classic-offer-pdf-v1767.js')&&!index.includes('20260907-v17-6-0-stability-security'),'index cache-busting points to v17.7.3');
|
||||
check(performance.includes('SunAttachmentGuard')&&performance.includes('TARGET=2*1024*1024'),'chat photo auto-compression is versioned');
|
||||
check(performance.includes("rpc('sun_dev_dashboard')")&&performance.includes('server_size')&&performance.includes('storage_size'),'Developer Console server/storage counters are versioned');
|
||||
check(performance.includes('MEMORY_REFRESH_MS=30000')&&performance.includes('MEMORY_TIMEOUT_MS=8000')&&performance.includes('memoryPromise'),'Developer Console memory refresh is bounded');
|
||||
@ -39,7 +39,7 @@ check(!/sb_secret_[A-Za-z0-9_-]{20,}|service_role\s*[:=]\s*["'][A-Za-z0-9._-]{30
|
||||
check(lock.version===pkg.version&&lock.packages?.['']?.version===pkg.version,'package.json and package-lock.json versions match');
|
||||
check(releaseManifest.version===`v${pkg.version}`,'release manifest version matches package.json');
|
||||
check(releaseManifest.channel==='production','release manifest channel is production');
|
||||
check(String(releaseManifest.pwaCache||'').includes('v95-20260918-proposal-loading'),'release manifest points to current PWA cache');
|
||||
check(String(releaseManifest.pwaCache||'').includes('v96-20260918-single-login'),'release manifest points to current PWA cache');
|
||||
check(['17.6.2','17.6.3','17.6.4','17.6.5','17.6.6','17.6.7','17.6.8','17.6.9','17.7.0','17.7.1','17.7.2','17.7.3'].every(v=>fs.existsSync(path.join(root,`docs/releases/V${v}-CHANGES.txt`))),'release notes exist through v17.7.3');
|
||||
check(runtime.includes('CLOUD_RPC_TIMEOUT_MS=45000')&&runtime.includes('CLOUD_CONFLICT_MAX_RETRIES=4')&&runtime.includes('retryCount'),'cloud sync has timeout and capped exponential conflict retries');
|
||||
check(runtime.includes("const VERSION = '17.7.3'")&&runtime.includes('ERROR_DEDUPE_MS=5*60*1000')&&runtime.includes('mirrorBusy=false')&&runtime.includes('backupBusy=false'),'stability logger uses current version, dedupe and single-flight guards');
|
||||
@ -65,8 +65,8 @@ check(offerWorkspace.includes('PDF и предпросмотр')&&offerWorkspace
|
||||
check(offerWorkspace.includes('SunClassicOfferPDFV1767')&&offerWorkspace.includes('finalGallery=galleryFor'),'custom gallery is injected into PDF renderer');
|
||||
check(releaseManifest.offerWorkspaceTabs===true&&releaseManifest.offerTemplatesSeparateTab===true&&releaseManifest.offerTwoCustomGalleryPhotos===true,'release manifest records offer workspace changes');
|
||||
check(pkg.version==='17.7.3','package version is v17.7.3');
|
||||
check(index.includes('20260918-proposal-loading'),'index cache bust is v17.7.3');
|
||||
check(sw.includes('v95-20260918-proposal-loading')&&sw.includes('data-layer-v1773.js')&&sw.includes('server-automation-v1770.js'),'PWA caches v17.7.3 client foundation modules');
|
||||
check(index.includes('20260918-single-login'),'index cache bust is v17.7.3');
|
||||
check(sw.includes('v96-20260918-single-login')&&sw.includes('data-layer-v1773.js')&&sw.includes('server-automation-v1770.js'),'PWA caches v17.7.3 client foundation modules');
|
||||
check(fs.existsSync(path.join(root,'public/core/data-layer-v1773.js'))&&fs.existsSync(path.join(root,'public/core/server-automation-v1770.js')),'data layer and server automation modules exist');
|
||||
check(ux.includes('CateriumServerAutomationV1770?.enabled'),'cloud browser auto completion is disabled when server automation is active');
|
||||
check(runtime.includes("const VERSION = '17.7.3'")&&runtime.includes("v17.7.3 Clients Server Read"),'stability logger reports v17.7.3');
|
||||
|
||||
@ -28,8 +28,8 @@ if(current!==113)fail(`current catalog photo count ${current}, expected 113`);el
|
||||
if(legacyCount!==60)fail(`legacy catalog photo count ${legacyCount}, expected 60`);else ok('60 legacy catalog photos');
|
||||
const gallery=fs.readdirSync(path.join(pub,'offer-gallery')).filter(x=>/\.jpg$/i.test(x));
|
||||
if(gallery.length!==2)fail(`offer gallery contains ${gallery.length} jpg files, expected 2`);else ok('offer gallery trimmed');
|
||||
if(!sw.includes('20260918-proposal-loading')||!sw.includes('login-signature-v1776.js')||!sw.includes('data-layer-v1773.js')||!sw.includes('server-automation-v1770.js')||!sw.includes('offer-workspace-v1769.js')||sw.includes('offer-gallery-data.js'))fail('service worker cache is stale');else ok('PWA cache updated for login refresh');
|
||||
if(html.includes('20260907-v17-6-0-stability-security')||html.includes('20260909-v17-7-3-clients-server-read')||!html.includes('20260918-proposal-loading')||!html.includes('classic-offer-pdf-v1767.js'))fail('index still serves stale core asset version');else ok('index cache-busting is current');
|
||||
if(!sw.includes('20260918-single-login')||!sw.includes('login-signature-v1776.js')||!sw.includes('data-layer-v1773.js')||!sw.includes('server-automation-v1770.js')||!sw.includes('offer-workspace-v1769.js')||sw.includes('offer-gallery-data.js'))fail('service worker cache is stale');else ok('PWA cache updated for login refresh');
|
||||
if(html.includes('20260907-v17-6-0-stability-security')||html.includes('20260909-v17-7-3-clients-server-read')||!html.includes('20260918-single-login')||!html.includes('classic-offer-pdf-v1767.js'))fail('index still serves stale core asset version');else ok('index cache-busting is current');
|
||||
if(!performance.includes('SunAttachmentGuard')||!performance.includes('MAX_SIDE=2048'))fail('chat photo compression guard missing');else ok('chat photo compression guard present');
|
||||
if(!performance.includes("rpc('sun_dev_dashboard')")||!performance.includes('storage_size')||!performance.includes('server_size'))fail('Developer Console memory counters missing');else ok('Developer Console memory counters present');
|
||||
if(performance.includes('records.forEach(r=>r.addedNodes.forEach(n=>{if(n.nodeType===1)scan(n)}));enhanceDeveloperMemory()'))fail('Developer Console memory refresh is still coupled to MutationObserver');else ok('Developer Console memory refresh loop removed');
|
||||
|
||||
Loading…
Reference in New Issue
Block a user