@@ -61,6 +61,11 @@ type BeginResult = {
6161 } ;
6262 isError ?: boolean ;
6363} ;
64+ type WaitToolResult = {
65+ structuredContent ?: {
66+ state ?: "authenticated" | "failed" | "pending" ;
67+ } ;
68+ } ;
6469
6570let nextRequestId = 1 ;
6671const pendingRequests = new Map < number , PendingRequest > ( ) ;
@@ -118,11 +123,11 @@ function sendNotification(method: string, params: JsonObject) {
118123 postToHost ( { jsonrpc : "2.0" , method, params } ) ;
119124}
120125
121- function callTool ( name : string , args : JsonObject ) : Promise < BeginResult > {
126+ function callTool < T = BeginResult > ( name : string , args : JsonObject ) : Promise < T > {
122127 return sendRequest ( "tools/call" , {
123128 name,
124129 arguments : args ,
125- } ) as Promise < BeginResult > ;
130+ } ) as Promise < T > ;
126131}
127132
128133function applyHostContext ( context : JsonObject | undefined ) {
@@ -247,6 +252,37 @@ function sanitizeBeginArguments(input: JsonObject): JsonObject {
247252 ) ;
248253}
249254
255+ function waitArgumentsFromLauncher (
256+ content : JsonObject | undefined ,
257+ ) : JsonObject | null {
258+ const nextAction = content ?. next_action as
259+ | {
260+ tool ?: unknown ;
261+ arguments ?: JsonObject ;
262+ }
263+ | undefined ;
264+ if ( nextAction ?. tool !== "manage_auth_connections" || ! nextAction . arguments ) {
265+ return null ;
266+ }
267+ const args = nextAction . arguments ;
268+ if ( args . action !== "wait" ) return null ;
269+ const allowed = [
270+ "action" ,
271+ "id" ,
272+ "domain_filter" ,
273+ "profile_name" ,
274+ "wait_seconds" ,
275+ "required_flow_type" ,
276+ "previous_flow_expires_at" ,
277+ "previous_flow_event_id" ,
278+ ] ;
279+ return Object . fromEntries (
280+ allowed
281+ . filter ( ( key ) => args [ key ] !== undefined )
282+ . map ( ( key ) => [ key , args [ key ] ] ) ,
283+ ) ;
284+ }
285+
250286function ManagedAuthApp ( ) {
251287 const launcher = useLauncherData ( ) ;
252288 const [ beginResult , setBeginResult ] = useState < BeginResult | null > ( null ) ;
@@ -266,6 +302,7 @@ function ManagedAuthApp() {
266302 const launcherContent = launcher . result ?. structuredContent as
267303 | {
268304 connection ?: { domain ?: string ; profile_name ?: string } ;
305+ next_action ?: { tool ?: string ; arguments ?: JsonObject } ;
269306 }
270307 | undefined ;
271308 const targetDomain =
@@ -277,6 +314,9 @@ function ManagedAuthApp() {
277314 const privateAuth =
278315 beginResult ?. _meta ?. auth_login ??
279316 beginResult ?. structuredContent ?. app_private ;
317+ const waitArguments = waitArgumentsFromLauncher (
318+ launcher . result ?. structuredContent as JsonObject | undefined ,
319+ ) ;
280320
281321 const appearance = useMemo (
282322 ( ) => ( { theme : launcher . theme , layout : { skipPrimeStep : true } } ) ,
@@ -450,6 +490,24 @@ function ManagedAuthApp() {
450490 current . flow_status === "SUCCESS" &&
451491 current . status === "AUTHENTICATED"
452492 ) {
493+ if ( waitArguments ) {
494+ const wait = await callTool < WaitToolResult > (
495+ "manage_auth_connections" ,
496+ waitArguments ,
497+ ) ;
498+ const waitState = wait . structuredContent ?. state ;
499+ if ( waitState === "authenticated" ) {
500+ finish ( "success" ) ;
501+ return ;
502+ }
503+ if ( waitState === "failed" ) {
504+ finish ( "failure" ) ;
505+ return ;
506+ }
507+ setStatusText ( "Secure login is still in progress…" ) ;
508+ pollTimer . current = window . setTimeout ( checkStatus , 2000 ) ;
509+ return ;
510+ }
453511 finish ( "success" ) ;
454512 return ;
455513 }
0 commit comments