const {requireSection}=require('./managed-settings.cjs'); function libraryVisible(settings){return !!settings?.available&&!settings.hiddenSections.includes('library');} function bookmarkState({policy,ready,settings}){ const rules=policy?.browser?.bookmarks; if(!ready||!libraryVisible(settings)||!rules)return {managed:[],personal:{revision:0,items:[]},allowUserAdd:false,allowUserEdit:false,allowUserDelete:false}; const result=structuredClone(rules);if(!settings.visible||settings.lockedSections.includes('library'))result.allowUserAdd=result.allowUserEdit=result.allowUserDelete=false;return result; } function validateMutation(input,{policy,ready,settings,destinationAllowed,now=Date.now()}){ if(!ready||!policy||Date.parse(policy.expiresAt)<=now)throw Error('Managed browser access is paused'); requireSection(settings,'library'); const rules=policy.browser.bookmarks; if(!input||!['add','update','delete'].includes(input.action)||Object.keys(input).some(key=>!['action','bookmark','id','expectedRevision','policyVersion'].includes(key)))throw Error('Invalid bookmark operation'); if(input.expectedRevision!==rules.personal.revision||input.policyVersion!==policy.version)throw Error('Bookmarks changed. Refresh before editing.'); if(!rules[{add:'allowUserAdd',update:'allowUserEdit',delete:'allowUserDelete'}[input.action]])throw Error('Bookmark changes are controlled by your administrator'); const id=input.action==='delete'?input.id:input.bookmark?.id; if(typeof id!=='string'||!/^[A-Za-z0-9_-]{1,80}$/.test(id)||rules.managed.some(item=>item.id===id))throw Error('Company bookmarks cannot be changed'); if(input.action==='add'&&rules.personal.items.some(item=>item.id===id)||input.action!=='add'&&!rules.personal.items.some(item=>item.id===id))throw Error('Bookmark identity is unavailable'); if(input.action==='delete')return {action:input.action,id,expectedRevision:input.expectedRevision,policyVersion:input.policyVersion}; const item=input.bookmark; if(Object.keys(item).some(key=>!['id','title','url','folder'].includes(key))||typeof item.title!=='string'||!item.title.trim()||item.title.length>120||/[\u0000-\u001f\u007f]/.test(item.title)||typeof item.folder!=='string'||item.folder.length>80||/[\u0000-\u001f\u007f]/.test(item.folder)||typeof item.url!=='string'||item.url.length>2048)throw Error('Invalid bookmark details'); let url;try{url=new URL(item.url);}catch{throw Error('Invalid bookmark URL');} if(!['https:','http:'].includes(url.protocol)||url.username||url.password||url.search||url.hash||!destinationAllowed(url.href,policy))throw Error('Bookmark destination is not approved'); return {action:input.action,bookmark:{id,title:item.title.trim(),url:url.href,folder:item.folder.trim()},expectedRevision:input.expectedRevision,policyVersion:input.policyVersion}; } module.exports={bookmarkState,validateMutation,libraryVisible};