Authentication
Learn how to implement authentication in Supastart.
Authentication
Supastart provides a comprehensive authentication system powered by Supabase Auth with built-in security features, activity logging, and form validation.
Authentication Provider
Supastart uses Supabase Auth for user management with these key features:
- Email/password authentication
- Google OAuth integration
- Password reset flow
- Email verification
- Session management with automatic refresh
- Protected routes
Authentication Flows
Sign Up Flow
- User registers with email/password or Google OAuth
- For email signup:
- Password is validated against security requirements
- User data is stored in Supabase Auth system
- Verification email is sent automatically
- User status is set to 'PENDING' until verified
- For Google OAuth:
- User is redirected to Google authentication
- Upon success, redirected back to
/auth/callback
- User is automatically verified and active
- Profile is created with 'ACTIVE' status
Sign In Flow
- User signs in with email/password or Google
- Credentials are validated by Supabase
- On success:
- User session is created
- Auth provider context is updated
- User is redirected to the dashboard
- Failed attempts are logged and appropriate error messages displayed
Password Reset Flow
- User requests password reset
- System sends reset email with Supabase-generated link
- User clicks link which redirects to
/auth/callback?type=recovery
- Callback route validates and creates a session
- User is redirected to change password page
- After password change, user is directed to sign in
Password Requirements
Supastart enforces strong password requirements:
- Minimum 8 characters
- At least one uppercase letter
- At least one lowercase letter
- At least one number
- At least one special character (
!@#$%^&*(),.?":{}|<>
)
Form Validation
Login Schema
// app/(auth)/forms/signin-schema.ts
export const getSigninSchema = () => {
return z.object({
email: z
.string()
.email({ message: 'Please enter a valid email address.' })
.min(1, { message: 'Email is required.' }),
password: z
.string()
.min(1, { message: 'Password is required.' }),
rememberMe: z.boolean().optional(),
});
};
Registration Schema
// app/(auth)/forms/signup-schema.ts
export const getSignupSchema = () => {
return z
.object({
name: z
.string()
.min(2, { message: 'Name must be at least 2 characters long.' })
.min(1, { message: 'Name is required.' }),
email: z
.string()
.email({ message: 'Please enter a valid email address.' })
.min(1, { message: 'Email is required.' }),
password: getPasswordSchema(), // Enforces strong password requirements
passwordConfirmation: z.string().min(1, {
message: 'Password confirmation is required.',
}),
accept: z.boolean().refine((val) => val === true, {
message: 'You must accept the terms and conditions.',
}),
})
.refine((data) => data.password === data.passwordConfirmation, {
message: 'Passwords do not match.',
path: ['passwordConfirmation'],
});
};
Password Schema
// app/(auth)/forms/password-schema.ts
export const getPasswordSchema = (minLength = 8) => {
return z
.string()
.min(minLength, {
message: `Password must be at least ${minLength} characters long.`,
})
.regex(/[A-Z]/, {
message: 'Password must contain at least one uppercase letter.',
})
.regex(/[a-z]/, {
message: 'Password must contain at least one lowercase letter.',
})
.regex(/\d/, {
message: 'Password must contain at least one number.',
})
.regex(/[!@#$%^&*(),.?":{}|<>]/, {
message: 'Password must contain at least one special character.',
});
};
Authentication Components
Login Form Features
- Email/Password login
- Google OAuth integration
- Remember Me functionality
- Password visibility toggle
- Forgot password link
- Real-time validation
- Responsive error handling
Registration Form Features
- Name, Email, Password fields
- Password strength requirements and validation
- Password confirmation
- Google OAuth signup option
- Terms and conditions acceptance
- Password visibility toggles
- Automatic email verification flow
Setting Up Google Authentication
Supastart provides Google authentication integration using Supabase Auth. Follow these steps to set up Google authentication in your project:
Google OAuth Configuration
-
Create a Google Cloud Project
- Go to the Google Cloud Console
- Create a new project or select an existing one
- Navigate to "APIs & Services" > "Credentials"
-
Configure OAuth Consent Screen
- Go to "OAuth consent screen" tab
- Select "External" as the user type
- Fill in required app information
- Add your Supabase project's domain (
<PROJECT_ID>.supabase.co
) under "Authorized domains" - Configure the following non-sensitive scopes:
.../auth/userinfo.email
.../auth/userinfo.profile
openid
-
Create OAuth Credentials
- Go to "Credentials" tab
- Click "Create credentials" and choose "OAuth Client ID"
- Select "Web application" as the application type
- Add your site URL under "Authorized JavaScript origins"
- Add the Supabase callback URL from your Supabase dashboard under "Authorized redirect URLs"
- The callback URL will be in format:
https://[YOUR_SUPABASE_PROJECT_ID].supabase.co/auth/v1/callback
-
Add Credentials to Supabase
- In the Supabase dashboard, go to "Authentication" > "Providers"
- Enable Google provider
- Add your Google OAuth Client ID and Client Secret
-
Update Environment Variables
- Add Google credentials to your
.env.local
file:
# Google OAuth GOOGLE_CLIENT_ID=your-google-client-id GOOGLE_CLIENT_SECRET=your-google-client-secret CALLBACK_URL=https://[YOUR_SUPABASE_PROJECT_REF].supabase.co/auth/v1/callback
- Add Google credentials to your
Implementing Google Sign-In
Supastart implements Google authentication in two ways:
1. Standard OAuth Flow
This implementation uses Supabase's built-in OAuth methods:
// Sign in with Google using OAuth
const signInWithGoogle = async () => {
const { data, error } = await supabase.auth.signInWithOAuth({
provider: 'google',
options: {
redirectTo: `${window.location.origin}/auth/callback`,
},
});
if (error) {
console.error('Google sign-in error:', error);
// Handle error
}
};
2. Auth Callback Handler
Supastart includes an auth callback handler in src/app/auth/callback/route.ts
that processes OAuth redirects:
// src/app/auth/callback/route.ts (simplified)
export async function GET(request: NextRequest) {
const requestUrl = new URL(request.url);
const code = requestUrl.searchParams.get('code');
const type = requestUrl.searchParams.get('type');
// Create Supabase client
const cookieStore = cookies();
const supabase = createRouteHandlerClient({ cookies: () => cookieStore });
// Handle PKCE flow with code exchange
if (code) {
const { data, error } = await supabase.auth.exchangeCodeForSession(code);
// If user signed in with Google, update profile
if (data?.user?.app_metadata?.provider === 'google') {
await supabase
.from('profiles')
.upsert({
id: data.user.id,
status: 'active'
}, {
onConflict: 'id'
});
}
}
// Redirect based on auth flow type
if (type === 'recovery') {
return NextResponse.redirect(new URL('/change-password', request.url));
} else if (type === 'signup') {
return NextResponse.redirect(new URL('/verify-email', request.url));
} else {
return NextResponse.redirect(new URL('/dashboard', request.url));
}
}
Google Sign-In Button Component
Supastart provides a pre-styled Google sign-in button component:
// OAuth button component example
export function GoogleSignInButton({ onClick }: { onClick: () => void }) {
return (
<Button
variant="outline"
type="button"
onClick={onClick}
className="flex items-center justify-center gap-2 w-full"
>
<Image
src="/media/svg/google-icon.svg"
alt="Google"
width={20}
height={20}
/>
<span>Continue with Google</span>
</Button>
);
}
Usage in Forms
The Google Sign-In button is incorporated into both login and registration forms:
// Usage in login form
<div className="flex flex-col gap-3 mt-8">
<GoogleSignInButton onClick={handleGoogleSignIn} />
<div className="relative flex items-center gap-4">
<div className="h-px flex-grow bg-[#E1E3EA]" />
<div className="text-muted-foreground text-sm">or</div>
<div className="h-px flex-grow bg-[#E1E3EA]" />
</div>
</div>
Error Handling
Supastart provides user-friendly error messages and comprehensive error logging for authentication events:
// Error handling in sign-in logic
if (error) {
console.error('Sign-in error details:', error);
setError(error.message);
return;
}
// Error handling in Google auth
if (error) {
console.error('Google sign-in error:', error);
setError(error.message);
}
Activity Logging
All authentication events are securely logged:
- Login attempts (success/failure)
- Signup events
- Google OAuth actions
- Password reset requests
- Password changes
- Logout events
// Example of authentication logging
await AuthLogger.logLoginSuccess(data.session.user, ip);
await AuthLogger.logSignupSuccess(data.user, ip);
await AuthLogger.logPasswordResetRequest(email, ip);
Session Management
The AuthProvider component maintains the authentication state:
export type AuthContextProps = {
user: User | null;
session: Session | null;
hasInitialized: boolean;
isLoading: boolean;
signOut: () => Promise<void>;
};
Security Features
-
Password Security
- Supabase secure password hashing
- Strong password requirements
- Password visibility toggle
- Password confirmation validation
-
Email Security
- Email verification required for new accounts
- Secure password reset flow
- Email templates with security best practices
-
OAuth Security
- Secure state validation
- Email account linking
- Profile data syncing
- Profile status management
-
API Security
- Protected routes with session validation
- Rate limiting
- CSRF protection
- Activity logging with IP tracking
User Invitation
For admin-initiated user creation:
const { data, error } = await supabase.auth.admin.createUser({
email,
password: tempPassword,
email_confirm: false,
user_metadata: {
full_name: name || ''
}
});
// Send an invitation email
const { error: resetError } = await supabase.auth.admin.inviteUserByEmail(email);