How email and password authentication works in this template.
Users can:
- Sign up with email and password
- Sign in with email and password
- Request password resets (via Resend email)
- Verify their email addresses
The auth factory (backend/src/lib/auth.ts) configures email/password:
emailAndPassword: {
enabled: true,
requireEmailVerification: true,
minPasswordLength: 8,
maxPasswordLength: 128,
sendResetPassword: async ({ user, url }) => {
await sendEmail({ to: user.email, subject: "Reset your password", ... }, emailEnv);
},
resetPasswordTokenExpiresIn: 3600, // 1 hour
}import { authClient } from '@/lib/auth.client';
const result = await authClient.signUp.email({
email: "user@example.com",
password: "testpassword123",
name: "Test User",
});const result = await authClient.signIn.email({
email: "user@example.com",
password: "testpassword123",
});- Minimum length: 8 characters
- Maximum length: 128 characters
- Stored using scrypt hashing (OWASP recommended)
Emails are sent via Resend using raw fetch (no SDK, works on all runtimes).
Development: If RESEND_API_KEY is not set, emails are skipped with a console warning. Check backend logs for verification links and OTP codes.
Production: Set RESEND_API_KEY and RESEND_FROM_EMAIL in your environment.
Better Auth provides these automatically:
| Endpoint | Method | Description |
|---|---|---|
/api/auth/sign-up/email |
POST | Create account |
/api/auth/sign-in/email |
POST | Sign in |
/api/auth/sign-out |
POST | Sign out |
/api/auth/forget-password |
POST | Request reset email |
/api/auth/reset-password |
POST | Reset with token |
/api/auth/send-verification-email |
POST | Send verify email |
/api/auth/verify-email |
POST | Verify with token |
Email/password uses Better Auth's standard tables:
user— Stores profile (id, email, name, image)account— Stores credentials (providerId: "credential", password hash)session— Manages user sessions
- Password Hashing: scrypt algorithm (OWASP recommended)
- Email Verification: Required before sign-in
- Secure Cookies: HTTP-only, secure in production
- CORS Protection: Trusted origins only
- Start backend:
cd backend && bun run dev - Start frontend:
cd frontend && bun run dev - Open http://localhost:4000
- Click "Sign in" → "Sign up"
- Create account with email/password
- Check backend console for verification email (dev mode)
- Check backend logs for errors
- Ensure email is not already registered
- Verify database is running
- Check email and password are correct
- If email verification is required, verify email first
- Check
RESEND_API_KEYis set - In dev mode, check backend console for verification link
- Verify sender email domain is configured in Resend