-
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.
feat(frontend, auth): authentication (data entry) design (#11)
* Scaffold online login page * Add auth0 login * Use shared button * Add offline login page * Finish offline login page * Move use network hook * Add a modal for reconnection * Make location select required * Add protected route * Check for internet connection * Make online login work * Remove console logs * Fix refresh removing authentication * Add function to open reconnected modal * Make protected route work when offline authenticated * Add tests * Remove location select from login page * Add log out button * Balance login page * 💅 make pretty
- Loading branch information
1 parent
e6aeadb
commit aea9eba
Showing
29 changed files
with
1,036 additions
and
42 deletions.
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
34 changes: 34 additions & 0 deletions
34
apps/frontend/src/app/login/auth0-provider/auth0-provider.tsx
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,34 @@ | ||
/* eslint-disable @typescript-eslint/no-non-null-assertion */ | ||
import React from 'react'; | ||
import { Auth0Provider as Auth0ReactProvider } from '@auth0/auth0-react'; | ||
|
||
type Auth0ProviderProps = { | ||
children: React.ReactNode; | ||
}; | ||
|
||
const AUTH0_CLIENT_ID = | ||
process.env['NODE_ENV'] === 'development' | ||
? process.env['NX_AUTH0_CLIENT_ID_DEV'] | ||
: process.env['NX_AUTH0_CLIENT_ID_PROD']; | ||
|
||
const AUTH0_REDIRECT_URI = | ||
process.env['NODE_ENV'] === 'development' | ||
? process.env['NX_AUTH0_REDIRECT_URI_DEV'] | ||
: process.env['NX_AUTH0_REDIRECT_URI_PROD']; | ||
|
||
export const Auth0Provider = (props: Auth0ProviderProps) => { | ||
return ( | ||
<Auth0ReactProvider | ||
domain={process.env['NX_AUTH0_DOMAIN']!} | ||
clientId={AUTH0_CLIENT_ID!} | ||
redirectUri={AUTH0_REDIRECT_URI!} | ||
scope="openid" | ||
responseType="token" | ||
cacheLocation="localstorage" | ||
> | ||
{props.children} | ||
</Auth0ReactProvider> | ||
); | ||
}; | ||
|
||
export default Auth0Provider; |
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 @@ | ||
export * from './auth0-provider'; |
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,3 @@ | ||
export * from './login-page'; | ||
export * from './auth0-provider'; | ||
export * from './reconnected-login-modal'; |
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 @@ | ||
export * from './login-page'; |
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,9 @@ | ||
import { render } from '@testing-library/react'; | ||
import LoginPage from './login-page'; | ||
|
||
describe('Login Page', () => { | ||
it('should render successfully', () => { | ||
const { baseElement } = render(<LoginPage />); | ||
expect(baseElement).toBeTruthy(); | ||
}); | ||
}); |
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,45 @@ | ||
import React from 'react'; | ||
import { Group, Stack, Text, Title } from '@mantine/core'; | ||
import { Button, Logo } from '@shared'; | ||
import { useAuth0 } from '@auth0/auth0-react'; | ||
import { useNetwork } from '@shared'; | ||
import { OfflineLoginPage } from '../offline-login-page'; | ||
import { IconWifi } from '@tabler/icons'; | ||
|
||
export const LoginPage = () => { | ||
const { loginWithRedirect } = useAuth0(); | ||
const { online } = useNetwork(); | ||
|
||
const handleClickLogin = () => { | ||
loginWithRedirect(); | ||
}; | ||
|
||
if (!online) { | ||
return <OfflineLoginPage />; | ||
} else { | ||
return ( | ||
<Stack className="items-center justify-center h-full m-auto w-1/4 2xl:w-1/6"> | ||
<Logo size="sm" /> | ||
<Title | ||
color="blue.9" | ||
order={3} | ||
className="w-full font-extrabold text-center" | ||
> | ||
Welcome to SuperVision! | ||
</Title> | ||
<Group className="w-full flex-nowrap" spacing={0}> | ||
<IconWifi size={36} className="mx-4" /> | ||
<Text> | ||
Your device is online <br /> Please log in to continue to | ||
SuperVision. | ||
</Text> | ||
</Group> | ||
<Button uppercase fullWidth size="lg" onClick={handleClickLogin}> | ||
Login with Auth0 | ||
</Button> | ||
</Stack> | ||
); | ||
} | ||
}; | ||
|
||
export default LoginPage; |
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 @@ | ||
export * from './offline-login-page'; |
14 changes: 14 additions & 0 deletions
14
apps/frontend/src/app/login/offline-login-page/offline-login-page.spec.tsx
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,14 @@ | ||
import { render } from '@testing-library/react'; | ||
import { BrowserRouter } from 'react-router-dom'; | ||
import OfflineLoginPage from './offline-login-page'; | ||
|
||
describe('Offline Login Page', () => { | ||
it('should render successfully', () => { | ||
const { baseElement } = render( | ||
<BrowserRouter> | ||
<OfflineLoginPage /> | ||
</BrowserRouter> | ||
); | ||
expect(baseElement).toBeTruthy(); | ||
}); | ||
}); |
63 changes: 63 additions & 0 deletions
63
apps/frontend/src/app/login/offline-login-page/offline-login-page.tsx
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,63 @@ | ||
import React from 'react'; | ||
import { Group, Stack, Text, TextInput, Title } from '@mantine/core'; | ||
import { Button, Logo } from '@shared'; | ||
import { useNavigate } from 'react-router-dom'; | ||
import { IconWifiOff } from '@tabler/icons'; | ||
|
||
export const OfflineLoginPage = () => { | ||
const navigate = useNavigate(); | ||
|
||
const [email, setEmail] = React.useState(''); | ||
const [errorMessage, setErrorMessage] = React.useState<string | undefined>( | ||
undefined | ||
); | ||
|
||
const navigateToPatientDetails = () => { | ||
if (email === '') { | ||
setErrorMessage('Please enter an email address'); | ||
} else if ( | ||
!email.endsWith('@auckland.ac.nz') && | ||
!email.endsWith('@aucklanduni.ac.nz') | ||
) { | ||
setErrorMessage('Invalid email - please ensure you enter a UoA email'); | ||
} else { | ||
setErrorMessage(undefined); | ||
sessionStorage.setItem('userEmail', email); | ||
navigate('/patient-details'); | ||
} | ||
}; | ||
|
||
return ( | ||
<Stack className="items-center justify-center h-full m-auto w-1/4 2xl:w-1/6"> | ||
<Logo size="sm" /> | ||
<Title | ||
color="blue.9" | ||
order={3} | ||
className="w-full font-extrabold text-center" | ||
> | ||
Welcome to SuperVision! | ||
</Title> | ||
<Group className="w-full flex-nowrap" spacing={0}> | ||
<IconWifiOff size={36} className="mx-4" /> | ||
<Text> | ||
Your device is offline <br /> Please enter your university email | ||
address to identify yourself. | ||
</Text> | ||
</Group> | ||
<TextInput | ||
label="Your email" | ||
placeholder="Enter your email" | ||
required | ||
value={email} | ||
onChange={(event) => setEmail(event.currentTarget.value)} | ||
error={errorMessage} | ||
className="w-full" | ||
/> | ||
<Button uppercase fullWidth size="lg" onClick={navigateToPatientDetails}> | ||
Continue | ||
</Button> | ||
</Stack> | ||
); | ||
}; | ||
|
||
export default OfflineLoginPage; |
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 @@ | ||
export * from './reconnected-login-modal'; |
9 changes: 9 additions & 0 deletions
9
apps/frontend/src/app/login/reconnected-login-modal/reconnected-login-modal.spec.tsx
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,9 @@ | ||
import { render } from '@testing-library/react'; | ||
import ReconnectedLoginModal from './reconnected-login-modal'; | ||
|
||
describe('Reconnected Login Modal', () => { | ||
it('should render successfully', () => { | ||
const { baseElement } = render(<ReconnectedLoginModal />); | ||
expect(baseElement).toBeTruthy(); | ||
}); | ||
}); |
53 changes: 53 additions & 0 deletions
53
apps/frontend/src/app/login/reconnected-login-modal/reconnected-login-modal.tsx
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,53 @@ | ||
import { useAuth0 } from '@auth0/auth0-react'; | ||
import { Modal, Text } from '@mantine/core'; | ||
import { Button } from '@shared'; | ||
import React, { | ||
ForwardedRef, | ||
forwardRef, | ||
useImperativeHandle, | ||
useState, | ||
} from 'react'; | ||
|
||
export interface ReconnectedLoginModalRef { | ||
show(): void; | ||
} | ||
|
||
export const ReconnectedLoginModal = forwardRef( | ||
(props, ref: ForwardedRef<ReconnectedLoginModalRef>) => { | ||
const { loginWithPopup } = useAuth0(); | ||
const [opened, setOpened] = useState(false); | ||
|
||
useImperativeHandle(ref, () => ({ | ||
show() { | ||
setOpened(true); | ||
}, | ||
})); | ||
|
||
const login = () => { | ||
setOpened(false); | ||
loginWithPopup(); | ||
}; | ||
|
||
return ( | ||
<Modal | ||
title="Your internet connection was restored" | ||
opened={opened} | ||
onClose={() => setOpened(false)} | ||
withCloseButton={false} | ||
closeOnClickOutside={false} | ||
closeOnEscape={false} | ||
centered | ||
classNames={{ | ||
title: 'font-extrabold', | ||
}} | ||
> | ||
<Text className="-mt-2 pb-10">Please log in</Text> | ||
<Button uppercase fullWidth size="lg" onClick={login}> | ||
Login with Auth0 | ||
</Button> | ||
</Modal> | ||
); | ||
} | ||
); | ||
|
||
export default ReconnectedLoginModal; |
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,29 @@ | ||
import React from 'react'; | ||
import { useAuth0 } from '@auth0/auth0-react'; | ||
import { Navigate } from 'react-router-dom'; | ||
import { Center, Loader } from '@mantine/core'; | ||
import { useNetwork } from '@shared'; | ||
|
||
type ProtectedRouteProps = { | ||
component: JSX.Element; | ||
}; | ||
|
||
const ProtectedRoute = ({ component }: ProtectedRouteProps): JSX.Element => { | ||
const { isLoading, isAuthenticated } = useAuth0(); | ||
const { online, isLoading: onlineStatusLoading } = useNetwork(); | ||
const userEmail = sessionStorage.getItem('userEmail'); | ||
|
||
if (isLoading || onlineStatusLoading) { | ||
return ( | ||
<Center className="w-full h-full"> | ||
<Loader /> | ||
</Center> | ||
); | ||
} else if (isAuthenticated || (!online && userEmail)) { | ||
return component; | ||
} else { | ||
return <Navigate to="/" />; | ||
} | ||
}; | ||
|
||
export default ProtectedRoute; |
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
Oops, something went wrong.