| 1234567891011121314151617181920212223242526272829303132333435 |
- /** Fetch the authority in the existing browser session; renderer count input is never trusted. */
- export function installUnreadBadge({ ipcMain, app, owner, origins, url, quitting, fetch, interval = 3000 }) {
- let account=null,generation=0,poll,pending=false
- const badge=count=>{if(app.dock)app.dock.setBadge(count ? String(count) : '')}
- const clear=()=>{account=null;generation++;pending=false;clearInterval(poll);poll=undefined;badge(0)}
- const trusted=event=>{
- try{return !quitting()&&event.sender===owner()?.webContents&&event.senderFrame===owner().webContents.mainFrame&&origins().includes(new URL(event.senderFrame.url).origin)}catch{return false}
- }
- async function refresh(){
- if(!account||pending||quitting())return
- const current=generation,identity=account,origin=new URL(url()).origin;pending=true
- try{
- const options={credentials:'include',redirect:'error',cache:'no-store'}
- const auth=await fetch(`${origin}/api/app/bootstrap?csrfOnly=1`,options)
- if(!auth.ok)throw new Error('authentication required')
- const user=await auth.json()
- // auth-disabled local identity is represented as null by csrfOnly.
- if((user.userId??'local')!==identity){if(current===generation)clear();return}
- const response=await fetch(`${origin}/api/app/unread`,options)
- if([401,403].includes(response.status)){if(current===generation)clear();return}
- if(!response.ok)return
- const value=await response.json()
- if(current===generation&&account===identity&&origins().includes(origin)&&Number.isSafeInteger(value.total)&&value.total>=0)badge(value.total)
- }catch{ /* Offline preserves the last authenticated count. Navigation/logout clears immediately. */ }
- finally{if(current===generation)pending=false}
- }
- ipcMain.handle('desktop:unread-state',async(event,input)=>{
- if(!trusted(event))throw new Error('不允许此页面更新未读状态')
- if(input!==null&&(typeof input!=='string'||!input.trim()||input.length>256))throw new Error('无效账号范围')
- if(input===null){clear();return}
- if(account!==input){clear();account=input;poll=setInterval(()=>void refresh(),interval);poll.unref?.()}
- await refresh()
- })
- return { clear,refresh,stop(){clear();ipcMain.removeHandler('desktop:unread-state')} }
- }
|