Files
safetynet/packages/core/transport-facts.cjs
T

13 lines
1.5 KiB
JavaScript

'use strict';
const {z}=require('zod');
const TransportFactsSchema=z.object({transportId:z.string().uuid(),protocol:z.literal('webtransport'),phase:z.enum(['created','closed','established']),realm:z.enum(['window','worker','iframe']),sessionId:z.string().uuid(),connectionEstablished:z.boolean()}).strict().refine(f=>f.phase==='closed'||f.connectionEstablished===(f.phase==='established'));
const TRANSPORT_MONITOR_REASONS=Object.freeze(['transport-observer-detached','transport-observer-command-timeout','transport-observer-overflow','transport-observer-audit-failed','transport-observer-unavailable','unexpected-webtransport-established']);
const TRANSPORT_KINDS=Object.freeze(['transport.created','transport.closed','transport.established','transport.monitor-unavailable']);
function canonicalTransportHostname(host){
if(typeof host!=='string'||!host.length||host.length>253)return false;
try{const url=new URL(`https://${host}`);return url.hostname===host&&url.host===host&&url.username===''&&url.password===''&&url.port===''&&url.pathname==='/'&&url.search===''&&url.hash==='';}catch{return false;}
}
function transportFacts(value){return TransportFactsSchema.parse(value);}
function transportFactsForEvent(kind,value){const parsed=TransportFactsSchema.safeParse(value);return parsed.success&&kind===`transport.${parsed.data.phase}`?parsed.data:null;}
module.exports={canonicalTransportHostname,TransportFactsSchema,transportFacts,transportFactsForEvent,TRANSPORT_MONITOR_REASONS,TRANSPORT_KINDS};