Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
23 changes: 11 additions & 12 deletions packages/ra-core/src/auth/useAuthState.ts
Original file line number Diff line number Diff line change
Expand Up @@ -62,22 +62,21 @@ const useAuthState = <ErrorType = Error>(

const queryResult = useQuery<boolean, any>({
queryKey: ['auth', 'checkAuth', params],
queryFn: ({ signal }) => {
queryFn: async ({ signal }) => {
// The authProvider is optional in react-admin
if (!authProvider) {
return true;
}
return authProvider
.checkAuth({ ...params, signal })
.then(() => true)
.catch(error => {
// This is necessary because react-query requires the error to be defined
if (error != null) {
throw error;
}

throw new Error();
});
try {
await authProvider.checkAuth({ ...params, signal });
return true;
} catch (error) {
// This is necessary because react-query requires the error to be defined
if (error != null) {
throw error;
}
throw new Error();
}
},
retry: false,
...options,
Expand Down
57 changes: 31 additions & 26 deletions packages/ra-core/src/auth/useCheckAuth.ts
Original file line number Diff line number Diff line change
Expand Up @@ -51,38 +51,43 @@ export const useCheckAuth = (): CheckAuth => {
`${basename}/${defaultAuthParams.loginUrl}`
);

const checkAuth = useCallback(
(params: any = {}, logoutOnFailure = true, redirectTo = loginUrl) =>
authProvider
? authProvider.checkAuth(params).catch(error => {
if (logoutOnFailure) {
logout(
{},
error && error.redirectTo != null
? error.redirectTo
: redirectTo
);
const shouldSkipNotify =
error && error.message === false;
!shouldSkipNotify &&
notify(
getErrorMessage(
error,
'ra.auth.auth_check_error'
),
{ type: 'error' }
);
}
throw error;
})
: checkAuthWithoutAuthProvider(),
const checkAuth = useCallback<CheckAuth>(
async (
params: any = {},
logoutOnFailure = true,
redirectTo = loginUrl
) => {
// The authProvider is optional in react-admin
if (!authProvider) {
return checkAuthWithoutAuthProvider();
}
try {
return await authProvider.checkAuth(params);
} catch (error: any) {
if (logoutOnFailure) {
logout(
{},
error && error.redirectTo != null
? error.redirectTo
: redirectTo
);
const shouldSkipNotify = error && error.message === false;
!shouldSkipNotify &&
notify(
getErrorMessage(error, 'ra.auth.auth_check_error'),
{ type: 'error' }
);
}
throw error;
}
},
[authProvider, logout, notify, loginUrl]
);

return checkAuth;
};

const checkAuthWithoutAuthProvider = () => Promise.resolve();
const checkAuthWithoutAuthProvider = async () => undefined;

/**
* Check if the current user is authenticated by calling authProvider.checkAuth().
Expand Down
113 changes: 56 additions & 57 deletions packages/ra-core/src/auth/useLogoutIfAccessDenied.ts
Original file line number Diff line number Diff line change
Expand Up @@ -55,78 +55,77 @@ const useLogoutIfAccessDenied = (): LogoutIfAccessDenied => {
[navigate]
);

const logoutIfAccessDenied = useCallback(
(error?: any) => {
const logoutIfAccessDenied = useCallback<LogoutIfAccessDenied>(
async (error?: any) => {
if (!authProvider) {
return logoutIfAccessDeniedWithoutProvider();
}
return authProvider
.checkError(error)
.then(() => false)
.catch(async e => {
const logoutUser = e?.logoutUser ?? true;
//manual debounce
if (timer) {
// side effects already triggered in this tick, exit
return true;
}
timer = setTimeout(() => {
timer = undefined;
}, 0);
try {
await authProvider.checkError(error);
return false;
} catch (e: any) {
const logoutUser = e?.logoutUser ?? true;
// manual debounce
if (timer) {
return true; // side effects already triggered in this tick, exit
}
timer = setTimeout(() => {
timer = undefined;
}, 0);

const redirectTo =
e && e.redirectTo != null
? e.redirectTo
: error && error.redirectTo
? error.redirectTo
: undefined;
const redirectTo =
e && e.redirectTo != null
? e.redirectTo
: error && error.redirectTo
? error.redirectTo
: undefined;

const shouldNotify = !(
(e && e.message === false) ||
(error && error.message === false) ||
redirectTo?.startsWith('http')
);
if (shouldNotify) {
const shouldNotify = !(
(e && e.message === false) ||
(error && error.message === false) ||
redirectTo?.startsWith('http')
);
if (shouldNotify) {
try {
// notify only if not yet logged out
authProvider
.checkAuth({})
.then(() => {
if (logoutUser) {
notify(
getErrorMessage(
e,
'ra.notification.logged_out'
),
{ type: 'error' }
);
} else {
notify(
getErrorMessage(
e,
'ra.notification.not_authorized'
),
{ type: 'error' }
);
}
})
.catch(() => {});
await authProvider.checkAuth({});
if (logoutUser) {
notify(
getErrorMessage(
e,
'ra.notification.logged_out'
),
{ type: 'error' }
);
} else {
notify(
getErrorMessage(
e,
'ra.notification.not_authorized'
),
{ type: 'error' }
);
}
} catch {
// ignore
}
}

if (logoutUser) {
logout({}, redirectTo);
} else if (redirectTo) {
handleRedirect(redirectTo);
}
if (logoutUser) {
logout({}, redirectTo);
} else if (redirectTo) {
handleRedirect(redirectTo);
}

return true;
});
return true;
}
},
[authProvider, logout, notify, handleRedirect]
);
return logoutIfAccessDenied;
};

const logoutIfAccessDeniedWithoutProvider = () => Promise.resolve(false);
const logoutIfAccessDeniedWithoutProvider = async () => false;

/**
* Call the authProvider.authError() method, using the error passed as argument.
Expand Down
Loading