refactor(web): dependency management (#2386)
This commit is contained in:
@@ -15,39 +15,23 @@ import Vaults from './Panes/Vaults/Vaults'
|
||||
|
||||
const PaneSelector: FunctionComponent<PreferencesProps & { menu: PreferencesSessionController }> = ({
|
||||
menu,
|
||||
viewControllerManager,
|
||||
application,
|
||||
mfaProvider,
|
||||
userProvider,
|
||||
}) => {
|
||||
switch (menu.selectedPaneId) {
|
||||
case 'general':
|
||||
return (
|
||||
<General
|
||||
viewControllerManager={viewControllerManager}
|
||||
application={application}
|
||||
extensionsLatestVersions={menu.extensionsLatestVersions}
|
||||
/>
|
||||
)
|
||||
return <General application={application} extensionsLatestVersions={menu.extensionsLatestVersions} />
|
||||
case 'account':
|
||||
return <AccountPreferences application={application} viewControllerManager={viewControllerManager} />
|
||||
return <AccountPreferences application={application} />
|
||||
case 'appearance':
|
||||
return <Appearance application={application} />
|
||||
case 'home-server':
|
||||
return <HomeServer />
|
||||
case 'security':
|
||||
return (
|
||||
<Security
|
||||
mfaProvider={mfaProvider}
|
||||
userProvider={userProvider}
|
||||
viewControllerManager={viewControllerManager}
|
||||
application={application}
|
||||
/>
|
||||
)
|
||||
return <Security application={application} />
|
||||
case 'vaults':
|
||||
return <Vaults />
|
||||
case 'backups':
|
||||
return <Backups application={application} viewControllerManager={viewControllerManager} />
|
||||
return <Backups application={application} />
|
||||
case 'listed':
|
||||
return <Listed application={application} />
|
||||
case 'shortcuts':
|
||||
@@ -61,13 +45,7 @@ const PaneSelector: FunctionComponent<PreferencesProps & { menu: PreferencesSess
|
||||
case 'whats-new':
|
||||
return <WhatsNew application={application} />
|
||||
default:
|
||||
return (
|
||||
<General
|
||||
viewControllerManager={viewControllerManager}
|
||||
application={application}
|
||||
extensionsLatestVersions={menu.extensionsLatestVersions}
|
||||
/>
|
||||
)
|
||||
return <General application={application} extensionsLatestVersions={menu.extensionsLatestVersions} />
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
import { observer } from 'mobx-react-lite'
|
||||
|
||||
import { WebApplication } from '@/Application/WebApplication'
|
||||
import { ViewControllerManager } from '@/Controllers/ViewControllerManager'
|
||||
import Authentication from './Authentication'
|
||||
import Credentials from './Credentials'
|
||||
import Sync from './Sync'
|
||||
@@ -15,30 +14,29 @@ import DeleteAccount from '@/Components/Preferences/Panes/Account/DeleteAccount'
|
||||
|
||||
type Props = {
|
||||
application: WebApplication
|
||||
viewControllerManager: ViewControllerManager
|
||||
}
|
||||
|
||||
const AccountPreferences = ({ application, viewControllerManager }: Props) => {
|
||||
const AccountPreferences = ({ application }: Props) => {
|
||||
const isUsingThirdPartyServer = application.isThirdPartyHostUsed()
|
||||
|
||||
return (
|
||||
<PreferencesPane>
|
||||
{!application.hasAccount() ? (
|
||||
<Authentication application={application} viewControllerManager={viewControllerManager} />
|
||||
<Authentication application={application} />
|
||||
) : (
|
||||
<>
|
||||
<Credentials application={application} viewControllerManager={viewControllerManager} />
|
||||
<Credentials application={application} />
|
||||
<Sync application={application} />
|
||||
</>
|
||||
)}
|
||||
<Subscription />
|
||||
<SubscriptionSharing application={application} viewControllerManager={viewControllerManager} />
|
||||
{application.hasAccount() && viewControllerManager.featuresController.entitledToFiles && (
|
||||
<SubscriptionSharing application={application} />
|
||||
{application.hasAccount() && application.featuresController.entitledToFiles && (
|
||||
<FilesSection application={application} />
|
||||
)}
|
||||
{application.hasAccount() && !isUsingThirdPartyServer && <Email application={application} />}
|
||||
<SignOutWrapper application={application} viewControllerManager={viewControllerManager} />
|
||||
<DeleteAccount application={application} viewControllerManager={viewControllerManager} />
|
||||
<SignOutWrapper application={application} />
|
||||
<DeleteAccount application={application} />
|
||||
</PreferencesPane>
|
||||
)
|
||||
}
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
import Button from '@/Components/Button/Button'
|
||||
import { Title } from '@/Components/Preferences/PreferencesComponents/Content'
|
||||
import { WebApplication } from '@/Application/WebApplication'
|
||||
import { ViewControllerManager } from '@/Controllers/ViewControllerManager'
|
||||
import { observer } from 'mobx-react-lite'
|
||||
import { FunctionComponent } from 'react'
|
||||
import { AccountIllustration } from '@standardnotes/icons'
|
||||
@@ -11,20 +10,19 @@ import PreferencesSegment from '../../PreferencesComponents/PreferencesSegment'
|
||||
|
||||
type Props = {
|
||||
application: WebApplication
|
||||
viewControllerManager: ViewControllerManager
|
||||
}
|
||||
|
||||
const Authentication: FunctionComponent<Props> = ({ viewControllerManager }) => {
|
||||
const Authentication: FunctionComponent<Props> = ({ application }) => {
|
||||
const clickSignIn = () => {
|
||||
viewControllerManager.preferencesController.closePreferences()
|
||||
viewControllerManager.accountMenuController.setCurrentPane(AccountMenuPane.SignIn)
|
||||
viewControllerManager.accountMenuController.setShow(true)
|
||||
application.preferencesController.closePreferences()
|
||||
application.accountMenuController.setCurrentPane(AccountMenuPane.SignIn)
|
||||
application.accountMenuController.setShow(true)
|
||||
}
|
||||
|
||||
const clickRegister = () => {
|
||||
viewControllerManager.preferencesController.closePreferences()
|
||||
viewControllerManager.accountMenuController.setCurrentPane(AccountMenuPane.Register)
|
||||
viewControllerManager.accountMenuController.setShow(true)
|
||||
application.preferencesController.closePreferences()
|
||||
application.accountMenuController.setCurrentPane(AccountMenuPane.Register)
|
||||
application.accountMenuController.setShow(true)
|
||||
}
|
||||
|
||||
return (
|
||||
|
||||
@@ -1,14 +1,14 @@
|
||||
import Button from '@/Components/Button/Button'
|
||||
import { ViewControllerManager } from '@/Controllers/ViewControllerManager'
|
||||
import { observer } from 'mobx-react-lite'
|
||||
import { FunctionComponent } from 'react'
|
||||
import { Title, Text } from '../../PreferencesComponents/Content'
|
||||
import PreferencesGroup from '../../PreferencesComponents/PreferencesGroup'
|
||||
import PreferencesSegment from '../../PreferencesComponents/PreferencesSegment'
|
||||
import { useApplication } from '@/Components/ApplicationProvider'
|
||||
|
||||
const ClearSessionDataView: FunctionComponent = () => {
|
||||
const application = useApplication()
|
||||
|
||||
const ClearSessionDataView: FunctionComponent<{
|
||||
viewControllerManager: ViewControllerManager
|
||||
}> = ({ viewControllerManager }) => {
|
||||
return (
|
||||
<PreferencesGroup>
|
||||
<PreferencesSegment>
|
||||
@@ -18,7 +18,7 @@ const ClearSessionDataView: FunctionComponent<{
|
||||
colorStyle="danger"
|
||||
label="Clear workspace"
|
||||
onClick={() => {
|
||||
viewControllerManager.accountMenuController.setSigningOut(true)
|
||||
application.accountMenuController.setSigningOut(true)
|
||||
}}
|
||||
/>
|
||||
</PreferencesSegment>
|
||||
|
||||
@@ -6,7 +6,6 @@ import HorizontalSeparator from '@/Components/Shared/HorizontalSeparator'
|
||||
import { dateToLocalizedString } from '@standardnotes/snjs'
|
||||
import { useCallback, useState, FunctionComponent } from 'react'
|
||||
import ChangeEmail from '@/Components/Preferences/Panes/Account/ChangeEmail/ChangeEmail'
|
||||
import { ViewControllerManager } from '@/Controllers/ViewControllerManager'
|
||||
import PasswordWizard from '@/Components/PasswordWizard/PasswordWizard'
|
||||
import PreferencesGroup from '../../PreferencesComponents/PreferencesGroup'
|
||||
import PreferencesSegment from '../../PreferencesComponents/PreferencesSegment'
|
||||
@@ -14,14 +13,13 @@ import ModalOverlay from '@/Components/Modal/ModalOverlay'
|
||||
|
||||
type Props = {
|
||||
application: WebApplication
|
||||
viewControllerManager: ViewControllerManager
|
||||
}
|
||||
|
||||
const Credentials: FunctionComponent<Props> = ({ application }: Props) => {
|
||||
const [isChangeEmailDialogOpen, setIsChangeEmailDialogOpen] = useState(false)
|
||||
const [shouldShowPasswordWizard, setShouldShowPasswordWizard] = useState(false)
|
||||
|
||||
const user = application.getUser()
|
||||
const user = application.sessions.getUser()
|
||||
|
||||
const passwordCreatedAtTimestamp = application.getUserPasswordCreationDate() as Date
|
||||
const passwordCreatedOn = dateToLocalizedString(passwordCreatedAtTimestamp)
|
||||
|
||||
@@ -3,15 +3,13 @@ import PreferencesSegment from '@/Components/Preferences/PreferencesComponents/P
|
||||
import { Text, Title } from '@/Components/Preferences/PreferencesComponents/Content'
|
||||
import Button from '@/Components/Button/Button'
|
||||
import PreferencesGroup from '@/Components/Preferences/PreferencesComponents/PreferencesGroup'
|
||||
import { ViewControllerManager } from '@Controllers/ViewControllerManager'
|
||||
import { WebApplication } from '@/Application/WebApplication'
|
||||
|
||||
type Props = {
|
||||
application: WebApplication
|
||||
viewControllerManager: ViewControllerManager
|
||||
}
|
||||
|
||||
const DeleteAccount = ({ application, viewControllerManager }: Props) => {
|
||||
const DeleteAccount = ({ application }: Props) => {
|
||||
if (!application.hasAccount()) {
|
||||
return null
|
||||
}
|
||||
@@ -25,7 +23,7 @@ const DeleteAccount = ({ application, viewControllerManager }: Props) => {
|
||||
colorStyle="danger"
|
||||
label="Delete my account"
|
||||
onClick={() => {
|
||||
viewControllerManager.accountMenuController.setDeletingAccount(true)
|
||||
application.accountMenuController.setDeletingAccount(true)
|
||||
}}
|
||||
/>
|
||||
</div>
|
||||
|
||||
@@ -43,7 +43,7 @@ const Email: FunctionComponent<Props> = ({ application }: Props) => {
|
||||
}
|
||||
|
||||
const loadSettings = useCallback(async () => {
|
||||
if (!application.getUser()) {
|
||||
if (!application.sessions.getUser()) {
|
||||
return
|
||||
}
|
||||
setIsLoading(true)
|
||||
|
||||
@@ -2,7 +2,6 @@ import Button from '@/Components/Button/Button'
|
||||
import OtherSessionsSignOutContainer from '@/Components/OtherSessionsSignOut/OtherSessionsSignOut'
|
||||
import HorizontalSeparator from '@/Components/Shared/HorizontalSeparator'
|
||||
import { WebApplication } from '@/Application/WebApplication'
|
||||
import { ViewControllerManager } from '@/Controllers/ViewControllerManager'
|
||||
import { observer } from 'mobx-react-lite'
|
||||
import { FunctionComponent } from 'react'
|
||||
import { Subtitle, Title, Text } from '../../PreferencesComponents/Content'
|
||||
@@ -12,10 +11,9 @@ import ClearSessionDataView from './ClearSessionDataView'
|
||||
|
||||
type Props = {
|
||||
application: WebApplication
|
||||
viewControllerManager: ViewControllerManager
|
||||
}
|
||||
|
||||
const SignOutView: FunctionComponent<Props> = observer(({ application, viewControllerManager }) => {
|
||||
const SignOutView: FunctionComponent<Props> = observer(({ application }) => {
|
||||
return (
|
||||
<>
|
||||
<PreferencesGroup>
|
||||
@@ -27,10 +25,10 @@ const SignOutView: FunctionComponent<Props> = observer(({ application, viewContr
|
||||
<Button
|
||||
label="Sign out other sessions"
|
||||
onClick={() => {
|
||||
viewControllerManager.accountMenuController.setOtherSessionsSignOut(true)
|
||||
application.accountMenuController.setOtherSessionsSignOut(true)
|
||||
}}
|
||||
/>
|
||||
<Button label="Manage sessions" onClick={() => viewControllerManager.openSessionsModal()} />
|
||||
<Button label="Manage sessions" onClick={() => application.openSessionsModal()} />
|
||||
</div>
|
||||
</PreferencesSegment>
|
||||
<HorizontalSeparator classes="my-4" />
|
||||
@@ -42,23 +40,23 @@ const SignOutView: FunctionComponent<Props> = observer(({ application, viewContr
|
||||
colorStyle="danger"
|
||||
label="Sign out workspace"
|
||||
onClick={() => {
|
||||
viewControllerManager.accountMenuController.setSigningOut(true)
|
||||
application.accountMenuController.setSigningOut(true)
|
||||
}}
|
||||
/>
|
||||
</PreferencesSegment>
|
||||
</PreferencesGroup>
|
||||
<OtherSessionsSignOutContainer viewControllerManager={viewControllerManager} application={application} />
|
||||
<OtherSessionsSignOutContainer application={application} />
|
||||
</>
|
||||
)
|
||||
})
|
||||
|
||||
SignOutView.displayName = 'SignOutView'
|
||||
|
||||
const SignOutWrapper: FunctionComponent<Props> = ({ application, viewControllerManager }) => {
|
||||
const SignOutWrapper: FunctionComponent<Props> = ({ application }) => {
|
||||
if (!application.hasAccount()) {
|
||||
return <ClearSessionDataView viewControllerManager={viewControllerManager} />
|
||||
return <ClearSessionDataView />
|
||||
}
|
||||
return <SignOutView viewControllerManager={viewControllerManager} application={application} />
|
||||
return <SignOutView application={application} />
|
||||
}
|
||||
|
||||
export default observer(SignOutWrapper)
|
||||
|
||||
@@ -12,16 +12,16 @@ const Subscription: FunctionComponent = () => {
|
||||
const application = useApplication()
|
||||
|
||||
const [onlineSubscription, setOnlineSubscription] = useState<Subscription | undefined>(
|
||||
application.controllers.subscriptionController.onlineSubscription,
|
||||
application.subscriptionController.onlineSubscription,
|
||||
)
|
||||
|
||||
useEffect(() => {
|
||||
return application.subscriptions.addEventObserver((event) => {
|
||||
if (event === SubscriptionManagerEvent.DidFetchSubscription) {
|
||||
setOnlineSubscription(application.controllers.subscriptionController.onlineSubscription)
|
||||
setOnlineSubscription(application.subscriptionController.onlineSubscription)
|
||||
}
|
||||
})
|
||||
}, [application.subscriptions, application.controllers.subscriptionController])
|
||||
}, [application.subscriptions, application.subscriptionController])
|
||||
|
||||
useEffect(() => {
|
||||
void application.subscriptions.fetchOnlineSubscription()
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
import { observer } from 'mobx-react-lite'
|
||||
import Button from '@/Components/Button/Button'
|
||||
import { openSubscriptionDashboard } from '@/Utils/ManageSubscription'
|
||||
import SubscriptionStatusText from './SubscriptionStatusText'
|
||||
import { useApplication } from '@/Components/ApplicationProvider'
|
||||
|
||||
@@ -8,7 +7,7 @@ const SubscriptionInformation = () => {
|
||||
const application = useApplication()
|
||||
|
||||
const manageSubscription = async () => {
|
||||
void openSubscriptionDashboard(application)
|
||||
void application.openSubscriptionDashboard.execute()
|
||||
}
|
||||
|
||||
return (
|
||||
|
||||
@@ -1,10 +1,8 @@
|
||||
import { FeatureStatus, NativeFeatureIdentifier } from '@standardnotes/snjs'
|
||||
import { observer } from 'mobx-react-lite'
|
||||
import { FunctionComponent, useState } from 'react'
|
||||
|
||||
import { Title } from '@/Components/Preferences/PreferencesComponents/Content'
|
||||
import { WebApplication } from '@/Application/WebApplication'
|
||||
import { ViewControllerManager } from '@/Controllers/ViewControllerManager'
|
||||
import PreferencesGroup from '@/Components/Preferences/PreferencesComponents/PreferencesGroup'
|
||||
import PreferencesSegment from '@/Components/Preferences/PreferencesComponents/PreferencesSegment'
|
||||
import HorizontalSeparator from '@/Components/Shared/HorizontalSeparator'
|
||||
@@ -18,13 +16,12 @@ import ModalOverlay from '@/Components/Modal/ModalOverlay'
|
||||
|
||||
type Props = {
|
||||
application: WebApplication
|
||||
viewControllerManager: ViewControllerManager
|
||||
}
|
||||
|
||||
const SubscriptionSharing: FunctionComponent<Props> = ({ application, viewControllerManager }: Props) => {
|
||||
const SubscriptionSharing: FunctionComponent<Props> = ({ application }: Props) => {
|
||||
const [isInviteDialogOpen, setIsInviteDialogOpen] = useState(false)
|
||||
|
||||
const subscriptionState = viewControllerManager.subscriptionController
|
||||
const subscriptionState = application.subscriptionController
|
||||
|
||||
const isReadOnlySession = application.sessions.isCurrentSessionReadOnly()
|
||||
|
||||
|
||||
@@ -1,5 +1,4 @@
|
||||
import { WebApplication } from '@/Application/WebApplication'
|
||||
import { ViewControllerManager } from '@/Controllers/ViewControllerManager'
|
||||
import { FunctionComponent } from 'react'
|
||||
import PreferencesPane from '@/Components/Preferences/PreferencesComponents/PreferencesPane'
|
||||
import DataBackups from './DataBackups'
|
||||
@@ -10,16 +9,15 @@ import TextBackupsCrossPlatform from './TextBackups/TextBackupsCrossPlatform'
|
||||
import PlaintextBackupsCrossPlatform from './PlaintextBackups/PlaintextBackupsCrossPlatform'
|
||||
|
||||
type Props = {
|
||||
viewControllerManager: ViewControllerManager
|
||||
application: WebApplication
|
||||
}
|
||||
|
||||
const Backups: FunctionComponent<Props> = ({ application, viewControllerManager }) => {
|
||||
const Backups: FunctionComponent<Props> = ({ application }) => {
|
||||
const isUsingThirdPartyServer = application.isThirdPartyHostUsed()
|
||||
|
||||
return (
|
||||
<PreferencesPane>
|
||||
<DataBackups application={application} viewControllerManager={viewControllerManager} />
|
||||
<DataBackups application={application} />
|
||||
<TextBackupsCrossPlatform application={application} />
|
||||
<PlaintextBackupsCrossPlatform />
|
||||
<FileBackupsCrossPlatform application={application} />
|
||||
|
||||
@@ -12,7 +12,6 @@ import {
|
||||
import { BackupFile } from '@standardnotes/snjs'
|
||||
import { ChangeEventHandler, MouseEventHandler, useCallback, useEffect, useRef, useState } from 'react'
|
||||
import { WebApplication } from '@/Application/WebApplication'
|
||||
import { ViewControllerManager } from '@/Controllers/ViewControllerManager'
|
||||
import { observer } from 'mobx-react-lite'
|
||||
import { Title, Subtitle } from '@/Components/Preferences/PreferencesComponents/Content'
|
||||
import Button from '@/Components/Button/Button'
|
||||
@@ -24,10 +23,9 @@ import { downloadOrShareBlobBasedOnPlatform } from '@/Utils/DownloadOrShareBased
|
||||
|
||||
type Props = {
|
||||
application: WebApplication
|
||||
viewControllerManager: ViewControllerManager
|
||||
}
|
||||
|
||||
const DataBackups = ({ application, viewControllerManager }: Props) => {
|
||||
const DataBackups = ({ application }: Props) => {
|
||||
const fileInputRef = useRef<HTMLInputElement>(null)
|
||||
const [isImportDataLoading, setIsImportDataLoading] = useState(false)
|
||||
const {
|
||||
@@ -36,7 +34,7 @@ const DataBackups = ({ application, viewControllerManager }: Props) => {
|
||||
setIsBackupEncrypted,
|
||||
setIsEncryptionEnabled,
|
||||
setEncryptionStatusString,
|
||||
} = viewControllerManager.accountMenuController
|
||||
} = application.accountMenuController
|
||||
|
||||
const refreshEncryptionStatus = useCallback(() => {
|
||||
const hasUser = application.hasAccount()
|
||||
@@ -73,16 +71,30 @@ const DataBackups = ({ application, viewControllerManager }: Props) => {
|
||||
})
|
||||
|
||||
if (isBackupEncrypted) {
|
||||
const filename = `Standard Notes Encrypted Backup and Import File - ${application
|
||||
.getArchiveService()
|
||||
.formattedDateForExports()}`
|
||||
const filename = `Standard Notes Encrypted Backup and Import File - ${application.archiveService.formattedDateForExports()}`
|
||||
const sanitizedFilename = sanitizeFileName(filename) + '.txt'
|
||||
void downloadOrShareBlobBasedOnPlatform(application, blobData, sanitizedFilename)
|
||||
void downloadOrShareBlobBasedOnPlatform({
|
||||
archiveService: application.archiveService,
|
||||
platform: application.platform,
|
||||
mobileDevice: application.mobileDevice,
|
||||
blob: blobData,
|
||||
filename: sanitizedFilename,
|
||||
isNativeMobileWeb: application.isNativeMobileWeb(),
|
||||
showToastOnAndroid: undefined,
|
||||
})
|
||||
} else {
|
||||
const zippedDecryptedItemsBlob = await application.getArchiveService().getZippedDecryptedItemsBlob(data)
|
||||
const filename = `Standard Notes Backup - ${application.getArchiveService().formattedDateForExports()}`
|
||||
const zippedDecryptedItemsBlob = await application.archiveService.getZippedDecryptedItemsBlob(data)
|
||||
const filename = `Standard Notes Backup - ${application.archiveService.formattedDateForExports()}`
|
||||
const sanitizedFilename = sanitizeFileName(filename) + '.zip'
|
||||
void downloadOrShareBlobBasedOnPlatform(application, zippedDecryptedItemsBlob, sanitizedFilename)
|
||||
void downloadOrShareBlobBasedOnPlatform({
|
||||
archiveService: application.archiveService,
|
||||
platform: application.platform,
|
||||
mobileDevice: application.mobileDevice,
|
||||
blob: zippedDecryptedItemsBlob,
|
||||
filename: sanitizedFilename,
|
||||
isNativeMobileWeb: application.isNativeMobileWeb(),
|
||||
showToastOnAndroid: undefined,
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -25,7 +25,7 @@ const EmailBackups = ({ application }: Props) => {
|
||||
const hasAccount = application.hasAccount()
|
||||
|
||||
const loadEmailFrequencySetting = useCallback(async () => {
|
||||
if (!application.getUser()) {
|
||||
if (!application.sessions.getUser()) {
|
||||
return
|
||||
}
|
||||
setIsLoading(true)
|
||||
|
||||
@@ -41,7 +41,7 @@ const TextBackupsDesktop = ({ backupsService }: Props) => {
|
||||
}, [backupsEnabled, backupsService])
|
||||
|
||||
const performBackup = useCallback(async () => {
|
||||
void application.getDesktopService()?.saveDesktopBackup()
|
||||
void application.desktopManager?.saveDesktopBackup()
|
||||
}, [application])
|
||||
|
||||
return (
|
||||
|
||||
@@ -2,7 +2,6 @@ import { FunctionComponent } from 'react'
|
||||
import OfflineSubscription from '@/Components/Preferences/Panes/General/Advanced/OfflineSubscription'
|
||||
import { WebApplication } from '@/Application/WebApplication'
|
||||
import { observer } from 'mobx-react-lite'
|
||||
import { ViewControllerManager } from '@/Controllers/ViewControllerManager'
|
||||
import PackagesPreferencesSection from '@/Components/Preferences/Panes/General/Advanced/Packages/Section'
|
||||
import { PackageProvider } from '@/Components/Preferences/Panes/General/Advanced/Packages/Provider/PackageProvider'
|
||||
import AccordionItem from '@/Components/Shared/AccordionItem'
|
||||
@@ -11,18 +10,17 @@ import PreferencesSegment from '../../../PreferencesComponents/PreferencesSegmen
|
||||
|
||||
type Props = {
|
||||
application: WebApplication
|
||||
viewControllerManager: ViewControllerManager
|
||||
extensionsLatestVersions: PackageProvider
|
||||
}
|
||||
|
||||
const Advanced: FunctionComponent<Props> = ({ application, viewControllerManager, extensionsLatestVersions }) => {
|
||||
const Advanced: FunctionComponent<Props> = ({ application, extensionsLatestVersions }) => {
|
||||
return (
|
||||
<PreferencesGroup>
|
||||
<PreferencesSegment>
|
||||
<AccordionItem title={'Advanced options'}>
|
||||
<div className="flex flex-row items-center">
|
||||
<div className="flex max-w-full flex-grow flex-col">
|
||||
<OfflineSubscription application={application} viewControllerManager={viewControllerManager} />
|
||||
<OfflineSubscription application={application} />
|
||||
<PackagesPreferencesSection
|
||||
className={'mt-3'}
|
||||
application={application}
|
||||
|
||||
@@ -3,7 +3,6 @@ import { Subtitle } from '@/Components/Preferences/PreferencesComponents/Content
|
||||
import DecoratedInput from '@/Components/Input/DecoratedInput'
|
||||
import Button from '@/Components/Button/Button'
|
||||
import { WebApplication } from '@/Application/WebApplication'
|
||||
import { ViewControllerManager } from '@/Controllers/ViewControllerManager'
|
||||
import { observer } from 'mobx-react-lite'
|
||||
import { STRING_REMOVE_OFFLINE_KEY_CONFIRMATION } from '@/Constants/Strings'
|
||||
import { ButtonType, ClientDisplayableError } from '@standardnotes/snjs'
|
||||
@@ -11,7 +10,6 @@ import HorizontalSeparator from '@/Components/Shared/HorizontalSeparator'
|
||||
|
||||
type Props = {
|
||||
application: WebApplication
|
||||
viewControllerManager: ViewControllerManager
|
||||
onSuccess?: () => void
|
||||
}
|
||||
|
||||
@@ -46,7 +44,7 @@ const OfflineSubscription: FunctionComponent<Props> = ({ application, onSuccess
|
||||
return
|
||||
}
|
||||
|
||||
const signedInUser = application.getUser()
|
||||
const signedInUser = application.sessions.getUser()
|
||||
if (!signedInUser) {
|
||||
return
|
||||
}
|
||||
|
||||
@@ -34,12 +34,12 @@ const PackageEntry: FunctionComponent<PackageEntryProps> = ({ application, exten
|
||||
const toggleOfflineOnly = () => {
|
||||
const newOfflineOnly = !offlineOnly
|
||||
setOfflineOnly(newOfflineOnly)
|
||||
application
|
||||
.changeAndSaveItem<ComponentMutator>(extension, (mutator) => {
|
||||
application.changeAndSaveItem
|
||||
.execute<ComponentMutator>(extension, (mutator) => {
|
||||
mutator.offlineOnly = newOfflineOnly
|
||||
})
|
||||
.then((item) => {
|
||||
const component = item as ComponentInterface
|
||||
.then((result) => {
|
||||
const component = result.getValue() as ComponentInterface
|
||||
setOfflineOnly(component.offlineOnly)
|
||||
})
|
||||
.catch((e) => {
|
||||
@@ -49,12 +49,12 @@ const PackageEntry: FunctionComponent<PackageEntryProps> = ({ application, exten
|
||||
|
||||
const changeExtensionName = (newName: string) => {
|
||||
setExtensionName(newName)
|
||||
application
|
||||
.changeAndSaveItem<ComponentMutator>(extension, (mutator) => {
|
||||
application.changeAndSaveItem
|
||||
.execute<ComponentMutator>(extension, (mutator) => {
|
||||
mutator.name = newName
|
||||
})
|
||||
.then((item) => {
|
||||
const component = item as ComponentInterface
|
||||
.then((result) => {
|
||||
const component = result.getValue() as ComponentInterface
|
||||
setExtensionName(component.name)
|
||||
})
|
||||
.catch(console.error)
|
||||
|
||||
@@ -1,5 +1,4 @@
|
||||
import { WebApplication } from '@/Application/WebApplication'
|
||||
import { ViewControllerManager } from '@/Controllers/ViewControllerManager'
|
||||
import { FunctionComponent } from 'react'
|
||||
import { PackageProvider } from '@/Components/Preferences/Panes/General/Advanced/Packages/Provider/PackageProvider'
|
||||
import { observer } from 'mobx-react-lite'
|
||||
@@ -13,24 +12,19 @@ import SmartViews from './SmartViews/SmartViews'
|
||||
import Moments from './Moments'
|
||||
|
||||
type Props = {
|
||||
viewControllerManager: ViewControllerManager
|
||||
application: WebApplication
|
||||
extensionsLatestVersions: PackageProvider
|
||||
}
|
||||
|
||||
const General: FunctionComponent<Props> = ({ viewControllerManager, application, extensionsLatestVersions }) => (
|
||||
const General: FunctionComponent<Props> = ({ application, extensionsLatestVersions }) => (
|
||||
<PreferencesPane>
|
||||
<Persistence application={application} />
|
||||
<Defaults application={application} />
|
||||
<Tools application={application} />
|
||||
<SmartViews application={application} featuresController={viewControllerManager.featuresController} />
|
||||
<SmartViews application={application} featuresController={application.featuresController} />
|
||||
<Moments application={application} />
|
||||
<LabsPane application={application} />
|
||||
<Advanced
|
||||
application={application}
|
||||
viewControllerManager={viewControllerManager}
|
||||
extensionsLatestVersions={extensionsLatestVersions}
|
||||
/>
|
||||
<Advanced application={application} extensionsLatestVersions={extensionsLatestVersions} />
|
||||
</PreferencesPane>
|
||||
)
|
||||
|
||||
|
||||
@@ -21,9 +21,9 @@ const Persistence = ({ application }: Props) => {
|
||||
setShouldPersistNoteState(shouldPersist)
|
||||
|
||||
if (shouldPersist) {
|
||||
application.controllers.persistValues()
|
||||
application.persistence.persistCurrentState()
|
||||
} else {
|
||||
application.controllers.clearPersistedValues()
|
||||
application.persistence.clearPersistedValues()
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -88,7 +88,7 @@ export class EditSmartViewModalController {
|
||||
|
||||
this.setIsSaving(true)
|
||||
|
||||
await this.application.changeAndSaveItem<SmartViewMutator>(this.view, (mutator) => {
|
||||
await this.application.changeAndSaveItem.execute<SmartViewMutator>(this.view, (mutator) => {
|
||||
mutator.title = this.title
|
||||
mutator.iconString = (this.icon as string) || SmartViewDefaultIconName
|
||||
mutator.predicate = JSON.parse(this.predicateJson) as PredicateJsonForm
|
||||
|
||||
@@ -33,7 +33,7 @@ const SmartViews = ({ application, featuresController }: Props) => {
|
||||
)
|
||||
|
||||
useEffect(() => {
|
||||
const disposeItemStream = application.streamItems([ContentType.TYPES.SmartView], () => {
|
||||
const disposeItemStream = application.items.streamItems([ContentType.TYPES.SmartView], () => {
|
||||
setSmartViews(application.items.getSmartViews().filter((view) => !isSystemView(view)))
|
||||
})
|
||||
|
||||
|
||||
@@ -9,7 +9,7 @@ import { MouseEventHandler } from 'react'
|
||||
const HelpAndFeedback = ({ application }: { application: WebApplication }) => {
|
||||
const openLinkOnMobile = (link: string) => {
|
||||
if (application.isNativeMobileWeb()) {
|
||||
application.mobileDevice().openUrl(link)
|
||||
application.mobileDevice.openUrl(link)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -25,7 +25,6 @@ const HomeServerSettings = () => {
|
||||
const homeServerService = application.homeServer as HomeServerServiceInterface
|
||||
const featuresService = application.features
|
||||
const sessionsService = application.sessions
|
||||
const viewControllerManager = application.controllers
|
||||
|
||||
const logsTextarea = useRef<HTMLTextAreaElement>(null)
|
||||
|
||||
@@ -392,7 +391,6 @@ const HomeServerSettings = () => {
|
||||
{showOfflineSubscriptionActivation && (
|
||||
<OfflineSubscription
|
||||
application={application}
|
||||
viewControllerManager={viewControllerManager}
|
||||
onSuccess={() => {
|
||||
setIsAPremiumUser(true)
|
||||
setShowOfflineSubscriptionActivation(false)
|
||||
|
||||
@@ -39,7 +39,7 @@ const StatusIndicator = ({ status, className, homeServerService }: Props) => {
|
||||
|
||||
useEffect(() => {
|
||||
async function updateSignedInStatus() {
|
||||
const signedInUser = application.getUser()
|
||||
const signedInUser = application.sessions.getUser()
|
||||
if (signedInUser) {
|
||||
const isUsingHomeServer = await application.isUsingHomeServer()
|
||||
if (isUsingHomeServer) {
|
||||
|
||||
@@ -84,13 +84,14 @@ const Listed = ({ application }: Props) => {
|
||||
<Subtitle>What is Listed?</Subtitle>
|
||||
<Text>
|
||||
Listed is a free blogging platform that allows you to create a public journal published directly from your
|
||||
notes. {!application.getUser() && 'To get started, sign in or register for a Standard Notes account.'}
|
||||
notes.{' '}
|
||||
{!application.sessions.getUser() && 'To get started, sign in or register for a Standard Notes account.'}
|
||||
</Text>
|
||||
<a className="mt-2 text-info" target="_blank" href="https://listed.to" rel="noreferrer noopener">
|
||||
Learn more
|
||||
</a>
|
||||
</PreferencesSegment>
|
||||
{application.getUser() && (
|
||||
{application.sessions.getUser() && (
|
||||
<>
|
||||
<HorizontalSeparator classes="my-4" />
|
||||
<PreferencesSegment>
|
||||
|
||||
@@ -1,16 +1,15 @@
|
||||
import { STRING_E2E_ENABLED, STRING_ENC_NOT_ENABLED, STRING_LOCAL_ENC_ENABLED } from '@/Constants/Strings'
|
||||
import { ViewControllerManager } from '@/Controllers/ViewControllerManager'
|
||||
import { observer } from 'mobx-react-lite'
|
||||
import { FunctionComponent } from 'react'
|
||||
import { Title, Text } from '../../PreferencesComponents/Content'
|
||||
import PreferencesGroup from '../../PreferencesComponents/PreferencesGroup'
|
||||
import PreferencesSegment from '../../PreferencesComponents/PreferencesSegment'
|
||||
import EncryptionEnabled from './EncryptionEnabled'
|
||||
import { useApplication } from '@/Components/ApplicationProvider'
|
||||
|
||||
type Props = { viewControllerManager: ViewControllerManager }
|
||||
const Encryption: FunctionComponent = () => {
|
||||
const app = useApplication()
|
||||
|
||||
const Encryption: FunctionComponent<Props> = ({ viewControllerManager }) => {
|
||||
const app = viewControllerManager.application
|
||||
const hasUser = app.hasAccount()
|
||||
const hasPasscode = app.hasPasscode()
|
||||
const isEncryptionEnabled = app.isEncryptionAvailable()
|
||||
|
||||
@@ -14,7 +14,7 @@ const ErroredItems: FunctionComponent = () => {
|
||||
const [erroredItems, setErroredItems] = useState(application.items.invalidNonVaultedItems)
|
||||
|
||||
useEffect(() => {
|
||||
return application.streamItems(ContentType.TYPES.Any, () => {
|
||||
return application.items.streamItems(ContentType.TYPES.Any, () => {
|
||||
setErroredItems(application.items.invalidNonVaultedItems)
|
||||
})
|
||||
}, [application])
|
||||
@@ -83,7 +83,7 @@ const ErroredItems: FunctionComponent = () => {
|
||||
className="mr-2 mt-3 min-w-20"
|
||||
label="Export all"
|
||||
onClick={() => {
|
||||
void application.getArchiveService().downloadEncryptedItems(erroredItems)
|
||||
void application.archiveService.downloadEncryptedItems(erroredItems)
|
||||
}}
|
||||
/>
|
||||
<Button
|
||||
@@ -117,7 +117,7 @@ const ErroredItems: FunctionComponent = () => {
|
||||
className="mr-2 mt-3 min-w-20"
|
||||
label="Export"
|
||||
onClick={() => {
|
||||
void application.getArchiveService().downloadEncryptedItem(item)
|
||||
void application.archiveService.downloadEncryptedItem(item)
|
||||
}}
|
||||
/>
|
||||
<Button
|
||||
|
||||
@@ -1,12 +1,12 @@
|
||||
import { observer } from 'mobx-react-lite'
|
||||
import { WebApplication } from '@/Application/WebApplication'
|
||||
import { isIOS } from '@/Utils'
|
||||
import { useEffect, useState } from 'react'
|
||||
import { MobileDeviceInterface } from '@standardnotes/services'
|
||||
import PreferencesSegment from '@/Components/Preferences/PreferencesComponents/PreferencesSegment'
|
||||
import { Title } from '@/Components/Preferences/PreferencesComponents/Content'
|
||||
import Button from '@/Components/Button/Button'
|
||||
import PreferencesGroup from '@/Components/Preferences/PreferencesComponents/PreferencesGroup'
|
||||
import { isIOS } from '@standardnotes/ui-services'
|
||||
|
||||
type Props = {
|
||||
application: WebApplication
|
||||
|
||||
@@ -14,7 +14,6 @@ import { alertDialog } from '@standardnotes/ui-services'
|
||||
import { FormEvent, useCallback, useEffect, useRef, useState } from 'react'
|
||||
import { ApplicationEvent, MobileUnlockTiming } from '@standardnotes/snjs'
|
||||
import { observer } from 'mobx-react-lite'
|
||||
import { ViewControllerManager } from '@/Controllers/ViewControllerManager'
|
||||
import { Title, Text } from '@/Components/Preferences/PreferencesComponents/Content'
|
||||
import Button from '@/Components/Button/Button'
|
||||
import PreferencesGroup from '../../PreferencesComponents/PreferencesGroup'
|
||||
@@ -24,15 +23,13 @@ import { classNames } from '@standardnotes/utils'
|
||||
|
||||
type Props = {
|
||||
application: WebApplication
|
||||
viewControllerManager: ViewControllerManager
|
||||
}
|
||||
|
||||
const PasscodeLock = ({ application, viewControllerManager }: Props) => {
|
||||
const PasscodeLock = ({ application }: Props) => {
|
||||
const isNativeMobileWeb = application.isNativeMobileWeb()
|
||||
const keyStorageInfo = StringUtils.keyStorageInfo(application)
|
||||
|
||||
const { setIsEncryptionEnabled, setIsBackupEncrypted, setEncryptionStatusString } =
|
||||
viewControllerManager.accountMenuController
|
||||
const { setIsEncryptionEnabled, setIsBackupEncrypted, setEncryptionStatusString } = application.accountMenuController
|
||||
|
||||
const passcodeInputRef = useRef<HTMLInputElement>(null)
|
||||
|
||||
@@ -58,7 +55,7 @@ const PasscodeLock = ({ application, viewControllerManager }: Props) => {
|
||||
}
|
||||
|
||||
const reloadDesktopAutoLockInterval = useCallback(async () => {
|
||||
const interval = await application.getAutolockService()?.getAutoLockInterval()
|
||||
const interval = await application.autolockService?.getAutoLockInterval()
|
||||
setSelectedAutoLockInterval(interval)
|
||||
}, [application])
|
||||
|
||||
@@ -86,7 +83,7 @@ const PasscodeLock = ({ application, viewControllerManager }: Props) => {
|
||||
return
|
||||
}
|
||||
|
||||
await application.getAutolockService()?.setAutoLockInterval(interval)
|
||||
await application.autolockService?.setAutoLockInterval(interval)
|
||||
reloadDesktopAutoLockInterval().catch(console.error)
|
||||
}
|
||||
|
||||
@@ -99,7 +96,7 @@ const PasscodeLock = ({ application, viewControllerManager }: Props) => {
|
||||
await preventRefreshing(STRING_CONFIRM_APP_QUIT_DURING_PASSCODE_REMOVAL, async () => {
|
||||
if (await application.removePasscode()) {
|
||||
if (!isNativeMobileWeb) {
|
||||
await application.getAutolockService()?.deleteAutolockPreference()
|
||||
await application.autolockService?.deleteAutolockPreference()
|
||||
await reloadDesktopAutoLockInterval()
|
||||
}
|
||||
refreshEncryptionStatus()
|
||||
@@ -184,7 +181,7 @@ const PasscodeLock = ({ application, viewControllerManager }: Props) => {
|
||||
setPasscodeConfirmation(undefined)
|
||||
}
|
||||
|
||||
const autolockService = application.getAutolockService()
|
||||
const autolockService = application.autolockService
|
||||
|
||||
return (
|
||||
<>
|
||||
|
||||
@@ -30,7 +30,7 @@ const Privacy: FunctionComponent<Props> = ({ application }: Props) => {
|
||||
}
|
||||
|
||||
const loadSettings = useCallback(async () => {
|
||||
if (!application.getUser()) {
|
||||
if (!application.sessions.getUser()) {
|
||||
return
|
||||
}
|
||||
setIsLoading(true)
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
import { NativeFeatureIdentifier, FeatureStatus } from '@standardnotes/snjs'
|
||||
|
||||
import { WebApplication } from '@/Application/WebApplication'
|
||||
import { ViewControllerManager } from '@/Controllers/ViewControllerManager'
|
||||
import { FunctionComponent } from 'react'
|
||||
import TwoFactorAuthWrapper from './TwoFactorAuth/TwoFactorAuthWrapper'
|
||||
import { MfaProps } from './TwoFactorAuth/MfaProps'
|
||||
@@ -16,7 +15,6 @@ import MultitaskingPrivacy from '@/Components/Preferences/Panes/Security/Multita
|
||||
import U2FWrapper from './U2F/U2FWrapper'
|
||||
|
||||
interface SecurityProps extends MfaProps {
|
||||
viewControllerManager: ViewControllerManager
|
||||
application: WebApplication
|
||||
}
|
||||
|
||||
@@ -26,23 +24,19 @@ const Security: FunctionComponent<SecurityProps> = (props) => {
|
||||
const isU2FFeatureAvailable =
|
||||
props.application.features.getFeatureStatus(
|
||||
NativeFeatureIdentifier.create(NativeFeatureIdentifier.TYPES.UniversalSecondFactor).getValue(),
|
||||
) === FeatureStatus.Entitled && props.userProvider.getUser() !== undefined
|
||||
) === FeatureStatus.Entitled && props.application.sessions.getUser() !== undefined
|
||||
|
||||
return (
|
||||
<PreferencesPane>
|
||||
<Encryption viewControllerManager={props.viewControllerManager} />
|
||||
<Encryption />
|
||||
{props.application.items.invalidNonVaultedItems.length > 0 && <ErroredItems />}
|
||||
<Protections application={props.application} />
|
||||
<TwoFactorAuthWrapper
|
||||
mfaProvider={props.mfaProvider}
|
||||
userProvider={props.userProvider}
|
||||
application={props.application}
|
||||
/>
|
||||
{isU2FFeatureAvailable && <U2FWrapper userProvider={props.userProvider} application={props.application} />}
|
||||
<TwoFactorAuthWrapper application={props.application} />
|
||||
{isU2FFeatureAvailable && <U2FWrapper application={props.application} />}
|
||||
{isNativeMobileWeb && <MultitaskingPrivacy application={props.application} />}
|
||||
<PasscodeLock viewControllerManager={props.viewControllerManager} application={props.application} />
|
||||
<PasscodeLock application={props.application} />
|
||||
{isNativeMobileWeb && <BiometricsLock application={props.application} />}
|
||||
{props.application.getUser() && <Privacy application={props.application} />}
|
||||
{props.application.sessions.getUser() && <Privacy application={props.application} />}
|
||||
</PreferencesPane>
|
||||
)
|
||||
}
|
||||
|
||||
@@ -1,8 +1,5 @@
|
||||
import { WebApplication } from '@/Application/WebApplication'
|
||||
import { MfaProvider, UserProvider } from '@/Components/Preferences/Providers'
|
||||
|
||||
export interface MfaProps {
|
||||
userProvider: UserProvider
|
||||
mfaProvider: MfaProvider
|
||||
application: WebApplication
|
||||
}
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import { MfaProvider } from '@/Components/Preferences/Providers'
|
||||
import { MfaServiceInterface } from '@standardnotes/snjs'
|
||||
import { action, makeAutoObservable, observable } from 'mobx'
|
||||
|
||||
type ActivationStep = 'scan-qr-code' | 'save-secret-key' | 'verification' | 'success'
|
||||
@@ -15,7 +15,7 @@ export class TwoFactorActivation {
|
||||
private inputOtpToken = ''
|
||||
|
||||
constructor(
|
||||
private mfaProvider: MfaProvider,
|
||||
private mfa: MfaServiceInterface,
|
||||
private readonly email: string,
|
||||
private readonly _secretKey: string,
|
||||
private _cancelActivation: () => void,
|
||||
@@ -102,7 +102,7 @@ export class TwoFactorActivation {
|
||||
return
|
||||
}
|
||||
|
||||
this.mfaProvider
|
||||
this.mfa
|
||||
.enableMfa(this.inputSecretKey, this.inputOtpToken)
|
||||
.then(
|
||||
action(() => {
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
import { MfaProvider, UserProvider } from '@/Components/Preferences/Providers'
|
||||
import { action, makeAutoObservable, observable } from 'mobx'
|
||||
import { TwoFactorActivation } from './TwoFactorActivation'
|
||||
import { MfaServiceInterface, SessionsClientInterface } from '@standardnotes/snjs'
|
||||
|
||||
type TwoFactorStatus = 'two-factor-enabled' | TwoFactorActivation | 'two-factor-disabled'
|
||||
|
||||
@@ -17,8 +17,8 @@ export class TwoFactorAuth {
|
||||
private _errorMessage: string | null
|
||||
|
||||
constructor(
|
||||
private readonly mfaProvider: MfaProvider,
|
||||
private readonly userProvider: UserProvider,
|
||||
private readonly sessions: SessionsClientInterface,
|
||||
private readonly mfa: MfaServiceInterface,
|
||||
) {
|
||||
this._errorMessage = null
|
||||
|
||||
@@ -40,13 +40,13 @@ export class TwoFactorAuth {
|
||||
this._status = 'two-factor-enabled'
|
||||
this.fetchStatus()
|
||||
})
|
||||
this.mfaProvider
|
||||
this.mfa
|
||||
.generateMfaSecret()
|
||||
.then(
|
||||
action((secret) => {
|
||||
this._status = new TwoFactorActivation(
|
||||
this.mfaProvider,
|
||||
this.userProvider.getUser()?.email as string,
|
||||
this.mfa,
|
||||
this.sessions.getUser()?.email as string,
|
||||
secret,
|
||||
setDisabled,
|
||||
setEnabled,
|
||||
@@ -61,7 +61,7 @@ export class TwoFactorAuth {
|
||||
}
|
||||
|
||||
private deactivate2FA(): void {
|
||||
this.mfaProvider
|
||||
this.mfa
|
||||
.disableMfa()
|
||||
.then(
|
||||
action(() => {
|
||||
@@ -76,7 +76,7 @@ export class TwoFactorAuth {
|
||||
}
|
||||
|
||||
isLoggedIn(): boolean {
|
||||
return this.userProvider.getUser() != undefined
|
||||
return this.sessions.getUser() != undefined
|
||||
}
|
||||
|
||||
fetchStatus(): void {
|
||||
@@ -84,7 +84,7 @@ export class TwoFactorAuth {
|
||||
return
|
||||
}
|
||||
|
||||
this.mfaProvider
|
||||
this.mfa
|
||||
.isMfaActivated()
|
||||
.then(
|
||||
action((active) => {
|
||||
|
||||
@@ -4,7 +4,7 @@ import { TwoFactorAuth } from './TwoFactorAuth'
|
||||
import TwoFactorAuthView from './TwoFactorAuthView/TwoFactorAuthView'
|
||||
|
||||
const TwoFactorAuthWrapper: FunctionComponent<MfaProps> = (props) => {
|
||||
const [auth] = useState(() => new TwoFactorAuth(props.mfaProvider, props.userProvider))
|
||||
const [auth] = useState(() => new TwoFactorAuth(props.application.sessions, props.application.mfa))
|
||||
auth.fetchStatus()
|
||||
return <TwoFactorAuthView auth={auth} application={props.application} />
|
||||
}
|
||||
|
||||
@@ -3,23 +3,19 @@ import { observer } from 'mobx-react-lite'
|
||||
import { AddAuthenticator } from '@standardnotes/snjs'
|
||||
|
||||
import DecoratedInput from '@/Components/Input/DecoratedInput'
|
||||
import { UserProvider } from '@/Components/Preferences/Providers'
|
||||
import Modal from '@/Components/Modal/Modal'
|
||||
import { MutuallyExclusiveMediaQueryBreakpoints, useMediaQuery } from '@/Hooks/useMediaQuery'
|
||||
import { useApplication } from '@/Components/ApplicationProvider'
|
||||
|
||||
type Props = {
|
||||
userProvider: UserProvider
|
||||
addAuthenticator: AddAuthenticator
|
||||
onDeviceAddingModalToggle: (show: boolean) => void
|
||||
onDeviceAdded: () => Promise<void>
|
||||
}
|
||||
|
||||
const U2FAddDeviceView: FunctionComponent<Props> = ({
|
||||
userProvider,
|
||||
addAuthenticator,
|
||||
onDeviceAddingModalToggle,
|
||||
onDeviceAdded,
|
||||
}) => {
|
||||
const U2FAddDeviceView: FunctionComponent<Props> = ({ addAuthenticator, onDeviceAddingModalToggle, onDeviceAdded }) => {
|
||||
const application = useApplication()
|
||||
|
||||
const [deviceName, setDeviceName] = useState('')
|
||||
const [errorMessage, setErrorMessage] = useState('')
|
||||
|
||||
@@ -33,7 +29,7 @@ const U2FAddDeviceView: FunctionComponent<Props> = ({
|
||||
return
|
||||
}
|
||||
|
||||
const user = userProvider.getUser()
|
||||
const user = application.sessions.getUser()
|
||||
if (user === undefined) {
|
||||
setErrorMessage('User not found')
|
||||
return
|
||||
@@ -50,7 +46,7 @@ const U2FAddDeviceView: FunctionComponent<Props> = ({
|
||||
|
||||
onDeviceAddingModalToggle(false)
|
||||
await onDeviceAdded()
|
||||
}, [deviceName, setErrorMessage, userProvider, addAuthenticator, onDeviceAddingModalToggle, onDeviceAdded])
|
||||
}, [deviceName, setErrorMessage, application, addAuthenticator, onDeviceAddingModalToggle, onDeviceAdded])
|
||||
|
||||
const closeModal = () => {
|
||||
onDeviceAddingModalToggle(false)
|
||||
|
||||
@@ -1,7 +1,5 @@
|
||||
import { WebApplication } from '@/Application/WebApplication'
|
||||
import { UserProvider } from '@/Components/Preferences/Providers'
|
||||
|
||||
export interface U2FProps {
|
||||
userProvider: UserProvider
|
||||
application: WebApplication
|
||||
}
|
||||
|
||||
@@ -2,17 +2,12 @@ import { FunctionComponent } from 'react'
|
||||
import { observer } from 'mobx-react-lite'
|
||||
|
||||
import { Text } from '@/Components/Preferences/PreferencesComponents/Content'
|
||||
import { UserProvider } from '@/Components/Preferences/Providers'
|
||||
import { useApplication } from '@/Components/ApplicationProvider'
|
||||
|
||||
type Props = {
|
||||
userProvider: UserProvider
|
||||
}
|
||||
|
||||
const U2FDescription: FunctionComponent<Props> = ({ userProvider }) => {
|
||||
const U2FDescription: FunctionComponent = () => {
|
||||
const application = useApplication()
|
||||
|
||||
if (userProvider.getUser() === undefined) {
|
||||
if (application.sessions.getUser() === undefined) {
|
||||
return <Text>Sign in or register for an account to configure hardware security keys.</Text>
|
||||
}
|
||||
|
||||
|
||||
@@ -2,14 +2,12 @@ import { FunctionComponent } from 'react'
|
||||
import { observer } from 'mobx-react-lite'
|
||||
|
||||
import { Title } from '@/Components/Preferences/PreferencesComponents/Content'
|
||||
import { UserProvider } from '@/Components/Preferences/Providers'
|
||||
import { useApplication } from '@/Components/ApplicationProvider'
|
||||
|
||||
type Props = {
|
||||
userProvider: UserProvider
|
||||
}
|
||||
const U2FTitle: FunctionComponent = () => {
|
||||
const application = useApplication()
|
||||
|
||||
const U2FTitle: FunctionComponent<Props> = ({ userProvider }) => {
|
||||
if (userProvider.getUser() === undefined) {
|
||||
if (application.sessions.getUser() === undefined) {
|
||||
return <Title>Hardware security key authentication not available</Title>
|
||||
}
|
||||
|
||||
|
||||
@@ -4,7 +4,6 @@ import { observer } from 'mobx-react-lite'
|
||||
import PreferencesGroup from '@/Components/Preferences/PreferencesComponents/PreferencesGroup'
|
||||
import PreferencesSegment from '@/Components/Preferences/PreferencesComponents/PreferencesSegment'
|
||||
import { WebApplication } from '@/Application/WebApplication'
|
||||
import { UserProvider } from '@/Components/Preferences/Providers'
|
||||
|
||||
import U2FTitle from './U2FTitle'
|
||||
import U2FDescription from './U2FDescription'
|
||||
@@ -16,10 +15,9 @@ import RecoveryCodeBanner from '@/Components/RecoveryCodeBanner/RecoveryCodeBann
|
||||
|
||||
type Props = {
|
||||
application: WebApplication
|
||||
userProvider: UserProvider
|
||||
}
|
||||
|
||||
const U2FView: FunctionComponent<Props> = ({ application, userProvider }) => {
|
||||
const U2FView: FunctionComponent<Props> = ({ application }) => {
|
||||
const [showDeviceAddingModal, setShowDeviceAddingModal] = useState(false)
|
||||
const [devices, setDevices] = useState<Array<{ id: string; name: string }>>([])
|
||||
const [error, setError] = useState('')
|
||||
@@ -48,8 +46,8 @@ const U2FView: FunctionComponent<Props> = ({ application, userProvider }) => {
|
||||
<PreferencesGroup>
|
||||
<PreferencesSegment>
|
||||
<div className="flex flex-col">
|
||||
<U2FTitle userProvider={userProvider} />
|
||||
<U2FDescription userProvider={userProvider} />
|
||||
<U2FTitle />
|
||||
<U2FDescription />
|
||||
</div>
|
||||
</PreferencesSegment>
|
||||
<PreferencesSegment classes="mt-2">
|
||||
@@ -80,7 +78,6 @@ const U2FView: FunctionComponent<Props> = ({ application, userProvider }) => {
|
||||
<U2FAddDeviceView
|
||||
onDeviceAddingModalToggle={setShowDeviceAddingModal}
|
||||
onDeviceAdded={loadAuthenticatorDevices}
|
||||
userProvider={userProvider}
|
||||
addAuthenticator={application.addAuthenticator}
|
||||
/>
|
||||
</ModalOverlay>
|
||||
|
||||
@@ -4,7 +4,7 @@ import { U2FProps } from './U2FProps'
|
||||
import U2FView from './U2FView/U2FView'
|
||||
|
||||
const U2FWrapper: FunctionComponent<U2FProps> = (props) => {
|
||||
return <U2FView application={props.application} userProvider={props.userProvider} />
|
||||
return <U2FView application={props.application} />
|
||||
}
|
||||
|
||||
export default U2FWrapper
|
||||
|
||||
@@ -75,7 +75,7 @@ const Vaults = () => {
|
||||
}, [application.vaultInvites, updateAllData])
|
||||
|
||||
useEffect(() => {
|
||||
return application.streamItems([ContentType.TYPES.VaultListing, ContentType.TYPES.TrustedContact], () => {
|
||||
return application.items.streamItems([ContentType.TYPES.VaultListing, ContentType.TYPES.TrustedContact], () => {
|
||||
void updateAllData()
|
||||
})
|
||||
}, [application, updateAllData])
|
||||
|
||||
@@ -1,9 +1,7 @@
|
||||
import { WebApplication } from '@/Application/WebApplication'
|
||||
import { MfaProps } from './Panes/Security/TwoFactorAuth/MfaProps'
|
||||
import { ViewControllerManager } from '@/Controllers/ViewControllerManager'
|
||||
|
||||
export interface PreferencesProps extends MfaProps {
|
||||
application: WebApplication
|
||||
viewControllerManager: ViewControllerManager
|
||||
closePreferences: () => void
|
||||
}
|
||||
|
||||
@@ -11,21 +11,15 @@ import { useAvailableSafeAreaPadding } from '@/Hooks/useSafeAreaPadding'
|
||||
import { MutuallyExclusiveMediaQueryBreakpoints, useMediaQuery } from '@/Hooks/useMediaQuery'
|
||||
import Icon from '../Icon/Icon'
|
||||
|
||||
const PreferencesView: FunctionComponent<PreferencesProps> = ({
|
||||
application,
|
||||
viewControllerManager,
|
||||
closePreferences,
|
||||
userProvider,
|
||||
mfaProvider,
|
||||
}) => {
|
||||
const PreferencesView: FunctionComponent<PreferencesProps> = ({ application, closePreferences }) => {
|
||||
const menu = useMemo(
|
||||
() => new PreferencesSessionController(application, viewControllerManager.enableUnfinishedFeatures),
|
||||
[viewControllerManager.enableUnfinishedFeatures, application],
|
||||
() => new PreferencesSessionController(application, application.enableUnfinishedFeatures),
|
||||
[application],
|
||||
)
|
||||
|
||||
useEffect(() => {
|
||||
menu.selectPane(viewControllerManager.preferencesController.currentPane)
|
||||
}, [menu, viewControllerManager.preferencesController.currentPane])
|
||||
menu.selectPane(application.preferencesController.currentPane)
|
||||
}, [menu, application.preferencesController.currentPane])
|
||||
|
||||
const isMobileScreen = useMediaQuery(MutuallyExclusiveMediaQueryBreakpoints.sm)
|
||||
|
||||
@@ -92,14 +86,7 @@ const PreferencesView: FunctionComponent<PreferencesProps> = ({
|
||||
actions={modalActions}
|
||||
customFooter={<></>}
|
||||
>
|
||||
<PreferencesCanvas
|
||||
menu={menu}
|
||||
application={application}
|
||||
viewControllerManager={viewControllerManager}
|
||||
closePreferences={closePreferences}
|
||||
userProvider={userProvider}
|
||||
mfaProvider={mfaProvider}
|
||||
/>
|
||||
<PreferencesCanvas menu={menu} application={application} closePreferences={closePreferences} />
|
||||
</Modal>
|
||||
)
|
||||
}
|
||||
|
||||
@@ -9,18 +9,15 @@ import { usePaneSwipeGesture } from '../Panes/usePaneGesture'
|
||||
import { performSafariAnimationFix } from '../Panes/PaneAnimator'
|
||||
import { IosModalAnimationEasing } from '../Modal/useModalAnimation'
|
||||
|
||||
const PreferencesViewWrapper: FunctionComponent<PreferencesViewWrapperProps> = ({
|
||||
viewControllerManager,
|
||||
application,
|
||||
}) => {
|
||||
const PreferencesViewWrapper: FunctionComponent<PreferencesViewWrapperProps> = ({ application }) => {
|
||||
const commandService = useCommandService()
|
||||
|
||||
useEffect(() => {
|
||||
return commandService.addCommandHandler({
|
||||
command: OPEN_PREFERENCES_COMMAND,
|
||||
onKeyDown: () => viewControllerManager.preferencesController.openPreferences(),
|
||||
onKeyDown: () => application.preferencesController.openPreferences(),
|
||||
})
|
||||
}, [commandService, viewControllerManager])
|
||||
}, [commandService, application])
|
||||
|
||||
const [setElement] = usePaneSwipeGesture('right', async (element) => {
|
||||
const animation = element.animate(
|
||||
@@ -43,22 +40,19 @@ const PreferencesViewWrapper: FunctionComponent<PreferencesViewWrapperProps> = (
|
||||
|
||||
animation.finish()
|
||||
|
||||
viewControllerManager.preferencesController.closePreferences()
|
||||
application.preferencesController.closePreferences()
|
||||
})
|
||||
|
||||
return (
|
||||
<ModalOverlay
|
||||
isOpen={viewControllerManager.preferencesController.isOpen}
|
||||
isOpen={application.preferencesController.isOpen}
|
||||
ref={setElement}
|
||||
animationVariant="horizontal"
|
||||
close={viewControllerManager.preferencesController.closePreferences}
|
||||
close={application.preferencesController.closePreferences}
|
||||
>
|
||||
<PreferencesView
|
||||
closePreferences={viewControllerManager.preferencesController.closePreferences}
|
||||
closePreferences={application.preferencesController.closePreferences}
|
||||
application={application}
|
||||
viewControllerManager={viewControllerManager}
|
||||
mfaProvider={application}
|
||||
userProvider={application}
|
||||
/>
|
||||
</ModalOverlay>
|
||||
)
|
||||
|
||||
@@ -1,7 +1,5 @@
|
||||
import { WebApplication } from '@/Application/WebApplication'
|
||||
import { ViewControllerManager } from '@/Controllers/ViewControllerManager'
|
||||
|
||||
export interface PreferencesViewWrapperProps {
|
||||
viewControllerManager: ViewControllerManager
|
||||
application: WebApplication
|
||||
}
|
||||
|
||||
@@ -1,11 +0,0 @@
|
||||
export interface MfaProvider {
|
||||
isMfaActivated(): Promise<boolean>
|
||||
|
||||
generateMfaSecret(): Promise<string>
|
||||
|
||||
getOtpToken(secret: string): Promise<string>
|
||||
|
||||
enableMfa(secret: string, otpToken: string): Promise<void>
|
||||
|
||||
disableMfa(): Promise<void>
|
||||
}
|
||||
@@ -1,3 +0,0 @@
|
||||
export interface UserProvider {
|
||||
getUser(): { uuid: string; email: string } | undefined
|
||||
}
|
||||
@@ -1,2 +0,0 @@
|
||||
export * from './MfaProvider'
|
||||
export * from './UserProvider'
|
||||
Reference in New Issue
Block a user