Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: Add authentification dialog #2469

Merged
merged 5 commits into from
Jul 5, 2023
Merged
Changes from 1 commit
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
Prev Previous commit
feat: Add AuthentificationDialog
cballevre committed Jul 5, 2023
commit cde78f9c051fbe931d9b0480976c0a2e3c49a706
109 changes: 109 additions & 0 deletions react/CozyDialogs/SpecificDialogs/AuthentificationDialog.jsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,109 @@
import React, { useMemo, useState } from 'react'
import PropTypes from 'prop-types'

import PermissionDialog from '../PermissionDialog'
import Buttons from '../../Buttons'
import { useI18n } from '../../I18n'
import Typography from '../../Typography'
import { useClient } from 'cozy-client'
import CozyAuthentificationIcon from '../../Icons/CozyAuthentification'
import PasswordField from '../../PasswordField'

import withSpecificDialogsLocales from './withSpecificDialogsLocales'

/**
* Dialog used to authenticate a user in the cozy system.
* The authentication logic is implemented in the applications.
*/
const AuthentificationDialog = ({
onClose,
onSubmit,
isLoading,
isOIDC,
error
}) => {
const { t } = useI18n()
const client = useClient()
const [password, setPassword] = useState('')

const handleSubmit = e => {
e.preventDefault()
onSubmit(password)
}

const onPasswordChange = e => {
setPassword(e.currentTarget.value)
}

const passphraseResetUrl = useMemo(() => {
const url = new URL('/auth/passphrase_reset', client.getStackClient().uri)
return url.href
}, [client])

return (
<PermissionDialog
open
onClose={onClose}
title={t(`authentification-dialog.${isOIDC ? 'title-oidc' : 'title'}`)}
icon={CozyAuthentificationIcon}
content={
<form onSubmit={handleSubmit}>
<Typography variant="body1" className="u-ta-center">
{t('authentification-dialog.subtitle')}
</Typography>
<PasswordField
autoFocus
disabled={isLoading}
value={password}
onChange={onPasswordChange}
className="u-mv-1"
label={t(
`authentification-dialog.${isOIDC ? 'label-oidc' : 'label'}`
)}
error={Boolean(error)}
helperText={error && t(`authentification-dialog.errors.${error}`)}
fullWidth
required
/>
<Typography
variant="body1"
component="a"
color="primary"
href={passphraseResetUrl}
className="u-link"
>
{t('authentification-dialog.forgotten-password')}
</Typography>
</form>
}
actions={
<Buttons
busy={isLoading}
disabled={isLoading || password.length === 0}
onClick={handleSubmit}
label={t('authentification-dialog.unlock')}
fullWidth
/>
}
/>
)
}

AuthentificationDialog.defaultProps = {
isOIDC: false
}

AuthentificationDialog.propTypes = {
/** A function call on clicking the close button */
onClose: PropTypes.func,
/** A function call on submitting the form with the password entered */
onSubmit: PropTypes.func,
/** Waiting status, e.g. processing of form submission */
isLoading: PropTypes.bool,
/** Show specific wording for OIDC */
isOIDC: PropTypes.bool,
/** Error key to display a message */
error: PropTypes.string
}

export default withSpecificDialogsLocales(AuthentificationDialog)
58 changes: 58 additions & 0 deletions react/CozyDialogs/SpecificDialogs/Readme.md
Original file line number Diff line number Diff line change
@@ -21,3 +21,61 @@ const [open, setOpen] = useState(isTesting());
<Buttons onClick={() => { setOpen(true) }} label="Open InstallFlagshipAppDialog" />
</DemoProvider>
```

### Authentification dialog

Dialog used to authenticate a user in the cozy system. The authentication logic is implemented in the applications.

```jsx
import { AuthentificationDialog } from 'cozy-ui/transpiled/react/CozyDialogs'
import Button from 'cozy-ui/transpiled/react/Buttons'
import DemoProvider from 'cozy-ui/docs/components/DemoProvider'
import Variants from 'cozy-ui/docs/components/Variants'
import FormControlLabel from 'cozy-ui/transpiled/react/FormControlLabel'
import RadioGroup from 'cozy-ui/transpiled/react/RadioGroup'
import Radio from 'cozy-ui/transpiled/react/Radios'
import FormControl from 'cozy-ui/transpiled/react/FormControl'
import FormLabel from 'cozy-ui/transpiled/react/FormLabel'

