Caterium v17.7.1 password security

This commit is contained in:
github-actions[bot] 2026-09-08 13:37:14 +00:00
parent ebbd773b27
commit ee378b3b1a
9 changed files with 73 additions and 17 deletions

View File

@ -1,6 +1,6 @@
{
"app": "Caterium",
"version": "v17.7.0",
"version": "v17.7.1",
"channel": "production",
"schema": 17,
"legacyStateKept": true,
@ -11,7 +11,7 @@
"serverReady": true,
"workspaceAutoDiscovery": true,
"invitesTemporarilyDisabled": false,
"pwaCache": "v75-20260908-v17-7-0-architecture-foundation",
"pwaCache": "v76-20260908-v17-7-1-password-security",
"fullOfferDescriptions": true,
"dynamicOfferRows": true,
"pdfOfferDescriptionFix": true,
@ -108,7 +108,7 @@
"catalogCompositionTildaEndpoint": "getproduct",
"catalogCompositionPremiumForceRefresh": true,
"catalogCompositionCacheRequiresPremium": true,
"notes": "Architecture foundation: explicit data layer, server-side order automation with legacy/cloud compatibility, telemetry hygiene, current stability version, regression checks.",
"notes": "Account security: temporary-password employees are blocked by an independent mandatory password-change gate that survives workspace loading; every signed-in account gets Change password in Profile.",
"catalogPhotoSources": 113,
"catalogPhotosStoredInCatalog": true,
"catalogLegacyPhotosInCatalog": 60,
@ -246,7 +246,7 @@
"signupTrial": "14-day Full",
"developerMfaInputSelectorFixed": true,
"developerMfaRepeatedValidationToastsFixed": true,
"release": "20260908-v17-7-0-architecture-foundation",
"release": "20260908-v17-7-1-password-security",
"registrationFlow": "email-password-confirm-company-auto-login",
"emailConfirmationRequired": false,
"employeeInviteLinks": false,
@ -367,5 +367,9 @@
"browserOrderAutomationCloudDisabled": true,
"errorTelemetryRejectsLocalFile": true,
"errorTelemetryServerDedupMinutes": 5,
"errorTelemetryRetentionDays": 30
"errorTelemetryRetentionDays": 30,
"forcedTemporaryPasswordChange": true,
"passwordChangeInEveryAccount": true,
"passwordMinimumLength": 8,
"passwordChangeRequiresCurrentPassword": true
}

View File

@ -0,0 +1,10 @@
Caterium v17.7.1 — Account password security
Date: 2026-09-08
1. First login with an employee temporary password opens an independent mandatory password-change security gate.
2. The mandatory gate is not owned by the workspace/auth loading DOM, so workspace loading cannot make it disappear.
3. Until a new password is saved, the user cannot continue into the application; only Sign out is available.
4. Every signed-in account gets Profile → Security → Change password.
5. Normal password change verifies the current password, requires a minimum of 8 characters and confirmation.
6. Successful first-login change clears user_metadata.must_change_password and refreshes the session.
7. PWA cache v76 / 20260908-v17-7-1-password-security.

4
package-lock.json generated
View File

