Files
safetynet/packages/core/enterprise.mjs
T

24 lines
4.1 KiB
JavaScript
Raw Normal View History

2026-10-13 10:33:31 +02:00
import { z } from 'zod';
import { isIP } from 'node:net';
const endpoint=(protocols)=>z.string().max(2048).refine(value=>{try{const u=new URL(value);return protocols.includes(u.protocol)&&!!u.hostname&&!u.username&&!u.password&&!u.hash&&!u.search&&u.pathname.length>1;}catch{return false;}},'Use an absolute service URL without credentials, query or fragment');
export const EnterpriseSchema=z.object({
dns:z.object({mode:z.enum(['system','secure']).default('system'),templates:z.array(endpoint(['https:'])).max(4).default([])}).strict().prefault({}),
vpn:z.object({required:z.boolean().default(false),interfaceNames:z.array(z.string().trim().min(1).max(100)).max(20).default([]),requiredDnsServers:z.array(z.string().refine(v=>isIP(v)>0,'Expected a DNS server IP address')).max(20).default([])}).strict().prefault({}),
icap:z.object({enabled:z.boolean().default(false),url:z.union([z.literal(''),endpoint(['icaps:','icap:'])]).default(''),method:z.enum(['RESPMOD','REQMOD']).default('RESPMOD'),allow204:z.literal(true).default(true),allowInsecureTransport:z.boolean().default(false),scanUploads:z.boolean().default(true),scanDownloads:z.boolean().default(true),scanClipboard:z.boolean().default(true),scanAI:z.boolean().default(true),timeoutMs:z.number().int().min(1000).max(60000).default(10000),maxBytes:z.number().int().min(1024).max(20*1024*1024).default(20*1024*1024),failClosed:z.literal(true).default(true)}).strict().prefault({})
}).strict().prefault({}).superRefine((p,c)=>{
if(p.dns.mode==='secure'&&!p.dns.templates.length)c.addIssue({code:'custom',path:['dns','templates'],message:'Secure DNS requires a corporate HTTPS resolver'});
if(p.dns.mode==='system'&&p.dns.templates.length)c.addIssue({code:'custom',path:['dns','templates'],message:'Clear resolver templates when using system DNS'});
if(p.vpn.required&&!p.vpn.interfaceNames.length)c.addIssue({code:'custom',path:['vpn','interfaceNames'],message:'Required VPN needs approved Windows interface names'});
if(p.icap.enabled&&!p.icap.url)c.addIssue({code:'custom',path:['icap','url'],message:'Enabled ICAP requires a TLS ICAP service URL'});
if(p.icap.enabled&&p.icap.url.startsWith('icap:')&&!p.icap.allowInsecureTransport&&!['127.0.0.1','[::1]','localhost'].includes(new URL(p.icap.url).hostname))c.addIssue({code:'custom',path:['icap','url'],message:'Remote plaintext ICAP requires explicit insecure transport approval'});
if(p.icap.enabled&&![p.icap.scanUploads,p.icap.scanDownloads,p.icap.scanClipboard,p.icap.scanAI].some(Boolean))c.addIssue({code:'custom',path:['icap'],message:'Select at least one inspection channel'});
});
export function enterpriseReadiness(p){return [
{id:'proxy',label:'Corporate proxy',state:p.proxy.mode==='direct'?'direct':'configured',detail:p.proxy.mode==='system'?'Uses Windows proxy and existing PAC configuration.':p.proxy.mode==='direct'?'Direct network access explicitly selected.':'Centrally managed proxy configuration.'},
{id:'dns',label:'Corporate DNS',state:p.enterprise.dns.mode==='secure'?'configured':'system',detail:p.enterprise.dns.mode==='secure'?'Required HTTPS DNS resolver; no insecure fallback.':'Uses OS DNS, including VPN-provided servers.'},
{id:'vpn',label:'VPN presence gate',state:p.enterprise.vpn.required?'configured':'optional',detail:'Windows interface presence is a gate, not proof of VPN routing or tunnel health.'},
{id:'icap',label:'External antivirus / sandbox',state:p.enterprise.icap.enabled?'configured':'off',detail:'ICAP request/response scanning, full payload, allow or block only. No content modification or deferred verdict support; unavailable inspection blocks selected channels.'},
{id:'downloads',label:'Download release',state:p.browser.allowDownloads&&((p.security.yara.enabled&&p.security.yara.rules.length)||(p.enterprise.icap.enabled&&p.enterprise.icap.scanDownloads))?'configured':'blocked',detail:'Downloads require configured local YARA or external ICAP scanning; enabled scanners are mandatory.'},
{id:'semantic',label:'Local semantic DLP',state:p.dlp.semantic.enabled?'configured':'off',detail:'Requires installed pinned model and calibrated references. Configuration does not prove device readiness.'}
];}