Add MFA Setup UI in Settings page
Implements user interface for setting up and managing two-factor authentication: MFA Setup UI Features: - MFASettings component with full MFA management UI - TOTP setup dialog with QR code display - Manual entry code for authenticator apps - Backup codes display with copy functionality - Verification code input for TOTP enabling - Email MFA setup dialog with confirmation - Disable MFA dialog with warning - Real-time MFA status indicator (enabled/disabled) - Method type chip (Authenticator App / Email) User Experience: - Step-by-step TOTP setup wizard - QR code scanning for easy authenticator app setup - Backup codes shown only once during setup - Copy-to-clipboard for backup codes - Visual feedback (success/error alerts) - Loading states for all async operations - Animated transitions with Framer Motion API Integration: - MFA API client in lib/api/mfa.ts - Get MFA status - Setup TOTP with QR code - Verify and enable TOTP - Setup Email MFA - Disable MFA - Regenerate backup codes Settings Page Updates: - Added Security section with MFA settings - Integrated MFASettings component - Maintains existing settings page structure 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
93
maternal-web/lib/api/mfa.ts
Normal file
93
maternal-web/lib/api/mfa.ts
Normal file
@@ -0,0 +1,93 @@
|
||||
import axios from 'axios';
|
||||
|
||||
const API_BASE_URL = process.env.NEXT_PUBLIC_API_URL || 'http://localhost:3020';
|
||||
|
||||
export interface MFAStatus {
|
||||
enabled: boolean;
|
||||
method?: 'totp' | 'email';
|
||||
hasBackupCodes: boolean;
|
||||
}
|
||||
|
||||
export interface TOTPSetupResult {
|
||||
secret: string;
|
||||
qrCodeUrl: string;
|
||||
backupCodes: string[];
|
||||
}
|
||||
|
||||
export const mfaApi = {
|
||||
// Get MFA status
|
||||
async getStatus(): Promise<MFAStatus> {
|
||||
const response = await axios.get(`${API_BASE_URL}/api/v1/auth/mfa/status`, {
|
||||
headers: {
|
||||
Authorization: `Bearer ${localStorage.getItem('accessToken')}`,
|
||||
},
|
||||
});
|
||||
return response.data;
|
||||
},
|
||||
|
||||
// Setup TOTP (Google Authenticator)
|
||||
async setupTOTP(): Promise<TOTPSetupResult> {
|
||||
const response = await axios.post(
|
||||
`${API_BASE_URL}/api/v1/auth/mfa/totp/setup`,
|
||||
{},
|
||||
{
|
||||
headers: {
|
||||
Authorization: `Bearer ${localStorage.getItem('accessToken')}`,
|
||||
},
|
||||
}
|
||||
);
|
||||
return response.data;
|
||||
},
|
||||
|
||||
// Enable TOTP
|
||||
async enableTOTP(code: string): Promise<{ success: boolean; message: string }> {
|
||||
const response = await axios.post(
|
||||
`${API_BASE_URL}/api/v1/auth/mfa/totp/enable`,
|
||||
{ code },
|
||||
{
|
||||
headers: {
|
||||
Authorization: `Bearer ${localStorage.getItem('accessToken')}`,
|
||||
},
|
||||
}
|
||||
);
|
||||
return response.data;
|
||||
},
|
||||
|
||||
// Setup Email MFA
|
||||
async setupEmailMFA(): Promise<{ success: boolean; message: string }> {
|
||||
const response = await axios.post(
|
||||
`${API_BASE_URL}/api/v1/auth/mfa/email/setup`,
|
||||
{},
|
||||
{
|
||||
headers: {
|
||||
Authorization: `Bearer ${localStorage.getItem('accessToken')}`,
|
||||
},
|
||||
}
|
||||
);
|
||||
return response.data;
|
||||
},
|
||||
|
||||
// Disable MFA
|
||||
async disableMFA(): Promise<{ success: boolean; message: string }> {
|
||||
const response = await axios.delete(`${API_BASE_URL}/api/v1/auth/mfa`, {
|
||||
headers: {
|
||||
Authorization: `Bearer ${localStorage.getItem('accessToken')}`,
|
||||
},
|
||||
});
|
||||
return response.data;
|
||||
},
|
||||
|
||||
// Regenerate backup codes
|
||||
async regenerateBackupCodes(): Promise<{ success: boolean; backupCodes: string[] }> {
|
||||
const response = await axios.post(
|
||||
`${API_BASE_URL}/api/v1/auth/mfa/backup-codes/regenerate`,
|
||||
{},
|
||||
{
|
||||
headers: {
|
||||
Authorization: `Bearer ${localStorage.getItem('accessToken')}`,
|
||||
},
|
||||
}
|
||||
);
|
||||
return response.data;
|
||||
},
|
||||
};
|
||||
Reference in New Issue
Block a user