Skip to content

Commit 377f29f

Browse files
authored
Merge pull request #10890 from marmelab/fix-auth-hook
Fix error when authProvider check methods are not async
2 parents 36a452b + 27e9590 commit 377f29f

File tree

3 files changed

+98
-95
lines changed

3 files changed

+98
-95
lines changed

packages/ra-core/src/auth/useAuthState.ts

Lines changed: 11 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -62,22 +62,21 @@ const useAuthState = <ErrorType = Error>(
6262

6363
const queryResult = useQuery<boolean, any>({
6464
queryKey: ['auth', 'checkAuth', params],
65-
queryFn: ({ signal }) => {
65+
queryFn: async ({ signal }) => {
6666
// The authProvider is optional in react-admin
6767
if (!authProvider) {
6868
return true;
6969
}
70-
return authProvider
71-
.checkAuth({ ...params, signal })
72-
.then(() => true)
73-
.catch(error => {
74-
// This is necessary because react-query requires the error to be defined
75-
if (error != null) {
76-
throw error;
77-
}
78-
79-
throw new Error();
80-
});
70+
try {
71+
await authProvider.checkAuth({ ...params, signal });
72+
return true;
73+
} catch (error) {
74+
// This is necessary because react-query requires the error to be defined
75+
if (error != null) {
76+
throw error;
77+
}
78+
throw new Error();
79+
}
8180
},
8281
retry: false,
8382
...options,

packages/ra-core/src/auth/useCheckAuth.ts

Lines changed: 31 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -51,38 +51,43 @@ export const useCheckAuth = (): CheckAuth => {
5151
`${basename}/${defaultAuthParams.loginUrl}`
5252
);
5353

54-
const checkAuth = useCallback(
55-
(params: any = {}, logoutOnFailure = true, redirectTo = loginUrl) =>
56-
authProvider
57-
? authProvider.checkAuth(params).catch(error => {
58-
if (logoutOnFailure) {
59-
logout(
60-
{},
61-
error && error.redirectTo != null
62-
? error.redirectTo
63-
: redirectTo
64-
);
65-
const shouldSkipNotify =
66-
error && error.message === false;
67-
!shouldSkipNotify &&
68-
notify(
69-
getErrorMessage(
70-
error,
71-
'ra.auth.auth_check_error'
72-
),
73-
{ type: 'error' }
74-
);
75-
}
76-
throw error;
77-
})
78-
: checkAuthWithoutAuthProvider(),
54+
const checkAuth = useCallback<CheckAuth>(
55+
async (
56+
params: any = {},
57+
logoutOnFailure = true,
58+
redirectTo = loginUrl
59+
) => {
60+
// The authProvider is optional in react-admin
61+
if (!authProvider) {
62+
return checkAuthWithoutAuthProvider();
63+
}
64+
try {
65+
return await authProvider.checkAuth(params);
66+
} catch (error: any) {
67+
if (logoutOnFailure) {
68+
logout(
69+
{},
70+
error && error.redirectTo != null
71+
? error.redirectTo
72+
: redirectTo
73+
);
74+
const shouldSkipNotify = error && error.message === false;
75+
!shouldSkipNotify &&
76+
notify(
77+
getErrorMessage(error, 'ra.auth.auth_check_error'),
78+
{ type: 'error' }
79+
);
80+
}
81+
throw error;
82+
}
83+
},
7984
[authProvider, logout, notify, loginUrl]
8085
);
8186

8287
return checkAuth;
8388
};
8489

85-
const checkAuthWithoutAuthProvider = () => Promise.resolve();
90+
const checkAuthWithoutAuthProvider = async () => undefined;
8691

8792
/**
8893
* Check if the current user is authenticated by calling authProvider.checkAuth().

packages/ra-core/src/auth/useLogoutIfAccessDenied.ts

Lines changed: 56 additions & 57 deletions
Original file line numberDiff line numberDiff line change
@@ -55,78 +55,77 @@ const useLogoutIfAccessDenied = (): LogoutIfAccessDenied => {
5555
[navigate]
5656
);
5757

58-
const logoutIfAccessDenied = useCallback(
59-
(error?: any) => {
58+
const logoutIfAccessDenied = useCallback<LogoutIfAccessDenied>(
59+
async (error?: any) => {
6060
if (!authProvider) {
6161
return logoutIfAccessDeniedWithoutProvider();
6262
}
63-
return authProvider
64-
.checkError(error)
65-
.then(() => false)
66-
.catch(async e => {
67-
const logoutUser = e?.logoutUser ?? true;
68-
//manual debounce
69-
if (timer) {
70-
// side effects already triggered in this tick, exit
71-
return true;
72-
}
73-
timer = setTimeout(() => {
74-
timer = undefined;
75-
}, 0);
63+
try {
64+
await authProvider.checkError(error);
65+
return false;
66+
} catch (e: any) {
67+
const logoutUser = e?.logoutUser ?? true;
68+
// manual debounce
69+
if (timer) {
70+
return true; // side effects already triggered in this tick, exit
71+
}
72+
timer = setTimeout(() => {
73+
timer = undefined;
74+
}, 0);
7675

77-
const redirectTo =
78-
e && e.redirectTo != null
79-
? e.redirectTo
80-
: error && error.redirectTo
81-
? error.redirectTo
82-
: undefined;
76+
const redirectTo =
77+
e && e.redirectTo != null
78+
? e.redirectTo
79+
: error && error.redirectTo
80+
? error.redirectTo
81+
: undefined;
8382

84-
const shouldNotify = !(
85-
(e && e.message === false) ||
86-
(error && error.message === false) ||
87-
redirectTo?.startsWith('http')
88-
);
89-
if (shouldNotify) {
83+
const shouldNotify = !(
84+
(e && e.message === false) ||
85+
(error && error.message === false) ||
86+
redirectTo?.startsWith('http')
87+
);
88+
if (shouldNotify) {
89+
try {
9090
// notify only if not yet logged out
91-
authProvider
92-
.checkAuth({})
93-
.then(() => {
94-
if (logoutUser) {
95-
notify(
96-
getErrorMessage(
97-
e,
98-
'ra.notification.logged_out'
99-
),
100-
{ type: 'error' }
101-
);
102-
} else {
103-
notify(
104-
getErrorMessage(
105-
e,
106-
'ra.notification.not_authorized'
107-
),
108-
{ type: 'error' }
109-
);
110-
}
111-
})
112-
.catch(() => {});
91+
await authProvider.checkAuth({});
92+
if (logoutUser) {
93+
notify(
94+
getErrorMessage(
95+
e,
96+
'ra.notification.logged_out'
97+
),
98+
{ type: 'error' }
99+
);
100+
} else {
101+
notify(
102+
getErrorMessage(
103+
e,
104+
'ra.notification.not_authorized'
105+
),
106+
{ type: 'error' }
107+
);
108+
}
109+
} catch {
110+
// ignore
113111
}
112+
}
114113

115-
if (logoutUser) {
116-
logout({}, redirectTo);
117-
} else if (redirectTo) {
118-
handleRedirect(redirectTo);
119-
}
114+
if (logoutUser) {
115+
logout({}, redirectTo);
116+
} else if (redirectTo) {
117+
handleRedirect(redirectTo);
118+
}
120119

121-
return true;
122-
});
120+
return true;
121+
}
123122
},
124123
[authProvider, logout, notify, handleRedirect]
125124
);
126125
return logoutIfAccessDenied;
127126
};
128127

129-
const logoutIfAccessDeniedWithoutProvider = () => Promise.resolve(false);
128+
const logoutIfAccessDeniedWithoutProvider = async () => false;
130129

131130
/**
132131
* Call the authProvider.authError() method, using the error passed as argument.

0 commit comments

Comments
 (0)