@@ -73,8 +73,8 @@ interface RunStatus {
7373type SyncState =
7474 | { kind : 'idle' }
7575 | { kind : 'starting' }
76- | { kind : 'running' ; runId : string ; message : string }
77- | { kind : 'needs-otp' ; runId : string ; message : string }
76+ | { kind : 'running' ; runId : string ; message : string ; signin ?: { ticket : string } }
77+ | { kind : 'needs-otp' ; runId : string ; message : string ; signin ?: { ticket : string } }
7878 | { kind : 'success' ; accountsCount : number ; transactionsCount : number }
7979 | { kind : 'error' ; message : string } ;
8080
@@ -279,11 +279,12 @@ export function AccountsView() {
279279 const pollRun = useCallback ( async ( connectionId : string , runId : string ) => {
280280 try {
281281 const { run } = await api < { run : RunStatus } > ( `/scrape/${ encodeURIComponent ( runId ) } ` ) ;
282+ const signin = run . needsRemoteSignin && run . vncTicket ? { ticket : run . vncTicket } : undefined ;
282283 if ( run . status === 'running' ) {
283- setSyncForConnection ( connectionId , { kind : 'running' , runId, message : run . message } ) ;
284+ setSyncForConnection ( connectionId , { kind : 'running' , runId, message : run . message , signin } ) ;
284285 schedule ( connectionId , ( ) => void pollRun ( connectionId , runId ) , SCRAPE_POLL_INTERVAL_MS ) ;
285286 } else if ( run . status === 'needs-otp' ) {
286- setSyncForConnection ( connectionId , { kind : 'needs-otp' , runId, message : run . message } ) ;
287+ setSyncForConnection ( connectionId , { kind : 'needs-otp' , runId, message : run . message , signin } ) ;
287288 // Keep polling — the OTP modal posts the code, then the run goes
288289 // back to running and eventually success/error.
289290 schedule ( connectionId , ( ) => void pollRun ( connectionId , runId ) , SCRAPE_POLL_INTERVAL_MS ) ;
@@ -382,11 +383,12 @@ export function AccountsView() {
382383 || ( ( cur . kind === 'running' || cur . kind === 'needs-otp' ) && cur . runId === run . runId )
383384 ) ;
384385 if ( alreadyTracking ) continue ;
386+ const signin = run . needsRemoteSignin && run . vncTicket ? { ticket : run . vncTicket } : undefined ;
385387 setSyncForConnection (
386388 conn . id ,
387389 run . status === 'needs-otp'
388- ? { kind : 'needs-otp' , runId : run . runId , message : run . message }
389- : { kind : 'running' , runId : run . runId , message : run . message } ,
390+ ? { kind : 'needs-otp' , runId : run . runId , message : run . message , signin }
391+ : { kind : 'running' , runId : run . runId , message : run . message , signin } ,
390392 ) ;
391393 void pollRun ( conn . id , run . runId ) ;
392394 }
@@ -859,6 +861,16 @@ function ConnectionCard({ connection, company, accounts, callbacks, showHistory
859861 { syncing ? 'Syncing…' : 'Sync' }
860862 </ button >
861863 ) }
864+ { ( syncState . kind === 'running' || syncState . kind === 'needs-otp' ) && syncState . signin && (
865+ < a
866+ className = "mini primary"
867+ href = { `/vnc/vnc_lite.html?path=${ encodeURIComponent ( `vnc/websockify?ticket=${ syncState . signin . ticket } ` ) } &ticket=${ encodeURIComponent ( syncState . signin . ticket ) } &autoconnect=true&resize=remote` }
868+ target = "_blank"
869+ rel = "noreferrer"
870+ >
871+ Open sign-in window
872+ </ a >
873+ ) }
862874 { connection . hasCredentials && showHistory && (
863875 < span className = "conn-history-label" >
864876 < span className = "conn-history-text" > History</ span >
0 commit comments