{"version":3,"file":"TOTPEntryScreen.mjs","sources":["../../../../../../../../../web/src/ui/b2b/screens/TOTPEntryScreen.tsx"],"sourcesContent":["import { useLingui } from '@lingui/react/macro';\nimport { B2BMFAProducts, B2BTOTPAuthenticateResponse, StytchProjectConfigurationInput } from '@stytch/core/public';\nimport React, { useMemo } from 'react';\n\nimport Button from '../../components/atoms/Button';\nimport Column from '../../components/atoms/Column';\nimport ButtonColumn from '../../components/molecules/ButtonColumn';\nimport OTPEntry from '../../components/molecules/OTPEntry';\nimport { useConfig, useGlobalReducer, useStytch } from '../GlobalContextProvider';\nimport { AppScreens } from '../types/AppScreens';\nimport { StytchMutationKey, useMutate } from '../utils';\n\nexport const TOTPEntryScreen = () => {\n  const stytchClient = useStytch();\n  const {\n    sessionOptions: { sessionDurationMinutes },\n  } = useConfig();\n  const { t } = useLingui();\n\n  const [state, dispatch] = useGlobalReducer();\n  const {\n    mfa: { isEnrolling },\n  } = state;\n\n  // This screen should only be shown if primary info is available\n  const { enrolledMfaMethods, memberId, organizationId, organizationMfaOptionsSupported } = state.mfa.primaryInfo!;\n\n  const {\n    trigger: authenticate,\n    isMutating: isSubmitting,\n    error: authenticateError,\n  } = useMutate<\n    B2BTOTPAuthenticateResponse<StytchProjectConfigurationInput>,\n    unknown,\n    StytchMutationKey,\n    { memberId: string; organizationId: string; otp: string; sessionDurationMinutes: number }\n  >(\n    'stytch.totp.authenticate',\n    (\n      _: string,\n      {\n        arg: { memberId, organizationId, otp, sessionDurationMinutes },\n      }: { arg: { memberId: string; organizationId: string; otp: string; sessionDurationMinutes: number } },\n    ) =>\n      stytchClient.totp.authenticate({\n        code: otp,\n        member_id: memberId,\n        organization_id: organizationId,\n        session_duration_minutes: sessionDurationMinutes,\n      }),\n    {\n      onSuccess: () => {\n        dispatch({ type: 'totp/authenticate_success' });\n      },\n    },\n  );\n\n  const isSmsOtpAvailable = useMemo(\n    () =>\n      !isEnrolling &&\n      enrolledMfaMethods.includes(B2BMFAProducts.smsOtp) &&\n      (organizationMfaOptionsSupported.length === 0 || organizationMfaOptionsSupported.includes(B2BMFAProducts.smsOtp)),\n    [enrolledMfaMethods, isEnrolling, organizationMfaOptionsSupported],\n  );\n\n  const errorMessage = authenticateError\n    ? t({ id: 'error.passcodeInvalid', message: 'Invalid passcode, please try again.' })\n    : undefined;\n  const canGoBack = isEnrolling;\n\n  const handleSubmit = (otp: string) => authenticate({ memberId, organizationId, otp, sessionDurationMinutes });\n\n  const handleSwitchToRecoveryCode = () => {\n    dispatch({ type: 'transition', history: 'push', screen: AppScreens.RecoveryCodeEntry });\n  };\n\n  const handleSwitchToSms = () => {\n    dispatch({ type: 'transition', history: 'push', screen: AppScreens.SMSOTPEntry });\n  };\n\n  return (\n    <Column gap={6}>\n      <OTPEntry\n        header={t({ id: 'totp.title', message: 'Enter verification code' })}\n        instruction={t({ id: 'totp.content', message: 'Enter the 6-digit code from your authenticator app.' })}\n        helperContent={\n          isEnrolling\n            ? t({\n                id: 'mfa.totpEntry.getNewCode',\n                message: 'If the verification code doesn’t work, go back to your authenticator app to get a new code.',\n              })\n            : null\n        }\n        isSubmitting={isSubmitting}\n        onSubmit={handleSubmit}\n        errorMessage={errorMessage}\n      />\n\n      <ButtonColumn\n        top={null}\n        bottom={\n          <>\n            {isSmsOtpAvailable && (\n              <Button variant=\"outline\" onClick={handleSwitchToSms}>\n                {t({ id: 'mfa.totpEntry.switchToSms', message: 'Text me a code instead' })}\n              </Button>\n            )}\n\n            {!isEnrolling && (\n              <Button variant=\"outline\" onClick={handleSwitchToRecoveryCode}>\n                {t({ id: 'mfa.totpEntry.useBackupCode', message: 'Use a backup code' })}\n              </Button>\n            )}\n\n            {canGoBack && (\n              <Button variant=\"ghost\" onClick={() => dispatch({ type: 'navigate_back' })}>\n                {t({ id: 'button.goBack', message: 'Go back' })}\n              </Button>\n            )}\n          </>\n        }\n      />\n    </Column>\n  );\n};\n"],"names":["TOTPEntryScreen","stytchClient","useStytch","sessionOptions","sessionDurationMinutes","useConfig","useLingui","state","dispatch","useGlobalReducer","mfa","isEnrolling","enrolledMfaMethods","memberId","organizationId","organizationMfaOptionsSupported","primaryInfo","trigger","authenticate","isMutating","isSubmitting","error","authenticateError","useMutate","_","arg","otp","totp","code","member_id","organization_id","session_duration_minutes","onSuccess","type","isSmsOtpAvailable","useMemo","includes","B2BMFAProducts","smsOtp","length","errorMessage","undefined","canGoBack","handleSubmit","handleSwitchToRecoveryCode","history","screen","AppScreens","RecoveryCodeEntry","handleSwitchToSms","SMSOTPEntry","React","Column","gap","OTPEntry","header","instruction","helperContent","onSubmit","ButtonColumn","top","bottom","Button","variant","onClick"],"mappings":"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"}