Authentication
Learn how to implement authentication in Supastart.
Overview
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
- Upon clicking the verification link, user is redirected to
/auth/callback?type=signup
endpoint
- For Google OAuth:
- User is redirected to Google authentication
- Upon success, redirected back to
/auth/callback
- Auth code is exchanged for session using Supabase Auth
- 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 with JWT tokens stored in cookies
- 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&token_hash=[HASH]
- Callback route validates token 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 using Supabase's recommended PKCE flow:
1. Client-Side OAuth Initiation
// Initiate Google sign-in with 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
Create a route handler at app/auth/callback/route.ts
to handle OAuth redirects:
// app/auth/callback/route.ts
import { NextResponse } from 'next/server';
import { createClient } from '@/utils/supabase/server';
export async function GET(request: Request) {
const { searchParams, origin } = new URL(request.url);
const code = searchParams.get('code');
const type = searchParams.get('type');
const next = searchParams.get('next') ?? '/dashboard';
if (code) {
const supabase = await createClient();
const { error } = await supabase.auth.exchangeCodeForSession(code);
if (!error) {
// If this is a signup or sign-in with Google, handle profile creation
if (type === 'signup') {
// Handle new user signup if needed
return NextResponse.redirect(`${origin}/verify-email`);
} else if (type === 'recovery') {
// Handle password recovery
return NextResponse.redirect(`${origin}/change-password`);
} else {
// Standard login or OAuth callback
return NextResponse.redirect(`${origin}${next}`);
}
}
}
// Return user to error page if code exchange fails
return NextResponse.redirect(`${origin}/auth/error`);
}
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>
);
}
Email Templates Customization
To properly handle authentication flows, you'll need to customize the email templates in your Supabase project:
- Navigate to your Supabase dashboard
- Go to Authentication > Email Templates
- Customize the following templates:
- Confirm signup: Change
{{ .ConfirmationURL }}
to{{ .SiteURL }}/auth/callback?token_hash={{ .TokenHash }}&type=signup
- Reset password: Change
{{ .ConfirmationURL }}
to{{ .SiteURL }}/auth/callback?token_hash={{ .TokenHash }}&type=recovery
- Confirm signup: Change
This ensures email verification and password reset flows correctly redirect to your application's callback handler.
Server-Side Authentication
Supastart uses modern server-side authentication patterns with Next.js:
// utils/supabase/server.ts
import { createServerClient } from '@supabase/ssr';
import { cookies } from 'next/headers';
export async function createClient() {
const cookieStore = cookies();
return createServerClient(
process.env.NEXT_PUBLIC_SUPABASE_URL!,
process.env.NEXT_PUBLIC_SUPABASE_ANON_KEY!,
{
cookies: {
get(name) {
return cookieStore.get(name)?.value;
},
set(name, value, options) {
cookieStore.set({ name, value, ...options });
},
remove(name, options) {
cookieStore.set({ name, value: '', ...options });
},
},
}
);
}
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 with token verification
- Customizable email templates with security best practices
-
OAuth Security
- PKCE flow for enhanced security
- State validation to prevent CSRF attacks
- Email account linking
- Profile data syncing
- Profile status management
-
API Security
- Cookie-based authentication with HttpOnly cookies
- 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);