import { useMutation, useQuery, useQueryClient } from '@tanstack/vue-query' import { apiClient } from '@/lib/axios' import type { MfaConfirmResponse, MfaStatus, MfaTotpSetup, MfaVerifyPayload, TrustedDevice, } from '@/types/mfa' interface ApiResponse { success: boolean data: T message: string } // ─── Setup ─── export function useSetupTotp() { return useMutation({ mutationFn: async () => { const { data } = await apiClient.post>('/auth/mfa/setup/totp') return data.data }, }) } export function useConfirmTotp() { const queryClient = useQueryClient() return useMutation({ mutationFn: async (code: string) => { const { data } = await apiClient.post>('/auth/mfa/setup/totp/confirm', { code }) return data.data }, onSuccess: () => { queryClient.invalidateQueries({ queryKey: ['mfa-status'] }) }, }) } export function useSetupEmail() { return useMutation({ mutationFn: async () => { const { data } = await apiClient.post>('/auth/mfa/setup/email') return data }, }) } export function useConfirmEmail() { const queryClient = useQueryClient() return useMutation({ mutationFn: async (code: string) => { const { data } = await apiClient.post>('/auth/mfa/setup/email/confirm', { code }) return data.data }, onSuccess: () => { queryClient.invalidateQueries({ queryKey: ['mfa-status'] }) }, }) } // ─── Management ─── export function useDisableMfa() { const queryClient = useQueryClient() return useMutation({ mutationFn: async (payload: { code: string; method: string }) => { const { data } = await apiClient.post>('/auth/mfa/disable', payload) return data }, onSuccess: () => { queryClient.invalidateQueries({ queryKey: ['mfa-status'] }) }, }) } export function useRegenerateBackupCodes() { const queryClient = useQueryClient() return useMutation({ mutationFn: async (payload: { code: string }) => { const { data } = await apiClient.post>('/auth/mfa/backup-codes', payload) return data.data }, onSuccess: () => { queryClient.invalidateQueries({ queryKey: ['mfa-status'] }) }, }) } export function useMfaStatus() { return useQuery({ queryKey: ['mfa-status'], queryFn: async () => { const { data } = await apiClient.get>('/auth/mfa/status') return data.data }, }) } export function useSetPreferredMethod() { const queryClient = useQueryClient() return useMutation({ mutationFn: async (method: 'totp' | 'email') => { const { data } = await apiClient.put>('/auth/mfa/preferred-method', { method }) return data.data }, onSuccess: () => { queryClient.invalidateQueries({ queryKey: ['mfa-status'] }) }, }) } // ─── Trusted devices ─── export function useTrustedDevices() { return useQuery({ queryKey: ['trusted-devices'], queryFn: async () => { const { data } = await apiClient.get>('/auth/trusted-devices') return data.data }, }) } export function useRevokeDevice() { const queryClient = useQueryClient() return useMutation({ mutationFn: async (id: string) => { await apiClient.delete(`/auth/trusted-devices/${id}`) }, onSuccess: () => { queryClient.invalidateQueries({ queryKey: ['trusted-devices'] }) }, }) } export function useRevokeAllDevices() { const queryClient = useQueryClient() return useMutation({ mutationFn: async () => { await apiClient.delete('/auth/trusted-devices') }, onSuccess: () => { queryClient.invalidateQueries({ queryKey: ['trusted-devices'] }) }, }) } // ─── Login flow (no auth needed — uses session token) ─── export function useVerifyMfa() { return useMutation({ mutationFn: async (payload: MfaVerifyPayload) => { const { data } = await apiClient.post('/auth/mfa/verify', payload) return data }, }) } export function useSendMfaEmailCode() { return useMutation({ mutationFn: async (mfaSessionToken: string) => { const { data } = await apiClient.post('/auth/mfa/email/send', { mfa_session_token: mfaSessionToken, }) return data }, }) }