reset password
parent
d6016c3d4d
commit
66b470e46e
|
@ -36,6 +36,7 @@
|
||||||
"emailPlaceholderNew": "Geben Sie Ihre neue E-Mail ein",
|
"emailPlaceholderNew": "Geben Sie Ihre neue E-Mail ein",
|
||||||
"password": "Passwort",
|
"password": "Passwort",
|
||||||
"passwordPlaceholder": "Geben Sie Ihr Passwort ein",
|
"passwordPlaceholder": "Geben Sie Ihr Passwort ein",
|
||||||
|
"passwordPlaceholderNew": "Geben Sie Ihr neues Passwort ein",
|
||||||
"noDataFound": "Keine Einträge gefunden",
|
"noDataFound": "Keine Einträge gefunden",
|
||||||
"calendarMaxFutureBookingDays": "Max. Tage im Voraus",
|
"calendarMaxFutureBookingDays": "Max. Tage im Voraus",
|
||||||
"calendarMinEarliestBookingTime": "Min. früheste Buchungszeit",
|
"calendarMinEarliestBookingTime": "Min. früheste Buchungszeit",
|
||||||
|
@ -144,6 +145,7 @@
|
||||||
"signUpLink": "Jetzt registrieren",
|
"signUpLink": "Jetzt registrieren",
|
||||||
"login": {
|
"login": {
|
||||||
"button": "Anmelden",
|
"button": "Anmelden",
|
||||||
|
"forgotPassword": "Passwort vergessen?",
|
||||||
"dontHaveAccount": "Sie haben noch kein Konto?",
|
"dontHaveAccount": "Sie haben noch kein Konto?",
|
||||||
"stateAccountPendingDeletion": {
|
"stateAccountPendingDeletion": {
|
||||||
"title": "Anstehende Kontolöschung",
|
"title": "Anstehende Kontolöschung",
|
||||||
|
@ -171,7 +173,6 @@
|
||||||
"pendingEmailVerification": {
|
"pendingEmailVerification": {
|
||||||
"title": "E-Mail-Verifizierung ausstehend",
|
"title": "E-Mail-Verifizierung ausstehend",
|
||||||
"description": "Bitte überprüfen Sie Ihr E-Mail-Postfach und klicken Sie auf den Link in der E-Mail, um Ihre E-Mail-Adresse zu verifizieren."
|
"description": "Bitte überprüfen Sie Ihr E-Mail-Postfach und klicken Sie auf den Link in der E-Mail, um Ihre E-Mail-Adresse zu verifizieren."
|
||||||
}
|
|
||||||
},
|
},
|
||||||
"request": {
|
"request": {
|
||||||
"400": {
|
"400": {
|
||||||
|
@ -180,6 +181,17 @@
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"forgotPassword": {
|
||||||
|
"title": "Problem beim Anmelden?",
|
||||||
|
"info": "Geben Sie Ihre E-Mail-Adresse ein, und wir senden Ihnen einen Link zum Zurücksetzen Ihres Passworts.",
|
||||||
|
"button": "Passwort zurücksetzen",
|
||||||
|
"backToLogin": "Zurück zur Anmeldung",
|
||||||
|
"resetLinkSent": {
|
||||||
|
"title": "Link zum Zurücksetzen gesendet",
|
||||||
|
"description": "Wir haben Ihnen eine E-Mail mit einem Link zum Zurücksetzen Ihres Passworts geschickt. Bitte prüfen Sie Ihren E-Mail-Posteingang"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
"storeServices": {
|
"storeServices": {
|
||||||
"pageTitle": "Dienstleistungen",
|
"pageTitle": "Dienstleistungen",
|
||||||
"buttonAddService": "Dienstleistung hinzufügen",
|
"buttonAddService": "Dienstleistung hinzufügen",
|
||||||
|
@ -395,9 +407,8 @@
|
||||||
"requesting": {
|
"requesting": {
|
||||||
"title": "E-Mail-Verifizierung ausstehend"
|
"title": "E-Mail-Verifizierung ausstehend"
|
||||||
},
|
},
|
||||||
"Erfolg": {
|
"success": {
|
||||||
"title": "E-Mail-Überprüfung erfolgreich",
|
"title": "E-Mail-Überprüfung erfolgreich"
|
||||||
"button": "Jetzt anmelden"
|
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
@ -411,6 +422,18 @@
|
||||||
"success": {
|
"success": {
|
||||||
"title": "E-Mail-Änderung erfolgreich"
|
"title": "E-Mail-Änderung erfolgreich"
|
||||||
}
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"init": {
|
||||||
|
"title": "Passwort zurücksetzen",
|
||||||
|
"subTitle": "Geben Sie Ihr neues Passwort ein"
|
||||||
|
},
|
||||||
|
"requesting": {
|
||||||
|
"title": "Passwort wird zurückgesetzt"
|
||||||
|
},
|
||||||
|
"success": {
|
||||||
|
"title": "Passwort erfolgreich zurückgesetzt"
|
||||||
|
}
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
|
|
|
@ -36,6 +36,7 @@
|
||||||
"emailPlaceholderNew": "Enter your new email",
|
"emailPlaceholderNew": "Enter your new email",
|
||||||
"password": "Password",
|
"password": "Password",
|
||||||
"passwordPlaceholder": "Enter your password",
|
"passwordPlaceholder": "Enter your password",
|
||||||
|
"passwordPlaceholderNew": "Enter your new password",
|
||||||
"noDataFound": "No data found",
|
"noDataFound": "No data found",
|
||||||
"calendarMaxFutureBookingDays": "Max. future booking days",
|
"calendarMaxFutureBookingDays": "Max. future booking days",
|
||||||
"calendarMinEarliestBookingTime": "Min. earliest booking time",
|
"calendarMinEarliestBookingTime": "Min. earliest booking time",
|
||||||
|
@ -144,6 +145,7 @@
|
||||||
"signUpLink": "Sign up now",
|
"signUpLink": "Sign up now",
|
||||||
"login": {
|
"login": {
|
||||||
"button": "Login",
|
"button": "Login",
|
||||||
|
"forgotPassword": "Forgot password?",
|
||||||
"dontHaveAccount": "Don't have an account?",
|
"dontHaveAccount": "Don't have an account?",
|
||||||
"stateAccountPendingDeletion": {
|
"stateAccountPendingDeletion": {
|
||||||
"title": "Pending account deletion",
|
"title": "Pending account deletion",
|
||||||
|
@ -178,6 +180,16 @@
|
||||||
"description": "Please check your inputs and try again."
|
"description": "Please check your inputs and try again."
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
},
|
||||||
|
"forgotPassword": {
|
||||||
|
"title": "Problem when logging in?",
|
||||||
|
"info": "Enter your email address and we will send you a link to reset your password.",
|
||||||
|
"button": "Send reset link",
|
||||||
|
"backToLogin": "Back to login",
|
||||||
|
"resetLinkSent": {
|
||||||
|
"title": "Reset link sent",
|
||||||
|
"description": "We have sent you an email with a link to reset your password. Please check your email inbox."
|
||||||
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"services": {
|
"services": {
|
||||||
|
@ -414,6 +426,18 @@
|
||||||
"success": {
|
"success": {
|
||||||
"title": "Email change successful"
|
"title": "Email change successful"
|
||||||
}
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"init": {
|
||||||
|
"title": "Password reset",
|
||||||
|
"subTitle": "Enter your new password"
|
||||||
|
},
|
||||||
|
"requesting": {
|
||||||
|
"title": "Resetting password"
|
||||||
|
},
|
||||||
|
"success": {
|
||||||
|
"title": "Password reset successful"
|
||||||
|
}
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
|
|
|
@ -41,6 +41,15 @@ export function AuthenticationRoutes() {
|
||||||
}
|
}
|
||||||
/>
|
/>
|
||||||
|
|
||||||
|
<Route
|
||||||
|
path={Constants.ROUTE_PATHS.AUTHENTICATION.FORGOT_PASSWORD}
|
||||||
|
element={
|
||||||
|
<MySupsenseFallback>
|
||||||
|
<Authentication method={AuthenticationMethod.FORGOT_PASSWORD} />
|
||||||
|
</MySupsenseFallback>
|
||||||
|
}
|
||||||
|
/>
|
||||||
|
|
||||||
<Route
|
<Route
|
||||||
path="*"
|
path="*"
|
||||||
element={<Navigate to={Constants.ROUTE_PATHS.AUTHENTICATION.LOGIN} />}
|
element={<Navigate to={Constants.ROUTE_PATHS.AUTHENTICATION.LOGIN} />}
|
||||||
|
|
|
@ -45,6 +45,7 @@ export function MyPasswordFormInput({
|
||||||
label,
|
label,
|
||||||
inputPlaceholder,
|
inputPlaceholder,
|
||||||
formItemRules,
|
formItemRules,
|
||||||
|
newPassword,
|
||||||
}) {
|
}) {
|
||||||
const { t } = useTranslation();
|
const { t } = useTranslation();
|
||||||
|
|
||||||
|
@ -63,7 +64,11 @@ export function MyPasswordFormInput({
|
||||||
minLength: Constants.GLOBALS.MIN_PASSWORD_LENGTH,
|
minLength: Constants.GLOBALS.MIN_PASSWORD_LENGTH,
|
||||||
}
|
}
|
||||||
)}
|
)}
|
||||||
inputPlaceholder={inputPlaceholder || t("common.passwordPlaceholder")}
|
inputPlaceholder={
|
||||||
|
inputPlaceholder || newPassword
|
||||||
|
? t("common.passwordPlaceholderNew")
|
||||||
|
: t("common.passwordPlaceholder")
|
||||||
|
}
|
||||||
inputType="password"
|
inputType="password"
|
||||||
formItemRules={formItemRules}
|
formItemRules={formItemRules}
|
||||||
/>
|
/>
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
import {
|
import {
|
||||||
Button,
|
Button,
|
||||||
Checkbox,
|
Checkbox,
|
||||||
|
Divider,
|
||||||
Flex,
|
Flex,
|
||||||
Form,
|
Form,
|
||||||
Modal,
|
Modal,
|
||||||
|
@ -32,6 +33,7 @@ import ReCAPTCHA from "react-google-recaptcha";
|
||||||
export const AuthenticationMethod = {
|
export const AuthenticationMethod = {
|
||||||
LOGIN: 1,
|
LOGIN: 1,
|
||||||
SIGNUP: 2,
|
SIGNUP: 2,
|
||||||
|
FORGOT_PASSWORD: 3,
|
||||||
};
|
};
|
||||||
|
|
||||||
export default function Authentication({ method }) {
|
export default function Authentication({ method }) {
|
||||||
|
@ -61,14 +63,38 @@ export default function Authentication({ method }) {
|
||||||
|
|
||||||
{method === AuthenticationMethod.LOGIN ? (
|
{method === AuthenticationMethod.LOGIN ? (
|
||||||
<Login notificationApi={notificationApi} />
|
<Login notificationApi={notificationApi} />
|
||||||
) : (
|
) : method === AuthenticationMethod.SIGNUP ? (
|
||||||
<SignUp notificationApi={notificationApi} />
|
<SignUp notificationApi={notificationApi} />
|
||||||
|
) : (
|
||||||
|
<ForgotPassword notificationApi={notificationApi} />
|
||||||
)}
|
)}
|
||||||
</Modal>
|
</Modal>
|
||||||
</>
|
</>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export function MyRecaptcha({ recaptchaRef, recaptchaValueRef }) {
|
||||||
|
const { t } = useTranslation();
|
||||||
|
|
||||||
|
return (
|
||||||
|
<Form.Item
|
||||||
|
name="recaptcha"
|
||||||
|
rules={[
|
||||||
|
{
|
||||||
|
required: true,
|
||||||
|
message: t("common.inputRules.recaptchaRequired"),
|
||||||
|
},
|
||||||
|
]}
|
||||||
|
>
|
||||||
|
<ReCAPTCHA
|
||||||
|
ref={recaptchaRef}
|
||||||
|
sitekey={process.env.REACT_APP_RECAPTCHA_SITE_KEY}
|
||||||
|
onChange={(value) => (recaptchaValueRef.current = value)}
|
||||||
|
/>
|
||||||
|
</Form.Item>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
function RememberMeCheckbox() {
|
function RememberMeCheckbox() {
|
||||||
const { t } = useTranslation();
|
const { t } = useTranslation();
|
||||||
|
|
||||||
|
@ -242,23 +268,22 @@ function Login({ notificationApi }) {
|
||||||
>
|
>
|
||||||
<MyPasswordFormInput />
|
<MyPasswordFormInput />
|
||||||
|
|
||||||
|
<Flex justify="space-between">
|
||||||
<RememberMeCheckbox />
|
<RememberMeCheckbox />
|
||||||
|
<Button
|
||||||
<Form.Item
|
type="link"
|
||||||
name="recaptcha"
|
onClick={() =>
|
||||||
rules={[
|
navigate(Constants.ROUTE_PATHS.AUTHENTICATION.FORGOT_PASSWORD)
|
||||||
{
|
}
|
||||||
required: true,
|
|
||||||
message: t("common.inputRules.recaptchaRequired"),
|
|
||||||
},
|
|
||||||
]}
|
|
||||||
>
|
>
|
||||||
<ReCAPTCHA
|
{t("authentication.login.forgotPassword")}
|
||||||
ref={recaptchaRef}
|
</Button>
|
||||||
sitekey={process.env.REACT_APP_RECAPTCHA_SITE_KEY}
|
</Flex>
|
||||||
onChange={(value) => (recaptchaValueRef.current = value)}
|
|
||||||
|
<MyRecaptcha
|
||||||
|
recaptchaRef={recaptchaRef}
|
||||||
|
recaptchaValueRef={recaptchaValueRef}
|
||||||
/>
|
/>
|
||||||
</Form.Item>
|
|
||||||
|
|
||||||
<PrivacyPolicyCheckbox />
|
<PrivacyPolicyCheckbox />
|
||||||
</div>
|
</div>
|
||||||
|
@ -456,20 +481,7 @@ function SignUp({ notificationApi }) {
|
||||||
|
|
||||||
<RememberMeCheckbox />
|
<RememberMeCheckbox />
|
||||||
|
|
||||||
<Form.Item
|
<MyRecaptcha recaptchaValueRef={recaptchaValueRef} />
|
||||||
name="recaptcha"
|
|
||||||
rules={[
|
|
||||||
{
|
|
||||||
required: true,
|
|
||||||
message: t("common.inputRules.recaptchaRequired"),
|
|
||||||
},
|
|
||||||
]}
|
|
||||||
>
|
|
||||||
<ReCAPTCHA
|
|
||||||
sitekey={process.env.REACT_APP_RECAPTCHA_SITE_KEY}
|
|
||||||
onChange={(value) => (recaptchaValueRef.current = value)}
|
|
||||||
/>
|
|
||||||
</Form.Item>
|
|
||||||
|
|
||||||
<PrivacyPolicyCheckbox />
|
<PrivacyPolicyCheckbox />
|
||||||
|
|
||||||
|
@ -510,3 +522,98 @@ function PendingEmailVerification() {
|
||||||
/>
|
/>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const FORGOT_PASSWORD_STEP = {
|
||||||
|
ENTER_EMAIL: 1,
|
||||||
|
RESET_LINK_SENT: 2,
|
||||||
|
};
|
||||||
|
|
||||||
|
function ForgotPassword({ notificationApi }) {
|
||||||
|
const { t } = useTranslation();
|
||||||
|
const [form] = Form.useForm();
|
||||||
|
const navigate = useNavigate();
|
||||||
|
|
||||||
|
const [step, setStep] = useState(SignUpStep.SIGN_UP);
|
||||||
|
const [isRequesting, setIsRequesting] = useState(false);
|
||||||
|
const recaptchaValueRef = useRef(null);
|
||||||
|
|
||||||
|
if (step === FORGOT_PASSWORD_STEP.RESET_LINK_SENT) {
|
||||||
|
return (
|
||||||
|
<Result
|
||||||
|
status="warning"
|
||||||
|
title={t("authentication.forgotPassword.resetLinkSent.title")}
|
||||||
|
subTitle={t("authentication.forgotPassword.resetLinkSent.description")}
|
||||||
|
/>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
return (
|
||||||
|
<Form
|
||||||
|
form={form}
|
||||||
|
layout="vertical"
|
||||||
|
requiredMark={false}
|
||||||
|
initialValues={{
|
||||||
|
rememberMe: false,
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
<Typography.Title level={3} style={{ textAlign: "center" }}>
|
||||||
|
{t("authentication.forgotPassword.title")}
|
||||||
|
</Typography.Title>
|
||||||
|
|
||||||
|
<Typography.Paragraph
|
||||||
|
type="secondary"
|
||||||
|
style={{
|
||||||
|
textAlign: "center",
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
{t("authentication.forgotPassword.info")}
|
||||||
|
</Typography.Paragraph>
|
||||||
|
|
||||||
|
<MyEmailFormInput hasFeedback={true} disableEmailCheck />
|
||||||
|
|
||||||
|
<MyRecaptcha recaptchaValueRef={recaptchaValueRef} />
|
||||||
|
|
||||||
|
<Button
|
||||||
|
type="primary"
|
||||||
|
size="large"
|
||||||
|
block
|
||||||
|
loading={isRequesting}
|
||||||
|
onClick={() => {
|
||||||
|
form
|
||||||
|
.validateFields()
|
||||||
|
.then((values) => {
|
||||||
|
setIsRequesting(true);
|
||||||
|
|
||||||
|
myFetch({
|
||||||
|
url: `/user/auth/forgot-password`,
|
||||||
|
method: "POST",
|
||||||
|
body: {
|
||||||
|
email: values.email.toLocaleLowerCase(),
|
||||||
|
recaptcha: recaptchaValueRef.current,
|
||||||
|
},
|
||||||
|
notificationApi: notificationApi,
|
||||||
|
t: t,
|
||||||
|
})
|
||||||
|
.then(() => setStep(FORGOT_PASSWORD_STEP.RESET_LINK_SENT))
|
||||||
|
.catch(() => {
|
||||||
|
setIsRequesting(false);
|
||||||
|
showUnkownErrorNotification(notificationApi, t);
|
||||||
|
});
|
||||||
|
})
|
||||||
|
.catch(() => showInputsInvalidNotification(notificationApi, t));
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
{t("authentication.forgotPassword.button")}
|
||||||
|
</Button>
|
||||||
|
|
||||||
|
<Flex justify="center">
|
||||||
|
<Button
|
||||||
|
type="link"
|
||||||
|
onClick={() => navigate(Constants.ROUTE_PATHS.AUTHENTICATION.LOGIN)}
|
||||||
|
>
|
||||||
|
{t("authentication.forgotPassword.backToLogin")}
|
||||||
|
</Button>
|
||||||
|
</Flex>
|
||||||
|
</Form>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
|
@ -102,6 +102,52 @@ export default function Verification() {
|
||||||
extra: <ButtonToLogin />,
|
extra: <ButtonToLogin />,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
init: {
|
||||||
|
title: t("verification.content.2.init.title"),
|
||||||
|
subTitle: t("verification.content.2.init.subTitle"),
|
||||||
|
extra: (
|
||||||
|
<Form form={form} layout="vertical" requiredMark={false}>
|
||||||
|
<MyPasswordFormInput newPassword />
|
||||||
|
|
||||||
|
<Button
|
||||||
|
type="primary"
|
||||||
|
htmlType="submit"
|
||||||
|
block
|
||||||
|
onClick={() => {
|
||||||
|
form
|
||||||
|
.validateFields()
|
||||||
|
.then((values) => {
|
||||||
|
setIsRequesting(RequestState.REQUESTING);
|
||||||
|
|
||||||
|
sendVerifyRequest({
|
||||||
|
password: EncodeStringToBase64(values.password),
|
||||||
|
})
|
||||||
|
.then(() => setIsRequesting(RequestState.SUCCESS))
|
||||||
|
.catch(() => {
|
||||||
|
setIsRequesting(RequestState.INIT);
|
||||||
|
showPasswordIncorrectNotification(notificationApi, t);
|
||||||
|
});
|
||||||
|
})
|
||||||
|
.catch(() =>
|
||||||
|
showInputsInvalidNotification(notificationApi, t)
|
||||||
|
);
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
{t("common.button.confirm")}
|
||||||
|
</Button>
|
||||||
|
</Form>
|
||||||
|
),
|
||||||
|
},
|
||||||
|
requesting: {
|
||||||
|
title: t("verification.content.2.requesting.title"),
|
||||||
|
extra: <Spin size="large" />,
|
||||||
|
},
|
||||||
|
success: {
|
||||||
|
title: t("verification.content.2.success.title"),
|
||||||
|
extra: <ButtonToLogin />,
|
||||||
|
},
|
||||||
|
},
|
||||||
];
|
];
|
||||||
|
|
||||||
const parsedState = isNaN(state) ? 0 : parseInt(state);
|
const parsedState = isNaN(state) ? 0 : parseInt(state);
|
||||||
|
|
|
@ -46,6 +46,7 @@ export const Constants = {
|
||||||
AUTHENTICATION: {
|
AUTHENTICATION: {
|
||||||
LOGIN: "/login",
|
LOGIN: "/login",
|
||||||
SIGN_UP: "/signup",
|
SIGN_UP: "/signup",
|
||||||
|
FORGOT_PASSWORD: "/forgot-password",
|
||||||
},
|
},
|
||||||
VERIFY: "/verify",
|
VERIFY: "/verify",
|
||||||
OVERVIEW: "/",
|
OVERVIEW: "/",
|
||||||
|
|
Loading…
Reference in New Issue