-
-
Notifications
You must be signed in to change notification settings - Fork 2.8k
Fix ajax no access error #23910
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
base: 5.x-dev
Are you sure you want to change the base?
Fix ajax no access error #23910
Conversation
|
If you don't want this PR to be closed automatically in 28 days then you need to assign the label 'Do not close'. |
b8ea408 to
b795c1a
Compare
sgiehl
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Generally the changes might work, but are far away from "perfect". When working on such legacy parts it's important to also challenge the current implementation and consider fundamental changes instead of just relying on existing behavior.
I've used codex to create some code upon your changes, to implement a proper session timeout handling that is less error prone and improve the code overall a bit:
- Relying on 401 status code might still cause problems, as plugins might send 401 status codes, that should not result in reloads. I've update that to use a custom header instead.
- Setting a global Access state when the session has a real timeout makes the whole handling a lot more accurate, than trying to detect that based on the referrer.
- As the more accurate timeout detection would prevent the session timeout message to be displayed after page reload this state is temporarily stored in a cookie
- Properly differ between 401 (fully unauthorized requests) and 403 (authorized requests without permission)
See fix-ajax-no-access-error...fix-session-timeout-handling for the proposed changes.
Note: This was built upon my rough ideas. I haven't done a proper review or deeper testing yet
| const loginForm = await page.waitForSelector('#login_form_login', { visible: true }); | ||
| expect(loginForm).to.be.ok; | ||
|
|
||
| const expectedText = 'Error: Your session has expired due to inactivity. Please log in to continue.'; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Technically that might already have been incorrect before. Removing cookies isn't really a session timeout. It's just an unauthenticated request, that Matomo incorrectly reports as session timeout.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
As written here before. This can't be considered a session timeout. A missing cookie needs to be interpreted as unauthorized.
Thanks for your input on this @sgiehl. Cheers |
sgiehl
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Left some comments. I don't think the changes you made regarding the anonymous user are needed at all. The anonymous user does not need to log in. So even if the session times out, that user would not be redirected to the login form if view access to the website is granted.
| const result = new Promise<T | ErrorResponse>((resolve, reject) => { | ||
| this.requestHandle!.then((data: unknown) => { | ||
| this.requestHandle!.then((data: unknown, _textStatus: string, xhr: jqXHR) => { | ||
| const isInApp = !document.querySelector('#login_form'); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I can't see a good reason why this would be needed. If the request returns a 200, there was no problem. Even if the session might have timed out - e.g. for anonymous - it was no problem. Otherwise it would result in a 40X.
| } | ||
|
|
||
| it('should display password reset form when forgot password link clicked', async function () { | ||
| xit('should display password reset form when forgot password link clicked', async function () { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
What are those changes good for?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
That change looks incorrect. Why should it show the session message?
| const loginForm = await page.waitForSelector('#login_form_login', { visible: true }); | ||
| expect(loginForm).to.be.ok; | ||
|
|
||
| const expectedText = 'Error: Your session has expired due to inactivity. Please log in to continue.'; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
As written here before. This can't be considered a session timeout. A missing cookie needs to be interpreted as unauthorized.
core/Session/SessionAuth.php
Outdated
| { | ||
| $expirationTime = $sessionFingerprint->getExpirationTime(); | ||
| if (empty($expirationTime)) { | ||
| $this->sessionExpired = true; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think this line causes the test changes and should be reverted. From a technical perspective a session without an expiration time should not occur. It happens if there is no session at all. So the very first call to Matomo (without any cookie) is now always marked as timed out. Same happens for the tests using FakeAccess, as they are not using the SessionAuth.
…is not the same as token saved for user
…ession has expired or is invalid
…rue otherwise, just fail silently return error message
… for network to be idle before doing some page actions
…error message since we have put back most ajax calls to fail silently
…ion time is empty/null
…his results in a successful call (since we allow anonymous user to access the api), we just need to check the session timed out header and do a refresh if it exists
…hanges to returned http code and exception thrown.
345e17b to
ebc08c1
Compare
ebc08c1 to
07714c8
Compare
Description
Dev-19785
This PR is to fix the regression we had when we tried to redirect invalid session errors to login page (https://innocraft.atlassian.net/browse/UX-305).
We only want to force the redirect when we actually detect an invalid session issue and not to redirect ALL NoAccessExceptions. We will retain the original behaviour of NoAccessException for ajax calls to just fail silently and just returning the error message.
Testing:
NOTE: The only way I could test this fix was to try to do some datatable actions that will trigger saving of table preference. This would show errors and will refresh the page with no change in the sorting when the issue is not fixed. This happened when the regression was introduced and was noticeable on our Demo Site.
If the issue is fixed, the datatable should not give any errors and sorting should work (although it will not be saved because it is 'anonymous' user).
This should still error and redirect if a session becomes invalid (session expires or is deleted). I was able to test this by logging in as an admin to my local site. Then deleted my session (or changing the expire date to something in the past), then clicking on a new category/page or even just trying to sort the datatable.
Checklist
Review