Skip to main content
Documentation menu

Authentication

Learn how to set up and use authentication with Better Auth in MinuteShip

MinuteShip uses Better Auth for authentication, a TypeScript-native authentication library.

Setup

Environment Variables

Generate a random secret and add it to your environment variables file:

openssl rand -base64 32

.env

BETTER_AUTH_SECRET=your_generated_secret

Website Configuration

In most cases, the default configuration works fine. If you need to change it, modify the auth config in src/config/website.ts:

export const websiteConfig: WebsiteConfig = {
  // ...
  auth: {
    enable: true,
    enableGoogleLogin: true,     // Enable Google login
    enableCredentialLogin: true, // Enable email/password login
    enableDeleteAccount: true,   // Allow users to delete their account
  },
  // ...
};
OptionTypeDefaultDescription
enablebooleantrueEnable/disable authentication
enableGoogleLoginbooleantrueEnable Google OAuth login
enableCredentialLoginbooleantrueEnable email/password login
enableDeleteAccountbooleantrueAllow users to delete their account

Google OAuth (Optional)

If Google login is enabled, you need to configure Google OAuth:

  1. Go to Google Cloud Console
  2. Create a new project
  3. Go to APIs & Services > Credentials
  4. Click Create Credentials > OAuth client ID
  5. Configure the consent screen if prompted
  6. Select Web application as the application type
  7. Add http://localhost:3000 and https://your-domain.com to Authorized JavaScript origins
  8. Add http://localhost:3000/api/auth/callback/google and https://your-domain.com/api/auth/callback/google to Authorized redirect URIs
  9. Copy the Client ID and Client Secret to your environment variables file:

.env

GOOGLE_CLIENT_ID=your_google_client_id
GOOGLE_CLIENT_SECRET=your_google_client_secret

Note

If you are setting up your environment, you can now go back to the Environment Configuration and continue. The rest of this document can be read later.

Google One Tap (Optional)

Google One Tap shows Google's account chooser to signed-out visitors, so they can sign in from any page without opening the login page first. It reuses the OAuth client configured above and turns on as soon as VITE_GOOGLE_CLIENT_ID is set.

.env

GOOGLE_CLIENT_ID=your_google_client_id
GOOGLE_CLIENT_SECRET=your_google_client_secret
VITE_GOOGLE_CLIENT_ID=your_google_client_id

VITE_* values are compiled into the browser bundle at build time, so rebuild after changing them. The client ID is public and must match GOOGLE_CLIENT_ID.

The client options live in src/auth/client.ts:

oneTapClient({
  clientId: clientEnv.VITE_GOOGLE_CLIENT_ID ?? '',
  autoSelect: false,
  cancelOnTapOutside: true,
}),
  • clientId: public OAuth client ID. An empty value skips the prompt.
  • autoSelect: false: the visitor must confirm an account, so the prompt never signs anyone in silently.
  • cancelOnTapOutside: true: clicking outside the prompt dismisses it.

The server plugin in src/auth/auth.ts is registered only when enableGoogleLogin, GOOGLE_CLIENT_ID, and GOOGLE_CLIENT_SECRET are all set. GoogleOneTap in the root layout prompts once per page load for visitors without a session, then redirects to /dashboard; if the prompt fails, the Google button on the login page still works.

To keep Google login but drop the prompt, unset VITE_GOOGLE_CLIENT_ID and rebuild.


Verification Emails and Production Secrets

Production requires a unique random BETTER_AUTH_SECRET of at least 32 characters. Environment validation rejects the default better-auth-secret and shorter values. Upload the secret to the Worker before release; see Deployment.

Signup success does not guarantee email delivery. Signup and unverified-login forms offer verification-email resend. Accepted requests start a 60-second button cooldown; delivery failures display an error and allow retrying. Verification and password-reset emails attempt delivery up to three times, 250 ms apart. Password reset returns the same response for missing accounts and send failures. Verify delivery and links in a real inbox separately; see Email.

Authentication Architecture

The authentication system in MinuteShip consists of the following components:

  • src/
    • auth/
      • auth.ts: Better Auth server configuration
      • client.ts: Better Auth client configuration
      • types.ts: Authentication type definitions
    • components/
      • auth/: Authentication related components
    • routes/
      • auth/
        • login.tsx: Login page
        • register.tsx: Registration page
        • forgot-password.tsx: Forgot password page
        • reset-password.tsx: Reset password page
    • middlewares/
      • auth-middleware.ts: Auth middleware
      • admin-middleware.ts: Admin middleware

Auth Routes

MinuteShip provides the following authentication routes:

RouteDescription
/auth/loginLogin page
/auth/registerRegistration page
/auth/forgot-passwordPassword reset request
/auth/reset-passwordPassword reset form
/auth/errorError page

References

Next Steps

Now that you understand how authentication works in MinuteShip, you might want to explore these related features: