diff --git a/apps/client/pages/api/auth/[...nextauth].ts b/apps/client/pages/api/auth/[...nextauth].ts index 1b7dd354..360d56fd 100644 --- a/apps/client/pages/api/auth/[...nextauth].ts +++ b/apps/client/pages/api/auth/[...nextauth].ts @@ -64,7 +64,7 @@ export const authOptions = { .object({ firstName: z.string().optional(), lastName: z.string().optional(), - email: z.string().email(), + email: z.string().email({ message: 'Invalid email address' }), password: z.string().min(6), }) .safeParse(credentials) @@ -75,7 +75,8 @@ export const authOptions = { const authUser = await getAuthUserByEmail(email) if (!authUser) { - if (!firstName || !lastName) throw new Error('First and last name required') + if (!firstName || !lastName) + throw new Error(`Could not find an account with that email`) const hashedPassword = await bcrypt.hash(password, 10) const newAuthUser = await createAuthUser({ firstName, @@ -91,9 +92,13 @@ export const authOptions = { const passwordsMatch = await bcrypt.compare(password, authUser.password!) if (passwordsMatch) return authUser + throw new Error('Email or password is invalid') + } else { + const errorMessages = parsedCredentials.error.issues.map( + (issue) => issue.message + ) + throw new Error(errorMessages.join(', ')) } - - return null }, }), ], @@ -104,6 +109,7 @@ export const authOptions = { token['https://maybe.co/email'] = authUser.email token.firstName = authUser.firstName token.lastName = authUser.lastName + token.name = authUser.name } return token }, @@ -113,6 +119,7 @@ export const authOptions = { session['https://maybe.co/email'] = token['https://maybe.co/email'] session.firstName = token.firstName session.lastName = token.lastName + session.name = token.name return session }, }, diff --git a/apps/client/pages/login.tsx b/apps/client/pages/login.tsx index b45d1fc3..f29ab664 100644 --- a/apps/client/pages/login.tsx +++ b/apps/client/pages/login.tsx @@ -11,6 +11,7 @@ export default function LoginPage() { const [email, setEmail] = useState('') const [password, setPassword] = useState('') const [isValid, setIsValid] = useState(false) + const [errorMessage, setErrorMessage] = useState(null) const { data: session } = useSession() const router = useRouter() @@ -21,13 +22,18 @@ export default function LoginPage() { const onSubmit = async (e: React.FormEvent) => { e.preventDefault() - setEmail('') + setErrorMessage(null) setPassword('') - await signIn('credentials', { + + const response = await signIn('credentials', { email, password, redirect: false, }) + + if (response && response.error) { + setErrorMessage(response.error) + } } // _app.tsx will automatically redirect if not authenticated @@ -70,6 +76,12 @@ export default function LoginPage() { } /> + {errorMessage && password.length === 0 ? ( +
+ {errorMessage} +
+ ) : null} +