diff --git a/packages/web/src/javascripts/Components/Preferences/Panes/Security/Security.tsx b/packages/web/src/javascripts/Components/Preferences/Panes/Security/Security.tsx index 66e8d1430f6..6ed50686405 100644 --- a/packages/web/src/javascripts/Components/Preferences/Panes/Security/Security.tsx +++ b/packages/web/src/javascripts/Components/Preferences/Panes/Security/Security.tsx @@ -1,8 +1,7 @@ import { NativeFeatureIdentifier, FeatureStatus } from '@standardnotes/snjs' -import { FunctionComponent, useState } from 'react' +import { FunctionComponent, useEffect, useState } from 'react' import { WebApplication } from '@/Application/WebApplication' -import TwoFactorAuthWrapper from './TwoFactorAuth/TwoFactorAuthWrapper' import Encryption from './Encryption' import PasscodeLock from './PasscodeLock' import Privacy from './Privacy' @@ -11,8 +10,9 @@ import ErroredItems from './ErroredItems' import PreferencesPane from '@/Components/Preferences/PreferencesComponents/PreferencesPane' import BiometricsLock from '@/Components/Preferences/Panes/Security/BiometricsLock' import MultitaskingPrivacy from '@/Components/Preferences/Panes/Security/MultitaskingPrivacy' -import U2FWrapper from './U2F/U2FWrapper' import { TwoFactorAuth, is2FAEnabled as checkIf2FAIsEnabled } from './TwoFactorAuth/TwoFactorAuth' +import U2FView from './U2F/U2FView/U2FView' +import TwoFactorAuthView from './TwoFactorAuth/TwoFactorAuthView/TwoFactorAuthView' interface SecurityProps { application: WebApplication @@ -21,6 +21,7 @@ interface SecurityProps { const Security: FunctionComponent = (props) => { const isNativeMobileWeb = props.application.isNativeMobileWeb() const [is2FAEnabled, setIs2FAEnabled] = useState(false) + const [canDisable2FA, setCanDisable2FA] = useState(true) const [auth] = useState( () => @@ -28,7 +29,14 @@ const Security: FunctionComponent = (props) => { setIs2FAEnabled(checkIf2FAIsEnabled(status)), ), ) - auth.fetchStatus() + + useEffect(() => { + auth.fetchStatus() + }, [auth]) + + const onU2FDevicesLoaded = (devices: Array<{ id: string; name: string }>) => { + setCanDisable2FA(devices.length === 0) + } const isU2FFeatureAvailable = props.application.features.getFeatureStatus( @@ -40,8 +48,14 @@ const Security: FunctionComponent = (props) => { {props.application.items.invalidNonVaultedItems.length > 0 && } - - {isU2FFeatureAvailable && } + + {isU2FFeatureAvailable && ( + + )} {isNativeMobileWeb && } {isNativeMobileWeb && } diff --git a/packages/web/src/javascripts/Components/Preferences/Panes/Security/TwoFactorAuth/MfaProps.ts b/packages/web/src/javascripts/Components/Preferences/Panes/Security/TwoFactorAuth/MfaProps.ts deleted file mode 100644 index 2fb45cd76cb..00000000000 --- a/packages/web/src/javascripts/Components/Preferences/Panes/Security/TwoFactorAuth/MfaProps.ts +++ /dev/null @@ -1,7 +0,0 @@ -import { WebApplication } from '@/Application/WebApplication' -import { TwoFactorAuth } from './TwoFactorAuth' - -export interface MfaProps { - application: WebApplication - auth: TwoFactorAuth -} diff --git a/packages/web/src/javascripts/Components/Preferences/Panes/Security/TwoFactorAuth/TwoFactorAuthView/TwoFactorAuthView.tsx b/packages/web/src/javascripts/Components/Preferences/Panes/Security/TwoFactorAuth/TwoFactorAuthView/TwoFactorAuthView.tsx index 28001198c78..af63accb284 100644 --- a/packages/web/src/javascripts/Components/Preferences/Panes/Security/TwoFactorAuth/TwoFactorAuthView/TwoFactorAuthView.tsx +++ b/packages/web/src/javascripts/Components/Preferences/Panes/Security/TwoFactorAuth/TwoFactorAuthView/TwoFactorAuthView.tsx @@ -16,9 +16,10 @@ import ModalOverlay from '@/Components/Modal/ModalOverlay' type Props = { auth: TwoFactorAuth application: WebApplication + canDisable2FA: boolean } -const TwoFactorAuthView: FunctionComponent = ({ auth, application }) => { +const TwoFactorAuthView: FunctionComponent = ({ auth, application, canDisable2FA }) => { const shouldShowActivationModal = auth.status !== 'fetching' && is2FAActivation(auth.status) const activationModalTitle = shouldShowActivationModal @@ -96,7 +97,7 @@ const TwoFactorAuthView: FunctionComponent = ({ auth, application }) => { - + diff --git a/packages/web/src/javascripts/Components/Preferences/Panes/Security/TwoFactorAuth/TwoFactorAuthView/TwoFactorSwitch.tsx b/packages/web/src/javascripts/Components/Preferences/Panes/Security/TwoFactorAuth/TwoFactorAuthView/TwoFactorSwitch.tsx index eecfb8b99cf..dab2a2bda94 100644 --- a/packages/web/src/javascripts/Components/Preferences/Panes/Security/TwoFactorAuth/TwoFactorAuthView/TwoFactorSwitch.tsx +++ b/packages/web/src/javascripts/Components/Preferences/Panes/Security/TwoFactorAuth/TwoFactorAuthView/TwoFactorSwitch.tsx @@ -6,9 +6,10 @@ import Spinner from '@/Components/Spinner/Spinner' type Props = { auth: TwoFactorAuth + canDisable2FA: boolean } -const TwoFactorSwitch: FunctionComponent = ({ auth }) => { +const TwoFactorSwitch: FunctionComponent = ({ auth, canDisable2FA }) => { if (!auth.isLoggedIn()) { return null } @@ -17,7 +18,9 @@ const TwoFactorSwitch: FunctionComponent = ({ auth }) => { return } - return + const shouldSwitchBeDisabled = auth.status === 'two-factor-enabled' && !canDisable2FA + + return } export default observer(TwoFactorSwitch) diff --git a/packages/web/src/javascripts/Components/Preferences/Panes/Security/TwoFactorAuth/TwoFactorAuthWrapper.tsx b/packages/web/src/javascripts/Components/Preferences/Panes/Security/TwoFactorAuth/TwoFactorAuthWrapper.tsx deleted file mode 100644 index 5e575beab62..00000000000 --- a/packages/web/src/javascripts/Components/Preferences/Panes/Security/TwoFactorAuth/TwoFactorAuthWrapper.tsx +++ /dev/null @@ -1,10 +0,0 @@ -import { FunctionComponent } from 'react' - -import { MfaProps } from './MfaProps' -import TwoFactorAuthView from './TwoFactorAuthView/TwoFactorAuthView' - -const TwoFactorAuthWrapper: FunctionComponent = (props) => { - return -} - -export default TwoFactorAuthWrapper diff --git a/packages/web/src/javascripts/Components/Preferences/Panes/Security/U2F/U2FProps.ts b/packages/web/src/javascripts/Components/Preferences/Panes/Security/U2F/U2FProps.ts deleted file mode 100644 index 20f0ab8e63e..00000000000 --- a/packages/web/src/javascripts/Components/Preferences/Panes/Security/U2F/U2FProps.ts +++ /dev/null @@ -1,6 +0,0 @@ -import { WebApplication } from '@/Application/WebApplication' - -export interface U2FProps { - application: WebApplication - is2FAEnabled: boolean -} diff --git a/packages/web/src/javascripts/Components/Preferences/Panes/Security/U2F/U2FView/U2FView.tsx b/packages/web/src/javascripts/Components/Preferences/Panes/Security/U2F/U2FView/U2FView.tsx index cbaa42750af..e997e669849 100644 --- a/packages/web/src/javascripts/Components/Preferences/Panes/Security/U2F/U2FView/U2FView.tsx +++ b/packages/web/src/javascripts/Components/Preferences/Panes/Security/U2F/U2FView/U2FView.tsx @@ -16,9 +16,10 @@ import RecoveryCodeBanner from '@/Components/RecoveryCodeBanner/RecoveryCodeBann type Props = { application: WebApplication is2FAEnabled: boolean + loadAuthenticatorsCallback: (devices: Array<{ id: string; name: string }>) => void } -const U2FView: FunctionComponent = ({ application, is2FAEnabled }) => { +const U2FView: FunctionComponent = ({ application, is2FAEnabled, loadAuthenticatorsCallback }) => { const [showDeviceAddingModal, setShowDeviceAddingModal] = useState(false) const [devices, setDevices] = useState>([]) const [error, setError] = useState('') @@ -35,8 +36,10 @@ const U2FView: FunctionComponent = ({ application, is2FAEnabled }) => { return } - setDevices(authenticatorListOrError.getValue()) - }, [setError, setDevices, application]) + const authenticatorList = authenticatorListOrError.getValue() + setDevices(authenticatorList) + loadAuthenticatorsCallback(authenticatorList) + }, [setError, setDevices, application, loadAuthenticatorsCallback]) useEffect(() => { loadAuthenticatorDevices().catch(console.error) diff --git a/packages/web/src/javascripts/Components/Preferences/Panes/Security/U2F/U2FWrapper.tsx b/packages/web/src/javascripts/Components/Preferences/Panes/Security/U2F/U2FWrapper.tsx deleted file mode 100644 index d8d098e76ea..00000000000 --- a/packages/web/src/javascripts/Components/Preferences/Panes/Security/U2F/U2FWrapper.tsx +++ /dev/null @@ -1,10 +0,0 @@ -import { FunctionComponent } from 'react' - -import { U2FProps } from './U2FProps' -import U2FView from './U2FView/U2FView' - -const U2FWrapper: FunctionComponent = (props) => { - return -} - -export default U2FWrapper