supabase-node-kit
Version:
A backend utility package for Supabase authentication and database functionality.
226 lines (208 loc) • 7.13 kB
text/typescript
import { supabaseClient, supabaseAdmin } from "../config/supabaseClient";
import { Provider, Session } from "@supabase/supabase-js";
// Client-side auth operations
export const authService = {
/**
* Authenticates a user with email and password
* @param email - User's email address
* @param password - User's password
* @returns Promise containing the sign in response
* @example
* const { data, error } = await authService.signIn('user@example.com', 'password123')
*/
async signIn(email: string, password: string) {
return await supabaseClient.auth.signInWithPassword({ email, password });
},
/**
* Signs out the currently authenticated user
* @returns Promise containing the sign out response
* @example
* await authService.signOutCurrentUser()
*/
async signOutCurrentUser() {
return await supabaseClient.auth.signOut();
},
/**
* Retrieves the currently authenticated user's details
* @returns Promise containing the current user data
* @example
* const { data: { user }, error } = await authService.getCurrentUser()
*/
async getCurrentUser() {
return await supabaseClient.auth.getUser();
},
async signUp(email: string, password: string) {
// Check if user exists
const { data: existingUser } = await supabaseClient
.from('users')
.select()
.eq('email', email)
.single();
if (existingUser) {
throw new Error('User with this email already exists');
}
return await supabaseClient.auth.signUp({
email,
password,
options: {
emailRedirectTo: `${window.location.origin}/auth/callback`,
},
});
},
/**
* Signs in with a third-party provider
* @param provider - The authentication provider (google, github, etc.)
* @returns Promise containing the sign in response
* @example
* await authService.signInWithProvider('google')
*/
async signInWithProvider(provider: Provider) {
return await supabaseClient.auth.signInWithOAuth({
provider,
options: {
redirectTo: `${window.location.origin}/auth/callback`,
scopes: 'email profile',
},
});
},
/**
* Sends a password reset email
* @param email - User's email address
* @returns Promise containing the reset response
* @example
* const { data, error } = await authService.resetPassword('user@example.com')
*/
async resetPassword(email: string) {
return await supabaseClient.auth.resetPasswordForEmail(email, {
redirectTo: `${window.location.origin}/auth/reset-password`,
});
},
/**
* Updates user's password
* @param newPassword - New password
* @returns Promise containing the update response
* @example
* const { data, error } = await authService.updatePassword('newPassword123')
*/
async updatePassword(newPassword: string) {
return await supabaseClient.auth.updateUser({
password: newPassword,
});
},
};
// Server-side admin auth operations
export const authAdminService = {
/**
* Creates a new user account (Server-side only)
* @param email - New user's email address
* @param password - New user's password
* @returns Promise containing the created user data
* @throws Error if called from client-side
* @example
* // Only in API routes or server-side code
* const { data, error } = await authAdminService.createUser('newuser@example.com', 'password123')
*/
async createUser(email: string, password: string) {
if (!supabaseAdmin) {
throw new Error("Admin operations can only be performed server-side");
}
return await supabaseAdmin.auth.admin.createUser({
email,
password,
email_confirm: true
});
},
/**
* Deletes a user account by ID (Server-side only)
* @param userId - The UUID of the user to delete
* @returns Promise containing the deletion response
* @throws Error if called from client-side
* @example
* // Only in API routes or server-side code
* await authAdminService.deleteUser('user-uuid-here')
*/
async deleteUser(userId: string) {
if (!supabaseAdmin) {
throw new Error("Admin operations can only be performed server-side");
}
return await supabaseAdmin.auth.admin.deleteUser(userId);
},
/**
* Retrieves user details by ID (Server-side only)
* @param userId - The UUID of the user to fetch
* @returns Promise containing the user data
* @throws Error if called from client-side
* @example
* // Only in API routes or server-side code
* const { data: { user }, error } = await authAdminService.getUserById('user-uuid-here')
*/
async getUserById(userId: string) {
if (!supabaseAdmin) {
throw new Error("Admin operations can only be performed server-side");
}
return await supabaseAdmin.auth.admin.getUserById(userId);
},
/**
* Forces sign out for a specific user (Server-side only)
* @param userId - The UUID of the user to sign out
* @returns Promise containing the sign out response
* @throws Error if called from client-side
* @example
* // Only in API routes or server-side code
* await authAdminService.signOutUser('user-uuid-here')
*/
async signOutUser(userId: string) {
if (!supabaseAdmin) {
throw new Error("Admin operations can only be performed server-side");
}
return await supabaseAdmin.auth.admin.signOut(userId);
},
async checkUserExists(email: string) {
if (!supabaseAdmin) {
throw new Error("Admin operations can only be performed server-side");
}
const { data, error } = await supabaseAdmin
.from('users')
.select('id')
.eq('email', email)
.single();
return { exists: !!data, error };
},
/**
* Updates user's email verification status (Server-side only)
* @param userId - The UUID of the user
* @param verified - Boolean indicating verification status
* @throws Error if called from client-side
* @example
* await authAdminService.updateEmailVerification('user-uuid', true)
*/
async updateEmailVerification(userId: string, verified: boolean) {
if (!supabaseAdmin) {
throw new Error("Admin operations can only be performed server-side");
}
return await supabaseAdmin.auth.admin.updateUserById(userId, {
email_confirm: verified,
});
},
/**
* Initialize auth session from existing session data
* @returns Promise containing the session data
* @example
* const { data: { session }, error } = await authService.initializeSession()
*/
async initializeSession() {
return await supabaseClient.auth.getSession();
},
/**
* Set up an auth state change listener
* @param callback - Function to handle auth state changes
* @returns Cleanup function to remove the listener
* @example
* const unsubscribe = authService.onAuthStateChange((event, session) => {
* console.log('Auth event:', event, session)
* })
*/
onAuthStateChange(callback: (event: string, session: Session | null) => void) {
return supabaseClient.auth.onAuthStateChange(callback);
},
};