-
Notifications
You must be signed in to change notification settings - Fork 4
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
HAI-1884 Identify user coming from invitation link
When user comes to Haitaton from invitation link, call identify endpoint with token included in the link. After identifying user, show success notification and redirect user to front page. If user is not signed in before coming to Haitaton, redirect user to login and after login, do the identifying.
- Loading branch information
1 parent
780dd03
commit 9be8485
Showing
6 changed files
with
168 additions
and
1 deletion.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,80 @@ | ||
import React from 'react'; | ||
import { render, screen, waitFor } from '@testing-library/react'; | ||
import { MemoryRouter } from 'react-router-dom'; | ||
import { I18nextProvider } from 'react-i18next'; | ||
import { QueryClient, QueryClientProvider } from 'react-query'; | ||
import { InitialEntry } from '@remix-run/router'; | ||
import { User } from 'oidc-client'; | ||
import { Provider } from 'react-redux'; | ||
import AppRoutes from '../../../common/routes/AppRoutes'; | ||
import { FeatureFlagsProvider } from '../../../common/components/featureFlags/FeatureFlagsContext'; | ||
import { GlobalNotificationProvider } from '../../../common/components/globalNotification/GlobalNotificationContext'; | ||
import GlobalNotification from '../../../common/components/globalNotification/GlobalNotification'; | ||
import { store } from '../../../common/redux/store'; | ||
import i18n from '../../../locales/i18n'; | ||
import authService from '../authService'; | ||
import { REDIRECT_PATH_KEY } from '../../../common/routes/constants'; | ||
|
||
afterEach(() => { | ||
sessionStorage.clear(); | ||
}); | ||
|
||
const path = '/fi/kutsu?id=5ArrqPT6kW97QTK7t7ya9PA2'; | ||
|
||
const mockUser: Partial<User> = { | ||
id_token: 'fffff-aaaaaa-11111', | ||
access_token: '.BnutWVN1x7RSAP5bU2a-tXdVPuof_9pBNd_Ozw', | ||
profile: { | ||
iss: '', | ||
sub: '', | ||
aud: '', | ||
exp: 0, | ||
iat: 0, | ||
}, | ||
}; | ||
|
||
function getWrapper(routerInitialEntries?: InitialEntry[]) { | ||
const queryClient = new QueryClient({ | ||
defaultOptions: { | ||
queries: { | ||
retryDelay: 0, | ||
}, | ||
}, | ||
}); | ||
|
||
return render( | ||
<MemoryRouter initialEntries={routerInitialEntries}> | ||
<Provider store={store}> | ||
<QueryClientProvider client={queryClient}> | ||
<I18nextProvider i18n={i18n}> | ||
<FeatureFlagsProvider> | ||
<GlobalNotificationProvider> | ||
<AppRoutes /> | ||
<GlobalNotification /> | ||
</GlobalNotificationProvider> | ||
</FeatureFlagsProvider> | ||
</I18nextProvider> | ||
</QueryClientProvider> | ||
</Provider> | ||
</MemoryRouter>, | ||
); | ||
} | ||
|
||
test('Should save path with query string to session storage and navigate to login when going to invitation route', async () => { | ||
const login = jest.spyOn(authService, 'login').mockResolvedValue(); | ||
|
||
getWrapper([path]); | ||
|
||
await waitFor(() => expect(login).toHaveBeenCalled()); | ||
expect(window.sessionStorage.getItem(REDIRECT_PATH_KEY)).toBe(path); | ||
}); | ||
|
||
test('Should identify user after login', async () => { | ||
sessionStorage.setItem(REDIRECT_PATH_KEY, path); | ||
jest.spyOn(authService.userManager, 'getUser').mockResolvedValue(mockUser as User); | ||
|
||
getWrapper(); | ||
|
||
await waitFor(() => expect(window.document.title).toBe('Haitaton - Etusivu')); | ||
expect(screen.queryByText('Tunnistautuminen onnistui')).toBeInTheDocument(); | ||
}); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,66 @@ | ||
import { useEffect, useRef } from 'react'; | ||
import { useTranslation } from 'react-i18next'; | ||
import { useMutation } from 'react-query'; | ||
import { Navigate, useLocation, useSearchParams } from 'react-router-dom'; | ||
import ErrorLoadingText from '../../../common/components/errorLoadingText/ErrorLoadingText'; | ||
import { useGlobalNotification } from '../../../common/components/globalNotification/GlobalNotificationContext'; | ||
import useLocale from '../../../common/hooks/useLocale'; | ||
import { REDIRECT_PATH_KEY } from '../../../common/routes/constants'; | ||
import { identifyUser } from '../../hanke/hankeUsers/hankeUsersApi'; | ||
import useUser from '../useUser'; | ||
|
||
function UserIdentify() { | ||
const { data: user } = useUser(); | ||
const isAuthenticated = Boolean(user?.profile); | ||
const locale = useLocale(); | ||
const { t } = useTranslation(); | ||
const location = useLocation(); | ||
const [searchParams] = useSearchParams(); | ||
const id = searchParams.get('id'); | ||
const { setNotification } = useGlobalNotification(); | ||
const identifyUserCalled = useRef(false); | ||
|
||
const { mutate, isSuccess, isError } = useMutation(identifyUser); | ||
|
||
useEffect(() => { | ||
if (!isAuthenticated) { | ||
sessionStorage.setItem(REDIRECT_PATH_KEY, `${location.pathname}${location.search}`); | ||
} | ||
}, [isAuthenticated, location.pathname, location.search]); | ||
|
||
useEffect(() => { | ||
if (isAuthenticated && id !== null && !identifyUserCalled.current) { | ||
mutate(id, { | ||
onSuccess() { | ||
setNotification(true, { | ||
label: t('hankeUsers:notifications:userIdentifiedLabel'), | ||
message: t('hankeUsers:notifications:userIdentifiedText'), | ||
type: 'success', | ||
dismissible: true, | ||
closeButtonLabelText: t('common:components:notification:closeButtonLabelText'), | ||
}); | ||
}, | ||
onSettled() { | ||
identifyUserCalled.current = true; | ||
sessionStorage.removeItem(REDIRECT_PATH_KEY); | ||
}, | ||
}); | ||
} | ||
}, [isAuthenticated, id, mutate, setNotification, t]); | ||
|
||
if (isError) { | ||
return <ErrorLoadingText>{t('hankeUsers:notifications:userIdentifiedError')}</ErrorLoadingText>; | ||
} | ||
|
||
if (!isAuthenticated) { | ||
return <Navigate to="/login" />; | ||
} | ||
|
||
if (isSuccess) { | ||
return <Navigate to={`/${locale}`} />; | ||
} | ||
|
||
return null; | ||
} | ||
|
||
export default UserIdentify; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -346,6 +346,13 @@ | |
"meta": { | ||
"title": "Haitaton - Käyttöohjeet ja tuki" | ||
} | ||
}, | ||
"IDENTIFY_USER": { | ||
"path": "/kutsu", | ||
"headerLabel": "Tunnistaudu Haitattomaan", | ||
"meta": { | ||
"title": "Haitaton - Tunnistaudu Haitattomaan" | ||
} | ||
} | ||
}, | ||
"hanke": { | ||
|
@@ -850,7 +857,10 @@ | |
"rightsUpdatedSuccessLabel": "Käyttöoikeudet päivitetty", | ||
"rightsUpdatedSuccessText": "Käyttöoikeudet on päivitetty onnistuneesti", | ||
"rightsUpdatedErrorLabel": "Virhe päivityksessä", | ||
"rightsUpdatedErrorText": "<0>Käyttöoikeuksien päivityksessä tapahtui virhe. Yritä myöhemmin uudelleen tai ota yhteyttä Haitattoman tekniseen tukeen sähköpostiosoitteessa <1>[email protected]</1>.</0>" | ||
"rightsUpdatedErrorText": "<0>Käyttöoikeuksien päivityksessä tapahtui virhe. Yritä myöhemmin uudelleen tai ota yhteyttä Haitattoman tekniseen tukeen sähköpostiosoitteessa <1>[email protected]</1>.</0>", | ||
"userIdentifiedLabel": "Tunnistautuminen onnistui", | ||
"userIdentifiedText": "Tunnistautuminen onnistui. Sinut on nyt lisätty hankkeelle.", | ||
"userIdentifiedError": "Tunnistautuminen epäonnistui" | ||
} | ||
}, | ||
"map": { | ||
|