@bettercone/ui
GuidesAuthentication

Email & Password

Email and password authentication in BetterCone

Email and password authentication is the most common authentication method, enabled by default in BetterCone.

Sign Up

Create a new user account with email and password:

const { data, error } = await authClient.signUp.email({
  email: "user@example.com",
  password: "securePassword123",
  name: "John Doe",
  // Optional custom fields
  company: "My Company",
  phone: "+1234567890",
});

if (error) {
  console.error("Sign up failed:", error);
  return;
}

console.log("User created:", data.user);

Password Requirements

By default, Better Auth requires:

  • Minimum 8 characters
  • At least one uppercase letter
  • At least one lowercase letter
  • At least one number

You can customize these requirements in the auth configuration.

Sign In

Authenticate existing users:

const { data, error } = await authClient.signIn.email({
  email: "user@example.com",
  password: "securePassword123",
});

if (error) {
  console.error("Sign in failed:", error);
  return;
}

console.log("Signed in:", data.user);

Forgot Password

Send a password reset link to the user's email:

const { data, error } = await authClient.forgetPassword({
  email: "user@example.com",
  redirectTo: "/reset-password", // Where to redirect after clicking link
});

if (error) {
  console.error("Password reset failed:", error);
  return;
}

console.log("Password reset email sent");

Email Configuration

Configure the password reset email in your auth setup:

emailAndPassword: {
  enabled: true,
  sendResetPassword: async ({ user, url }) => {
    // Send email using your email service (Resend, SendGrid, etc.)
    await sendEmail({
      to: user.email,
      subject: "Reset your password",
      html: `
        <p>Click the link below to reset your password:</p>
        <a href="${url}">Reset Password</a>
      `,
    });
  },
}

Reset Password

After clicking the reset link, allow users to set a new password:

const { data, error } = await authClient.resetPassword({
  newPassword: "newSecurePassword123",
});

if (error) {
  console.error("Password reset failed:", error);
  return;
}

console.log("Password reset successful");

Change Password

Authenticated users can change their password:

const { data, error } = await authClient.changePassword({
  currentPassword: "oldPassword",
  newPassword: "newPassword123",
  revokeOtherSessions: true, // Optional: sign out other devices
});

if (error) {
  console.error("Password change failed:", error);
  return;
}

console.log("Password changed successfully");

Email Verification

Enable Email Verification

For production, enable email verification:

emailAndPassword: {
  enabled: true,
  requireEmailVerification: true,
}

Send Verification Email

const { data, error } = await authClient.sendVerificationEmail({
  email: "user@example.com",
  callbackURL: "/verify-email",
});

Verify Email

const { data, error } = await authClient.verifyEmail({
  token: verificationToken, // From email link
});

UI Components

BetterCone uses pre-built components from @daveyplate/better-auth-ui:

Sign Up Page

import { AuthView } from "@daveyplate/better-auth-ui";

export default function SignUpPage() {
  return (
    <div className="min-h-screen flex items-center justify-center">
      <div className="w-full max-w-md">
        <AuthView view="SIGN_UP" />
      </div>
    </div>
  );
}

Sign In Page

import { AuthView } from "@daveyplate/better-auth-ui";

export default function SignInPage() {
  return (
    <div className="min-h-screen flex items-center justify-center">
      <div className="w-full max-w-md">
        <AuthView view="SIGN_IN" />
      </div>
    </div>
  );
}

Forgot Password Page

import { AuthView } from "@daveyplate/better-auth-ui";

export default function ForgotPasswordPage() {
  return (
    <div className="min-h-screen flex items-center justify-center">
      <div className="w-full max-w-md">
        <AuthView view="FORGET_PASSWORD" />
      </div>
    </div>
  );
}

Error Handling

Handle common authentication errors:

const { data, error } = await authClient.signIn.email({
  email: "user@example.com",
  password: "password",
});

if (error) {
  switch (error.code) {
    case "INVALID_CREDENTIALS":
      console.error("Email or password is incorrect");
      break;
    case "EMAIL_NOT_VERIFIED":
      console.error("Please verify your email first");
      break;
    case "USER_NOT_FOUND":
      console.error("No account found with this email");
      break;
    default:
      console.error("Authentication failed:", error.message);
  }
}

Best Practices

  1. Use strong passwords - Enforce minimum requirements
  2. Enable email verification in production
  3. Rate limit sign-up and sign-in attempts
  4. Sanitize inputs - validate email format
  5. Secure password reset - use short-lived tokens
  6. Log authentication events for security auditing
  7. Inform users of password changes via email

Next Steps

Continue exploring authentication options: