mirror of
https://github.com/maybe-finance/maybe.git
synced 2025-08-09 07:25:19 +02:00
add basic error messages for login and register
This commit is contained in:
parent
18a8d7a455
commit
6323495738
3 changed files with 38 additions and 7 deletions
|
@ -64,7 +64,7 @@ export const authOptions = {
|
||||||
.object({
|
.object({
|
||||||
firstName: z.string().optional(),
|
firstName: z.string().optional(),
|
||||||
lastName: z.string().optional(),
|
lastName: z.string().optional(),
|
||||||
email: z.string().email(),
|
email: z.string().email({ message: 'Invalid email address' }),
|
||||||
password: z.string().min(6),
|
password: z.string().min(6),
|
||||||
})
|
})
|
||||||
.safeParse(credentials)
|
.safeParse(credentials)
|
||||||
|
@ -75,7 +75,8 @@ export const authOptions = {
|
||||||
const authUser = await getAuthUserByEmail(email)
|
const authUser = await getAuthUserByEmail(email)
|
||||||
|
|
||||||
if (!authUser) {
|
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 hashedPassword = await bcrypt.hash(password, 10)
|
||||||
const newAuthUser = await createAuthUser({
|
const newAuthUser = await createAuthUser({
|
||||||
firstName,
|
firstName,
|
||||||
|
@ -91,9 +92,13 @@ export const authOptions = {
|
||||||
|
|
||||||
const passwordsMatch = await bcrypt.compare(password, authUser.password!)
|
const passwordsMatch = await bcrypt.compare(password, authUser.password!)
|
||||||
if (passwordsMatch) return authUser
|
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['https://maybe.co/email'] = authUser.email
|
||||||
token.firstName = authUser.firstName
|
token.firstName = authUser.firstName
|
||||||
token.lastName = authUser.lastName
|
token.lastName = authUser.lastName
|
||||||
|
token.name = authUser.name
|
||||||
}
|
}
|
||||||
return token
|
return token
|
||||||
},
|
},
|
||||||
|
@ -113,6 +119,7 @@ export const authOptions = {
|
||||||
session['https://maybe.co/email'] = token['https://maybe.co/email']
|
session['https://maybe.co/email'] = token['https://maybe.co/email']
|
||||||
session.firstName = token.firstName
|
session.firstName = token.firstName
|
||||||
session.lastName = token.lastName
|
session.lastName = token.lastName
|
||||||
|
session.name = token.name
|
||||||
return session
|
return session
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
|
|
@ -11,6 +11,7 @@ export default function LoginPage() {
|
||||||
const [email, setEmail] = useState('')
|
const [email, setEmail] = useState('')
|
||||||
const [password, setPassword] = useState('')
|
const [password, setPassword] = useState('')
|
||||||
const [isValid, setIsValid] = useState(false)
|
const [isValid, setIsValid] = useState(false)
|
||||||
|
const [errorMessage, setErrorMessage] = useState<string | null>(null)
|
||||||
|
|
||||||
const { data: session } = useSession()
|
const { data: session } = useSession()
|
||||||
const router = useRouter()
|
const router = useRouter()
|
||||||
|
@ -21,13 +22,18 @@ export default function LoginPage() {
|
||||||
|
|
||||||
const onSubmit = async (e: React.FormEvent<HTMLFormElement>) => {
|
const onSubmit = async (e: React.FormEvent<HTMLFormElement>) => {
|
||||||
e.preventDefault()
|
e.preventDefault()
|
||||||
setEmail('')
|
setErrorMessage(null)
|
||||||
setPassword('')
|
setPassword('')
|
||||||
await signIn('credentials', {
|
|
||||||
|
const response = await signIn('credentials', {
|
||||||
email,
|
email,
|
||||||
password,
|
password,
|
||||||
redirect: false,
|
redirect: false,
|
||||||
})
|
})
|
||||||
|
|
||||||
|
if (response && response.error) {
|
||||||
|
setErrorMessage(response.error)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// _app.tsx will automatically redirect if not authenticated
|
// _app.tsx will automatically redirect if not authenticated
|
||||||
|
@ -70,6 +76,12 @@ export default function LoginPage() {
|
||||||
}
|
}
|
||||||
/>
|
/>
|
||||||
|
|
||||||
|
{errorMessage && password.length === 0 ? (
|
||||||
|
<div className="py-1 text-center text-red text-sm">
|
||||||
|
{errorMessage}
|
||||||
|
</div>
|
||||||
|
) : null}
|
||||||
|
|
||||||
<Button
|
<Button
|
||||||
type="submit"
|
type="submit"
|
||||||
disabled={!isValid}
|
disabled={!isValid}
|
||||||
|
|
|
@ -13,6 +13,7 @@ export default function RegisterPage() {
|
||||||
const [email, setEmail] = useState('')
|
const [email, setEmail] = useState('')
|
||||||
const [password, setPassword] = useState('')
|
const [password, setPassword] = useState('')
|
||||||
const [isValid, setIsValid] = useState(false)
|
const [isValid, setIsValid] = useState(false)
|
||||||
|
const [errorMessage, setErrorMessage] = useState<string | null>(null)
|
||||||
|
|
||||||
const { data: session } = useSession()
|
const { data: session } = useSession()
|
||||||
const router = useRouter()
|
const router = useRouter()
|
||||||
|
@ -24,18 +25,23 @@ export default function RegisterPage() {
|
||||||
const onSubmit = async (e: React.FormEvent<HTMLFormElement>) => {
|
const onSubmit = async (e: React.FormEvent<HTMLFormElement>) => {
|
||||||
e.preventDefault()
|
e.preventDefault()
|
||||||
|
|
||||||
|
setErrorMessage(null)
|
||||||
setFirstName('')
|
setFirstName('')
|
||||||
setLastName('')
|
setLastName('')
|
||||||
setEmail('')
|
setEmail('')
|
||||||
setPassword('')
|
setPassword('')
|
||||||
|
|
||||||
await signIn('credentials', {
|
const response = await signIn('credentials', {
|
||||||
email,
|
email,
|
||||||
password,
|
password,
|
||||||
firstName,
|
firstName,
|
||||||
lastName,
|
lastName,
|
||||||
redirect: false,
|
redirect: false,
|
||||||
})
|
})
|
||||||
|
|
||||||
|
if (response && response.error) {
|
||||||
|
setErrorMessage(response.error)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// _app.tsx will automatically redirect if not authenticated
|
// _app.tsx will automatically redirect if not authenticated
|
||||||
|
@ -90,6 +96,12 @@ export default function RegisterPage() {
|
||||||
}
|
}
|
||||||
/>
|
/>
|
||||||
|
|
||||||
|
{errorMessage && password.length === 0 ? (
|
||||||
|
<div className="py-1 text-center text-red text-sm">
|
||||||
|
{errorMessage}
|
||||||
|
</div>
|
||||||
|
) : null}
|
||||||
|
|
||||||
<Button
|
<Button
|
||||||
type="submit"
|
type="submit"
|
||||||
disabled={!isValid}
|
disabled={!isValid}
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue