Update all non-major dependencies
[ProtonMail-WebClient.git] / applications / pass-desktop / src / app / App.tsx
blob2a15f56932c91309b86ec3192995903c1096318d
1 import { Router } from 'react-router-dom';
3 import { createHashHistory } from 'history';
4 import { AppGuard } from 'proton-pass-web/app/AppGuard';
5 import { AuthServiceProvider } from 'proton-pass-web/app/Auth/AuthServiceProvider';
6 import { AuthSwitchProvider } from 'proton-pass-web/app/Auth/AuthSwitchProvider';
7 import { StoreProvider } from 'proton-pass-web/app/Store/StoreProvider';
8 import { store } from 'proton-pass-web/app/Store/store';
9 import { B2BEvents } from 'proton-pass-web/lib/b2b';
10 import { core } from 'proton-pass-web/lib/core';
11 import { i18n } from 'proton-pass-web/lib/i18n';
12 import { logStore } from 'proton-pass-web/lib/logger';
13 import { monitor } from 'proton-pass-web/lib/monitor';
14 import { settings } from 'proton-pass-web/lib/settings';
15 import { spotlightProxy as spotlight } from 'proton-pass-web/lib/spotlight';
16 import { telemetry } from 'proton-pass-web/lib/telemetry';
17 import { getInitialTheme } from 'proton-pass-web/lib/theme';
19 import {
20     ErrorBoundary,
21     ModalsChildren,
22     ModalsProvider,
23     NotificationsChildren,
24     NotificationsProvider,
25     StandardErrorPage,
26 } from '@proton/components';
27 import { Portal } from '@proton/components/components/portal';
28 import Icons from '@proton/icons/Icons';
29 import { AuthStoreProvider } from '@proton/pass/components/Core/AuthStoreProvider';
30 import { ConnectivityProvider } from '@proton/pass/components/Core/ConnectivityProvider';
31 import { Localized } from '@proton/pass/components/Core/Localized';
32 import type { PassCoreProviderProps } from '@proton/pass/components/Core/PassCoreProvider';
33 import { PassCoreProvider } from '@proton/pass/components/Core/PassCoreProvider';
34 import { PassExtensionLink } from '@proton/pass/components/Core/PassExtensionLink';
35 import { ThemeConnect } from '@proton/pass/components/Layout/Theme/ThemeConnect';
36 import { NavigationProvider } from '@proton/pass/components/Navigation/NavigationProvider';
37 import { getLocalPath } from '@proton/pass/components/Navigation/routing';
38 import { api, exposeApi } from '@proton/pass/lib/api/api';
39 import { createApi } from '@proton/pass/lib/api/factory';
40 import { createImageProxyHandler, imageResponsetoDataURL } from '@proton/pass/lib/api/images';
41 import { inferBiometricsStorageKey } from '@proton/pass/lib/auth/lock/biometrics/utils';
42 import { type AuthStore, createAuthStore, exposeAuthStore } from '@proton/pass/lib/auth/store';
43 import { exposePassCrypto } from '@proton/pass/lib/crypto';
44 import { createPassCrypto } from '@proton/pass/lib/crypto/pass-crypto';
45 import { createPassExport } from '@proton/pass/lib/export/export';
46 import { prepareImport } from '@proton/pass/lib/import/reader';
47 import { generateTOTPCode } from '@proton/pass/lib/otp/otp';
48 import { createTelemetryEvent } from '@proton/pass/lib/telemetry/event';
49 import { selectExportData } from '@proton/pass/store/selectors/export';
50 import { transferableToFile } from '@proton/pass/utils/file/transferable-file';
51 import { pipe } from '@proton/pass/utils/fp/pipe';
52 import { ping } from '@proton/shared/lib/api/tests';
53 import createSecureSessionStorage from '@proton/shared/lib/authentication/createSecureSessionStorage';
54 import sentry from '@proton/shared/lib/helpers/sentry';
56 import { PASS_CONFIG, SENTRY_CONFIG } from '../lib/env';
57 import { WelcomeScreen } from './Views/WelcomeScreen/WelcomeScreen';
58 import { isFirstLaunch } from './firstLaunch';
59 import locales from './locales';
61 import './app.scss';
63 const authStore = exposeAuthStore(createAuthStore(createSecureSessionStorage()));
65 exposeApi(createApi({ config: PASS_CONFIG }));
66 exposePassCrypto(createPassCrypto());
67 sentry({ config: PASS_CONFIG, sentryConfig: SENTRY_CONFIG });
69 const history = createHashHistory();
70 const imageProxy = createImageProxyHandler(api);
71 const showWelcome = isFirstLaunch();
73 export const getPassCoreProps = (): PassCoreProviderProps => ({
74     config: PASS_CONFIG,
75     core,
76     endpoint: 'desktop',
77     i18n: i18n(locales),
78     monitor,
79     settings,
80     spotlight,
82     exportData: async (options) => {
83         const state = store.getState();
84         const data = selectExportData({ config: PASS_CONFIG, format: options.format })(state);
85         return transferableToFile(await createPassExport(data, options));
86     },
88     generateOTP: (payload) => (payload.type === 'uri' ? generateTOTPCode(payload.totpUri) : null),
90     getApiState: api.getState,
92     getBiometricsKey: async (store: AuthStore) => {
93         try {
94             const { storageKey, version } = inferBiometricsStorageKey(store);
95             return (await window.ctxBridge?.getSecret(storageKey, version)) ?? null;
96         } catch {
97             return null;
98         }
99     },
101     getDomainImage: async (domain, signal) => {
102         const url = `${PASS_CONFIG.API_URL}/core/v4/images/logo?Domain=${domain}&Size=32&Mode=light&MaxScaleUpFactor=4`;
103         const res = await imageProxy(url, signal);
104         return imageResponsetoDataURL(res);
105     },
107     getLogs: logStore.read,
108     getTheme: getInitialTheme,
110     onLink: (url) => window.open(url, '_blank'),
111     onTelemetry: pipe(createTelemetryEvent, telemetry.push),
112     onB2BEvent: B2BEvents.push,
114     openSettings: (page) =>
115         history.push({
116             pathname: getLocalPath('settings'),
117             search: location.search,
118             hash: page,
119         }),
121     prepareImport: prepareImport,
123     writeToClipboard: async (str) => window.ctxBridge?.writeToClipboard(str),
125     isFirstLaunch,
128 export const App = () => {
129     return (
130         <PassCoreProvider {...getPassCoreProps()} wasm>
131             <Icons />
132             <ErrorBoundary component={<StandardErrorPage big />}>
133                 <NotificationsProvider>
134                     <ModalsProvider>
135                         <PassExtensionLink>
136                             <ConnectivityProvider
137                                 subscribe={api.subscribe}
138                                 onPing={() => api({ ...ping(), unauthenticated: true })}
139                             >
140                                 <Router history={history}>
141                                     <NavigationProvider>
142                                         <AuthStoreProvider store={authStore}>
143                                             <AuthSwitchProvider>
144                                                 <AuthServiceProvider>
145                                                     <StoreProvider>
146                                                         <ThemeConnect />
147                                                         <Localized>
148                                                             {showWelcome ? <WelcomeScreen /> : <AppGuard />}
149                                                         </Localized>
150                                                         <Portal>
151                                                             <ModalsChildren />
152                                                             <NotificationsChildren />
153                                                         </Portal>
154                                                     </StoreProvider>
155                                                 </AuthServiceProvider>
156                                             </AuthSwitchProvider>
157                                         </AuthStoreProvider>
158                                     </NavigationProvider>
159                                 </Router>
160                             </ConnectivityProvider>
161                         </PassExtensionLink>
162                     </ModalsProvider>
163                 </NotificationsProvider>
164             </ErrorBoundary>
165         </PassCoreProvider>
166     );