Authentication

Authentication is handled by remix-auth (opens in a new tab). It's follows the strategy pattern, which you may be familiar with from libraries like Passport.js (opens in a new tab), making it extremely flexible. The huge benefit of handling authentication in-house is that you are in full control over your user data and there is zero tangible cost to adding more users.

By default, authentication is handled with email and password combination, but it can be extended to use any OAuth provider. The app has pre-built implementations for GitHub and Google OAuth.

All authentication strategies are backed by session cookies which are stored in the sessions table in the database.

Registering new users

Users can register via email and password or via OAuth. Email and password signups involve an email verification step to ensure they are in control of the email account they're signing up with. Verification tokens live in the verification_tokens and are valid for 5 minutes.

Both OAuth and email/password users are stored in the users table. Email/password users will have their password one-way hashed and stored alongside a salt in the user_passwords table. OAuth users will have a new record added to the user_identities table.

By storing passwords and identities separately to the user records, it allows users to connect any number of OAuth accounts to their account to log in, as well as supporting email/password separately.

Password requirements

Password requirements are defined in the PasswordSchema variable in the app/services/auth/schemas.ts file. It is a zod schema so can be easily extended to add or remove any rules required.

By default, passwords must match the following conditions

  • Cannot contain whitespace
  • Must contain at least one number
  • Must contain at least one uppercase letter
  • Must contain at least one lowercase letter
  • Must contain at least one special character