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

Log out from other tabs. #1863

Merged
merged 1 commit into from
Dec 16, 2023
Merged

Log out from other tabs. #1863

merged 1 commit into from
Dec 16, 2023

Conversation

peregrineshahin
Copy link
Contributor

Logs users out from other tabs if they try to use them while they have logged-out or lost cookies. Worth noting that the page was already unusable and the user couldn't do actions due to an expired CSRF token.

steps in the issue cannot reproduce the error. I can only see this scenario causing it. Fixes: #1839

Needs Dev testing.

@vdbergh
Copy link
Contributor

vdbergh commented Dec 15, 2023

application.js already contains a general mechanism to execute code in other tabs (broadcast). I implemented it for the notifications (there is only one tab checking for events on the server, but the corresponding GUI changes have to happen in all open tabs). Not sure if it fits your purpose....

@peregrineshahin
Copy link
Contributor Author

I have just noticed that this does not work as intended, since the csrf token will also be invalid even if the user logs back.. drafting, maybe tonight I can look for a fix or see if I need the broadcasting..

@peregrineshahin peregrineshahin marked this pull request as draft December 15, 2023 14:54
@peregrineshahin peregrineshahin marked this pull request as ready for review December 15, 2023 23:07
@peregrineshahin
Copy link
Contributor Author

This seems the way to go! Thanks.
I also left out the cleanup to make the PR testable and reviewable.. maybe can do them later.

application.js already contains a general mechanism to execute code in other tabs (broadcast). I implemented it for the notifications (there is only one tab checking for events on the server, but the corresponding GUI changes have to happen in all open tabs). Not sure if it fits your purpose....

@vdbergh
Copy link
Contributor

vdbergh commented Dec 16, 2023

The cleanup is left over code. It has to be deleted.

The reason it is there is that the notification code went through many iterations and this created some garbage in local storage. So I made a PR to delete this garbage. But I forgot to revert it.

@ppigazzini
Copy link
Collaborator

ppigazzini commented Dec 16, 2023

DEV updated, I'm not able to logout.

application.js?v=BhYWqLYFMvRQOzSoqQH2/n0JyDoro4yHnIjE4hIg9ydkFPBagWWt3o6Js+Yt3ePS:8 2023-12-16T08:32:39.492Z: Web locks supported!
application.js?v=BhYWqLYFMvRQOzSoqQH2/n0JyDoro4yHnIjE4hIg9ydkFPBagWWt3o6Js+Yt3ePS:257  Uncaught (in promise) ReferenceError: csrfToken is not defined
    at log_out_ (application.js?v=BhYWqLYFMvRQOzSoqQH2/n0JyDoro4yHnIjE4hIg9ydkFPBagWWt3o6Js+Yt3ePS:257:23)
    at broadcast (application.js?v=BhYWqLYFMvRQOzSoqQH2/n0JyDoro4yHnIjE4hIg9ydkFPBagWWt3o6Js+Yt3ePS:293:8)
    at log_out (application.js?v=BhYWqLYFMvRQOzSoqQH2/n0JyDoro4yHnIjE4hIg9ydkFPBagWWt3o6Js+Yt3ePS:264:3)
    at HTMLAnchorElement.<anonymous> (application.js?v=BhYWqLYFMvRQOzSoqQH2/n0JyDoro4yHnIjE4hIg9ydkFPBagWWt3o6Js+Yt3ePS:133:5)
application.js?v=BhYWqLYFMvRQOzSoqQH2/n0JyDoro4yHnIjE4hIg9ydkFPBagWWt3o6Js+Yt3ePS:8 2023-12-16T08:32:48.478Z: Active notifications: []

@peregrineshahin
Copy link
Contributor Author

Afk, I will look later today.

@ppigazzini ppigazzini added enhancement server server side changes gui dev test currently undergoing test on DEV labels Dec 16, 2023
@ppigazzini
Copy link
Collaborator

ppigazzini commented Dec 16, 2023

DEV updated with "Fix prettier" 64564bd

application.js?v=c9T60cfwQOukm2m1GZYZdIpNOQ4WkJZfF70rpoRsS6iEoJ86IUYUHye7cR3N0WSl:8 2023-12-16T14:37:52.214Z: Web locks supported!
application.js?v=c9T60cfwQOukm2m1GZYZdIpNOQ4WkJZfF70rpoRsS6iEoJ86IUYUHye7cR3N0WSl:257  Uncaught (in promise) ReferenceError: csrfToken is not defined
    at log_out_ (application.js?v=c9T60cfwQOukm2m1GZYZdIpNOQ4WkJZfF70rpoRsS6iEoJ86IUYUHye7cR3N0WSl:257:23)
    at broadcast (application.js?v=c9T60cfwQOukm2m1GZYZdIpNOQ4WkJZfF70rpoRsS6iEoJ86IUYUHye7cR3N0WSl:293:8)
    at log_out (application.js?v=c9T60cfwQOukm2m1GZYZdIpNOQ4WkJZfF70rpoRsS6iEoJ86IUYUHye7cR3N0WSl:264:3)
    at HTMLAnchorElement.<anonymous> (application.js?v=c9T60cfwQOukm2m1GZYZdIpNOQ4WkJZfF70rpoRsS6iEoJ86IUYUHye7cR3N0WSl:133:5)