initialState = { showModal: false };

const initialVariants = [{
closable: true,
loading: false,
oidc: false
}]

const initialErrors = [{
default: true,
invalid_password: false,
server_error: false
}]

const onClose = () => setState({ showModal: false })

const onAuthentification = () => {
alert('authentification')
setState({ showModal: false })
};

<Variants initialVariants={initialVariants}>
{variant => (
<Variants initialVariants={initialErrors} radio>
{error => (
<DemoProvider>
<Button label="Open modal" onClick={() => setState({ showModal: true })}/>
{state.showModal && (
<AuthentificationDialog
onSubmit={onAuthentification}
onClose={variant.closable && onClose}
error={error.invalid_password ? 'invalid_password' : error.server_error ? 'server_error' : undefined }
isLoading={variant.loading}
isOIDC={variant.oidc}
/>
)}
</DemoProvider>
)}
</Variants>
)}
</Variants>
```
1 change: 1 addition & 0 deletions react/CozyDialogs/SpecificDialogs/index.jsx
Original file line number Diff line number Diff line change
@@ -1 +1,2 @@
export { default as InstallFlagshipAppDialog } from './InstallFlagshipAppDialog'
export { default as AuthentificationDialog } from './AuthentificationDialog'
14 changes: 14 additions & 0 deletions react/CozyDialogs/SpecificDialogs/locales/en.json
Original file line number Diff line number Diff line change
@@ -3,5 +3,19 @@
"title": "Scan the QR Code",
"text": "or go directly to the <img src=%{iosIconSrc} /> <a href='%{iosUrl}' class='u-link' target='_blank' rel='noopener'>App Store</a><br>or <img src=%{androidIconSrc} /> <a href='%{androidUrl}' class='u-link' target='_blank' rel='noopener'>Play Store</a> to install the Cozy Cloud app",
"a11n": "Go to the Cozy Cloud application download page"
},
"authentification-dialog": {
"title": "Login",
"title-oidc": "Cozy Pass",
"subtitle": "For security, please confirm your identity",
"label": "Cozy password",
"label-oidc": "Cozy Pass password",
"abort": "Leave",
"unlock": "Unlock",
"forgotten-password": "I forgot my password",
"errors": {
"invalid_password": "Incorrect password, try again.",
"server_error": "Something went wrong with the server. Please, reload the page."
}
}
}
14 changes: 14 additions & 0 deletions react/CozyDialogs/SpecificDialogs/locales/fr.json
Original file line number Diff line number Diff line change
@@ -3,5 +3,19 @@
"title": "Scannez le QR Code",
"text": "ou rendez vous directement sur <img src=%{iosIconSrc} /> <a href='%{iosUrl}' class='u-link' target='_blank' rel='noopener'>l’App Store</a><br>ou sur le <img src=%{androidIconSrc} /> <a href='%{androidUrl}' class='u-link' target='_blank' rel='noopener'>Play Store</a> pour installer l’app Cloud Personnel Cozy",
"a11n": "Aller sur la page de téléchargement de l'application Cloud Personnel Cozy"
},
"authentification-dialog": {
"title": "Authentification",
"title-oidc": "Cozy Pass",
"subtitle": "Par sécurité, merci de confirmer votre identité",
"label": "Mot de passe Cozy",
"label-oidc": "Mot de passe Cozy Pass",
"abort": "Quitter",
"unlock": "Déverrouiller",
"forgotten-password": "J'ai oublié mon mot de passe",
"errors": {
"invalid_password": "Mot de passe incorrect, essayer à nouveau.",
"server_error": "Une erreur s'est produite. Merci de recharger la page."
}
}
}
5 changes: 4 additions & 1 deletion react/CozyDialogs/index.jsx
Original file line number Diff line number Diff line change
@@ -9,4 +9,7 @@ export { default as IllustrationDialog } from './IllustrationDialog'
export { default as PermissionDialog } from './PermissionDialog'
export { default as useCozyDialog } from './useCozyDialog'
export { default as TopAnchoredDialog } from './TopAnchoredDialog'
export { InstallFlagshipAppDialog } from './SpecificDialogs'
export {
InstallFlagshipAppDialog,
AuthentificationDialog
} from './SpecificDialogs'