-
Notifications
You must be signed in to change notification settings - Fork 3
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
* creates password complexity component and adds it to the signup and reset password pages * adds error message for not-complex-enough password to reset password page * adds confirm password input to the signup screen * adds existing user check (doesn't work) * fixes user already exists check * fixes type error (jinkang is not gonna like this) * adds password cannot be same as previous check, cleans up error messages * makes changes to fix the console error for PasswordComplexity * fixes the documentation for the Supabase password verification query * me when i move the formdiv from the layout to every file * rebases, replaces all FormDivs with SmallCardForm * makes changes in response to feedback * replaces all SpacerDiv with Flex * makes changes in response to feedback * switches back from testing link * fixes ts compiler errors * uses CONFIG.onboardingHome instead of /onboarding * addresses nits * updates error messages * fixes hacky email wxists check * addresses nits * removes punctuation from email/password error messages
- Loading branch information
1 parent
c24ce44
commit eed1657
Showing
12 changed files
with
280 additions
and
213 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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,17 @@ | ||
import supabase from '../createClient'; | ||
|
||
/** | ||
* Checks if the current email is already tied to a user account. | ||
* @returns a Promise of whether the email is already in use | ||
*/ | ||
export async function checkEmailExists(email: string): Promise<boolean> { | ||
const { data, error } = await supabase.rpc('check_email_exists', { | ||
p_email: email, | ||
}); | ||
|
||
if (error) { | ||
throw new Error(`Error checking email existence: ${error.message}`); | ||
} | ||
|
||
return data; | ||
} |
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,17 @@ | ||
import supabase from '../createClient'; | ||
|
||
/** | ||
* Checks if the current password is different from the current user's password | ||
* @returns a Promise of whether the password is different | ||
*/ | ||
export async function verifyUserPassword(password: string): Promise<boolean> { | ||
const { data, error } = await supabase.rpc('verify_user_password', { | ||
password, | ||
}); | ||
|
||
if (error) { | ||
throw new Error(`Error verifying user password: ${error.message}`); | ||
} | ||
|
||
return data; | ||
} |
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,16 +1,18 @@ | ||
'use client'; | ||
|
||
import { BigBlueLinkButton } from '@/components/Buttons'; | ||
import { H2Centered, H4 } from '@/styles/text'; | ||
import { SpacerDiv } from '../styles'; | ||
import { Flex, SmallCard } from '@/styles/containers'; | ||
import { H2, H4 } from '@/styles/text'; | ||
|
||
export default function ConfirmResetPassword() { | ||
return ( | ||
<SpacerDiv> | ||
<H2Centered>Your password has been reset!</H2Centered> | ||
<BigBlueLinkButton href="/login"> | ||
<H4 $color="white">Go to Log In</H4> | ||
</BigBlueLinkButton> | ||
</SpacerDiv> | ||
<SmallCard> | ||
<Flex $direction="column" $gap="20px"> | ||
<H2>Your password has been reset.</H2> | ||
<BigBlueLinkButton href="/login"> | ||
<H4 $color="white">Go to Log In</H4> | ||
</BigBlueLinkButton> | ||
</Flex> | ||
</SmallCard> | ||
); | ||
} |
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,16 +1,19 @@ | ||
'use client'; | ||
|
||
import { SpacerDiv } from '@/app/(auth)/styles'; | ||
import { BigBlueLinkButton } from '@/components/Buttons'; | ||
import { H2Centered } from '@/styles/text'; | ||
import CONFIG from '@/lib/configs'; | ||
import { Flex, SmallCard } from '@/styles/containers'; | ||
import { H2 } from '@/styles/text'; | ||
|
||
export default function EmailVerified() { | ||
return ( | ||
<SpacerDiv> | ||
<H2Centered>Your email has been verified!</H2Centered> | ||
<BigBlueLinkButton type="button" href="/onboarding/roles"> | ||
Go to Onboarding | ||
</BigBlueLinkButton> | ||
</SpacerDiv> | ||
<SmallCard> | ||
<Flex $direction="column" $gap="20px"> | ||
<H2>Your email has been verified!</H2> | ||
<BigBlueLinkButton type="button" href={CONFIG.onboardingHome}> | ||
Go to Onboarding | ||
</BigBlueLinkButton> | ||
</Flex> | ||
</SmallCard> | ||
); | ||
} |
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 |
---|---|---|
|
@@ -3,69 +3,68 @@ | |
import { useState } from 'react'; | ||
import isEmail from 'validator/lib/isEmail'; | ||
import supabase from '@/api/supabase/createClient'; | ||
import { HorizontalDiv, SpacerDiv } from '@/app/(auth)/styles'; | ||
import { HorizontalDiv } from '@/app/(auth)/styles'; | ||
import { BigBlueButton, Button } from '@/components/Buttons'; | ||
import TextInput from '@/components/TextInput/index'; | ||
import COLORS from '@/styles/colors'; | ||
import { Flex, SmallCardForm } from '@/styles/containers'; | ||
import { H1, H2, H4, P } from '@/styles/text'; | ||
|
||
export default function ForgotPassword() { | ||
const [email, setEmail] = useState(''); | ||
const [emailSentCount, setEmailSentCount] = useState(0); | ||
const [emailError, setEmailError] = useState(''); | ||
|
||
const sendPasswordResetLink = async () => { | ||
const handleForgotPassword = async (e: React.FormEvent<HTMLFormElement>) => { | ||
e.preventDefault(); | ||
if (!isEmail(email)) { | ||
setEmailError('Could not find email'); | ||
setEmailError('Email not found'); | ||
return; | ||
} | ||
await supabase.auth.resetPasswordForEmail(email, { | ||
const { error } = await supabase.auth.resetPasswordForEmail(email, { | ||
redirectTo: | ||
'https://immigration-justice-project.vercel.app/reset-password', | ||
}); | ||
if (error) { | ||
setEmailError('Something went wrong. Please try again later.'); | ||
return; | ||
} | ||
setEmailSentCount(emailSentCount + 1); | ||
}; | ||
|
||
return ( | ||
<> | ||
{!emailSentCount && ( | ||
<> | ||
<H1>Forgot Password</H1> | ||
<TextInput | ||
label="Email" | ||
placeholder="[email protected]" | ||
type="email" | ||
id="email" | ||
errorText={emailError} | ||
value={email} | ||
setValue={setEmail} | ||
/> | ||
<BigBlueButton type="button" onClick={sendPasswordResetLink}> | ||
<H4 $color="white">Send link to email</H4> | ||
return emailSentCount === 0 ? ( | ||
<SmallCardForm onSubmit={handleForgotPassword}> | ||
<H1>Forgot Password</H1> | ||
<TextInput | ||
label="Email" | ||
placeholder="[email protected]" | ||
type="email" | ||
id="email" | ||
errorText={emailError} | ||
value={email} | ||
setValue={setEmail} | ||
/> | ||
<BigBlueButton type="submit"> | ||
<H4 $color="white">Send link to email</H4> | ||
</BigBlueButton> | ||
</SmallCardForm> | ||
) : ( | ||
<SmallCardForm onSubmit={handleForgotPassword}> | ||
<Flex $direction="column" $gap="20px"> | ||
<H2>A password reset link has been sent to your email.</H2> | ||
<H4 $color={COLORS.greyDark}> | ||
This link will direct you to the next step. If you didn’t receive an | ||
email, please click Resend Email. | ||
</H4> | ||
<HorizontalDiv> | ||
<BigBlueButton type="submit"> | ||
<H4 $color="white">Resend Email</H4> | ||
</BigBlueButton> | ||
</> | ||
)} | ||
{emailSentCount > 0 && ( | ||
<SpacerDiv> | ||
<H2>A password reset link has been sent to your email.</H2> | ||
<H4 $color={COLORS.greyDark}> | ||
This link will direct you to the next step. If you didn’t receive an | ||
email, please click Resend Email. | ||
</H4> | ||
<HorizontalDiv> | ||
<Button | ||
$primaryColor={COLORS.blueMid} | ||
$secondaryColor={COLORS.blueDark} | ||
onClick={sendPasswordResetLink} | ||
> | ||
<H4 $color="white">Resend Email</H4> | ||
</Button> | ||
{emailSentCount > 1 && ( | ||
<P $color={COLORS.greyMid}>Email has been resent!</P> | ||
)} | ||
</HorizontalDiv> | ||
</SpacerDiv> | ||
)} | ||
</> | ||
{emailSentCount > 1 && ( | ||
<P $color={COLORS.greyMid}>Email has been resent!</P> | ||
)} | ||
</HorizontalDiv> | ||
</Flex> | ||
</SmallCardForm> | ||
); | ||
} |
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 |
---|---|---|
|
@@ -3,11 +3,12 @@ | |
import { useContext, useEffect, useState } from 'react'; | ||
import { useRouter } from 'next/navigation'; | ||
import isEmail from 'validator/lib/isEmail'; | ||
import { H4Centered, SpacerDiv } from '@/app/(auth)/styles'; | ||
import { H4Centered } from '@/app/(auth)/styles'; | ||
import { BigBlueButton } from '@/components/Buttons'; | ||
import TextInput from '@/components/TextInput/index'; | ||
import CONFIG from '@/lib/configs'; | ||
import COLORS from '@/styles/colors'; | ||
import { Flex, SmallCardForm } from '@/styles/containers'; | ||
import { H1, LinkColored, P } from '@/styles/text'; | ||
import { useAuth } from '@/utils/AuthProvider'; | ||
import { ProfileContext } from '@/utils/ProfileProvider'; | ||
|
@@ -33,9 +34,15 @@ export default function Login() { | |
if (auth.userId && !isLoggingIn) push(CONFIG.settings); | ||
}, [auth, profile, push, isLoggingIn]); | ||
|
||
const handleSignIn = async () => { | ||
setEmailError(validEmail(email) ? '' : 'Invalid Email'); | ||
setPasswordError(password !== '' ? '' : 'Invalid Password'); | ||
const handleSignIn = async (e: React.FormEvent<HTMLFormElement>) => { | ||
e.preventDefault(); | ||
if (!auth) { | ||
setErrorMessage(''); | ||
return; | ||
} | ||
|
||
setEmailError(validEmail(email) ? '' : 'Email not found'); | ||
setPasswordError(password !== '' ? '' : 'Password is incorrect'); | ||
if (!validEmail(email) || password === '') { | ||
setErrorMessage(''); | ||
return; | ||
|
@@ -68,13 +75,13 @@ export default function Login() { | |
}; | ||
|
||
return ( | ||
<> | ||
<SpacerDiv $gap={0.625}> | ||
<SmallCardForm onSubmit={handleSignIn}> | ||
<Flex $direction="column" $gap="10px"> | ||
<H1>Log In</H1> | ||
{errorMessage !== '' && <P $color={COLORS.redMid}>{errorMessage}</P>} | ||
</SpacerDiv> | ||
<SpacerDiv $gap={0.8125}> | ||
<SpacerDiv> | ||
</Flex> | ||
<Flex $direction="column" $gap="13px"> | ||
<Flex $direction="column" $gap="20px"> | ||
<TextInput | ||
label="Email" | ||
placeholder="[email protected]" | ||
|
@@ -93,24 +100,22 @@ export default function Login() { | |
value={password} | ||
setValue={setPassword} | ||
/> | ||
</SpacerDiv> | ||
</Flex> | ||
<P> | ||
<LinkColored href="/forgot-password" $color={COLORS.greyMid}> | ||
Forgot your password? | ||
</LinkColored> | ||
</P> | ||
</SpacerDiv> | ||
<SpacerDiv> | ||
<BigBlueButton type="button" onClick={handleSignIn}> | ||
Log in | ||
</BigBlueButton> | ||
</Flex> | ||
<Flex $direction="column" $gap="20px"> | ||
<BigBlueButton type="submit">Log In</BigBlueButton> | ||
<H4Centered> | ||
Don’t have an account yet?{' '} | ||
<LinkColored $color={COLORS.greyDark} href="/signup"> | ||
Sign up | ||
</LinkColored> | ||
</H4Centered> | ||
</SpacerDiv> | ||
</> | ||
</Flex> | ||
</SmallCardForm> | ||
); | ||
} |
Oops, something went wrong.