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
11 changes: 11 additions & 0 deletions packages/ra-core/src/auth/useLogin.spec.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import { CoreAdminContext } from '../core/CoreAdminContext';
import useLogin from './useLogin';

import { TestMemoryRouter } from '../routing';
import { PermissionsState } from './useLogin.stories';

describe('useLogin', () => {
describe('redirect after login', () => {
Expand Down Expand Up @@ -99,4 +100,14 @@ describe('useLogin', () => {
expect(screen.queryByText('Login')).not.toBeNull();
});
});

it('should invalidate the getPermissions cache', async () => {
render(<PermissionsState />);
await screen.findByText('PERMISSIONS: guest');
fireEvent.click(screen.getByText('Login'));
await screen.findByText('PERMISSIONS: admin');
fireEvent.click(screen.getByText('Logout'));
await screen.findByText('LOADING');
await screen.findByText('PERMISSIONS: guest');
});
});
63 changes: 63 additions & 0 deletions packages/ra-core/src/auth/useLogin.stories.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
import * as React from 'react';
import usePermissions from './usePermissions';
import { CoreAdminContext, TestMemoryRouter, useLogin, useLogout } from '..';

export default {
title: 'ra-core/auth/useLogin',
};

const getAuthProviderWithLoginAndLogout = () => {
let isLoggedIn = false;
return {
login: () => {
isLoggedIn = true;
return Promise.resolve();
},
logout: () => {
isLoggedIn = false;
return Promise.resolve();
},
checkAuth: () => (isLoggedIn ? Promise.resolve() : Promise.reject()),
checkError: () => Promise.reject('bad method'),
getPermissions: () =>
new Promise(resolve =>
setTimeout(resolve, 300, isLoggedIn ? 'admin' : 'guest')
),
};
};

const LoginButton = () => {
const login = useLogin();
return <button onClick={login}>Login</button>;
};

const LogoutButton = () => {
const logout = useLogout();
return <button onClick={logout}>Logout</button>;
};

const UsePermissions = () => {
const permissionQueryParams = {
retry: false,
};
const state = usePermissions({}, permissionQueryParams);
return (
<div>
{state.isPending ? <span>LOADING</span> : null}
{state.permissions ? (
<span>PERMISSIONS: {state.permissions}</span>
) : null}
{state.error ? <span>ERROR</span> : null}
</div>
);
};

export const PermissionsState = () => (
<TestMemoryRouter>
<CoreAdminContext authProvider={getAuthProviderWithLoginAndLogout()}>
<UsePermissions />
<LoginButton />
<LogoutButton />
</CoreAdminContext>
</TestMemoryRouter>
);
6 changes: 6 additions & 0 deletions packages/ra-core/src/auth/useLogin.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import { useNotificationContext } from '../notification';
import { useBasename } from '../routing';
import useAuthProvider, { defaultAuthParams } from './useAuthProvider';
import { removeDoubleSlashes } from '../routing/useCreatePath';
import { useQueryClient } from '@tanstack/react-query';

/**
* Get a callback for calling the authProvider.login() method
Expand All @@ -31,6 +32,7 @@ import { removeDoubleSlashes } from '../routing/useCreatePath';
*/
const useLogin = (): Login => {
const authProvider = useAuthProvider();
const queryClient = useQueryClient();
const location = useLocation();
const locationState = location.state as any;
const navigate = useNavigate();
Expand All @@ -47,6 +49,9 @@ const useLogin = (): Login => {
if (authProvider) {
return authProvider.login(params).then(ret => {
resetNotifications();
queryClient.invalidateQueries({
queryKey: ['auth', 'getPermissions'],
});
if (ret && ret.hasOwnProperty('redirectTo')) {
if (ret) {
navigate(ret.redirectTo);
Expand All @@ -67,6 +72,7 @@ const useLogin = (): Login => {
},
[
authProvider,
queryClient,
navigate,
nextPathName,
nextSearch,
Expand Down
Loading