log_out_ @ application.js?v=c9T60cfwQOukm2m1GZYZdIpNOQ4WkJZfF70rpoRsS6iEoJ86IUYUHye7cR3N0WSl:257
broadcast @ application.js?v=c9T60cfwQOukm2m1GZYZdIpNOQ4WkJZfF70rpoRsS6iEoJ86IUYUHye7cR3N0WSl:293
log_out @ application.js?v=c9T60cfwQOukm2m1GZYZdIpNOQ4WkJZfF70rpoRsS6iEoJ86IUYUHye7cR3N0WSl:264
(anonymous) @ application.js?v=c9T60cfwQOukm2m1GZYZdIpNOQ4WkJZfF70rpoRsS6iEoJ86IUYUHye7cR3N0WSl:133
application.js?v=c9T60cfwQOukm2m1GZYZdIpNOQ4WkJZfF70rpoRsS6iEoJ86IUYUHye7cR3N0WSl:8 2023-12-16T14:38:06.737Z: Active notifications: []
application.js?v=c9T60cfwQOukm2m1GZYZdIpNOQ4WkJZfF70rpoRsS6iEoJ86IUYUHye7cR3N0WSl:257  Uncaught (in promise) ReferenceError: csrfToken is not defined
    at log_out_ (application.js?v=c9T60cfwQOukm2m1GZYZdIpNOQ4WkJZfF70rpoRsS6iEoJ86IUYUHye7cR3N0WSl:257:23)
    at broadcast (application.js?v=c9T60cfwQOukm2m1GZYZdIpNOQ4WkJZfF70rpoRsS6iEoJ86IUYUHye7cR3N0WSl:293:8)
    at log_out (application.js?v=c9T60cfwQOukm2m1GZYZdIpNOQ4WkJZfF70rpoRsS6iEoJ86IUYUHye7cR3N0WSl:264:3)
    at HTMLAnchorElement.<anonymous> (application.js?v=c9T60cfwQOukm2m1GZYZdIpNOQ4WkJZfF70rpoRsS6iEoJ86IUYUHye7cR3N0WSl:133:5)
log_out_ @ application.js?v=c9T60cfwQOukm2m1GZYZdIpNOQ4WkJZfF70rpoRsS6iEoJ86IUYUHye7cR3N0WSl:257
broadcast @ application.js?v=c9T60cfwQOukm2m1GZYZdIpNOQ4WkJZfF70rpoRsS6iEoJ86IUYUHye7cR3N0WSl:293
log_out @ application.js?v=c9T60cfwQOukm2m1GZYZdIpNOQ4WkJZfF70rpoRsS6iEoJ86IUYUHye7cR3N0WSl:264
(anonymous) @ application.js?v=c9T60cfwQOukm2m1GZYZdIpNOQ4WkJZfF70rpoRsS6iEoJ86IUYUHye7cR3N0WSl:133

@ppigazzini
Copy link
Collaborator

ppigazzini commented Dec 16, 2023

DEV updated with "Try also this ..." 65007cf

application.js?v=81GuotSs91f25KDS8FnBTGLKONO0f3r2/NnU5sUnpfj/LpBrOKiwcP4217fm6XA4:8 2023-12-16T14:43:00.148Z: Web locks supported!
application.js?v=81GuotSs91f25KDS8FnBTGLKONO0f3r2/NnU5sUnpfj/LpBrOKiwcP4217fm6XA4:267  Uncaught (in promise) ReferenceError: csrfToken is not defined
    at log_out_ (application.js?v=81GuotSs91f25KDS8FnBTGLKONO0f3r2/NnU5sUnpfj/LpBrOKiwcP4217fm6XA4:267:23)
    at broadcast (application.js?v=81GuotSs91f25KDS8FnBTGLKONO0f3r2/NnU5sUnpfj/LpBrOKiwcP4217fm6XA4:260:8)
    at log_out (application.js?v=81GuotSs91f25KDS8FnBTGLKONO0f3r2/NnU5sUnpfj/LpBrOKiwcP4217fm6XA4:274:3)
    at HTMLAnchorElement.<anonymous> (application.js?v=81GuotSs91f25KDS8FnBTGLKONO0f3r2/NnU5sUnpfj/LpBrOKiwcP4217fm6XA4:133:5)
