2026-10-14 22:03:21 -07:00
import assert from "node:assert/strict" ;
import test from "node:test" ;
import { randomUUID } from "node:crypto" ;
import {
AgentPushClient , agentPushAuthorityScope , agentPushCursor , createAgentPresenceReporter , createAgentPushController ,
MAX_AGENT_PUSH_REVOCATIONS , parseAgentPushConfig , parseAgentPushConsent ,
} from "../src/lib/agent-push.ts" ;
import { agentAuthFrame , applyAgentEvent , createAgentRoomState , parseAgentRoomEvent } from "../src/lib/agent-room.ts" ;
const sourceId = "4599d348-e053-4937-987d-1392746fb2ce" ;
const replacementSourceId = "22222222-2222-4222-8222-222222222222" ;
const configuration = () => ({ version : 1 , enabled : true , webPushAvailable : true , apnsAvailable : false , sourceId , quarantined : false ,
vapidPublicKey : "B" . repeat ( 87 ), policy : { presenceHeartbeatMs : 15000 , presenceLeaseMs : 60000 } });
const deferred = () => { let resolve , reject ; const promise = new Promise (( yes , no ) => { resolve = yes ; reject = no ; }); return { promise , resolve , reject }; };
const settle = () => new Promise ( resolve => setImmediate ( resolve ));
function fixture ( overrides = {}, shared = {}) {
let record = shared . record || null , subscription = null , permission = "default" , support = "supported" , config = configuration ();
const calls = [], states = [];
const api = {
config : async () => config ,
register : async ( id , value ) => { calls . push ([ "register" , id , value ]); },
revoke : async id => { calls . push ([ "revoke" , id ]); },
... overrides . api ,
};
const makeSubscription = ( endpoint = "https://push.example.test/opaque" ) => ({
toJSON : () => ({ endpoint , keys : { p256dh : "fixture-public" , auth : "fixture-auth" } }),
unsubscribe : async () => { calls . push ([ "unsubscribe" ]); subscription = null ; return true ; },
});
const platform = {
support : () => support , permission : () => permission ,
requestPermission : () => { calls . push ([ "permission" ]); permission = "granted" ; return Promise . resolve ( permission ); },
subscription : async () => subscription ,
subscribe : async key => { calls . push ([ "subscribe" , key ]); return subscription = makeSubscription (); },
clearNotifications : async () => { calls . push ([ "clear" ]); },
... overrides . platform ,
};
const options = {
api , platform , read : () => record , write : value => { record = structuredClone ( value ); }, uuid : randomUUID ,
scope : async () => "a" . repeat ( 64 ),
lock : async operation => operation (), changed : state => states . push ( state ), ... shared . options ,
};
const controller = createAgentPushController ( options );
return { controller , options , calls , states , api , platform , makeSubscription , record : () => record ,
setConfig ( value ) { config = value ; }, setPermission ( value ) { permission = value ; }, setSupport ( value ) { support = value ; }, setSubscription ( value ) { subscription = value ; } };
}
test ( "explicit gesture requests permission before yielding; permission alone never opts in" , async () => {
const f = fixture (); f . setPermission ( "granted" );
await f . controller . refresh ();
assert . equal ( f . record (), null ); assert . deepEqual ( f . calls , []);
const enabling = f . controller . enable ();
assert . deepEqual ( f . calls , [[ "permission" ]], "request runs directly inside the click stack" );
await enabling ;
assert . equal ( f . record (). enabled , true );
assert . equal ( f . record (). sourceId , sourceId );
assert . equal ( f . record (). revocationPending , false );
assert . equal ( f . calls . filter (([ name ]) => name === "register" ). length , 1 );
await f . controller . refresh (); await f . controller . refresh ();
assert . equal ( f . calls . filter (([ name ]) => name === "register" ). length , 1 , "heartbeat does not repeatedly register an unchanged subscription" );
});
test ( "denial, disabled config, unsupported browser and iOS installation guidance do not subscribe" , async () => {
for ( const support of [ "unsupported" , "install" ]) {
const f = fixture (); f . setSupport ( support ); await f . controller . refresh (); await f . controller . enable ();
assert . equal ( f . controller . state (). canEnable , false ); assert . deepEqual ( f . calls , []);
assert . match ( f . controller . state (). message , support === "install" ? /Home Screen/ : /HTTPS/ );
}
const disabled = fixture (); disabled . setConfig ({ ... configuration (), enabled : false });
await disabled . controller . refresh (); await disabled . controller . enable (); assert . deepEqual ( disabled . calls , []);
const denied = fixture ({ platform : { requestPermission : async () => "denied" } });
await denied . controller . refresh (); await denied . controller . enable ();
assert . equal ( denied . record (). enabled , false ); assert . equal ( denied . calls . length , 0 );
assert . match ( denied . controller . state (). error , /not allowed/ );
});
test ( "registration failure rolls back subscription, persists revoke intent and never echoes provider errors" , async () => {
const f = fixture ({ api : { register : async () => { throw new Error ( "https://private-provider/token-secret" ); }, revoke : async () => { throw new Error ( "offline" ); } } });
await f . controller . refresh (); await f . controller . enable ();
assert . equal ( f . record (). enabled , false ); assert . equal ( f . record (). revocationPending , true );
assert . ok ( f . calls . some (([ name ]) => name === "unsubscribe" ));
assert . doesNotMatch ( JSON . stringify ( f . states ), /private-provider|token-secret/ );
assert . equal ( f . controller . state (). canEnable , false );
});
test ( "offline logout writes tombstone synchronously, unsubscribes locally and retries before any enable" , async () => {
const f = fixture (); await f . controller . refresh (); await f . controller . enable ();
const id = f . record (). installationId ;
f . api . revoke = async () => { throw new Error ( "offline" ); };
const disabling = f . controller . disable ();
assert . equal ( f . record (). enabled , false ); assert . equal ( f . record (). revocationPending , true );
await disabling ;
assert . ok ( f . calls . some (([ name ]) => name === "unsubscribe" ));
const count = f . calls . filter (([ name ]) => name === "register" ). length ;
await f . controller . refresh (); await f . controller . enable ();
assert . equal ( f . calls . filter (([ name ]) => name === "register" ). length , count );
f . api . revoke = async revoked => { assert . equal ( revoked , id ); };
await f . controller . refresh ();
assert . equal ( f . record (). revocationPending , false ); assert . equal ( f . record (). enabled , false );
});
test ( "storage failures during logout still revoke, unsubscribe and close notifications" , async () => {
const f = fixture (); await f . controller . refresh (); await f . controller . enable ();
f . options . write = () => { throw new Error ( "quota" ); };
let removed = false ; f . options . remove = () => { removed = true ; };
await f . controller . disable ();
assert . ok ( removed ); assert . equal ( f . controller . state (). enabled , false );
for ( const name of [ "revoke" , "unsubscribe" , "clear" ]) assert . ok ( f . calls . some (([ action ]) => action === name ));
await f . controller . refresh ();
assert . equal ( f . controller . state (). enabled , false );
});
test ( "a stuck cross-tab lock cannot prevent server retirement or local logout cleanup" , async () => {
const f = fixture (); await f . controller . refresh (); await f . controller . enable ();
f . options . lock = async () => { throw new Error ( "lock acquisition expired" ); };
await f . controller . disable ();
assert . equal ( f . record (). enabled , false ); assert . equal ( f . record (). revocationPending , false );
for ( const name of [ "revoke" , "unsubscribe" , "clear" ]) assert . ok ( f . calls . some (([ action ]) => action === name ));
});
test ( "synchronous permission API failures remain a recoverable opt-in error" , async () => {
const f = fixture ({ platform : { requestPermission : () => { throw new Error ( "user gesture rejected" ); } } });
await f . controller . refresh (); await f . controller . enable ();
assert . equal ( f . record (). enabled , false ); assert . match ( f . controller . state (). error , /could not be requested/ );
});
test ( "subscription rotation upserts the same installation; permission revocation removes it" , async () => {
const f = fixture (); await f . controller . refresh (); await f . controller . enable ();
const id = f . record (). installationId ;
f . setSubscription ( f . makeSubscription ( "https://push.example.test/rotated" ));
await f . controller . refresh ();
const registrations = f . calls . filter (([ name ]) => name === "register" );
assert . equal ( registrations . length , 2 ); assert . ok ( registrations . every (([, installation ]) => installation === id ));
f . setPermission ( "denied" ); await f . controller . refresh ();
assert . equal ( f . record (). enabled , false ); assert . equal ( f . record (). revocationPending , false );
});
test ( "logout while permission prompt is open cancels the older opt-in" , async () => {
const prompt = deferred (), f = fixture ({ platform : { requestPermission : () => prompt . promise } });
await f . controller . refresh (); const enabling = f . controller . enable ();
await f . controller . disable (); prompt . resolve ( "granted" ); await enabling ;
assert . equal ( f . record (). enabled , false );
assert . ok ( ! f . calls . some (([ name ]) => name === "subscribe" || name === "register" ));
});
test ( "two-tab enable → disable → enable uses permanent server tombstones and a new installation UUID" , async () => {
let sharedRecord = null , queue = Promise . resolve (), currentRegistration = false ;
const calls = [], pendingRegister = deferred (), retired = new Set (); let first = true ;
const common = { options : {
read : () => sharedRecord , write : value => { sharedRecord = structuredClone ( value ); },
lock : operation => { const running = queue . then ( operation ); queue = running . catch (() => undefined ); return running ; },
} };
const api = {
register : async id => { calls . push ( "register" ); if ( first ) { first = false ; await pendingRegister . promise ; } assert . ok ( ! retired . has ( id ), "retired UUID must never be reused" ); currentRegistration = true ; },
revoke : async id => { calls . push ( "revoke" ); retired . add ( id ); currentRegistration = false ; },
};
const a = fixture ({ api }, common ), b = fixture ({ api }, common );
await a . controller . refresh (); await b . controller . refresh ();
const enabling = a . controller . enable (); await settle ();
assert . deepEqual ( calls , [ "register" ]);
const disabling = b . controller . disable ();
assert . equal ( sharedRecord . enabled , false ); assert . equal ( sharedRecord . revocationPending , true );
pendingRegister . resolve (); await Promise . all ([ enabling , disabling ]);
assert . equal ( currentRegistration , false );
const id = sharedRecord . installationId ;
await b . controller . enable ();
assert . equal ( currentRegistration , true ); assert . equal ( sharedRecord . enabled , true ); assert . notEqual ( sharedRecord . installationId , id );
assert . ok ( retired . has ( id ));
assert . equal ( calls . at ( - 1 ), "register" );
});
test ( "a timed-out old PUT completing after DELETE cannot revive the retired installation or affect a new opt-in" , async () => {
const retired = new Set (), active = new Set (), late = deferred (); let firstId , lateStatus , first = true ;
const f = fixture ({ api : {
register : async id => {
if ( first ) {
first = false ; firstId = id ;
late . promise . then (() => { lateStatus = retired . has ( id ) ? 409 : 200 ; if ( lateStatus === 200 ) active . add ( id ); });
throw new Error ( "request timed out while server is still processing" );
}
assert . ok ( ! retired . has ( id )); active . add ( id );
},
revoke : async id => { retired . add ( id ); active . delete ( id ); },
} });
await f . controller . refresh (); await f . controller . enable ();
assert . equal ( f . record (). enabled , false ); assert . equal ( f . record (). revocationPending , false ); assert . ok ( retired . has ( firstId ));
await f . controller . enable (); const currentId = f . record (). installationId ;
assert . notEqual ( currentId , firstId ); assert . ok ( active . has ( currentId ));
late . resolve (); await settle ();
assert . equal ( lateStatus , 409 ); assert . deepEqual ([... active ], [ currentId ]);
});
test ( "authority changes retain original-server cleanup without issuing a misleading DELETE to the new server" , async () => {
const f = fixture (); await f . controller . refresh (); await f . controller . enable ();
const oldId = f . record (). installationId , registrations = f . calls . filter (([ name ]) => name === "register" ). length ;
f . options . scope = async () => "b" . repeat ( 64 );
await f . controller . refresh (); await f . controller . refresh ();
assert . equal ( f . record (). enabled , false );
assert . equal ( f . record (). revocationPending , false , "local unsubscribe succeeded, but old server cleanup stays queued" );
assert . deepEqual ( f . record (). pendingRevocations , [{ installationId : oldId , scope : "a" . repeat ( 64 ) }]);
assert . ok ( ! f . calls . some (([ name ]) => name === "revoke" ), "new server's unknown-ID DELETE/204 cannot retire the original server registration" );
assert . equal ( f . calls . filter (([ name ]) => name === "register" ). length , registrations );
await f . controller . enable ();
const newId = f . record (). installationId ;
assert . notEqual ( newId , oldId ); assert . equal ( f . record (). scope , "b" . repeat ( 64 )); assert . equal ( f . record (). enabled , true );
assert . deepEqual ( f . record (). pendingRevocations , [{ installationId : oldId , scope : "a" . repeat ( 64 ) }]);
const reloaded = createAgentPushController ( f . options );
await reloaded . refresh ();
assert . deepEqual ( f . record (). pendingRevocations , [{ installationId : oldId , scope : "a" . repeat ( 64 ) }], "queue survives a reload on B" );
assert . ok ( ! f . calls . some (([ name ]) => name === "revoke" ));
f . options . scope = async () => "a" . repeat ( 64 );
await reloaded . refresh ();
assert . deepEqual ( f . calls . filter (([ name ]) => name === "revoke" ), [[ "revoke" , oldId ]], "returning with A credentials retries only A's intent" );
assert . deepEqual ( f . record (). pendingRevocations , [{ installationId : newId , scope : "b" . repeat ( 64 ) }]);
assert . equal ( f . record (). enabled , false );
await reloaded . enable ();
assert . equal ( f . record (). enabled , true ); assert . equal ( f . record (). scope , "a" . repeat ( 64 ));
assert . notEqual ( f . record (). installationId , oldId );
});
test ( "revoked old credentials do not prevent fresh opt-in after same-server credential rotation" , async () => {
const f = fixture (); await f . controller . refresh (); await f . controller . enable ();
const oldId = f . record (). installationId ;
f . api . revoke = async () => { throw new Error ( "old credentials revoked" ); };
await f . controller . disable ();
assert . equal ( f . record (). revocationPending , true );
f . options . scope = async () => "c" . repeat ( 64 );
await f . controller . refresh (); await f . controller . enable ();
assert . equal ( f . record (). enabled , true ); assert . equal ( f . record (). scope , "c" . repeat ( 64 ));
assert . notEqual ( f . record (). installationId , oldId );
assert . deepEqual ( f . record (). pendingRevocations , [{ installationId : oldId , scope : "a" . repeat ( 64 ) }]);
assert . doesNotMatch ( JSON . stringify ( f . record ()), /credentials|provider|opaque|fixture-auth/ );
});
test ( "failed old-authority retries retain intent while other queued authorities are never contacted" , async () => {
const f = fixture (); await f . controller . refresh (); await f . controller . enable (); await f . controller . disable ();
const queue = [{ installationId : randomUUID (), scope : "a" . repeat ( 64 ) }, { installationId : randomUUID (), scope : "b" . repeat ( 64 ) }];
f . options . write ({ ... f . record (), pendingRevocations : queue });
const attempted = []; f . api . revoke = async id => { attempted . push ( id ); throw new Error ( "offline" ); };
await f . controller . refresh ();
assert . deepEqual ( attempted , [ queue [ 0 ]. installationId ]); assert . deepEqual ( f . record (). pendingRevocations , queue );
await f . controller . enable ();
assert . equal ( f . record (). enabled , true ); assert . deepEqual ( f . record (). pendingRevocations , queue );
});
test ( "bounded revocation queue never silently evicts cleanup and gives actionable opt-in recovery" , async () => {
const f = fixture (); await f . controller . refresh (); await f . controller . enable (); await f . controller . disable ();
const queue = Array . from ({ length : MAX_AGENT_PUSH_REVOCATIONS }, () => ({ installationId : randomUUID (), scope : "b" . repeat ( 64 ) }));
f . options . write ({ ... f . record (), pendingRevocations : queue });
await f . controller . refresh ();
assert . equal ( f . controller . state (). canEnable , false ); assert . match ( f . controller . state (). message , /Sign in to a previous server/ );
const count = f . calls . filter (([ name ]) => name === "register" ). length ;
await f . controller . enable ();
assert . deepEqual ( f . record (). pendingRevocations , queue ); assert . equal ( f . calls . filter (([ name ]) => name === "register" ). length , count );
assert . ok ( parseAgentPushConsent ( JSON . stringify ( f . record ())));
assert . equal ( parseAgentPushConsent ( JSON . stringify ({ ... f . record (), pendingRevocations : [... queue , queue [ 0 ]] })), null );
assert . equal ( parseAgentPushConsent ( JSON . stringify ({ ... f . record (), pendingRevocations : [{ installationId : queue [ 0 ]. installationId , scope : "raw-token" }] })), null );
f . options . scope = async () => "b" . repeat ( 64 );
await f . controller . refresh ();
assert . deepEqual ( f . record (). pendingRevocations , []); assert . equal ( f . controller . state (). canEnable , true );
});
test ( "in-flight cleanup cannot overwrite a newer tab's consent revision" , async () => {
const f = fixture (); await f . controller . refresh (); await f . controller . enable ();
const entered = deferred (), release = deferred ();
let reads = 0 ;
f . options . scope = async () => {
if ( ++ reads === 2 ) { entered . resolve (); await release . promise ; }
return "a" . repeat ( 64 );
};
const disabling = f . controller . disable (); await entered . promise ;
const newer = { ... f . record (), installationId : randomUUID (), revision : randomUUID (), enabled : true , revocationPending : false };
f . options . write ( newer ); release . resolve (); await disabling ;
assert . deepEqual ( f . record (), newer );
});
test ( "principal scope changing while permission is pending prevents registration" , async () => {
const prompt = deferred (), f = fixture ({ platform : { requestPermission : () => prompt . promise } });
await f . controller . refresh (); const enabling = f . controller . enable ();
f . options . scope = async () => "b" . repeat ( 64 );
prompt . resolve ( "granted" ); await enabling ;
assert . equal ( f . record (). enabled , false ); assert . ok ( ! f . calls . some (([ name ]) => name === "subscribe" || name === "register" ));
});
test ( "authority changing during config fetch cannot enable against a mixed identity snapshot" , async () => {
const f = fixture ({ api : { config : async () => { f . options . scope = async () => "b" . repeat ( 64 ); return configuration (); } } });
await f . controller . refresh (); await f . controller . enable ();
assert . equal ( f . controller . state (). canEnable , false ); assert . equal ( f . record (), null ); assert . deepEqual ( f . calls , []);
});
test ( "same backend/token with a replaced source invalidates persisted consent on reload and requires a new opt-in" , async () => {
const f = fixture (); await f . controller . refresh (); await f . controller . enable ();
const old = structuredClone ( f . record ());
f . setConfig ({ ... configuration (), sourceId : replacementSourceId });
const reloaded = createAgentPushController ( f . options );
await reloaded . refresh (); await reloaded . refresh ();
assert . equal ( f . record (). enabled , false ); assert . equal ( f . record (). sourceId , sourceId );
assert . equal ( f . calls . filter (([ name ]) => name === "register" ). length , 1 , "source replacement cannot reuse old consent" );
assert . ok ( f . calls . some (([ name , id ]) => name === "revoke" && id === old . installationId ));
assert . ok ( f . calls . some (([ name ]) => name === "unsubscribe" ));
await reloaded . enable ();
assert . equal ( f . record (). enabled , true ); assert . equal ( f . record (). sourceId , replacementSourceId );
assert . equal ( f . record (). scope , old . scope ); assert . notEqual ( f . record (). installationId , old . installationId );
assert . equal ( f . calls . filter (([ name ]) => name === "permission" ). length , 2 , "replacement requires another explicit permission gesture" );
});
test ( "null or invalid source prevents new opt-in even when transport is configured" , async () => {
for ( const unknown of [ null , undefined , "not-a-source-uuid" ]) {
const f = fixture (); f . setConfig ({ ... configuration (), sourceId : unknown });
await f . controller . refresh (); await f . controller . enable ();
assert . equal ( f . controller . state (). canEnable , false ); assert . equal ( f . record (), null );
assert . deepEqual ( f . calls , [], "unknown source must not request permission, subscribe or register" );
}
});
test ( "losing a known source retires old consent and never resumes it automatically" , async () => {
const f = fixture (); await f . controller . refresh (); await f . controller . enable ();
const oldId = f . record (). installationId ;
f . setConfig ({ ... configuration (), sourceId : null });
await f . controller . refresh ();
assert . equal ( f . record (). enabled , false ); assert . equal ( f . controller . state (). canEnable , false );
assert . ok ( f . calls . some (([ name , id ]) => name === "revoke" && id === oldId ));
f . setConfig ( configuration ()); await f . controller . refresh ();
assert . equal ( f . record (). enabled , false ); assert . equal ( f . calls . filter (([ name ]) => name === "register" ). length , 1 );
});
test ( "legacy or malformed source bindings retain installation identity for retirement, not re-enrollment" , async () => {
for ( const invalid of [ undefined , null , "invalid-source" ]) {
const f = fixture (); await f . controller . refresh (); await f . controller . enable ();
const oldId = f . record (). installationId ;
const stored = parseAgentPushConsent ( JSON . stringify ({ ... f . record (), sourceId : invalid }));
assert . equal ( stored . installationId , oldId ); assert . equal ( stored . sourceId , undefined );
f . options . write ( stored );
await createAgentPushController ( f . options ). refresh ();
assert . equal ( f . record (). enabled , false ); assert . equal ( f . calls . filter (([ name ]) => name === "register" ). length , 1 );
assert . ok ( f . calls . some (([ name , id ]) => name === "revoke" && id === oldId ));
}
});
test ( "source change while permission is pending prevents subscription and retires the incomplete intent" , async () => {
const prompt = deferred (), f = fixture ({ platform : { requestPermission : () => prompt . promise } });
await f . controller . refresh (); const enabling = f . controller . enable ();
const oldId = f . record (). installationId ;
f . setConfig ({ ... configuration (), sourceId : replacementSourceId });
f . setPermission ( "granted" ); prompt . resolve ( "granted" ); await enabling ;
assert . equal ( f . record (). enabled , false ); assert . equal ( f . record (). sourceId , sourceId );
assert . ok ( ! f . calls . some (([ name ]) => name === "subscribe" || name === "register" ));
assert . ok ( f . calls . some (([ name , id ]) => name === "revoke" && id === oldId ));
});
test ( "source change while subscribe is pending unsubscribes without registering" , async () => {
const entered = deferred (), release = deferred ();
const f = fixture ({ platform : { subscribe : async () => {
entered . resolve (); await release . promise ;
const subscription = f . makeSubscription (); f . setSubscription ( subscription ); return subscription ;
} } });
await f . controller . refresh (); const enabling = f . controller . enable (); await entered . promise ;
f . setConfig ({ ... configuration (), sourceId : replacementSourceId }); release . resolve (); await enabling ;
assert . equal ( f . record (). enabled , false ); assert . equal ( f . calls . filter (([ name ]) => name === "register" ). length , 0 );
assert . ok ( f . calls . some (([ name ]) => name === "unsubscribe" ));
});
test ( "source change during initial registration rolls back instead of persisting enabled consent" , async () => {
const entered = deferred (), release = deferred (), registered = [], retired = [];
const f = fixture ({ api : {
register : async id => { registered . push ( id ); entered . resolve (); await release . promise ; },
revoke : async id => { retired . push ( id ); },
} });
await f . controller . refresh (); const enabling = f . controller . enable (); await entered . promise ;
f . setConfig ({ ... configuration (), sourceId : replacementSourceId }); release . resolve (); await enabling ;
assert . equal ( f . record (). enabled , false ); assert . equal ( f . record (). sourceId , sourceId );
assert . deepEqual ( retired , registered ); assert . ok ( f . calls . some (([ name ]) => name === "unsubscribe" ));
});
test ( "source change during automatic rotation registration retires the source-bound installation" , async () => {
const f = fixture (); await f . controller . refresh (); await f . controller . enable ();
const oldId = f . record (). installationId , entered = deferred (), release = deferred ();
f . setSubscription ( f . makeSubscription ( "https://push.example.test/rotated" ));
f . api . register = async id => { assert . equal ( id , oldId ); entered . resolve (); await release . promise ; };
const refreshing = f . controller . refresh (); await entered . promise ;
f . setConfig ({ ... configuration (), sourceId : replacementSourceId }); release . resolve (); await refreshing ;
assert . equal ( f . record (). enabled , false ); assert . ok ( f . calls . some (([ name , id ]) => name === "revoke" && id === oldId ));
});
test ( "source verification failure after registration fails closed and rolls back" , async () => {
const f = fixture ({ api : { register : async () => { f . api . config = async () => { throw new Error ( "source unavailable" ); }; } } });
await f . controller . refresh (); await f . controller . enable ();
assert . equal ( f . record (). enabled , false ); assert . ok ( f . calls . some (([ name ]) => name === "revoke" ));
assert . ok ( f . calls . some (([ name ]) => name === "unsubscribe" ));
});
test ( "attention is per-tab, ordered, focused while idle, and recent input persists until acknowledged" , async () => {
const rows = [], failure = deferred (); let focus = true ;
const a = createAgentPresenceReporter ({ snapshot : () => ({ visibility : "visible" , focused : focus }), send : async value => { rows . push ([ "a" , value ]); } });
const b = createAgentPresenceReporter ({ snapshot : () => ({ visibility : "hidden" , focused : true }), send : async value => { rows . push ([ "b" , value ]); } });
await a . report (); await b . report ();
assert . equal ( rows [ 0 ][ 1 ]. focused , true ); assert . equal ( rows [ 0 ][ 1 ]. interacted , false );
assert . equal ( rows [ 1 ][ 1 ]. focused , false ); assert . equal ( rows [ 1 ][ 1 ]. sequence , 1 );
a . interact (); focus = false ; await a . report (); await a . report ();
assert . equal ( rows [ 2 ][ 1 ]. interacted , true ); assert . equal ( rows [ 2 ][ 1 ]. focused , false );
assert . equal ( rows [ 3 ][ 1 ]. interacted , false ); assert . equal ( rows [ 3 ][ 1 ]. sequence , 3 );
let attempts = 0 ;
const c = createAgentPresenceReporter ({ snapshot : () => ({ visibility : "visible" , focused : false }), send : async value => {
assert . equal ( value . interacted , true ); if ( ++ attempts === 1 ) return failure . promise ;
} });
c . interact (); const report = c . report (); failure . reject ( new Error ( "offline" )); await assert . rejects ( report ); await c . report ();
const id = randomUUID (), frame = JSON . parse ( agentAuthFrame ( "fixture-token" , "2" , id ));
assert . equal ( frame . clientKind , "web" ); assert . equal ( frame . presenceSessionId , id );
2026-10-14 23:06:34 -07:00
assert . deepEqual ( JSON . parse ( agentAuthFrame ( null , "0" , "not-an-id" )), { type : "auth" , token : null , after : "0" , clientKind : "web" });
2026-10-14 22:03:21 -07:00
});
test ( "read frames validate source/cursor and preserve existing read semantics" , () => {
const event = parseAgentRoomEvent ( JSON . stringify ({ type : "read_state" , cursor : "9" , updatedAt : null , sourceId }));
assert . equal ( applyAgentEvent ( createAgentRoomState (), event ). readCursor , "9" );
for ( const cursor of [ "-1" , "1e5" , "9007199254740992" , "1" . repeat ( 200 )]) {
assert . equal ( agentPushCursor ( cursor ), false );
assert . throws (() => parseAgentRoomEvent ( JSON . stringify ({ type : "read_state" , cursor , updatedAt : null , sourceId })));
}
assert . throws (() => parseAgentRoomEvent ( JSON . stringify ({ type : "read_state" , cursor : "1" , updatedAt : null , sourceId : "https://evil.test" })));
assert . equal ( parseAgentPushConsent ( '{"enabled":true}' ), null );
assert . throws (() => parseAgentPushConfig ({ ... configuration (), policy : { presenceHeartbeatMs : 1 , presenceLeaseMs : 60000 } }));
});
test ( "API keeps credentials in headers, validates receipts, handles 204 and redacts provider bodies" , async () => {
const id = randomUUID (), requests = []; let mode = "config" ;
const api = new AgentPushClient ({ baseUrl : "/api" , token : () => "fixture-bearer" , fetch : async ( url , init ) => {
requests . push ({ url , init });
if ( mode === "revoke" ) return new Response ( null , { status : 204 });
if ( mode === "fail" ) return new Response ( JSON . stringify ({ error : "private-token-and-endpoint" }), { status : 500 });
if ( mode === "register" ) return Response . json ({ installationId : id , transport : "web" , enabled : true , version : 1 });
if ( mode === "read" ) return Response . json ({ cursor : "0008" , sourceId });
return Response . json ( configuration ());
} });
await api . config (); mode = "register" ; await api . register ( id , { endpoint : "https://provider.test/endpoint-secret" });
mode = "read" ; assert . deepEqual ( await api . readState (), { sourceId , cursor : "8" });
mode = "revoke" ; await api . revoke ( id );
mode = "fail" ; await assert . rejects ( api . revoke ( id ), error => ! /private-token/ . test ( error . message ));
for ( const request of requests ) {
assert . equal ( request . init . headers . Authorization , "Bearer fixture-bearer" );
assert . equal ( request . init . cache , "no-store" ); assert . equal ( request . init . redirect , "error" );
assert . doesNotMatch ( request . url , /fixture-bearer|endpoint-secret/ );
}
await assert . rejects ( api . revoke ( "../../bad" ));
const unauthenticated = new AgentPushClient ({ baseUrl : "/api" , token : () => null , fetch : () => { throw new Error ( "must not send" ); } });
await assert . rejects ( unauthenticated . config (), /Sign in/ );
});
test ( "authority-guarded API refuses mismatched credentials and pins the captured bearer across async hashing" , async () => {
const id = randomUUID (), requests = [], baseUrl = "https://sybil.example.test/api/" ;
const scope = await agentPushAuthorityScope ( baseUrl , "original-fixture-token" );
assert . equal ( scope , await agentPushAuthorityScope ( "/api" , "original-fixture-token" , "https://sybil.example.test/" ));
assert . match ( scope , /^[a-f0-9]{64}$/ ); assert . equal ( await agentPushAuthorityScope ( baseUrl , null ), null );
let token = "rotated-fixture-token" ;
const api = new AgentPushClient ({ baseUrl , token : () => token , fetch : async ( url , init ) => {
requests . push ({ url , init });
return init . method === "DELETE" ? new Response ( null , { status : 204 }) : Response . json ({ installationId : id , transport : "web" , enabled : true , version : 1 });
} });
await assert . rejects ( api . revoke ( id , scope ));
await assert . rejects ( api . register ( id , { endpoint : "https://provider.test/fixture" }, scope ));
assert . deepEqual ( requests , [], "wrong authority cannot send a mutation or falsely acknowledge cleanup" );
token = "original-fixture-token" ;
const deleting = api . revoke ( id , scope ); token = "rotated-fixture-token" ; await deleting ;
token = "original-fixture-token" ;
const registering = api . register ( id , { endpoint : "https://provider.test/fixture" }, scope ); token = "rotated-fixture-token" ; await registering ;
assert . equal ( requests . length , 2 );
assert . ok ( requests . every (({ init }) => init . headers . Authorization === "Bearer original-fixture-token" ));
assert . ok ( requests . every (({ url }) => ! url . includes ( "fixture-token" )));
});