From 6c873eb8e60917bff386ac3eb6613b4514232cc5 Mon Sep 17 00:00:00 2001 From: whooaami Date: Sat, 28 Oct 2023 19:20:37 +0300 Subject: [PATCH] Create page for reset password --- .../restorepassword/RestorePasswordForm.js | 33 ++ .../RestorePasswordForm.module.css | 131 +++++++ .../RestorePasswordFormContent.js | 149 ++++++++ .../RestorePasswordFormContent.module.css | 334 ++++++++++++++++++ .../pages/RestorePasswordModalPage.js | 29 ++ .../pages/RestorePasswordModalPage.module.css | 116 ++++++ .../pages/RestorePasswordPage.js | 25 ++ .../pages/RestorePasswordPage.module.css | 55 +++ .../components/authorization/LoginPage.jsx | 2 +- .../src/components/basicPage/BasicPage.jsx | 6 + forum/settings.py | 2 +- 11 files changed, 880 insertions(+), 2 deletions(-) create mode 100644 FrontEnd/src/components/RestorePassword/components/restorepassword/RestorePasswordForm.js create mode 100644 FrontEnd/src/components/RestorePassword/components/restorepassword/RestorePasswordForm.module.css create mode 100644 FrontEnd/src/components/RestorePassword/components/restorepassword/restorepassword-form/RestorePasswordFormContent.js create mode 100644 FrontEnd/src/components/RestorePassword/components/restorepassword/restorepassword-form/RestorePasswordFormContent.module.css create mode 100644 FrontEnd/src/components/RestorePassword/pages/RestorePasswordModalPage.js create mode 100644 FrontEnd/src/components/RestorePassword/pages/RestorePasswordModalPage.module.css create mode 100644 FrontEnd/src/components/RestorePassword/pages/RestorePasswordPage.js create mode 100644 FrontEnd/src/components/RestorePassword/pages/RestorePasswordPage.module.css diff --git a/FrontEnd/src/components/RestorePassword/components/restorepassword/RestorePasswordForm.js b/FrontEnd/src/components/RestorePassword/components/restorepassword/RestorePasswordForm.js new file mode 100644 index 000000000..2c6d70733 --- /dev/null +++ b/FrontEnd/src/components/RestorePassword/components/restorepassword/RestorePasswordForm.js @@ -0,0 +1,33 @@ +import styles from './RestorePasswordForm.module.css'; +import { RestorePasswordFormContentComponent } from './restorepassword-form/RestorePasswordFormContent'; +import { useState } from 'react'; +import { Link } from 'react-router-dom'; + + +export function RestorePasswordFormComponent() { + const [isValid, setIsValid] = useState(false); + const updateIsValid = (value) => { + setIsValid(value); + }; + return ( +
+
Відновлення паролю
+ +
+
+ + Головна + + +
+
+
+ ); +} diff --git a/FrontEnd/src/components/RestorePassword/components/restorepassword/RestorePasswordForm.module.css b/FrontEnd/src/components/RestorePassword/components/restorepassword/RestorePasswordForm.module.css new file mode 100644 index 000000000..c8c76a183 --- /dev/null +++ b/FrontEnd/src/components/RestorePassword/components/restorepassword/RestorePasswordForm.module.css @@ -0,0 +1,131 @@ +.form__container { + display: flex; + width: 572px; + flex-direction: column; + align-items: flex-start; + + border-radius: 2px; + background: var(--conditional-pop-over, #fff); + + /* drop-shadow/0.12+0.8+0.5 */ + box-shadow: 0px 9px 28px 8px rgba(0, 0, 0, 0.05), + 0px 6px 16px 0px rgba(0, 0, 0, 0.08), 0px 3px 6px -4px rgba(0, 0, 0, 0.12); +} + +.form__header { + display: flex; + padding: 16px 24px; + align-items: flex-start; + gap: 36px; + align-self: stretch; + background: var(--main-white, #fff); + + /* border & divider/divider ↓ */ + box-shadow: 0px -1px 0px 0px #f0f0f0 inset; + color: var(--character-title-85, rgba(0, 0, 0, 0.85)); + font-feature-settings: "calt" off; + + /* Text/Body/16-Semi bold */ + font-family: Inter, sans-serif; + font-size: 16px; + font-style: normal; + font-weight: 600; + line-height: 20px; + /* 125% */ + letter-spacing: -0.16px; +} + +.form__footer { + display: flex; + padding: 10px 16px; + justify-content: flex-end; + align-items: center; + gap: 8px; + align-self: stretch; + background: var(--main-white, #fff); + + /* border & divider/divider ↑ */ + box-shadow: 0px 1px 0px 0px #f0f0f0 inset; +} + +.button-container { + display: flex; + align-items: flex-start; + gap: 12px; +} + +.main-page__button { + display: flex; + padding: 5px 15px; + justify-content: center; + align-items: center; + gap: 10px; + border-radius: 4px; + border: 1px solid var(--primary-green-80, #1f9a7c); + background: var(--main-white, #fff); + + /* drop-shadow/button-secondary */ + box-shadow: 0px 2px 0px 0px rgba(0, 0, 0, 0.02); + + color: var(--primary-green-80, #1f9a7c); + text-align: center; + font-feature-settings: "calt" off; + + /* Text/Body/16-Semi bold */ + font-family: Inter, sans-serif; + font-size: 16px; + font-style: normal; + font-weight: 600; + line-height: 20px; + /* 125% */ + letter-spacing: -0.16px; + text-decoration: none; + + cursor: pointer; +} + +.main-page__button:hover { + border: 1px solid var(--primary-green-80, #1f9a7c); + background: var(--primary-green-80, #1f9a7c); + color: var(--main-white, #fff); +} + +.sign-up__button, +.sign-up__button__disabled { + display: flex; + padding: 5px 15px; + justify-content: center; + align-items: center; + gap: 10px; + border-radius: 4px; + border: 1px solid var(--primary-green-80, #1f9a7c); + background: var(--primary-green-80, #1f9a7c); + + /* drop-shadow/button-primary */ + box-shadow: 0px 2px 0px 0px rgba(0, 0, 0, 0.04); + color: var(--main-white, #fff); + text-align: center; + font-feature-settings: "calt" off; + + /* Text/Body/16-Semi bold */ + font-family: Inter, sans-serif; + font-size: 16px; + font-style: normal; + font-weight: 600; + line-height: 20px; + /* 125% */ + letter-spacing: -0.16px; + + cursor: pointer; +} + +.sign-up__button__disabled { + opacity: 50%; + cursor: default; +} + +.sign-up__button:hover { + border: 1px solid var(--primary-green-80, #1f9a7c); + background: var(--main-white, #fff); + color: var(--primary-green-80, #1f9a7c); +} diff --git a/FrontEnd/src/components/RestorePassword/components/restorepassword/restorepassword-form/RestorePasswordFormContent.js b/FrontEnd/src/components/RestorePassword/components/restorepassword/restorepassword-form/RestorePasswordFormContent.js new file mode 100644 index 000000000..071a584bb --- /dev/null +++ b/FrontEnd/src/components/RestorePassword/components/restorepassword/restorepassword-form/RestorePasswordFormContent.js @@ -0,0 +1,149 @@ +import React, { useEffect, useState } from 'react'; +import axios from 'axios'; +import { useForm } from 'react-hook-form'; +import { useNavigate } from 'react-router-dom'; +import { useParams } from 'react-router-dom'; +import EyeInvisible from '../../../../authorization/EyeInvisible'; +import EyeVisible from '../../../../authorization/EyeVisible'; +import styles from './RestorePasswordFormContent.module.css'; + +export function RestorePasswordFormContentComponent({ setIsValid }) { + const navigate = useNavigate(); + const { uid, token } = useParams(); + const [showPassword, setShowPassword] = useState(false); + const [showConfirmPassword, setShowConfirmPassword] = useState(false); + + const togglePassword = () => { + setShowPassword(!showPassword); + }; + + const toggleConfirmPassword = () => { + setShowConfirmPassword(!showConfirmPassword); + }; + + const errorMessageTemplates = { + required: 'Обов’язкове поле', + password: 'Пароль не відповідає вимогам', + confirmPassword: 'Паролі не збігаються', + }; + + const passwordPattern = /^(?=.*[0-9])(?=.*[a-zA-Z])[a-zA-Z0-9]{8,20}$/; + + const { + register, + handleSubmit, + getValues, + formState: { errors, isValid }, + } = useForm(); + + useEffect(() => { + const formIsValid = isValid; + setIsValid(formIsValid); + }, [isValid, setIsValid]); + + const onSubmit = (formData) => { + const dataToSend = { + uid: uid, + token: token, + new_password: formData.new_password, + re_new_password: formData.confirmPassword, + }; + + axios + .post( + `${process.env.REACT_APP_BASE_API_URL}/api/auth/users/reset_password_confirm/`, + dataToSend + ) + .then(() => { + setIsValid(true); + navigate('/login'); + }) + .catch((error) => { + console.log(error); + }); + }; + + return ( +
+ +
+
+
+
+
+ +
+ + +
+
+
+ + + {!showPassword ? : } + +
+
+ {errors.new_password && errors.new_password.message} +
+
+
+
+ +
+ +
+
+
+ + value === getValues('new_password') || + errorMessageTemplates.confirmPassword, + })} + /> + + {!showConfirmPassword ? : } + +
+
+ {errors.confirmPassword && errors.confirmPassword.message} +
+
+
+
+
+
+ ); +} diff --git a/FrontEnd/src/components/RestorePassword/components/restorepassword/restorepassword-form/RestorePasswordFormContent.module.css b/FrontEnd/src/components/RestorePassword/components/restorepassword/restorepassword-form/RestorePasswordFormContent.module.css new file mode 100644 index 000000000..2ff26f507 --- /dev/null +++ b/FrontEnd/src/components/RestorePassword/components/restorepassword/restorepassword-form/RestorePasswordFormContent.module.css @@ -0,0 +1,334 @@ +.signup-form { + display: flex; + padding: 24px; + flex-direction: column; + align-items: flex-start; + gap: 10px; + align-self: stretch; +} + +.signup-form__container { + display: flex; + flex-direction: column; + align-items: flex-start; + gap: 8px; +} + +.signup-form__row { + display: flex; + align-items: flex-start; + gap: 8px; +} + +.signup-form__column { + display: flex; + width: 257px; + height: 84px; + padding-bottom: 0px; + flex-direction: column; + align-items: flex-start; +} + +.signup-form__label { + display: flex; + gap: 4px; + align-self: stretch; + + color: var(--main-black-90, #292e32); + font-feature-settings: "calt" off; + + /* Text/Body/14-Regular */ + font-family: Inter, sans-serif; + font-size: 14px; + font-style: normal; + font-weight: 400; + line-height: 20px; /* 142.857% */ + letter-spacing: -0.14px; + text-align: left; +} + +.signup-form__label--password { + display: flex; + align-self: stretch; + flex-direction: column; + color: var(--main-black-90, #292e32); + font-feature-settings: "calt" off; + + /* Text/Body/14-Regular */ + text-align: left; + font-family: Inter, sans-serif; + font-size: 14px; + font-style: normal; + font-weight: 400; + line-height: 10px; + letter-spacing: -0.14px; +} + +.signup-form__label--hint { + align-self: stretch; + font-size: 8px; + line-height: 16px; + position: relative; + top: 0px; +} + +.signup-form__label--required { + color: var(--dust-red-5, #ff4d4f); + text-align: right; + font-family: SimSong; + font-size: 14px; + font-style: normal; + font-weight: 400; + line-height: 22.001px; +} + +.signup-form__label--text { + display: flex; + flex-direction: column; + justify-content: center; + flex: 1 0 0; +} + +.signup-form__field { + display: flex; + align-items: center; + align-self: stretch; + border-radius: 2px; + background: var(--main-white, #fff); +} + +.signup-form__field__password { + display: flex; + height: 22px; + padding: 5px 12px; + align-items: center; + gap: 4px; + align-self: stretch; + border-radius: 2px; + border: 1px solid var(--neutral-5, #D9D9D9); + background: var(--main-white, #FFF); +} + +.signup-form__input__password { + font-family: Roboto, sans-serif; + font-size: 14px; + font-style: normal; + font-weight: 400; + display: flex; + align-items: center; + align-self: stretch; + gap: 4px; + flex: 1 0 0; + border: none; +} + +.signup-form__input__password:focus { + outline: none; +} + +.signup-form__input { + display: flex; + height: 22px; + padding: 5px 12px; + align-items: center; + gap: 4px; + flex: 1 0 0; + border-radius: 2px; + border: 1px solid var(--neutral-5, #d9d9d9); + background: var(--main-white, #fff); + color: var(--character-title-85, rgba(0, 0, 0, 0.85)); + + /* Body/regular */ + font-family: Roboto, sans-serif; + font-size: 14px; + font-style: normal; + font-weight: 400; + line-height: 22px; +} + +.signup-form__input:focus { + outline: none; +} + +.signup-form__error { + display: flex; + padding: 1px 0px; + align-items: flex-start; + gap: 10px; + align-self: stretch; + color: var(--red-red-100, #f34444); + + /* Body/regular */ + font-family: Roboto, sans-serif; + font-size: 14px; + font-style: normal; + font-weight: 400; + line-height: 22px; +} + +.signup-form__checkboxes-container { + display: flex; + flex-direction: column; + align-items: flex-start; + gap: 24px; +} + +.signup-form__checkboxes-container--rules { + display: flex; + width: 328px; + align-items: flex-start; + gap: 8px; +} + +.rules__container { + display: flex; + align-items: center; + gap: 4px; + align-self: stretch; +} + +.rules__line { + display: flex; + align-items: center; + gap: 8px; +} + +.rules__line--text { + color: var(--main-black-90, #292e32); + font-feature-settings: "calt" off; + + /* Text/Body/14-Regular */ + font-family: Inter, sans-serif; + font-size: 14px; + font-style: normal; + font-weight: 400; + line-height: 20px; /* 142.857% */ + letter-spacing: -0.14px; +} + +.rules__line--link { + color: #00a3cf; + font-feature-settings: "calt" off; + font-family: Inter, sans-serif; + font-size: 14px; + font-style: normal; + font-weight: 400; + line-height: 20px; + letter-spacing: -0.14px; + text-decoration-line: underline; +} + +.rules__checkbox { + display: flex; + flex-direction: column; + justify-content: center; + align-items: center; +} + +.representative { + display: flex; + height: 100px; + flex-direction: column; + align-items: flex-start; + gap: 8px; +} + +.representative__title { + display: flex; + align-items: center; + gap: 4px; + color: var(--main-black-90, #292e32); + font-feature-settings: "calt" off; + + /* Text/Body/14-Semi bold */ + font-family: Inter, sans-serif; + font-size: 14px; + font-style: normal; + font-weight: 600; + line-height: 20px; /* 142.857% */ + letter-spacing: -0.14px; +} + +.representative__container { + display: flex; + flex-direction: row; + align-items: flex-start; + flex: 1 0 0; +} + +.representative__content { + display: flex; + padding: 0px 11px; + align-items: flex-start; + gap: 8px; +} + +.representative__column { + display: flex; + width: 246px; + align-items: flex-start; + gap: 273px; +} + +.representative__option { + display: flex; + align-items: flex-start; + gap: 8px; +} + +.representative__checkbox-container { + display: flex; + flex-direction: column; + justify-content: center; + align-items: center; +} + +.representative__label { + color: var(--main-black-90, #292e32); + font-feature-settings: "calt" off; + + /* Text/Body/14-Regular */ + font-family: Inter, sans-serif; + font-size: 14px; + font-style: normal; + font-weight: 400; + line-height: 20px; /* 142.857% */ + letter-spacing: -0.14px; + text-align: left; +} + +input[type="checkbox"] { + appearance: none; + background-color: #fff; + margin: 0; + display: grid; + place-content: center; + border-radius: 2px; + border: 1px solid var(--main-black-20, #e2e5eb); +} + +input[type="checkbox"]::before { + content: ""; + width: 16px; + height: 16px; +} + +input[type="checkbox"]:checked { + background: var(--primary-green-80, #1f9a7c); + border-radius: 2px; + border: 1px solid var(--primary-green-80, #1f9a7c); +} + +input[type="checkbox"]:checked::before { + transform: scale(1); + content: "\2713"; + font-size: 17px; + text-align: center; + position: relative; + bottom: 3px; + color: #f0f0f0; +} + +.password-visibility { + cursor: pointer; +} diff --git a/FrontEnd/src/components/RestorePassword/pages/RestorePasswordModalPage.js b/FrontEnd/src/components/RestorePassword/pages/RestorePasswordModalPage.js new file mode 100644 index 000000000..6e2ab062a --- /dev/null +++ b/FrontEnd/src/components/RestorePassword/pages/RestorePasswordModalPage.js @@ -0,0 +1,29 @@ +import { Link } from 'react-router-dom'; +import styles from './RestorePasswordModalPage.module.css'; +import DotDecorComponent from '../UI/dotDecor/DotDecor'; + +export function RestorePasswordModalPage() { + return ( +
+
+ +
+
Відновлення паролю майже завершено
+
+

+ На зазначену Вами електронну адресу були надіслені інструкції для зміни паролю.
+

+
+
+
+ + Закрити + +
+
+
+ +
+
+ ); +} diff --git a/FrontEnd/src/components/RestorePassword/pages/RestorePasswordModalPage.module.css b/FrontEnd/src/components/RestorePassword/pages/RestorePasswordModalPage.module.css new file mode 100644 index 000000000..9fe47b493 --- /dev/null +++ b/FrontEnd/src/components/RestorePassword/pages/RestorePasswordModalPage.module.css @@ -0,0 +1,116 @@ +.modal { + width: 1512px; + border-radius: 8px; + background: var(--wf-base-white, #fff); + } + + .modal__body { + display: flex; + align-items: center; + justify-content: space-around; + height: 725px; + background: var(--primary-green-20, #f1fff7); + } + + .container-modal { + width: 610px; + height: 290px; + position: absolute; + z-index: 2; + } + + .modal__header { + display: flex; + padding: 18px 24px; + align-items: flex-start; + gap: 36px; + align-self: stretch; + background: var(--main-white, #fff); + + /* border & divider/divider ↓ */ + box-shadow: 0px -1px 0px 0px #f0f0f0 inset; + color: var(--character-title-85, rgba(0, 0, 0, 0.85)); + font-feature-settings: "calt" off; + + /* Text/Body/16-Semi bold */ + font-family: Inter, sans-serif; + font-size: 16px; + font-style: normal; + font-weight: 600; + line-height: 20px; + /* 125% */ + letter-spacing: -0.16px; + } + + .modal__footer { + display: flex; + padding: 16px 24px; + justify-content: flex-end; + align-items: center; + gap: 8px; + align-self: stretch; + background: var(--main-white, #fff); + + /* border & divider/divider ↑ */ + box-shadow: 0px 1px 0px 0px #f0f0f0 inset; + } + + .resend-line { + margin-top: 20px; + } + + .resend-line__link { + color: var(--accent-accelerate-1500, #00a3cf); + font-feature-settings: "calt" off; + + /* Text/Body/14-Regular */ + font-family: Inter, sans-serif; + font-size: 14px; + font-style: normal; + font-weight: 400; + line-height: 20px; + letter-spacing: -0.14px; + } + + .button-container { + display: flex; + align-items: flex-start; + gap: 12px; + } + + .signup-page__button { + display: flex; + padding: 5px 15px; + justify-content: center; + align-items: center; + gap: 10px; + border-radius: 4px; + border: 1px solid var(--primary-green-80, #1f9a7c); + background: var(--main-white, #fff); + + /* drop-shadow/button-secondary */ + box-shadow: 0px 2px 0px 0px rgba(0, 0, 0, 0.02); + + color: var(--primary-green-80, #1f9a7c); + text-align: center; + font-feature-settings: "calt" off; + + /* Text/Body/16-Semi bold */ + font-family: Inter, sans-serif; + font-size: 16px; + font-style: normal; + font-weight: 600; + line-height: 20px; + /* 125% */ + letter-spacing: -0.16px; + text-decoration: none; + + cursor: pointer; + } + + .signup-page__button:hover { + border: 1px solid var(--primary-green-80, #1f9a7c); + background: var(--primary-green-80, #1f9a7c); + color: var(--main-white, #fff); + } + \ No newline at end of file diff --git a/FrontEnd/src/components/RestorePassword/pages/RestorePasswordPage.js b/FrontEnd/src/components/RestorePassword/pages/RestorePasswordPage.js new file mode 100644 index 000000000..402c08cf4 --- /dev/null +++ b/FrontEnd/src/components/RestorePassword/pages/RestorePasswordPage.js @@ -0,0 +1,25 @@ +import styles from './RestorePasswordPage.module.css'; +import DotDecorComponent from '../UI/dotDecor/DotDecor'; +import { RestorePasswordFormComponent } from '../components/restorepassword/RestorePasswordForm'; + +export function RestorePasswordPage() { + return ( +
+
+ +
+ +
+
+ Вже були на нашому сайті? +
+ + Увійти + +
+
+ +
+
+ ); +} diff --git a/FrontEnd/src/components/RestorePassword/pages/RestorePasswordPage.module.css b/FrontEnd/src/components/RestorePassword/pages/RestorePasswordPage.module.css new file mode 100644 index 000000000..7ef1e4f56 --- /dev/null +++ b/FrontEnd/src/components/RestorePassword/pages/RestorePasswordPage.module.css @@ -0,0 +1,55 @@ +.sign-up { + width: 1512px; + border-radius: 8px; + background: var(--wf-base-white, #fff); + } + + .sign-up__body { + display: flex; + align-items: center; + justify-content: space-around; + height: 725px; + background: var(--primary-green-20, #f1fff7); + } + + .container { + display: inline-flex; + flex-direction: column; + align-items: center; + gap: 24px; + position: absolute; + z-index: 2; + } + + .sign-in-line { + display: flex; + align-items: flex-start; + gap: 8px; + } + + .sign-in-line__text { + color: #000; + font-feature-settings: "calt" off; + + /* Text/Body/14-Regular */ + font-family: Inter, sans-serif; + font-size: 14px; + font-style: normal; + font-weight: 400; + line-height: 20px; + letter-spacing: -0.14px; + } + + .sign-in-line__link { + color: var(--accent-accelerate-1500, #00a3cf); + font-feature-settings: "calt" off; + + /* Text/Body/14-Regular */ + font-family: Inter, sans-serif; + font-size: 14px; + font-style: normal; + font-weight: 400; + line-height: 20px; + letter-spacing: -0.14px; + } + \ No newline at end of file diff --git a/FrontEnd/src/components/authorization/LoginPage.jsx b/FrontEnd/src/components/authorization/LoginPage.jsx index 9467c9e6f..bee8d3595 100644 --- a/FrontEnd/src/components/authorization/LoginPage.jsx +++ b/FrontEnd/src/components/authorization/LoginPage.jsx @@ -150,7 +150,7 @@ const LoginContent = (props) => { {errors.unspecifiedError && errors.unspecifiedError.message} - Забули пароль? + Забули пароль? diff --git a/FrontEnd/src/components/basicPage/BasicPage.jsx b/FrontEnd/src/components/basicPage/BasicPage.jsx index 957e300ea..039e79f51 100644 --- a/FrontEnd/src/components/basicPage/BasicPage.jsx +++ b/FrontEnd/src/components/basicPage/BasicPage.jsx @@ -14,6 +14,9 @@ import { SignUpPage } from '../SignUp/pages/SignUpPage'; import { SignUpModalPage } from '../SignUp/pages/SignUpModalPage'; import { ResendActivationPage } from '../SignUp/pages/ResendActivationPage'; import { ActivationProfilePage } from '../SignUp/pages/ActivateProfilePage'; +import { SendEmailRestorePasswordPage } from '../RestorePassword/pages/SendEmailRestorePasswordPage'; +import { RestorePasswordPage } from '../RestorePassword/pages/RestorePasswordPage'; +import { RestorePasswordModalPage } from '../RestorePassword/pages/RestorePasswordModalPage'; import ScrollToTopButton from '../PrivacyPolicyPage/privacy/ScrollToTopButton'; import TermsAndConditions from '../terms-and-conditions-app/terms_conditions/TermsAndConditionsComponent'; import { useAuth } from '../../hooks'; @@ -76,6 +79,9 @@ function BasicPage() { } /> } /> } /> + } /> + } /> + } /> } /> } /> } /> diff --git a/forum/settings.py b/forum/settings.py index 97f82780a..b688be24d 100644 --- a/forum/settings.py +++ b/forum/settings.py @@ -183,7 +183,7 @@ EMAIL_HOST_PASSWORD = config("EMAIL_HOST_PASSWORD") DJOSER = { - "PASSWORD_RESET_CONFIRM_URL": "#/password/reset/confirm/{uid}/{token}", + "PASSWORD_RESET_CONFIRM_URL": "password/reset/confirm/{uid}/{token}", "PASSWORD_RESET_CONFIRM_RETYPE": True, "PASSWORD_RESET_SHOW_EMAIL_NOT_FOUND": True, "ACTIVATION_URL": "activate/{uid}/{token}",