log_out_ @ application.js?v=81GuotSs91f25KDS8FnBTGLKONO0f3r2/NnU5sUnpfj/LpBrOKiwcP4217fm6XA4:267
broadcast @ application.js?v=81GuotSs91f25KDS8FnBTGLKONO0f3r2/NnU5sUnpfj/LpBrOKiwcP4217fm6XA4:260
log_out @ application.js?v=81GuotSs91f25KDS8FnBTGLKONO0f3r2/NnU5sUnpfj/LpBrOKiwcP4217fm6XA4:274
(anonymous) @ application.js?v=81GuotSs91f25KDS8FnBTGLKONO0f3r2/NnU5sUnpfj/LpBrOKiwcP4217fm6XA4:133
application.js?v=81GuotSs91f25KDS8FnBTGLKONO0f3r2/NnU5sUnpfj/LpBrOKiwcP4217fm6XA4:8 2023-12-16T14:43:09.726Z: Active notifications: []
application.js?v=81GuotSs91f25KDS8FnBTGLKONO0f3r2/NnU5sUnpfj/LpBrOKiwcP4217fm6XA4:8 2023-12-16T14:43:11.228Z: Purging stale notifications.

@peregrineshahin
Copy link
Contributor Author

Okay I should stop pushing commits from mobile, I will fix later when not afk

@ppigazzini
Copy link
Collaborator

DEV updated with "Update application.js" ac17f07

application.js?v=L5MRkhYBC3cpG4frZ34d6uRJqpH/RcqMP9qYQAajH72RFQ9C38LC52mW820n/wbl:254  Uncaught ReferenceError: Cannot access 'log_out_' before initialization
    at application.js?v=L5MRkhYBC3cpG4frZ34d6uRJqpH/RcqMP9qYQAajH72RFQ9C38LC52mW820n/wbl:254:38
notifications.js?v=9MrKyHwDdUxCvLKIi4E0ZhxjwR/tpLxXf0cswbgohoy1ib8Y/XoyWpzIfZCQpMi+:487  Uncaught ReferenceError: broadcast_dispatch is not defined
    at notifications.js?v=9MrKyHwDdUxCvLKIi4E0ZhxjwR/tpLxXf0cswbgohoy1ib8Y/XoyWpzIfZCQpMi+:487:1
application.js?v=L5MRkhYBC3cpG4frZ34d6uRJqpH/RcqMP9qYQAajH72RFQ9C38LC52mW820n/wbl:133  Uncaught ReferenceError: Cannot access 'log_out' before initialization
    at HTMLAnchorElement.<anonymous> (application.js?v=L5MRkhYBC3cpG4frZ34d6uRJqpH/RcqMP9qYQAajH72RFQ9C38LC52mW820n/wbl:133:5)

Logs users out from other tabs if they try to use them while they have logged-out or lost cookies.
Worth noting that the page was already unusable and the user couldn't do actions due to an expired CSRF token.

steps in the issue cannot reproduce the error. I can only see this scenario causing it.
Fixes: #1839
@peregrineshahin
Copy link
Contributor Author

Should be fixed. application.js definitely need refactoring.

@ppigazzini
Copy link
Collaborator

DEV updated, it looks good.

@ppigazzini ppigazzini merged commit 982a5e9 into official-stockfish:master Dec 16, 2023
17 checks passed
@ppigazzini
Copy link
Collaborator

PROD updated, thank you @peregrineshahin :)

@peregrineshahin
Copy link
Contributor Author

@vdbergh I just want to make sure you are okay with the change in the broadcast function to broadcast before calling the function for notifications?

Because I need to broadcast to other tabs before I reload the page or else I will lose excutionof code that comes afterwards

@peregrineshahin
Copy link
Contributor Author

Well not actually broadcasting before, I only set the storage before executing the function so it should be okay?

@vdbergh
Copy link
Contributor

vdbergh commented Dec 16, 2023

I guess it is ok. I think in normal circumstances the order should not matter.

@vdbergh
Copy link
Contributor

vdbergh commented Dec 16, 2023

BTW the dual thing does not work yet. Logging in in one tab requires a refresh in the other tab.

@peregrineshahin
Copy link
Contributor Author

BTW the dual thing does not work yet. Logging in in one tab requires a refresh in the other tab.

That's expected for logins, the PR only touches logout.
Taking Facebook as an example, they only do it on logouts.

@ppigazzini ppigazzini removed the dev test currently undergoing test on DEV label Dec 18, 2023
@vdbergh
Copy link
Contributor

vdbergh commented Dec 27, 2023

I wonder about a possible issue with this PR. We are calling an async function without await. While this works in this case, it creates a so-called floating promise, which seems to be frowned upon in the javascript world. https://typescript-eslint.io/rules/no-floating-promises.

Comments? If this is indeed an issue then we can extend the broadcast data structure with a field to indicate that the target function is async.