@ -1,12 +1,12 @@
{
"name": "caterium-app",
"version": "17.7.0",
"version": "17.7.1",
"lockfileVersion": 3,
"requires": true,
"packages": {
"": {
"name": "caterium-app",
"version": "17.7.0",
"version": "17.7.1",
"devDependencies": {
"@playwright/test": "^1.51.0",
"http-server": "^14.1.1",

View File

@ -1,10 +1,10 @@
{
"name": "caterium-app",
"private": true,
"version": "17.7.0",
"version": "17.7.1",
"type": "module",
"scripts": {
"check:syntax": "node --check public/app-runtime.js && node --check public/service-worker.js && node --check public/legacy/bootstrap.js && node --check public/core/sun-safe.js && node --check public/core/performance.js && node --check public/core/data-layer-v1770.js && node --check public/core/server-automation-v1770.js && node --check public/core/hotfix-v1763.js && node --check public/core/ops-ux-v1762.js && node --check public/core/ux-fixes-v1764.js && node --check public/core/pdf-engine.js && node --check public/core/classic-offer-pdf-v1767.js && node --check public/core/developer-console-v1768.js && node --check public/core/offer-workspace-v1769.js",
"check:syntax": "node --check public/app-runtime.js && node --check public/service-worker.js && node --check public/legacy/bootstrap.js && node --check public/core/sun-safe.js && node --check public/core/performance.js && node --check public/core/data-layer-v1770.js && node --check public/core/server-automation-v1770.js && node --check public/core/account-security-v1771.js && node --check public/core/hotfix-v1763.js && node --check public/core/ops-ux-v1762.js && node --check public/core/ux-fixes-v1764.js && node --check public/core/pdf-engine.js && node --check public/core/classic-offer-pdf-v1767.js && node --check public/core/developer-console-v1768.js && node --check public/core/offer-workspace-v1769.js",
"test:static": "node tests/static-security.mjs",
"check:release": "node tests/release-check.mjs",
"check:deploy": "npm run check:syntax && npm run test:static && npm run check:release",

View File

@ -1,7 +1,7 @@
(()=>{
'use strict';
const VERSION='17.7.0';
const RELEASE='20260908-v17-7-0-architecture-foundation';
const VERSION='17.7.1';
const RELEASE='20260908-v17-7-1-password-security';
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;
@ -119,14 +119,18 @@
if(window.SunOfferWorkspaceV1769||document.getElementById('sunOfferWorkspaceV1769Script'))return;
const script=document.createElement('script');script.id='sunOfferWorkspaceV1769Script';script.src=`core/offer-workspace-v1769.js?v=${RELEASE}`;script.async=true;script.onerror=()=>console.error('[Caterium] Не загрузился модуль offer-workspace-v1769.js');document.head.appendChild(script);
}
function loadAccountSecurity(){
if(window.CateriumAccountSecurityV1771||document.getElementById('cateriumAccountSecurityV1771Script'))return;
const script=document.createElement('script');script.id='cateriumAccountSecurityV1771Script';script.src=`core/account-security-v1771.js?v=${RELEASE}`;script.async=true;script.onerror=()=>console.error('[Caterium] Не загрузился модуль account-security-v1771.js');document.head.appendChild(script);
}
const start=()=>{
loadDataLayer();loadServerAutomation();loadHotfix();loadOpsUX();loadUXFix();loadDeveloperUX();loadOfferWorkspace();scan(document);startMemoryTimer();
loadDataLayer();loadServerAutomation();loadHotfix();loadOpsUX();loadUXFix();loadDeveloperUX();loadOfferWorkspace();loadAccountSecurity();scan(document);startMemoryTimer();
const mo=new MutationObserver(records=>{records.forEach(r=>r.addedNodes.forEach(n=>{if(n.nodeType===1)queueImageScan(n)}));});
mo.observe(document.documentElement,{childList:true,subtree:true});
document.addEventListener('click',e=>{if(e.target.closest('#sunDeveloperNavV22,[data-dev-tab],#sunDevRefresh'))scheduleMemoryRefresh(100,true)},true);
window.addEventListener('sun:cloud-state-applied',()=>scheduleMemoryRefresh(180,true));
document.addEventListener('visibilitychange',()=>{if(!document.hidden&&developerVisible())scheduleMemoryRefresh(50,false)});
window.SunPerformance={VERSION,scanImages:()=>scan(document),refreshDeveloperMemory:(force=true)=>enhanceDeveloperMemory({force}),loadDataLayer,loadServerAutomation,loadHotfix,loadOpsUX,loadUXFix,loadDeveloperUX,loadOfferWorkspace,disconnect:()=>{mo.disconnect();if(memoryTimer){clearInterval(memoryTimer);memoryTimer=0}if(imageScanTimer){clearTimeout(imageScanTimer);imageScanTimer=0}pendingImageRoots.clear();}};
window.SunPerformance={VERSION,scanImages:()=>scan(document),refreshDeveloperMemory:(force=true)=>enhanceDeveloperMemory({force}),loadDataLayer,loadServerAutomation,loadHotfix,loadOpsUX,loadUXFix,loadDeveloperUX,loadOfferWorkspace,loadAccountSecurity,disconnect:()=>{mo.disconnect();if(memoryTimer){clearInterval(memoryTimer);memoryTimer=0}if(imageScanTimer){clearTimeout(imageScanTimer);imageScanTimer=0}pendingImageRoots.clear();}};
};
if(document.readyState==='loading')document.addEventListener('DOMContentLoaded',start,{once:true});else start();
})();

File diff suppressed because one or more lines are too long

View File

@ -1,5 +1,5 @@
const CACHE='sun-catering-pwa-v75-20260908-v17-7-0-architecture-foundation';
const VERSION='20260908-v17-7-0-architecture-foundation';
const CACHE='sun-catering-pwa-v76-20260908-v17-7-1-password-security';
const VERSION='20260908-v17-7-1-password-security';
const CORE=[
'./','./index.html',
`./core/sun-safe.js?v=${VERSION}`,`./core/performance.js?v=${VERSION}`,`./core/data-layer-v1770.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}`,`./legacy/bootstrap.js?v=${VERSION}`,`./app-runtime.js?v=${VERSION}`,

View File

@ -273,3 +273,33 @@ test('v17.7.0 server automation applies returned normalized orders through data
await page.waitForFunction(()=>Boolean(window.CateriumServerAutomationV1770));await page.evaluate(async()=>{window.__signed=true;await window.CateriumServerAutomationV1770.run({force:true})});
expect(await page.evaluate(()=>window.__applied)).toEqual([{id:8,status:'Отдан заказчику'}]);
});
test('v17.7.1 temporary-password account gets persistent mandatory password gate', async ({ page }) => {
await page.goto('/index.html',{waitUntil:'domcontentloaded'});
await page.evaluate(()=>{
window.CateriumAccountSecurityV1771=undefined;
window.SunCloudV2={getSession:()=>({user:{id:'u1',email:'employee@example.com',user_metadata:{must_change_password:true},app_metadata:{}}}),getClient:()=>({auth:{getUser:async()=>({data:{user:{id:'u1',email:'employee@example.com',user_metadata:{must_change_password:true},app_metadata:{}}}}),updateUser:async()=>({data:{user:{}},error:null}),refreshSession:async()=>({})}})};
});
const src=fs.readFileSync(path.join(process.cwd(),'public/core/account-security-v1771.js'),'utf8');await page.addScriptTag({content:src});
await page.waitForSelector('#cateriumPasswordGateV1771');
expect(await page.locator('#cateriumPasswordGateV1771').isVisible()).toBe(true);
expect(await page.locator('#catPasswordCancelV1771').count()).toBe(0);
await page.evaluate(()=>{document.body.insertAdjacentHTML('beforeend','<div id="workspace-loader-repaint"></div>')});
await page.waitForTimeout(120);
expect(await page.locator('#cateriumPasswordGateV1771').isVisible()).toBe(true);
});
test('v17.7.1 every signed-in account gets Change password in Profile', async ({ page }) => {
await page.goto('/index.html',{waitUntil:'domcontentloaded'});
await page.evaluate(()=>{
window.CateriumAccountSecurityV1771=undefined;
document.body.insertAdjacentHTML('beforeend','<div id="sunCloudV2Card"><div class="sun-cloud-v2-box"><h3>Профиль</h3><div>user@example.com</div></div></div>');
window.SunCloudV2={getSession:()=>({user:{id:'u2',email:'user@example.com',user_metadata:{},app_metadata:{}}}),getClient:()=>({auth:{getUser:async()=>({data:{user:{id:'u2',email:'user@example.com',user_metadata:{},app_metadata:{}}}}),signInWithPassword:async()=>({error:null}),updateUser:async()=>({data:{user:{}},error:null}),refreshSession:async()=>({})}})};
});
const src=fs.readFileSync(path.join(process.cwd(),'public/core/account-security-v1771.js'),'utf8');await page.addScriptTag({content:src});
await page.waitForSelector('#catProfilePasswordV1771');
expect(await page.locator('#catProfilePasswordV1771').textContent()).toContain('Сменить пароль');
await page.locator('#catProfilePasswordV1771').click();
await expect(page.locator('#catCurrentPasswordV1771')).toBeVisible();
});

View File

@ -72,3 +72,11 @@ check(ux.includes('CateriumServerAutomationV1770?.enabled'),'cloud browser auto
check(runtime.includes("const VERSION = '17.7.0'")&&runtime.includes("v17.7.0 Architecture Foundation"),'stability logger reports v17.7.0');
check(fs.existsSync(path.join(root,'ops/sql/SUPABASE-V17.7.0-SERVER-ORDER-AUTOMATION.sql'))&&fs.existsSync(path.join(root,'ops/sql/SUPABASE-V17.7.0-ERROR-TELEMETRY-HYGIENE.sql')),'v17.7.0 server migrations are versioned');
if(bad)process.exit(1);
check(pkg.version==='17.7.1','package version is v17.7.1');
check(index.includes('20260908-v17-7-1-password-security'),'index cache token is v17.7.1');
check(sw.includes('v76-20260908-v17-7-1-password-security')&&sw.includes('account-security-v1771.js'),'service worker contains account security v17.7.1');
const accountSecurity=fs.readFileSync(path.join(root,'public/core/account-security-v1771.js'),'utf8');
check(accountSecurity.includes('must_change_password')&&accountSecurity.includes('cat-password-required-v1771')&&accountSecurity.includes('Сменить пароль'),'account security includes mandatory temporary-password gate and profile password change');
check(accountSecurity.includes('signInWithPassword')&&accountSecurity.includes('auth.updateUser')&&accountSecurity.includes('минимум 8 символов'),'password change verifies current password and updates Supabase Auth');
check(performance.includes('loadAccountSecurity')&&performance.includes('account-security-v1771.js'),'performance loader installs account security');