57 lines
1.7 KiB
TypeScript
57 lines
1.7 KiB
TypeScript
import { apiClient } from './api/client';
|
|
import { requireFeature, FEATURES } from '@/config/features';
|
|
|
|
interface TwoFactorSetupResponse {
|
|
secret: string;
|
|
qr_code_url: string;
|
|
recovery_codes: string[];
|
|
}
|
|
|
|
interface TwoFactorStatus {
|
|
enabled: boolean;
|
|
}
|
|
|
|
/**
|
|
* Two-Factor Authentication Service
|
|
*
|
|
* Backend endpoints: /auth/2fa/setup, /auth/2fa/verify, /auth/2fa/disable, /auth/2fa/status
|
|
*
|
|
* @see FEATURES.TWO_FACTOR_AUTH
|
|
*/
|
|
class TwoFactorService {
|
|
async getStatus(): Promise<TwoFactorStatus> {
|
|
requireFeature('TWO_FACTOR_AUTH');
|
|
// apiClient unwraps { success, data } format automatically
|
|
const response = await apiClient.get<TwoFactorStatus>('/auth/2fa/status');
|
|
return response.data;
|
|
}
|
|
|
|
async setup(): Promise<TwoFactorSetupResponse> {
|
|
requireFeature('TWO_FACTOR_AUTH');
|
|
// apiClient unwraps { success, data } format automatically
|
|
const response =
|
|
await apiClient.post<TwoFactorSetupResponse>('/auth/2fa/setup');
|
|
return response.data;
|
|
}
|
|
|
|
async verify(secret: string, code: string): Promise<void> {
|
|
requireFeature('TWO_FACTOR_AUTH');
|
|
// Backend expects { secret, code } and returns { success: true, data: { message: "2FA enabled successfully" } }
|
|
await apiClient.post('/auth/2fa/verify', { secret, code });
|
|
}
|
|
|
|
async disable(password: string): Promise<void> {
|
|
requireFeature('TWO_FACTOR_AUTH');
|
|
// Backend expects { password } and returns { success: true, data: { message: "2FA disabled successfully" } }
|
|
await apiClient.post('/auth/2fa/disable', { password });
|
|
}
|
|
}
|
|
|
|
export const twoFactorService = new TwoFactorService();
|
|
|
|
/**
|
|
* Check if 2FA is enabled (for UI conditional rendering)
|
|
*/
|
|
export function is2FAEnabled(): boolean {
|
|
return FEATURES.TWO_FACTOR_AUTH;
|
|
}
|