mediahub-fe/docs/AUTH_REFACTOR.md

405 lines
9.8 KiB
Markdown
Raw Normal View History

# Auth System Refactoring
## Overview
The authentication system has been completely refactored to improve code quality, maintainability, and user experience. This document outlines the changes and improvements made.
## Key Improvements
### 1. **Separation of Concerns**
- **Before**: Single 667-line monolithic component handling all auth logic
- **After**: Modular components with clear responsibilities:
- `AuthLayout`: Layout and styling
- `LoginForm`: Login form logic
- `EmailSetupForm`: Email validation form
- `OTPForm`: OTP verification form
- Custom hooks for business logic
- Utility functions for common operations
### 2. **Type Safety**
- **Before**: Extensive use of `any` types
- **After**: Comprehensive TypeScript interfaces and types:
- `LoginFormData`, `EmailValidationData`, `OTPData`
- `ProfileData`, `AuthState`, `AuthContextType`
- Proper API response types
- Component prop interfaces
### 3. **Form Validation**
- **Before**: Basic zod schema with unclear error messages
- **After**: Comprehensive validation with user-friendly messages:
- Username: 3-50 characters, required
- Password: 6-100 characters, required
- Email: Proper email format validation
- OTP: Exactly 6 digits, numbers only
### 4. **Error Handling**
- **Before**: Inconsistent error handling patterns
- **After**: Centralized error handling with:
- Consistent error messages
- Toast notifications
- Proper error boundaries
- Rate limiting for login attempts
### 5. **Accessibility**
- **Before**: Basic accessibility
- **After**: Enhanced accessibility with:
- Proper ARIA labels
- Keyboard navigation support
- Screen reader compatibility
- Focus management
- Error announcements
### 6. **Reusability**
- **Before**: Hardcoded components
- **After**: Highly reusable components:
- `FormField`: Reusable form input component
- `AuthLayout`: Reusable layout component
- Custom hooks for business logic
- Utility functions for common operations
## New File Structure
```
types/
├── auth.ts # TypeScript interfaces and types
lib/
├── auth-utils.ts # Auth utility functions
hooks/
├── use-auth.ts # Custom auth hooks
components/
├── auth/
│ ├── index.ts # Component exports
│ ├── auth-layout.tsx # Reusable auth layout
│ ├── form-field.tsx # Reusable form field
│ ├── login-form.tsx # Login form component
│ ├── email-setup-form.tsx # Email setup form
│ └── otp-form.tsx # OTP verification form
app/[locale]/auth/
├── page.tsx # Main auth page
```
## Components
### AuthLayout
Reusable layout component for all auth pages.
```tsx
import { AuthLayout } from "@/components/auth";
<AuthLayout showSidebar={true}>
{/* Auth form content */}
</AuthLayout>
```
### FormField
Reusable form input component with built-in validation and accessibility.
```tsx
import { FormField } from "@/components/auth";
<FormField
label="Username"
name="username"
type="text"
placeholder="Enter your username"
error={errors.username?.message}
required
inputProps={{
size: "lg",
...register("username"),
}}
/>
```
### LoginForm
Complete login form with validation and error handling.
```tsx
import { LoginForm } from "@/components/auth";
<LoginForm
onSuccess={(data) => console.log("Login successful", data)}
onError={(error) => console.error("Login failed", error)}
/>
```
### EmailSetupForm
Form for email validation and setup.
```tsx
import { EmailSetupForm } from "@/components/auth";
<EmailSetupForm
onSuccess={() => console.log("Email setup successful")}
onError={(error) => console.error("Email setup failed", error)}
onBack={() => console.log("Go back to login")}
/>
```
### OTPForm
OTP verification form with keyboard navigation.
```tsx
import { OTPForm } from "@/components/auth";
<OTPForm
onSuccess={() => console.log("OTP verification successful")}
onError={(error) => console.error("OTP verification failed", error)}
onResend={() => console.log("Resend OTP")}
/>
```
## Hooks
### useAuth
Main authentication hook providing login, logout, and token refresh functionality.
```tsx
import { useAuth } from "@/hooks/use-auth";
const { login, logout, isAuthenticated, user, loading, error } = useAuth();
```
### useEmailValidation
Hook for email validation step.
```tsx
import { useEmailValidation } from "@/hooks/use-auth";
const { validateEmail, loading, error } = useEmailValidation();
```
### useEmailSetup
Hook for email setup step.
```tsx
import { useEmailSetup } from "@/hooks/use-auth";
const { setupEmail, loading, error } = useEmailSetup();
```
### useOTPVerification
Hook for OTP verification.
```tsx
import { useOTPVerification } from "@/hooks/use-auth";
const { verifyOTP, loading, error } = useOTPVerification();
```
## Utilities
### Auth Utilities
Centralized utility functions for common auth operations.
```tsx
import {
setAuthCookies,
setProfileCookies,
clearAllCookies,
isUserEligible,
getNavigationPath,
showAuthError,
showAuthSuccess,
loginRateLimiter
} from "@/lib/auth-utils";
```
### Rate Limiting
Built-in rate limiting to prevent brute force attacks.
```tsx
// Check if user can attempt login
if (!loginRateLimiter.canAttempt(username)) {
const remainingTime = loginRateLimiter.getRemainingTime(username);
// Show lockout message
}
// Record failed attempt
loginRateLimiter.recordAttempt(username);
// Reset on successful login
loginRateLimiter.resetAttempts(username);
```
## Validation Schemas
### Login Schema
```tsx
import { loginSchema } from "@/types/auth";
const schema = z.object({
username: z
.string()
.min(1, { message: "Username is required" })
.min(3, { message: "Username must be at least 3 characters" })
.max(50, { message: "Username must be less than 50 characters" }),
password: z
.string()
.min(1, { message: "Password is required" })
.min(6, { message: "Password must be at least 6 characters" })
.max(100, { message: "Password must be less than 100 characters" }),
});
```
### Email Validation Schema
```tsx
import { emailValidationSchema } from "@/types/auth";
const schema = z.object({
oldEmail: z
.string()
.min(1, { message: "Old email is required" })
.email({ message: "Please enter a valid email address" }),
newEmail: z
.string()
.min(1, { message: "New email is required" })
.email({ message: "Please enter a valid email address" }),
});
```
### OTP Schema
```tsx
import { otpSchema } from "@/types/auth";
const schema = z.object({
otp: z
.string()
.length(6, { message: "OTP must be exactly 6 digits" })
.regex(/^\d{6}$/, { message: "OTP must contain only numbers" }),
});
```
## Best Practices Implemented
### 1. **Component Design**
- Single responsibility principle
- Props interface for type safety
- Default props where appropriate
- Proper error boundaries
### 2. **State Management**
- Custom hooks for business logic
- Local state for UI concerns
- Context for global auth state
- Proper loading states
### 3. **Error Handling**
- Consistent error patterns
- User-friendly error messages
- Proper error boundaries
- Toast notifications
### 4. **Performance**
- Memoized components where needed
- Efficient re-renders
- Proper dependency arrays
- Lazy loading for large components
### 5. **Security**
- Rate limiting for login attempts
- Input validation and sanitization
- Secure cookie handling
- XSS protection
### 6. **Accessibility**
- ARIA labels and descriptions
- Keyboard navigation
- Screen reader support
- Focus management
- Error announcements
## Migration Guide
### From Old LoginForm to New Components
**Before:**
```tsx
import LoginForm from "@/components/partials/auth/login-form";
<LoginForm />
```
**After:**
```tsx
import { AuthLayout, LoginForm } from "@/components/auth";
<AuthLayout>
<LoginForm
onSuccess={handleSuccess}
onError={handleError}
/>
</AuthLayout>
```
### Adding Custom Validation
**Before:**
```tsx
// Validation logic mixed with component
const schema = z.object({
username: z.string().min(1, { message: "Judul diperlukan" }),
password: z.string().min(4, { message: "Password must be at least 4 characters." }),
});
```
**After:**
```tsx
// Centralized validation schemas
import { loginSchema } from "@/types/auth";
const {
register,
handleSubmit,
formState: { errors },
} = useForm<LoginFormData>({
resolver: zodResolver(loginSchema),
mode: "onChange",
});
```
## Testing
The new components are designed to be easily testable:
```tsx
// Example test for LoginForm
import { render, screen, fireEvent } from "@testing-library/react";
import { LoginForm } from "@/components/auth";
test("renders login form", () => {
const mockOnSuccess = jest.fn();
const mockOnError = jest.fn();
render(
<LoginForm
onSuccess={mockOnSuccess}
onError={mockOnError}
/>
);
expect(screen.getByLabelText(/username/i)).toBeInTheDocument();
expect(screen.getByLabelText(/password/i)).toBeInTheDocument();
});
```
## Future Enhancements
1. **Multi-factor Authentication**: Support for additional MFA methods
2. **Social Login**: Integration with Google, Facebook, etc.
3. **Password Strength Indicator**: Visual feedback for password strength
4. **Remember Me**: Persistent login functionality
5. **Session Management**: Better session handling and timeout
6. **Audit Logging**: Track login attempts and security events
## Conclusion
The refactored auth system provides:
- Better code organization and maintainability
- Improved type safety and error handling
- Enhanced user experience and accessibility
- Better security with rate limiting
- Reusable components for future development
- Comprehensive documentation and testing support
This foundation makes it easier to add new features, maintain the codebase, and provide a better user experience.