feat(auth): implement email/password login form
This commit is contained in:
106
apps/web/src/services/authService.ts
Normal file
106
apps/web/src/services/authService.ts
Normal file
@@ -0,0 +1,106 @@
|
||||
import {
|
||||
signInWithEmailAndPassword,
|
||||
signOut,
|
||||
onAuthStateChanged,
|
||||
setPersistence,
|
||||
browserLocalPersistence,
|
||||
sendPasswordResetEmail,
|
||||
} from "firebase/auth";
|
||||
import type { User, AuthError } from "firebase/auth";
|
||||
import { app} from "../features/auth/firebase"
|
||||
import { getAuth } from "firebase/auth";
|
||||
|
||||
const auth = getAuth(app);
|
||||
|
||||
/**
|
||||
* Initialize Firebase Auth persistence
|
||||
* Ensures user session persists across page refreshes
|
||||
*/
|
||||
export const initializeAuthPersistence = async () => {
|
||||
try {
|
||||
await setPersistence(auth, browserLocalPersistence);
|
||||
} catch (error) {
|
||||
console.error("Error setting auth persistence:", error);
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Login user with email and password
|
||||
*/
|
||||
export const loginWithEmail = async (email: string, password: string) => {
|
||||
try {
|
||||
const userCredential = await signInWithEmailAndPassword(auth, email, password);
|
||||
return {
|
||||
success: true,
|
||||
user: userCredential.user,
|
||||
error: null,
|
||||
};
|
||||
} catch (error) {
|
||||
const authError = error as AuthError;
|
||||
return {
|
||||
success: false,
|
||||
user: null,
|
||||
error: getAuthErrorMessage(authError.code),
|
||||
};
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Sign out the current user
|
||||
*/
|
||||
export const logout = async () => {
|
||||
try {
|
||||
await signOut(auth);
|
||||
return { success: true };
|
||||
} catch (error) {
|
||||
return { success: false, error: (error as Error).message };
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Send password reset email
|
||||
*/
|
||||
export const sendPasswordReset = async (email: string) => {
|
||||
try {
|
||||
await sendPasswordResetEmail(auth, email);
|
||||
return { success: true };
|
||||
} catch (error) {
|
||||
const authError = error as AuthError;
|
||||
return { success: false, error: getAuthErrorMessage(authError.code) };
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Subscribe to auth state changes
|
||||
* Returns unsubscribe function
|
||||
*/
|
||||
export const subscribeToAuthState = (callback: (user: User | null) => void) => {
|
||||
return onAuthStateChanged(auth, callback);
|
||||
};
|
||||
|
||||
/**
|
||||
* Get current user synchronously
|
||||
*/
|
||||
export const getCurrentUser = () => {
|
||||
return auth.currentUser;
|
||||
};
|
||||
|
||||
/**
|
||||
* Convert Firebase error codes to user-friendly messages
|
||||
*/
|
||||
const getAuthErrorMessage = (errorCode: string): string => {
|
||||
const errorMessages: Record<string, string> = {
|
||||
"auth/invalid-email": "Invalid email address format.",
|
||||
"auth/user-disabled": "This user account has been disabled.",
|
||||
"auth/user-not-found": "Invalid email or password.",
|
||||
"auth/wrong-password": "Invalid email or password.",
|
||||
"auth/invalid-credential": "Invalid email or password.",
|
||||
"auth/too-many-requests": "Too many login attempts. Please try again later.",
|
||||
"auth/operation-not-allowed": "Login is currently disabled. Please try again later.",
|
||||
"auth/network-request-failed": "Network error. Please check your connection.",
|
||||
};
|
||||
|
||||
return errorMessages[errorCode] || "An error occurred during login. Please try again.";
|
||||
};
|
||||
export { app };
|
||||
|
||||
Reference in New Issue
Block a user