Implement managed browser security, individual agents and observability
This commit is contained in:
1 parent
ff482ebe23
commit
ea448de2d4
172 files changed
+5404
-347
No files matched your search
@@ -0,0 +1,20 @@
|
||||
import {test} from 'node:test';
|
||||
import assert from 'node:assert/strict';
|
||||
import fs from 'node:fs';
|
||||
import vm from 'node:vm';
|
||||
const source=fs.readFileSync(new URL('../apps/browser/renderer.js',import.meta.url),'utf8');
|
||||
function fixture(state){
|
||||
const elements=new Map(),calls=[];let tick;
|
||||
class Element{constructor(tag){this.tag=tag;this.children=[];this.open=false;this.listeners={};this.textContent='';}set id(value){this._id=value;elements.set(value,this);}get id(){return this._id;}setAttribute(){}append(...nodes){this.children.push(...nodes);}replaceChildren(){this.children=[];}addEventListener(name,fn){this.listeners[name]=fn;}showModal(){this.open=true;}close(){this.open=false;this.listeners.close?.();}}
|
||||
const agents=new Element('button');agents.id='agents';
|
||||
const context={lastState:state,Date,JSON,Number,Array,Error,setInterval:fn=>{tick=fn;},document:{createElement:tag=>new Element(tag),body:new Element('body')},$:id=>elements.get(id),requireSection:()=>{if(state.blocked)throw Error('managed');},call:async(method,id)=>{calls.push({method,id});return {address:'http://127.0.0.1:4567',credentialPath:'protected.json'};},updateChrome:async()=>{},task:fn=>fn,button:(label,fn)=>{const e=new Element('button');e.textContent=label;e.onclick=fn;return e;}};
|
||||
vm.createContext(context);vm.runInContext(source.slice(source.indexOf('// Pairing selects'),source.indexOf("$('ai-form').onsubmit")),context);
|
||||
return {context,elements,calls,tick:()=>tick()};
|
||||
}
|
||||
const grant={id:'reviewer',name:'Security reviewer',generation:2,expiresAt:new Date(Date.now()+60000).toISOString()};
|
||||
test('individual pairing requires selecting a published identity and closes on revocation',async()=>{
|
||||
const f=fixture({ready:true,agentsEnabled:true,agentIdentityMode:'individual',agentGrants:[grant]});await f.context.openAgentPairing();assert.equal(f.calls.length,0);const list=f.elements.get('agent-grant-list');assert.equal(list.children.length,1);await list.children[0].onclick();assert.equal(f.calls[0].id,'reviewer');assert.match(f.elements.get('agent-pairing-result').textContent,/Security reviewer/);f.context.lastState.agentGrants=[];f.tick();assert.equal(f.elements.get('agent-pairing').open,false);assert.equal(f.elements.get('agent-pairing-result').textContent,'');
|
||||
});
|
||||
test('empty individual mode cannot issue legacy credential and managed section rejects pairing',async()=>{
|
||||
const state={ready:true,agentsEnabled:true,agentIdentityMode:'individual',agentGrants:[]},f=fixture(state);await f.context.openAgentPairing();assert.match(f.elements.get('agent-grant-list').children[0].textContent,/No active agent/);assert.equal(f.calls.length,0);state.blocked=true;await assert.rejects(f.context.openAgentPairing(),/managed/);
|
||||
});
|
||||
Reference in new issue
Block a user