diff --git a/apps/mobile/src/modules/settings/compoents/OTPWindow.tsx b/apps/mobile/src/modules/settings/compoents/OTPWindow.tsx index 8427808c5..b7e38be34 100644 --- a/apps/mobile/src/modules/settings/compoents/OTPWindow.tsx +++ b/apps/mobile/src/modules/settings/compoents/OTPWindow.tsx @@ -1,5 +1,4 @@ import { useMutation } from "@tanstack/react-query" -import type { FC } from "react" import { useEffect, useRef, useState } from "react" import { Keyboard, Modal, StyleSheet, Text, useWindowDimensions, View } from "react-native" import type { OtpInputRef } from "react-native-otp-entry" @@ -8,13 +7,16 @@ import Animated, { FadeIn, FadeOut, useSharedValue, withSpring } from "react-nat import { useSafeAreaInsets } from "react-native-safe-area-context" import { useColor } from "react-native-uikit-colors" -import { isAuthCodeValid, twoFactor } from "@/src/lib/auth" +import { isAuthCodeValid } from "@/src/lib/auth" import { toast } from "@/src/lib/toast" import { accentColor } from "@/src/theme/colors" -export const OTPWindow: FC<{ - onSuccess: (token: string) => void -}> = ({ onSuccess }) => { +type OTPWindowProps = { + onSuccess: (data: T) => void + verifyFn: (code: string) => Promise +} + +export const OTPWindow = ({ onSuccess, verifyFn }: OTPWindowProps) => { const otpInputRef = useRef(null) const label = useColor("label") const tertiaryLabel = useColor("tertiaryLabel") @@ -26,21 +28,12 @@ export const OTPWindow: FC<{ toast.error(`Failed to verify: ${error.message}`) }, onSuccess(data) { - onSuccess(data.token) + onSuccess(data) }, onSettled() { setOpen(false) }, - mutationFn: async ({ code }: { code: string }) => { - const { data, error } = await twoFactor.verifyTotp({ code }) - if (!data || error) { - const errorMessage = error?.message ?? "Invalid TOTP code" - toast.error(errorMessage) - throw new Error(errorMessage) - } - - return data - }, + mutationFn: ({ code }: { code: string }) => verifyFn(code), }) const windowScaleValue = useSharedValue(0.9) @@ -53,12 +46,13 @@ export const OTPWindow: FC<{ }, []) useEffect(() => { + const preset = { stiffness: 100, damping: 10 } if (open) { - windowScaleValue.value = withSpring(1, { stiffness: 100, damping: 10 }) - windowOpacityValue.value = withSpring(1, { stiffness: 100, damping: 10 }) + windowScaleValue.value = withSpring(1, preset) + windowOpacityValue.value = withSpring(1, preset) } else { - windowOpacityValue.value = withSpring(0, { stiffness: 100, damping: 10 }) - windowScaleValue.value = withSpring(0.9, { stiffness: 100, damping: 10 }) + windowOpacityValue.value = withSpring(0, preset) + windowScaleValue.value = withSpring(0.9, preset) } }, [open, windowOpacityValue, windowScaleValue]) diff --git a/apps/mobile/src/modules/settings/hooks/useTOTPModalWrapper.tsx b/apps/mobile/src/modules/settings/hooks/useTOTPModalWrapper.tsx index 0706b4977..b0a3c79b2 100644 --- a/apps/mobile/src/modules/settings/hooks/useTOTPModalWrapper.tsx +++ b/apps/mobile/src/modules/settings/hooks/useTOTPModalWrapper.tsx @@ -1,4 +1,5 @@ import { useCallback } from "react" +import Siblings from "react-native-root-siblings" import { getFetchErrorInfo } from "@/src/lib/error-parser" import { useNavigation } from "@/src/lib/navigation/hooks" @@ -6,6 +7,8 @@ import { toast } from "@/src/lib/toast" import { TwoFactorAuthScreen } from "@/src/screens/(modal)/2fa" import { useWhoami } from "@/src/store/user/hooks" +import { OTPWindow } from "../compoents/OTPWindow" + export const useTOTPModalWrapper = ( callback: (input: T) => Promise, options?: { force?: boolean; dismiss?: () => any }, @@ -24,20 +27,23 @@ export const useTOTPModalWrapper = ( return } - // present({ - // title: t("profile.totp_code.title"), - // content: ({ dismiss }) => { - // return createElement(TOTPForm, { - // async onSubmitMutationFn(values) { - // await callback({ - // ...input, - // TOTPCode: values.code, - // }) - // dismiss() - // }, - // }) - // }, - // }) + const root = new Siblings( + ( + { + await callback({ + ...input, + TOTPCode, + }) + + root.destroy() + }} + onSuccess={async () => { + root.destroy() + }} + /> + ), + ) } if (options?.force) {