Documentation Index
Fetch the complete documentation index at: https://docs.onlyautomator.com/llms.txt
Use this file to discover all available pages before exploring further.
OnlyAutomator’s authentication system is built on Supabase Auth, providing secure and flexible user authentication with multiple sign-in methods.
Authentication Flow
The system supports a seamless authentication process for users:
- Multiple Sign-in Methods: Email/password, Google OAuth, and magic links
- Secure Password Management: Hashed storage and robust password policies
- Session Management: Token-based authentication with configurable expiration
- Email Verification: Automated verification for new email accounts
- Password Recovery: Self-service password reset functionality
Authentication flow with Supabase
Authentication Methods
Email Authentication
Standard email and password authentication with security features:
// Sign up with email/password
const signUp = async (email: string, password: string) => {
try {
const { data, error } = await supabase.auth.signUp({
email,
password,
});
if (error) throw error;
return data;
} catch (error) {
console.error('Error signing up:', error);
throw error;
}
};
// Sign in with email/password
const signIn = async (email: string, password: string) => {
try {
const { data, error } = await supabase.auth.signInWithPassword({
email,
password,
});
if (error) throw error;
return data;
} catch (error) {
console.error('Error signing in:', error);
throw error;
}
};
OAuth Authentication
Integration with Google OAuth for simplified sign-in:
// Sign in with Google
const signInWithGoogle = async () => {
try {
const { data, error } = await supabase.auth.signInWithOAuth({
provider: 'google',
options: {
redirectTo: `${window.location.origin}/auth/callback`,
},
});
if (error) throw error;
return data;
} catch (error) {
console.error('Error signing in with Google:', error);
throw error;
}
};
Magic Link Authentication
Passwordless authentication via email magic links:
// Sign in with magic link
const signInWithMagicLink = async (email: string) => {
try {
const { data, error } = await supabase.auth.signInWithOtp({
email,
options: {
emailRedirectTo: `${window.location.origin}/auth/callback`,
},
});
if (error) throw error;
return data;
} catch (error) {
console.error('Error sending magic link:', error);
throw error;
}
};
Session Management
OnlyAutomator handles user sessions through Supabase’s session API:
// Get current session
const getSession = async () => {
try {
const { data, error } = await supabase.auth.getSession();
if (error) throw error;
return data.session;
} catch (error) {
console.error('Error getting session:', error);
return null;
}
};
// Sign out
const signOut = async () => {
try {
const { error } = await supabase.auth.signOut();
if (error) throw error;
} catch (error) {
console.error('Error signing out:', error);
throw error;
}
};
User Profile Management
The authentication system also handles user profile data:
// Get user profile data
const getUserProfile = async (userId: string) => {
try {
const { data, error } = await supabase
.from('profiles')
.select('*')
.eq('id', userId)
.single();
if (error) throw error;
return data;
} catch (error) {
console.error('Error fetching user profile:', error);
throw error;
}
};
// Update user profile
const updateUserProfile = async (userId: string, updates: Partial<Profile>) => {
try {
const { data, error } = await supabase
.from('profiles')
.update(updates)
.eq('id', userId)
.select()
.single();
if (error) throw error;
return data;
} catch (error) {
console.error('Error updating user profile:', error);
throw error;
}
};
Row-Level Security (RLS)
Supabase provides Row-Level Security for data protection:
-- Example RLS policy for the profiles table
CREATE POLICY "Users can view their own profile"
ON profiles
FOR SELECT
USING (auth.uid() = id);
CREATE POLICY "Users can update their own profile"
ON profiles
FOR UPDATE
USING (auth.uid() = id);
Authentication Context
A React Context provides authentication state throughout the application:
// Auth context definition
import { createContext, useContext, useEffect, useState } from 'react';
import { User, Session } from '@supabase/supabase-js';
import { supabase } from '@/lib/supabase';
interface AuthContextType {
user: User | null;
session: Session | null;
loading: boolean;
signUp: (email: string, password: string) => Promise<any>;
signIn: (email: string, password: string) => Promise<any>;
signInWithGoogle: () => Promise<any>;
signInWithMagicLink: (email: string) => Promise<any>;
signOut: () => Promise<void>;
}
const AuthContext = createContext<AuthContextType | undefined>(undefined);
export function AuthProvider({ children }: { children: React.ReactNode }) {
const [user, setUser] = useState<User | null>(null);
const [session, setSession] = useState<Session | null>(null);
const [loading, setLoading] = useState(true);
useEffect(() => {
// Get initial session
supabase.auth.getSession().then(({ data: { session } }) => {
setSession(session);
setUser(session?.user ?? null);
setLoading(false);
});
// Listen for auth changes
const { data: { subscription } } = supabase.auth.onAuthStateChange(
(_event, session) => {
setSession(session);
setUser(session?.user ?? null);
setLoading(false);
}
);
return () => subscription.unsubscribe();
}, []);
const value = {
user,
session,
loading,
signUp: (email: string, password: string) =>
supabase.auth.signUp({ email, password }),
signIn: (email: string, password: string) =>
supabase.auth.signInWithPassword({ email, password }),
signInWithGoogle: () =>
supabase.auth.signInWithOAuth({
provider: 'google',
options: { redirectTo: `${window.location.origin}/auth/callback` }
}),
signInWithMagicLink: (email: string) =>
supabase.auth.signInWithOtp({
email,
options: { emailRedirectTo: `${window.location.origin}/auth/callback` }
}),
signOut: () => supabase.auth.signOut(),
};
return (
<AuthContext.Provider value={value}>
{children}
</AuthContext.Provider>
);
}
export const useAuth = () => {
const context = useContext(AuthContext);
if (context === undefined) {
throw new Error('useAuth must be used within an AuthProvider');
}
return context;
};
Protected Routes
Routes can be protected based on authentication status:
// Protected route component
import { useRouter } from 'next/router';
import { useAuth } from '@/lib/auth';
export function ProtectedRoute({ children }: { children: React.ReactNode }) {
const { user, loading } = useAuth();
const router = useRouter();
useEffect(() => {
if (!loading && !user) {
router.push('/login');
}
}, [user, loading, router]);
if (loading) {
return <div>Loading...</div>;
}
return user ? <>{children}</> : null;
}
User Roles and Permissions
OnlyAutomator implements role-based access control through Supabase:
-- User roles in the database
CREATE TABLE user_roles (
id UUID PRIMARY KEY DEFAULT uuid_generate_v4(),
user_id UUID REFERENCES auth.users(id) ON DELETE CASCADE,
role TEXT NOT NULL CHECK (role IN ('admin', 'user', 'creator')),
created_at TIMESTAMP WITH TIME ZONE DEFAULT NOW(),
UNIQUE(user_id, role)
);
-- Function to check if a user has a specific role
CREATE OR REPLACE FUNCTION public.user_has_role(user_id UUID, role_name TEXT)
RETURNS BOOLEAN AS $$
SELECT EXISTS (
SELECT 1
FROM user_roles
WHERE user_id = $1 AND role = $2
);
$$ LANGUAGE sql SECURITY DEFINER;
Configuration
The authentication system is configured through environment variables:
# Supabase authentication settings
NEXT_PUBLIC_SUPABASE_URL=https://your-project.supabase.co
NEXT_PUBLIC_SUPABASE_ANON_KEY=your-anon-key
SUPABASE_SERVICE_ROLE_KEY=your-service-role-key
# OAuth settings (for Google integration)
NEXT_PUBLIC_GOOGLE_CLIENT_ID=your-google-client-id
NEXT_PUBLIC_GOOGLE_CLIENT_SECRET=your-google-client-secret
NEXT_PUBLIC_SUPABASE_AUTH_URL=https://your-project.supabase.co/auth/v1/callback
Security Considerations
The authentication system follows security best practices:
- HTTPS Only: All authentication traffic is encrypted
- JWT Validation: Proper validation of JSON Web Tokens
- CORS Configuration: Restricts cross-origin requests
- Rate Limiting: Protection against brute-force attacks
- Session Expiration: Automatic expiry of inactive sessions
- Secure Cookies: HTTP-only cookies for session management