fix: redirect users to /login if their oauth token is invalid (#19429)

[As mentioned in the
issue](https://github.com/coder/coder/issues/12056#issuecomment-3206975879)
the problem here is the fact this endpoint is returning a 401 instead of
a 200 in this specific case.

Since we actually have enough information before performing this
mutation to know that it'll fail in the case of a bad auth token we'd
ideally re-work the code not to call the mutation on logout and just
perform the local clean up. Unfortunately it seems like the interactions
that this mutation is having with React Query at large is necessary for
our code to work as intended and thus it's not currently possible to
move the local clean up (the code inside of the `onSuccess`) outside of
the mutation. Shout out to @Parkreiner for helping me confirm this.

So until we can re-work the `AuthProvider` to be less brittle this PR
changes `onSuccess` to `onSettled` so that while the mutation still
fails with a 401, the local clean up still runs.

Closes #12056
This commit is contained in:
Brett Kolodny
2025-08-20 15:04:57 -04:00
committed by GitHub
parent 02fc173df4
commit ee789dac9a
+16 -2
View File
@@ -17,6 +17,7 @@ import {
} from "hooks/useEmbeddedMetadata";
import type { UsePaginatedQueryOptions } from "hooks/usePaginatedQuery";
import type {
MutationOptions,
QueryClient,
UseMutationOptions,
UseQueryOptions,
@@ -192,10 +193,15 @@ const loginFn = async ({
};
};
export const logout = (queryClient: QueryClient) => {
export const logout = (queryClient: QueryClient): MutationOptions => {
return {
mutationFn: API.logout,
onSuccess: () => {
// We're doing this cleanup in `onSettled` instead of `onSuccess` because in the case where an oAuth refresh token has expired this endpoint will return a 401 instead of 200.
onSettled: (_, error) => {
if (error) {
console.error(error);
}
/**
* 2024-05-02 - If we persist any form of user data after the user logs
* out, that will continue to seed the React Query cache, creating
@@ -210,6 +216,14 @@ export const logout = (queryClient: QueryClient) => {
* Deleting the user data will mean that all future requests have to take
* a full roundtrip, but this still felt like the best way to ensure that
* manually logging out doesn't blow the entire app up.
*
* 2025-08-20 - Since this endpoint is for performing a post logout clean up
* on the backend we should move this local clean up outside of the mutation
* so that it can be explicitly performed even in cases where we don't want
* run the clean up (e.g. when a user is unauthorized). Unfortunately our
* auth logic is too tangled up with some obscured React Query behaviors to
* be able to move right now. After `AuthProvider.tsx` is refactored this
* should be moved.
*/
defaultMetadataManager.clearMetadataByKey("user");
queryClient.removeQueries();