Email/Password
Traditional email and password authentication with verification
Email/password authentication is the primary method for user registration. It includes email verification via OTP and password reset functionality.
Registration Flow
User submits registration form
The form collects first name, last name, email, and password.
Backend validates and creates account
Input is validated, password is hashed, and a verification OTP is generated.
Verification email sent
A 6-digit code is sent to the user's email address.
User verifies email
User enters the OTP code to complete registration.
Profile created and tokens issued
User profile is created with an auto-generated username. JWT tokens are returned.
Password Requirements
| Requirement | Description |
|---|---|
| Length | Minimum 8 characters |
| Uppercase | At least one uppercase letter (A-Z) |
| Lowercase | At least one lowercase letter (a-z) |
| Number | At least one digit (0-9) |
| Special | At least one special character (!@#$%^&*) |
For detailed API documentation including request/response examples, see the Auth Endpoints reference.
Frontend Implementation
Registration Form
import { useCreateAccount } from '@/hooks/auth/useAuthMutations';
import { useRouter } from 'next/navigation';
function RegistrationForm() {
const router = useRouter();
const createAccount = useCreateAccount();
const handleSubmit = async (data: CreateAccountData) => {
createAccount.mutate(data, {
onSuccess: (response) => {
// Store email for verification page
sessionStorage.setItem('pendingEmail', data.email);
router.push('/email-verification');
},
});
};
return (
<form onSubmit={handleSubmit}>
{/* Form fields */}
</form>
);
}Login Form
import { useLogin } from '@/hooks/auth/useAuthMutations';
import { useAuth } from '@/providers/auth-provider';
function LoginForm() {
const { login: setAuth } = useAuth();
const loginMutation = useLogin();
const handleSubmit = async (data: LoginData) => {
loginMutation.mutate(data, {
onSuccess: (response) => {
const { accessToken, refreshToken, session, user } = response.data;
setAuth(accessToken, refreshToken, user, {
sessionId: session.sessionId,
});
router.push('/dashboard');
},
});
};
}Password Reset
import { useForgotPassword, useResetPassword } from '@/hooks/auth/useAuthMutations';
function ForgotPasswordForm() {
const forgotPassword = useForgotPassword();
const handleSubmit = (email: string) => {
forgotPassword.mutate({ email }, {
onSuccess: () => {
router.push(`/reset-password?email=${encodeURIComponent(email)}`);
},
});
};
}
function ResetPasswordForm({ email }: { email: string }) {
const resetPassword = useResetPassword();
const handleSubmit = (data: ResetPasswordData) => {
resetPassword.mutate({ ...data, email }, {
onSuccess: () => {
router.push('/log-in');
},
});
};
}Validation Schemas
The registration and login forms use Zod schemas for validation:
import { z } from 'zod';
export const createAccountSchema = z.object({
firstName: z.string().min(1).max(20),
lastName: z.string().min(1).max(20),
email: z.string().email(),
password: z.string()
.min(8)
.regex(/[A-Z]/, 'Must contain uppercase letter')
.regex(/[a-z]/, 'Must contain lowercase letter')
.regex(/[0-9]/, 'Must contain number')
.regex(/[!@#$%^&*]/, 'Must contain special character'),
confirmPassword: z.string(),
}).refine((data) => data.password === data.confirmPassword, {
message: 'Passwords do not match',
path: ['confirmPassword'],
});
export const loginSchema = z.object({
email: z.string().email(),
password: z.string().min(8),
});