-
Notifications
You must be signed in to change notification settings - Fork 123
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #367 from SkyAjax/main
[#355] Add reset password feature
- Loading branch information
Showing
15 changed files
with
279 additions
and
66 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
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 |
---|---|---|
@@ -1,18 +1,33 @@ | ||
doctype html | ||
head | ||
meta(charset='utf-8') | ||
meta(name='viewport' content='width=device-width, initial-scale=1') | ||
title Recover message | ||
link(href='https://cdn.jsdelivr.net/npm/[email protected]/dist/css/bootstrap.min.css' rel='stylesheet' integrity='sha384-GLhlTQ8iRABdZLl6O3oVMWSktQOp6b7In1Zl3/Jr59b6EGGoI1aFkw7cmDA6j6gD' crossorigin='anonymous') | ||
.container | ||
.d-flex.flex-wrap.align-items-center.justify-content-center.justify-content-lg-start | ||
p | ||
| Вы запросили ссылку для изменения вашего пароля на RunIT. Чтобы изменить пароль - | ||
a(href=url) перейдите по этой ссылке | ||
| или нажмите на кнопку ниже | ||
p | ||
| Если вы не запрашивали изменения пароля, просто проигнорируйте это письмо. Ваш пароль не изменится пока вы не перейдете по ссылке и не введете новый пароль | ||
html | ||
head | ||
meta(charset='utf-8') | ||
meta(name='viewport' content='width=device-width, initial-scale=1') | ||
title Recover message | ||
link(rel="preconnect" href="https://fonts.googleapis.com") | ||
link(rel="preconnect" href="https://fonts.gstatic.com" crossorigin) | ||
link(href='https://cdn.jsdelivr.net/npm/[email protected]/dist/css/bootstrap.min.css' rel='stylesheet' integrity='sha384-GLhlTQ8iRABdZLl6O3oVMWSktQOp6b7In1Zl3/Jr59b6EGGoI1aFkw7cmDA6j6gD' crossorigin='anonymous') | ||
link(href="https://fonts.googleapis.com/css2?family=Roboto:wght@300;400;700&display=swap" rel="stylesheet") | ||
style. | ||
body { | ||
font-family: 'Roboto', sans-serif !important; | ||
} | ||
body | ||
script(src='https://cdn.jsdelivr.net/npm/[email protected]/dist/js/bootstrap.bundle.min.js' integrity='sha384-w76AqPfDkMBDXo30jS1Sgez6pr3x5MlQ1ZAGC+nuZB+EYdgRZgiwxhTBTkF7CXvN' crossorigin='anonymous') | ||
.container | ||
.d-flex.flex-wrap.align-items-center.justify-content-center | ||
h1.text-center.font-weight-bold.pb-3 | ||
| Изменение пароля | ||
p | ||
| Вы запросили ссылку для изменения вашего пароля на RunIT. Чтобы изменить пароль - | ||
a(href=url) перейдите по этой ссылке | ||
| или нажмите на кнопку ниже. | ||
p | ||
| Если вы не запрашивали изменения пароля, просто проигнорируйте это | ||
| письмо. Ваш пароль не изменится пока вы не перейдете по ссылке и не | ||
| введете новый пароль. | ||
p.text-center | ||
a.btn.btn-primary(type="button" href=url)="Сменить пароль" | ||
|
||
a.btn.btn-primary(type="button" href=url)="Сменить пароль" | ||
|
||
script(src='https://cdn.jsdelivr.net/npm/[email protected]/dist/js/bootstrap.bundle.min.js' integrity='sha384-w76AqPfDkMBDXo30jS1Sgez6pr3x5MlQ1ZAGC+nuZB+EYdgRZgiwxhTBTkF7CXvN' crossorigin='anonymous') | ||
|
||
|
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
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,131 @@ | ||
import axios from 'axios'; | ||
|
||
import { useFormik } from 'formik'; | ||
import { useEffect, useRef, useState } from 'react'; | ||
import { useParams } from 'react-router'; | ||
import { useTranslation } from 'react-i18next'; | ||
import { object } from 'yup'; | ||
|
||
import Button from 'react-bootstrap/Button'; | ||
import Form from 'react-bootstrap/Form'; | ||
|
||
import { useAuth } from '../../hooks'; | ||
import routes from '../../routes'; | ||
import { password } from '../../utils/validationSchemas'; | ||
|
||
import FormAlert from './FormAlert.jsx'; | ||
import PasswordVisibilityButton from './PasswordVisibilityButton'; | ||
|
||
function ResetPasswordForm({ onSuccess = () => null }) { | ||
const { t } = useTranslation(); | ||
const { hash } = useParams(); | ||
const passwordRef = useRef(); | ||
const auth = useAuth(); | ||
|
||
const initialFormState = { state: 'initial', message: '' }; | ||
const [formState, setFormState] = useState(initialFormState); | ||
const [isPasswordVisible, setPasswordVisibility] = useState(false); | ||
const handlePasswordVisibility = () => { | ||
setPasswordVisibility(!isPasswordVisible); | ||
}; | ||
|
||
const validationSchema = object().shape({ | ||
password: password(), | ||
}); | ||
|
||
const formik = useFormik({ | ||
initialValues: { | ||
password: '', | ||
}, | ||
validationSchema, | ||
validateOnBlur: false, | ||
onSubmit: async (values) => { | ||
setFormState(initialFormState); | ||
const preparedValues = { ...validationSchema.cast(values), hash }; | ||
try { | ||
const { data } = await axios.post( | ||
`${routes.resetPassPath()}/${hash}`, | ||
preparedValues, | ||
); | ||
await axios.post(routes.signInPath(), { | ||
email: data.email, | ||
password: values.password, | ||
}); | ||
auth.signIn(); | ||
onSuccess(); | ||
} catch (err) { | ||
if (!err.isAxiosError) { | ||
setFormState({ | ||
state: 'failed', | ||
message: 'errors.unknown', | ||
}); | ||
throw err; | ||
} else { | ||
setFormState({ | ||
state: 'failed', | ||
message: 'errors.network', | ||
}); | ||
throw err; | ||
} | ||
} | ||
}, | ||
}); | ||
|
||
useEffect(() => { | ||
passwordRef.current.focus(); | ||
}, []); | ||
|
||
return ( | ||
<> | ||
<FormAlert | ||
onClose={() => setFormState(initialFormState)} | ||
state={formState.state} | ||
> | ||
{t(formState.message)} | ||
</FormAlert> | ||
<Form | ||
className="d-flex flex-column gap-4" | ||
noValidate | ||
onSubmit={formik.handleSubmit} | ||
> | ||
<Form.Group controlId="password"> | ||
<Form.Label className="visually-hidden"> | ||
{t('profileSettings.newPassword')} | ||
</Form.Label> | ||
<div className="input-group-inline-button input-group-inline-button"> | ||
<Form.Control | ||
ref={passwordRef} | ||
autoComplete="password" | ||
isInvalid={!!formik.touched.password && !!formik.errors.password} | ||
name="password" | ||
onBlur={formik.handleBlur} | ||
onChange={formik.handleChange} | ||
placeholder={t('profileSettings.newPassword')} | ||
required | ||
type={isPasswordVisible ? 'text' : 'password'} | ||
value={formik.values.password} | ||
/> | ||
<PasswordVisibilityButton | ||
enabled={isPasswordVisible} | ||
onClick={handlePasswordVisibility} | ||
/> | ||
<Form.Control.Feedback type="invalid"> | ||
{t(formik.errors.password)} | ||
</Form.Control.Feedback> | ||
</div> | ||
</Form.Group> | ||
|
||
<Button | ||
data-disable-with={t('profileSettings.changePassword')} | ||
disabled={formik.isSubmitting} | ||
type="submit" | ||
variant="primary" | ||
> | ||
{t('profileSettings.changePassword')} | ||
</Button> | ||
</Form> | ||
</> | ||
); | ||
} | ||
|
||
export default ResetPasswordForm; |
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.