Files
safetynet/apps/browser/managed-settings.cjs
T
2026-10-13 10:34:48 +02:00

25 lines
2.2 KiB
JavaScript

const SECTIONS=Object.freeze(['appearance','library','ai','passwords','documentScan','agents']);
const DEFAULT_APPEARANCE=Object.freeze({mode:'system',accent:'blue',tabMode:'separate'});
// This object is computed in the privileged process, never from renderer storage.
function settingsState({policy,ready,preferences={},now=Date.now()}){
const available=!!ready&&!!policy&&Date.parse(policy.expiresAt)>now;
const rules=policy?.browser?.settings||{};
const visible=available&&rules.visible!==false;
const hiddenSections=Array.isArray(rules.hiddenSections)?rules.hiddenSections:[];
const lockedSections=Array.isArray(rules.lockedSections)?rules.lockedSections:[];
const forced=!visible||hiddenSections.includes('appearance')||lockedSections.includes('appearance');
return {available,visible,hiddenSections:[...hiddenSections],lockedSections:[...lockedSections],appearance:{...DEFAULT_APPEARANCE,...rules.appearance,...(forced?{}:preferences)}};
}
function sectionVisible(state,section){return SECTIONS.includes(section)&&state.available&&state.visible&&!state.hiddenSections.includes(section);}
function sectionAllowed(state,section){return sectionVisible(state,section)&&!state.lockedSections.includes(section);}
function featureAllowed(state,section){return SECTIONS.includes(section)&&state.available&&!state.hiddenSections.includes(section)&&!state.lockedSections.includes(section);}
function requireFeature(state,section){if(!featureAllowed(state,section))throw Error('This feature is controlled by your administrator');}
function requireSection(state,section){if(!sectionAllowed(state,section))throw Error('This setting is controlled by your administrator');}
function validateAppearance(input){
if(!input||typeof input!=='object'||Array.isArray(input)||Object.keys(input).some(key=>!Object.hasOwn(DEFAULT_APPEARANCE,key))||!Object.keys(input).length)throw Error('Invalid appearance settings');
const values={mode:['system','light','dark'],accent:['blue','teal','violet'],tabMode:['separate','compact']};
for(const [key,value] of Object.entries(input))if(!values[key].includes(value))throw Error('Invalid appearance settings');
return {...input};
}
module.exports={settingsState,sectionVisible,sectionAllowed,featureAllowed,requireFeature,requireSection,validateAppearance};