diff --git a/app/(auth)/login/page.tsx b/app/(auth)/login/page.tsx index 8d0acf3ae7..12846ffdf3 100644 --- a/app/(auth)/login/page.tsx +++ b/app/(auth)/login/page.tsx @@ -16,15 +16,16 @@ import { import { Input } from '@/components/ui/input' import { Label } from '@/components/ui/label' import { client } from '@/lib/auth-client' +import { useNotificationStore } from '@/stores/notifications/store' +import { NotificationList } from '@/app/w/components/notifications/notifications' export default function LoginPage() { const router = useRouter() const [isLoading, setIsLoading] = useState(false) - const [error, setError] = useState('') + const { addNotification } = useNotificationStore() async function onSubmit(e: React.FormEvent) { e.preventDefault() - setError('') setIsLoading(true) const formData = new FormData(e.currentTarget) @@ -34,8 +35,27 @@ export default function LoginPage() { try { await client.signIn.email({ email, password }) router.push('/w/1') - } catch (err) { - setError('Invalid email or password') + } catch (err: any) { + let errorMessage = 'Invalid email or password' + + if (err.message?.includes('not verified')) { + errorMessage = + 'Please verify your email before signing in. Check your inbox for the verification link.' + } else if (err.message?.includes('not found')) { + errorMessage = 'No account found with this email. Please sign up first.' + } else if (err.message?.includes('invalid password')) { + errorMessage = 'Invalid password. Please try again or use the forgot password link.' + } else if (err.message?.includes('too many attempts')) { + errorMessage = 'Too many login attempts. Please try again later or reset your password.' + } else if (err.message?.includes('account locked')) { + errorMessage = 'Your account has been locked for security. Please reset your password.' + } else if (err.message?.includes('network')) { + errorMessage = 'Network error. Please check your connection and try again.' + } else if (err.message?.includes('rate limit')) { + errorMessage = 'Too many requests. Please wait a moment before trying again.' + } + + addNotification('error', errorMessage, null) } finally { setIsLoading(false) } @@ -44,21 +64,44 @@ export default function LoginPage() { async function signInWithGithub() { try { await client.signIn.social({ provider: 'github' }) - } catch (err) { - setError('Failed to sign in with GitHub') + } catch (err: any) { + let errorMessage = 'Failed to sign in with GitHub' + + if (err.message?.includes('account exists')) { + errorMessage = + 'An account with this email already exists. Please sign in with email instead.' + } else if (err.message?.includes('cancelled')) { + errorMessage = 'GitHub sign in was cancelled. Please try again.' + } else if (err.message?.includes('network')) { + errorMessage = 'Network error. Please check your connection and try again.' + } + + addNotification('error', errorMessage, null) } } async function signInWithGoogle() { try { await client.signIn.social({ provider: 'google' }) - } catch (err) { - setError('Failed to sign in with Google') + } catch (err: any) { + let errorMessage = 'Failed to sign in with Google' + + if (err.message?.includes('account exists')) { + errorMessage = + 'An account with this email already exists. Please sign in with email instead.' + } else if (err.message?.includes('cancelled')) { + errorMessage = 'Google sign in was cancelled. Please try again.' + } else if (err.message?.includes('network')) { + errorMessage = 'Network error. Please check your connection and try again.' + } + + addNotification('error', errorMessage, null) } } return (
+

Sim Studio

@@ -102,7 +145,6 @@ export default function LoginPage() {
- {error &&

{error}

} diff --git a/app/(auth)/signup/page.tsx b/app/(auth)/signup/page.tsx index 65da18f10a..2d9e63751b 100644 --- a/app/(auth)/signup/page.tsx +++ b/app/(auth)/signup/page.tsx @@ -37,13 +37,22 @@ export default function SignupPage() { await client.signUp.email({ email, password, name }) router.push('/verify-request') } catch (err: any) { - // Handle specific error messages - let errorMessage = 'Something went wrong. Please try again.' + let errorMessage = 'Failed to create account' if (err.message?.includes('Password is too short')) { errorMessage = 'Password must be at least 8 characters long' } else if (err.message?.includes('existing email')) { - errorMessage = 'An account with this email already exists' + errorMessage = 'An account with this email already exists. Please sign in instead.' + } else if (err.message?.includes('invalid email')) { + errorMessage = 'Please enter a valid email address' + } else if (err.message?.includes('password too long')) { + errorMessage = 'Password must be less than 128 characters' + } else if (err.message?.includes('rate limit')) { + errorMessage = 'Too many signup attempts. Please try again later.' + } else if (err.message?.includes('network')) { + errorMessage = 'Network error. Please check your connection and try again.' + } else if (err.message?.includes('invalid name')) { + errorMessage = 'Please enter a valid name' } addNotification('error', errorMessage, null) @@ -55,16 +64,40 @@ export default function SignupPage() { async function signUpWithGithub() { try { await client.signIn.social({ provider: 'github' }) - } catch (err) { - addNotification('error', 'Failed to sign up with GitHub', null) + } catch (err: any) { + let errorMessage = 'Failed to sign up with GitHub' + + if (err.message?.includes('account exists')) { + errorMessage = 'An account with this email already exists. Please sign in instead.' + } else if (err.message?.includes('cancelled')) { + errorMessage = 'GitHub sign up was cancelled. Please try again.' + } else if (err.message?.includes('network')) { + errorMessage = 'Network error. Please check your connection and try again.' + } else if (err.message?.includes('rate limit')) { + errorMessage = 'Too many attempts. Please try again later.' + } + + addNotification('error', errorMessage, null) } } async function signUpWithGoogle() { try { await client.signIn.social({ provider: 'google' }) - } catch (err) { - addNotification('error', 'Failed to sign up with Google', null) + } catch (err: any) { + let errorMessage = 'Failed to sign up with Google' + + if (err.message?.includes('account exists')) { + errorMessage = 'An account with this email already exists. Please sign in instead.' + } else if (err.message?.includes('cancelled')) { + errorMessage = 'Google sign up was cancelled. Please try again.' + } else if (err.message?.includes('network')) { + errorMessage = 'Network error. Please check your connection and try again.' + } else if (err.message?.includes('rate limit')) { + errorMessage = 'Too many attempts. Please try again later.' + } + + addNotification('error', errorMessage, null) } } diff --git a/lib/auth.ts b/lib/auth.ts index f82841240f..2f16c16aaa 100644 --- a/lib/auth.ts +++ b/lib/auth.ts @@ -6,11 +6,6 @@ import { Resend } from 'resend' import { db } from '@/db' import * as schema from '@/db/schema' -type EmailHandler = { - user: { email: string } - url: string -} - // If there is no resend key, it might be a local dev environment // In that case, we don't want to send emails and just log them const resend = process.env.RESEND_API_KEY @@ -35,8 +30,8 @@ export const auth = betterAuth({ emailAndPassword: { enabled: true, requireEmailVerification: true, - sendResetPassword: async ({ user, url }: EmailHandler) => { - await resend.emails.send({ + sendResetPassword: async ({ user, url, token }, request) => { + const result = await resend.emails.send({ from: 'Sim Studio ', to: user.email, subject: 'Reset your password', @@ -47,6 +42,10 @@ export const auth = betterAuth({

If you didn't request this, you can safely ignore this email.

`, }) + + if (!result) { + throw new Error('Failed to send reset password email') + } }, }, emailVerification: {