Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Paella: Fix error displayed before authenticating user. #5750

Merged
merged 3 commits into from
Apr 25, 2024

Conversation

miesgre
Copy link
Contributor

@miesgre miesgre commented Apr 16, 2024

This Fix a bug in the loading process when the player tries lo authenticate the user.
Before redirecting to the login page, an error message is briefly displayed.

To test, try to open a video that does not exists without being authenticated. Ex: https://develop.opencast.org/paella7/ui/watch.html?id=no-valid-video

Your pull request should…

This Fix a bug in the loading process when the player tries lo authenticate the user.
Before redirecting to the login page, an error message is briefly displayed
@miesgre miesgre requested a review from karendolan April 16, 2024 09:03
@miesgre
Copy link
Contributor Author

miesgre commented Apr 16, 2024

@KatrinIhler This PR should be to r/15.x? Or it is ok in r/14.x?

@KatrinIhler
Copy link
Member

@KatrinIhler This PR should be to r/15.x? Or it is ok in r/14.x?

Since this is a small bug fix, 14 is fine imo.

// We need to interrupt the player loading to redirect the user to the auth page.
await sleep(100);
// This Error should not happen, as the user is redirected to the auth page.
throw Error('Video not found and user is not authenticated. Try to log in.');
}
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hi @miesgre, our site has tried this same approach in the same part of the code. We still see the red error circle flashing prior to redirecting the page. It is as if the browser requires the current running Javascript function to complete prior to addressing the location.href at the point that it's requested. We have also wrapped promises and timeouts around everything to try break the execution chain, but still get the red error flash before the redirect is executed.

Is it possible to throw an exception, like a throw Error, to break the execution chain, but when caught, the red error UI artifact is not shown? Maybe a special keyword in the Error message like "not an error but a redirect request". It's a common approach in Java to throw an Exception to go down a different code path.

Another idea, which is more hacky, is to create a UI artifact that obscures the red error UI artifact, so that when the Error is thrown and breaks the execution chain, allowing the browser to address the location.href request, no red Error UI artifact shows prior to the location.href being executed.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[EDIT] Our site takes longer to for the location.href to resolve because we do an extra redirect. Opencast adopters that use the regular Opencast login might not have the same lag time response from location.href as we do.

Adding this sleep(100) might be sufficient to prevent the Error artifact from displaying for the default login page redirect. I don't want to imply that it doesn't help at all.

Copy link
Contributor Author

@miesgre miesgre Apr 17, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@karendolan , please test ithis exact code in your installation. I think it should word. The time in the sleep does not matter. The important is to break the execution chain because the location.href is not executed immediately..

The throw after the sleep is never executed!. I put it only in case one day browsers change this behavior.

You can even change the sleep function to a non resolve promise function if you want.

function nonResolvingPromise() {
  return new Promise(() => {});
}

...
await nonResolvingPromise();

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@miesgre What is different about our site is that the location.href does a redirect chain. It ` returns an HTTP 301, then HTTP 302, then HTTP 200 on the redirected page. This is different than the default Opencast login page which returns a HTTP 200 immediately. Our sites issue could be related to the back and forth of the HTTP 301.

I'll test adding a dummy location.href, that immediately returns a HTTP 200 instead of the HTTP 301, to see if I still see the following log after the sleep().

      await sleep(100);
      player.log.debug('After performing the auth redirect and sleep. With persisted logging on in the browser, this log should not show.');
      // This Error should not happen, as the user is redirected to the auth page.
      throw Error('Video not found and user is not authenticated. Try to log in.');
      ```
      

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'll test adding a dummy location.href, that immediately returns a HTTP 200 instead of the HTTP 301, to see if I still see the following log after the sleep().

In Safari, I verified that it's the HTTP 301 that causes the havoc. The HTTP 200 URL displays the log line before the sleep and not the log line after the sleep. The HTTP 301 URL displays the log line before the sleep, the one after the sleep, the error log, and the flash of red error on the page prior to the redirect.

Test by adding and not adding the redirect param .../watch.html?id=&redirect=301

      if (!me.roles.includes('ROLE_USER')) {
        player.log.info('Video not found and user is not authenticated. Try to log in.');
+            if( utils.getUrlParameter('redirect') === '301' ) {
+               // Redirect to a URL that returns a HTTP 301
+               location.href ='https://www.iana.org/domains/example';
+               player.log.debug('Redirected to HTTP 301 before sleep');
+               await sleep(100);
+               player.log.debug('Redirected to HTTP 301 after sleep');
+            } else {
+               // Redirect to a URL that returns a HTTP 200
+               location.href = 'https://example.com';
+               player.log.debug('Redirected to HTTP 200 before sleep');
+               await sleep(100);
+               player.log.debug('Redirected to HTTP 200 after sleep');
+            }
         // This Error should not happen, as the user is redirected to the auth page.
        throw Error('Video not found and user is not authenticated. Try to log in.');
      }
     

[EDIT] When I throttle the network and disable cache, both messages, the before and after sleep(), show on Chrome, Safari and Firefox. The HTTP 200 is faster than the HTTP 301 when the network is not throttled, so that the second message (and error message) is usually missing on fast loads. This implies that the location.href is asynchronous, but it cannot be awaited. The await nonResolvingPromise(); is working in my local tests.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks @karendolan for testing it! I updated the PR with a non resolving promise.
Please test it!

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@karendolan I added a spinner while redirecting. This should solve your problem.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@miesgre this works great for me!

I can approve it, but I can't merge it because there is a failing github actions Playright test that isn't related to the code but to the target test video.

    Error: Timed out 5000ms waiting for expect(locator).toHaveTitle(expected)

    Locator: locator(':root')
    Expected string: "Dual-Stream Demo - No series | Opencast"
    Received string: "Paella Player 7"
    ```

gregorydlogan added a commit that referenced this pull request Apr 24, 2024
…r/14.x

Pull request #5750

  Paella: Fix error displayed before authenticating user.
Copy link
Member

@karendolan karendolan left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The pull works, fixes the red error flash prior to auth redirect and the spinner shows when the redirect takes a few moments.

The github action Playright test fail needs to be addressed.

@miesgre
Copy link
Contributor Author

miesgre commented Apr 25, 2024

The pull works, fixes the red error flash prior to auth redirect and the spinner shows when the redirect takes a few moments.

The github action Playright test fail needs to be addressed.

@karendolan Don't worry about paella tests. Fails because in r/14.x tests are done using https://develop.opencast.org/paella7/ui/watch.html?id=ID-dual-stream-demo, but this video is not public now.

In #5684 It is solved, but it is only in develop

Copy link
Member

@karendolan karendolan left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Then all good! Approved.

@karendolan karendolan merged commit 5f68782 into opencast:r/14.x Apr 25, 2024
4 of 5 checks passed
@miesgre miesgre deleted the fix-paella-auth-red-flag-r14 branch April 25, 2024 21:49
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

3 participants