From 15589133cf4ade3a8e9ffa3912787c9a1602b379 Mon Sep 17 00:00:00 2001 From: Chenfeng Bao Date: Tue, 22 Oct 2024 10:57:32 -0700 Subject: [PATCH] add per-page timeout for passwordless auth --- src/D2L.Bmx/OktaAuthenticator.cs | 18 +++++++++++++++++- 1 file changed, 17 insertions(+), 1 deletion(-) diff --git a/src/D2L.Bmx/OktaAuthenticator.cs b/src/D2L.Bmx/OktaAuthenticator.cs index 75edfe70..f9b8df99 100644 --- a/src/D2L.Bmx/OktaAuthenticator.cs +++ b/src/D2L.Bmx/OktaAuthenticator.cs @@ -151,10 +151,20 @@ The provided Okta user '{providedLogin}' does not match the system configured pa private async Task GetSessionIdFromBrowserAsync( string browserPath, Uri orgUrl ) { await using var browser = await browserLauncher.LaunchAsync( browserPath ); - using var cancellationTokenSource = new CancellationTokenSource( TimeSpan.FromSeconds( 15 ) ); var sessionIdTcs = new TaskCompletionSource( TaskCreationOptions.RunContinuationsAsynchronously ); + + // cancel if the total time exceeds 15 seconds, including all page loads and retries + using var cancellationTokenSource = new CancellationTokenSource( TimeSpan.FromSeconds( 15 ) ); cancellationTokenSource.Token.Register( () => sessionIdTcs.TrySetCanceled() ); + // cancel if we're stuck on a single page for 3 seconds + using var pageTimer = new System.Timers.Timer( TimeSpan.FromSeconds( 3 ) ) { AutoReset = false }; + pageTimer.Elapsed += ( _, _ ) => { + sessionIdTcs.TrySetCanceled(); + cancellationTokenSource.Cancel(); + }; + pageTimer.Start(); + using var page = await browser.NewPageAsync().WaitAsync( cancellationTokenSource.Token ); int attempt = 1; @@ -163,6 +173,12 @@ The provided Okta user '{providedLogin}' does not match the system configured pa return await sessionIdTcs.Task; async Task OnPageLoadAsync() { + // reset on every page load, so only the last page load can trigger the timeout + lock( pageTimer ) { + pageTimer.Stop(); + pageTimer.Start(); + } + var url = new Uri( page.Url ); if( url.Host == orgUrl.Host ) { string title = await page.GetTitleAsync().WaitAsync( cancellationTokenSource.Token );