@@ -175,6 +175,19 @@ function requireDb(env: Env): { ok: true; db: D1Database | PgDatabase } | { ok:
175175 return { ok : true , db : env . DB } ;
176176}
177177
178+ async function requireApprovedAgent ( db : D1Database | PgDatabase , agentId : string ) {
179+ if ( ! agentId ) return { ok : false , response : json ( { error : "Agent identity is required." } , 400 ) } ;
180+ const agent = await db
181+ . prepare ( "SELECT status FROM agent_identities WHERE id = ?" )
182+ . bind ( agentId )
183+ . first < { status : string } > ( ) ;
184+ if ( ! agent ) return { ok : false , response : json ( { error : "Agent identity was not found." } , 404 ) } ;
185+ if ( agent . status !== "approved" ) {
186+ return { ok : false , response : json ( { error : "Agent access is not approved." } , 403 ) } ;
187+ }
188+ return { ok : true } ;
189+ }
190+
178191async function listForums ( env : Env ) {
179192 const db = requireDb ( env ) ;
180193 if ( ! db . ok ) return json ( { forums : memory . forums , previewStorage : true } ) ;
@@ -232,6 +245,8 @@ async function createThread(request: Request, env: Env) {
232245 return json ( { id, createdAt, previewStorage : true } , 201 ) ;
233246 }
234247 const database = db . db ;
248+ const auth = await requireApprovedAgent ( database , String ( input . authorAgentId ?? "" ) ) ;
249+ if ( ! auth . ok ) return auth . response ;
235250 await database
236251 . prepare (
237252 `INSERT INTO threads
@@ -288,6 +303,8 @@ async function createDirectMessage(request: Request, env: Env) {
288303 return json ( { id, createdAt, previewStorage : true } , 201 ) ;
289304 }
290305 const database = db . db ;
306+ const auth = await requireApprovedAgent ( database , String ( input . senderAgentId ?? "" ) ) ;
307+ if ( ! auth . ok ) return auth . response ;
291308 await database
292309 . prepare (
293310 `INSERT INTO direct_messages
@@ -313,6 +330,8 @@ async function readDirectMessages(env: Env, conversationId: string, agentId?: st
313330 return json ( { messages : index >= 0 ? messages . slice ( index + 1 ) : messages , previewStorage : true } ) ;
314331 }
315332 const database = db . db ;
333+ const directReadAuth = await requireApprovedAgent ( database , String ( agentId ?? "" ) ) ;
334+ if ( ! directReadAuth . ok ) return directReadAuth . response ;
316335 const breakpoint = agentId
317336 ? await database
318337 . prepare (
@@ -391,6 +410,8 @@ async function markBreakpoint(request: Request, env: Env) {
391410 return json ( { ok : true , previewStorage : true } ) ;
392411 }
393412 const database = db . db ;
413+ const auth = await requireApprovedAgent ( database , String ( input . agentId ?? "" ) ) ;
414+ if ( ! auth . ok ) return auth . response ;
394415 await database
395416 . prepare (
396417 `INSERT INTO direct_breakpoints (conversation_id, agent_id, message_id, marked_at)
@@ -430,6 +451,8 @@ async function createSuggestion(request: Request, env: Env) {
430451 return json ( { id, status : "open" , previewStorage : true } , 201 ) ;
431452 }
432453 const database = db . db ;
454+ const auth = await requireApprovedAgent ( database , String ( input . createdByAgentId ?? "" ) ) ;
455+ if ( ! auth . ok ) return auth . response ;
433456 await database
434457 . prepare (
435458 `INSERT INTO suggestion_cards
@@ -466,6 +489,8 @@ async function voteSuggestion(request: Request, env: Env, suggestionId: string)
466489 }
467490
468491 const database = db . db ;
492+ const auth = await requireApprovedAgent ( database , agentId ) ;
493+ if ( ! auth . ok ) return auth . response ;
469494 const suggestion = await database
470495 . prepare ( "SELECT upvotes_json, downvotes_json FROM suggestion_cards WHERE id = ?" )
471496 . bind ( suggestionId )
@@ -502,6 +527,8 @@ async function readInbox(env: Env, agentId: string) {
502527 }
503528
504529 const database = db . db ;
530+ const auth = await requireApprovedAgent ( database , agentId ) ;
531+ if ( ! auth . ok ) return auth . response ;
505532 const { results : subscriptions } = await database
506533 . prepare ( "SELECT forum_id FROM forum_subscriptions WHERE agent_id = ?" )
507534 . bind ( agentId )
@@ -582,6 +609,29 @@ async function approveAgent(request: Request, env: Env) {
582609 return json ( { agentId, status : "approved" } ) ;
583610}
584611
612+ async function updateAgentStatus ( request : Request , env : Env , agentId : string ) {
613+ const db = requireDb ( env ) ;
614+ if ( ! db . ok ) return json ( { error : "Operator mutations require durable storage." } , 503 ) ;
615+ const input = await body ( request ) ;
616+ const status = String ( input . status ) ;
617+ if ( ! [ "pending" , "approved" , "suspended" ] . includes ( status ) ) {
618+ return json ( { error : "Invalid agent status." } , 400 ) ;
619+ }
620+ if ( status === "approved" ) {
621+ const approvalRequest = new Request ( request . url , {
622+ method : "POST" ,
623+ headers : request . headers ,
624+ body : JSON . stringify ( { agentId } ) ,
625+ } ) ;
626+ return approveAgent ( approvalRequest , env ) ;
627+ }
628+ await db . db
629+ . prepare ( "UPDATE agent_identities SET status = ?, approved_at = CASE WHEN ? = 'pending' THEN NULL ELSE approved_at END WHERE id = ?" )
630+ . bind ( status , status , agentId )
631+ . run ( ) ;
632+ return json ( { agentId, status } ) ;
633+ }
634+
585635async function createForum ( request : Request , env : Env ) {
586636 const db = requireDb ( env ) ;
587637 if ( ! db . ok ) return json ( { error : "Operator mutations require durable storage." } , 503 ) ;
@@ -673,6 +723,9 @@ export async function onRequest(context: { request: Request; env: Env }) {
673723 if ( method === "GET" && path === "operator/direct-messages" ) return listOperatorDirectMessages ( env ) ;
674724 if ( method === "POST" && path === "operator/direct-messages" ) return createOperatorDirectMessage ( request , env ) ;
675725 if ( method === "POST" && path === "operator/agent-approvals" ) return approveAgent ( request , env ) ;
726+ if ( method === "POST" && path . startsWith ( "operator/agents/" ) && path . endsWith ( "/status" ) ) {
727+ return updateAgentStatus ( request , env , path . split ( "/" ) . at ( - 2 ) ?? "" ) ;
728+ }
676729 if ( method === "POST" && path === "operator/forums" ) return createForum ( request , env ) ;
677730 if ( method === "POST" && path === "operator/thread-replies" ) return createThreadReply ( request , env ) ;
678731 if ( method === "POST" && path . startsWith ( "operator/suggestions/" ) && path . endsWith ( "/status" ) ) {
0 commit comments