@vdbergh
Copy link
Contributor

vdbergh commented Dec 27, 2023

Alternatively, since I think awaiting a non-async function is harmless (the await has no effect), we could always treat the target function as async.

@peregrineshahin
Copy link
Contributor Author

Well, we are writing pure vanilla Javascript in fishtest.
IMO there is no point in adapting to a typescript standard while we don't use it.
they want this.

async function someAsyncFunction() {
  return 'someValue';
}
someAsyncFunction().catch(() => { });

Check the link below, as using await not inside an async function is also non-Eslint standard and even not a JS standard (i.e. wrong syntax).

https://typescript-eslint.io/play/#ts=5.3.2&fileType=.ts&code=IYZwngdgxgBAZgV2gFwJYHsIwE4FNkLYQgAK26AtqiLgBQCUMA3gFAw76FYDkAbsABsEubgG4WAXxZ4CRUuSo0GAOijBkUABa0GMALwA%2BZjAn1xLAPQWYANVzYQCECxahIsRCgxYZXeZWpcACZdVnZfIhg%2BQWExSWlOOTIAmhCzF0trdGwXN2h4JCg0TA5ZYmTFXABmULZSrij%2BIRFxKWAAd2BUZHqkhUCasyA&eslintrc=N4KABGBEBOCuA2BTAzpAXGUEKQAIBcBPABxQGNoBLY-AWhXkoDt8B6Jge1oDN4OBDfMwDmtYtA4BbSshTooiaBOiRwYAL4h1QA&tsconfig=&tokens=false

@vdbergh
Copy link
Contributor

vdbergh commented Dec 27, 2023

Of course you cannot use await inside a non-async function. I never said otherwise.

The problem with calling an async function without await is that you lose control of error handling. Floating promises are frowned upon also in pure javascript https://developer.mozilla.org/en-US/docs/Web/JavaScript/Guide/Using_promises .

@peregrineshahin
Copy link
Contributor Author

Sure I'm all in for Error handling.. so I think that the correct way of dealing with such a case and other cases is to catch these errors with .catch if it's floating like this.

@vdbergh
Copy link
Contributor

vdbergh commented Dec 27, 2023

Actually in https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/async_function there are many examples of async functions that are called without await. So I guess it is ok.

@peregrineshahin
Copy link
Contributor Author

peregrineshahin commented Dec 27, 2023

Actually in https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/async_function there are many examples of async functions that are called without await. So I guess it is ok.

It's not just okay it's necessary if the main function of all is the async function. or else you will fall into infinite loop trying to call it with await, since using await not inside an async function is bad syntax?

@peregrineshahin
Copy link
Contributor Author

trying to call it with await*

@vdbergh
Copy link
Contributor

vdbergh commented Dec 27, 2023

Actually in https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/async_function there are many examples of async functions that are called without await. So I guess it is ok.

It's not just okay it's necessary if the main function of all is the async function. or else you will fall into infinite loop trying to call it with await, since using await not inside an async function is bad syntax?

This situation occurs in tests_view.mak. However in that case an explicit .then is used to sequence operations.

Promise.all([spsa_promise, diff_promise, renderOnLoad])
    .then(() => {
    % if show_task >= 0:
      scroll_to(${show_task});
      document.getElementById("enclosure").style="visibility:visible;";
      document.documentElement.style="overflow:scroll;";
    % endif
    });

But I agree now that if one does not need the result and does not care about errors, and the order of things happening is not important, then calling an async function without await is ok...

I think there are proposals to add toplevel await to javascript. This would make things more consistent.

EDIT: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/await#top_level_await (only for modules though).

@vdbergh
Copy link
Contributor

vdbergh commented Dec 27, 2023

So what would, according to you, be the correct way to deal with a failing logout api-call? Just curious!

@peregrineshahin
Copy link
Contributor Author

peregrineshahin commented Dec 27, 2023

So what would, according to you, be the correct way to deal with a failing logout api-call? Just curious!

That's indeed an interesting topic! now since we use an httpOnly token for authTkt we cannot access the token with JavaScript so we cannot remove it from the client if the request fails and thus we cannot log out the user!

Now in such case, we should handle the fetch error and the response not being ok indeed.
the fetch error itself can happen if the user lost internet indeed.
the response not having an ok HTTP status will on the other hand continue executing the code and unfortunately mislead the user that the logout might have worked.

I think that redirecting elsewhere if the request fails should not happen (i.e. needs fixing), additionally, I have seen people in such cases asking the user with an alert to clear his/her browser cookies for the website (I'm neutral about this one) or implementing a mechanism to keep trying to log out with a time interval (I'm also not so sure about this).

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement gui server server side changes
Projects
None yet
Development

Successfully merging this pull request may close these issues.

check_csrf_token(): Invalid token
3 participants