import styled from '@emotion/styled'; import { Trans, useLingui } from '@lingui/react/macro'; import { FormProvider } from 'react-hook-form'; import QRCode from 'react-qr-code'; import { useRecoilValue } from 'recoil'; import { qrCodeState } from '@/auth/states/qrCode'; import { SaveAndCancelButtons } from '@/settings/components/SaveAndCancelButtons/SaveAndCancelButtons'; import { SettingsPageContainer } from '@/settings/components/SettingsPageContainer'; import { DeleteTwoFactorAuthentication } from '@/settings/two-factor-authentication/components/DeleteTwoFactorAuthenticationMethod'; import { TwoFactorAuthenticationSetupForSettingsEffect } from '@/settings/two-factor-authentication/components/TwoFactorAuthenticationSetupForSettingsEffect'; import { TwoFactorAuthenticationVerificationForSettings } from '@/settings/two-factor-authentication/components/TwoFactorAuthenticationVerificationForSettings'; import { useCurrentUserWorkspaceTwoFactorAuthentication } from '@/settings/two-factor-authentication/hooks/useCurrentUserWorkspaceTwoFactorAuthentication'; import { useTwoFactorVerificationForSettings } from '@/settings/two-factor-authentication/hooks/useTwoFactorVerificationForSettings'; import { extractSecretFromOtpUri } from '@/settings/two-factor-authentication/utils/extractSecretFromOtpUri'; import { SettingsPath } from '@/types/SettingsPath'; import { useSnackBar } from '@/ui/feedback/snack-bar-manager/hooks/useSnackBar'; import { SubMenuTopBarContainer } from '@/ui/layout/page/components/SubMenuTopBarContainer'; import { useTheme } from '@emotion/react'; import { H2Title, IconCopy } from 'twenty-ui/display'; import { Loader } from 'twenty-ui/feedback'; import { Section } from 'twenty-ui/layout'; import { getSettingsPath } from '~/utils/navigation/getSettingsPath'; const StyledQRCodeContainer = styled.div` margin: ${({ theme }) => theme.spacing(4)} 0; display: flex; flex-direction: column; align-items: flex-start; gap: ${({ theme }) => theme.spacing(3)}; `; const StyledQRCodeWrapper = styled.div` align-items: center; background-color: ${({ theme }) => theme.background.secondary}; border: 1px solid ${({ theme }) => theme.border.color.light}; border-radius: ${({ theme }) => theme.border.radius.md}; display: flex; justify-content: center; padding: ${({ theme }) => theme.spacing(4)}; `; const StyledQRCode = styled(QRCode)` height: 137px; width: 137px; `; const StyledCopySetupKeyText = styled.div` color: ${({ theme }) => theme.font.color.tertiary}; font-size: ${({ theme }) => theme.font.size.sm}; text-align: left; line-height: 1.5; `; const StyledCopySetupKeyLink = styled.button` background: none; border: none; color: ${({ theme }) => theme.font.color.tertiary}; cursor: pointer; display: inline; font-size: ${({ theme }) => theme.font.size.sm}; padding: 0; text-decoration: underline; margin-left: 0; &:hover { color: ${({ theme }) => theme.font.color.secondary}; } `; const StyledDivider = styled.div` margin: ${({ theme }) => theme.spacing(6)} 0; width: 100%; `; export const SettingsTwoFactorAuthenticationMethod = () => { const { t } = useLingui(); const theme = useTheme(); const { enqueueSuccessSnackBar } = useSnackBar(); const qrCode = useRecoilValue(qrCodeState); const { currentUserWorkspaceTwoFactorAuthenticationMethods } = useCurrentUserWorkspaceTwoFactorAuthentication(); const has2FAMethod = currentUserWorkspaceTwoFactorAuthenticationMethods['TOTP']?.status === 'VERIFIED'; const verificationForm = useTwoFactorVerificationForSettings(); const shouldShowActionButtons = !has2FAMethod; const handleCopySetupKey = async () => { if (!qrCode) return; const secret = extractSecretFromOtpUri(qrCode); if (secret !== null) { await navigator.clipboard.writeText(secret); enqueueSuccessSnackBar({ message: t`Setup key copied to clipboard`, options: { icon: , duration: 2000, }, }); } }; return ( // eslint-disable-next-line react/jsx-props-no-spreading User, href: getSettingsPath(SettingsPath.ProfilePage), }, { children: Profile, href: getSettingsPath(SettingsPath.ProfilePage), }, { children: Two-Factor Authentication, }, ]} actionButton={ shouldShowActionButtons ? ( ) : undefined } > {has2FAMethod ? (
) : (
{!qrCode ? ( ) : ( <> Can't scan? Copy the{' '} setup key )}
)}
); };