diff --git a/src/components/AuthenticationFlow/ResetPasswordForm.tsx b/src/components/AuthenticationFlow/ResetPasswordForm.tsx new file mode 100644 index 000000000..d512131a3 --- /dev/null +++ b/src/components/AuthenticationFlow/ResetPasswordForm.tsx @@ -0,0 +1,98 @@ +import { useEffect, useState } from 'preact/hooks'; +import Spinner from '../Spinner'; +import { httpPost } from '../../lib/http'; +import Cookies from 'js-cookie'; +import { TOKEN_COOKIE_NAME } from '../../lib/constants'; + +export default function ResetPasswordForm() { + const [code, setCode] = useState(''); + const [password, setPassword] = useState(''); + const [passwordConfirm, setPasswordConfirm] = useState(''); + const [isLoading, setIsLoading] = useState(false); + const [error, setError] = useState(''); + + useEffect(() => { + const urlParams = new URLSearchParams(window.location.search); + const code = urlParams.get('code'); + + if (!code) { + window.location.href = '/login'; + } else { + setCode(code); + } + }, []); + + const handleSubmit = async (e: Event) => { + e.preventDefault(); + setIsLoading(true); + + if (password !== passwordConfirm) { + setIsLoading(false); + setError('Passwords do not match.'); + return; + } + + const { response, error } = await httpPost( + `${import.meta.env.PUBLIC_API_URL}/v1-reset-forgotten-password`, + { + newPassword: password, + confirmPassword: passwordConfirm, + code, + } + ); + + if (error?.message) { + setIsLoading(false); + setError(error.message); + return; + } + + if (!response?.token) { + setIsLoading(false); + setError('Something went wrong. Please try again later.'); + return; + } + + const token = response.token; + Cookies.set(TOKEN_COOKIE_NAME, token); + window.location.href = '/'; + }; + + return ( +
+ setPassword((e.target as HTMLInputElement).value)} + /> + + + setPasswordConfirm((e.target as HTMLInputElement).value) + } + /> + + {error && ( +

{error}

+ )} + + +
+ ); +} diff --git a/src/components/Authenticator/authenticator.ts b/src/components/Authenticator/authenticator.ts index 91cf60bf4..76f9b24bb 100644 --- a/src/components/Authenticator/authenticator.ts +++ b/src/components/Authenticator/authenticator.ts @@ -47,7 +47,14 @@ function handleGuest() { // Prepares the UI for the user who is logged out function handleAuthenticated() { - const guestRoutes = ['/login', '/signup']; + const guestRoutes = [ + '/login', + '/signup', + '/verify-account', + '/verification-pending', + '/reset-password', + '/forgot-password', + ]; showHideGuestElements('hide'); showHideAuthElements('show'); diff --git a/src/components/Profile/ResetPasswordForm.tsx b/src/components/Profile/ResetPasswordForm.tsx deleted file mode 100644 index 6cc67db30..000000000 --- a/src/components/Profile/ResetPasswordForm.tsx +++ /dev/null @@ -1,135 +0,0 @@ -import { useState } from 'preact/hooks'; -import Spinner from '../Spinner'; - -export default function ResetPasswordForm() { - const [password, setPassword] = useState(''); - const [passwordConfirm, setPasswordConfirm] = useState(''); - const [isLoading, setIsLoading] = useState(false); - const [message, setMessage] = useState<{ - type: 'error' | 'success' | 'info'; - message: string; - }>(); - - const handleSubmit = async (e: Event) => { - e.preventDefault(); - setIsLoading(true); - - if (password !== passwordConfirm) { - setIsLoading(false); - return setMessage({ - type: 'error', - message: 'Passwords do not match.', - }); - } - - const urlParams = new URLSearchParams(window.location.search); - const code = urlParams.get('code'); - - const res = await fetch( - 'http://localhost:8080/v1-reset-forgotten-password', - { - method: 'POST', - headers: { - 'Content-Type': 'application/json', - }, - body: JSON.stringify({ - newPassword: password, - confirmPassword: passwordConfirm, - code, - }), - } - ); - - const data = await res.json(); - - if (!res.ok) { - setIsLoading(false); - setMessage({ - type: 'error', - message: data.message, - }); - return; - } - - setIsLoading(false); - setPassword(''); - setPasswordConfirm(''); - setMessage({ - type: 'success', - message: 'Your password has been reset.', - }); - - // TODO: Redirect to login page after 2 seconds - setTimeout(() => { - window.location.href = '/login'; - }, 2000); - }; - - return ( -
-

- Reset your password -

- - - setPassword((e.target as HTMLInputElement).value)} - /> - - - - setPasswordConfirm((e.target as HTMLInputElement).value) - } - /> - - {message && ( -
- {message.message} -
- )} - - -
- ); -} diff --git a/src/pages/reset-password.astro b/src/pages/reset-password.astro index e760949a0..d9b54bd6c 100644 --- a/src/pages/reset-password.astro +++ b/src/pages/reset-password.astro @@ -1,22 +1,23 @@ --- -import ResetPasswordForm from '../components/Profile/ResetPasswordForm'; +import ResetPasswordForm from '../components/AuthenticationFlow/ResetPasswordForm'; import SettingLayout from '../layouts/SettingLayout.astro'; --- -
- +
+
+
+

+ Reset Password +

+

+ Enter and confirm your new password below. +

+
+ + +
- -