fix(network): защитить ключи WireGuard и режим просмотра операций

This commit is contained in:
Denozordec committed 2026-10-13 20:12:33 +07:00
1 parent c8f9c83f45
commit a404da768d
23 files changed
+1648 -36

No files matched your search

+19
View File
@@ -0,0 +1,19 @@
import {test,expect,type Page} from '@playwright/test'
const sections=['wireguard','ipsec','gre','firewall','filters'] as const
const names={wireguard:'Новый интерфейс',ipsec:'Новый клиент',gre:'Добавить туннель',firewall:'Новое правило',filters:'Новое правило'}
async function setup(page:Page,writer:boolean){let writes=0
const jwt=[Buffer.from('{}').toString('base64url'),Buffer.from(JSON.stringify({sub:'own208',apps:['mm'],permissions:['mm:dashboard:read','mm:servers:read','mm:network:read','mm:filters:read',...(writer?['mm:network:write','mm:filters:write']:[])],exp:Math.floor(Date.now()/1000)+600})).toString('base64url'),'fixture'].join('.')
await page.addInitScript(t=>localStorage.setItem('mmapp_token',t),jwt)
await page.route('**/health',r=>r.fulfill({json:{ok:true}}))
await page.route('**/api/**',r=>{const path=new URL(r.request().url()).pathname;if(r.request().method()!=='GET'){writes++;return r.fulfill({status:403,json:{error:'Unexpected mutation in readonly workspace fixture'}})}
const iface={id:'1:*W',rosId:'*W',name:'own208-wg',serverId:'1',serverName:'Own208 router',listenPort:55208,mtu:1420,comment:'',enabled:true,status:'up',peers:[{id:'own208-peer',rosId:'*P',publicKey:'own208-public',allowedIps:['10.208.0.2/32'],disabled:false}]}
const tunnel={id:'own208-gre',serverId:'1',name:'own208-gre',localAddress:'192.0.2.1',remoteAddress:'192.0.2.2',localInnerIp:'10.208.0.1/30',remoteInnerIp:'10.208.0.2/30',poolId:'live',ipsec:null,mtu:1476,keepaliveInterval:10,keepaliveRetries:3,dscp:'inherit',clampTcpMss:true,allowFastPath:true,comment:'',enabled:true,status:'up'}
const rule={id:'own208-rule',rosId:'*R',serverId:'1',serverName:'Own208 router',family:'ip',table:'filter',chain:'forward',action:'accept',proto:'tcp',src:'',dst:'',port:'443',iface:'',comment:'Own208 rule',enabled:true,hits:1}
const json=path==='/api/auth/config'?{required:true,portal_url:'http://own.portal.invalid'}:path==='/api/servers'?[{id:1,name:'Own208 router',host:'192.0.2.208',type:'exit-node',enabled:true,country:'RU',site:'OWN',asn:'',status:'online',latency:1}]:path==='/api/wireguard'?{interfaces:[iface]}:path==='/api/ipsec'?{servers:[],clients:[]}:path==='/api/gre/tunnels'||path==='/api/filters/gre-tunnels'?{tunnels:[tunnel]}:path==='/api/firewall/all'?{rules:[rule],addressLists:[]}:path==='/api/filters/rules'?{rulesets:[{serverId:'1',rules:[{id:'own208-filter',community:'65001:208',gateway:'',gatewayTunnelId:'',action:'blackhole',description:'Own208 filter'}]}],greTunnels:[],live:true}:path==='/api/recursive-routes'?{routes:[]}:path==='/api/evobgp/settings'?{enabled:false,baseUrl:'',secretConfigured:false}:{}
return r.fulfill({json})});return ()=>writes
}
for(const width of [1440,320])for(const section of sections)for(const writer of [false,true])test(`Native208 ${section} ${writer?'writer':'reader'} ${width}`,async({page})=>{
await page.setViewportSize({width,height:1000});const writes=await setup(page,writer);await page.goto('/'+section+'?server=1');const create=page.getByRole('button',{name:names[section],exact:true}).first();await expect(create).toBeVisible();if(writer){await expect(create).toBeEnabled()}else{await expect(create).toBeDisabled();await expect(page.getByRole('status').filter({hasText:'Режим просмотра'})).toBeVisible();await create.evaluate(b=>(b as HTMLButtonElement).click())}
if(section==='wireguard'&&!writer){await expect(page.getByRole('button',{name:'Импорт',exact:true})).toBeDisabled();await page.getByRole('button',{name:'Действия: own208-wg',exact:true}).click();await expect(page.getByRole('menuitem',{name:'Экспорт',exact:true})).toBeDisabled();await expect(page.getByRole('menuitem',{name:'Добавить пира',exact:true})).toHaveCount(0);await page.keyboard.press('Escape')}
expect(writes()).toBe(0);expect(await page.evaluate(()=>document.documentElement.scrollWidth<=innerWidth+1)).toBe(true)
})