remnantchat/src/Init.tsx

86 lines
2.3 KiB
TypeScript
Raw Normal View History

import { lazy, Suspense, useEffect, useState } from 'react'
feat(verification): [closes #209] Verified peers (#216) * refactor(bootstrap): add BootstrapShim * feat(security): [#209] generate public/private keys * refactor(encryption): move encryption utils to a service * feat(encryption): [wip] implement convertCryptoKeyToString * fix(user-settings): serialize crypto keys to strings * feat(user-settings): deserialize user settings from IndexedDB * feat(user-settings): upgrade persisted settings on boot * feat(user-settings): automatically migrate persisted user settings * refactor(encryption): simplify CryptoKey stringification * refactor(encryption): DRY up EncryptionService * feat(verification): send public key to new peers * refactor(encryption): use class instance * refactor(serialization): use class instance * refactor(verification): [wip] create usePeerVerification hook * feat(verification): encrypt verification token * feat(verification): send encrypted token to peer * feat(verification): verify peer * refactor(verification): use enum for verification state * feat(verification): expire verification requests * fix(updatePeer): update with fresh state data * feat(verification): display verification state * refactor(usePeerVerification): store verification timer in Peer * feat(verification): present tooltips explaining verification state * feat(ui): show full page loading indicator * feat(init): present bootup failure reasons * refactor(init): move init to its own file * feat(verification): show errors upon verification failure * refactor(verification): move workaround to usePeerVerification * feat(verification): present peer public keys * refactor(verification): move peer public key rendering to its own component * refactor(verification): only pass publicKey into renderer * feat(verification): show user's own public key * refactor(naming): rename Username to UserInfo * refactor(loading): encapsulate height styling * feat(verification): improve user messaging * refactor(style): improve formatting and variable names * feat(verification): add user info tooltip * docs(verification): explain verification
2023-12-09 23:47:05 +00:00
import Box from '@mui/material/Box'
import Typography from '@mui/material/Typography'
import { v4 as uuid } from 'uuid'
import { encryption } from 'services/Encryption'
feat(verification): [closes #209] Verified peers (#216) * refactor(bootstrap): add BootstrapShim * feat(security): [#209] generate public/private keys * refactor(encryption): move encryption utils to a service * feat(encryption): [wip] implement convertCryptoKeyToString * fix(user-settings): serialize crypto keys to strings * feat(user-settings): deserialize user settings from IndexedDB * feat(user-settings): upgrade persisted settings on boot * feat(user-settings): automatically migrate persisted user settings * refactor(encryption): simplify CryptoKey stringification * refactor(encryption): DRY up EncryptionService * feat(verification): send public key to new peers * refactor(encryption): use class instance * refactor(serialization): use class instance * refactor(verification): [wip] create usePeerVerification hook * feat(verification): encrypt verification token * feat(verification): send encrypted token to peer * feat(verification): verify peer * refactor(verification): use enum for verification state * feat(verification): expire verification requests * fix(updatePeer): update with fresh state data * feat(verification): display verification state * refactor(usePeerVerification): store verification timer in Peer * feat(verification): present tooltips explaining verification state * feat(ui): show full page loading indicator * feat(init): present bootup failure reasons * refactor(init): move init to its own file * feat(verification): show errors upon verification failure * refactor(verification): move workaround to usePeerVerification * feat(verification): present peer public keys * refactor(verification): move peer public key rendering to its own component * refactor(verification): only pass publicKey into renderer * feat(verification): show user's own public key * refactor(naming): rename Username to UserInfo * refactor(loading): encapsulate height styling * feat(verification): improve user messaging * refactor(style): improve formatting and variable names * feat(verification): add user info tooltip * docs(verification): explain verification
2023-12-09 23:47:05 +00:00
import {
EnvironmentUnsupportedDialog,
isEnvironmentSupported,
} from 'components/Shell/EnvironmentUnsupportedDialog'
import { WholePageLoading } from 'components/Loading/Loading'
import { ColorMode, UserSettings } from 'models/settings'
import type { BootstrapProps } from './Bootstrap'
chore: Migrate from Create React App to Vite (#231) * chore(vite): use vite * fix(vite): alias lib directory * chore(vite): set type: module * chore: update vite and MUI * fix(vite): make MUI components load * fix: use node path resolution * chore(vite): add svg support * fix(vite): polyfill global * fix(vite): use import.meta * fix(vite): use correct svg module resolution * chore(vite): migrate to vitest * fix(vite): remove PUBLIC_URL * fix(tests): mock audio service * chore(deps): upgrade to react test library 14 * refactor(tests): simplify room test setup * refactor(tests): make Date.now() mockable * refactor(vite): remove bootstrap shim * chore(deps): drop react-scripts * chore(deps): remove source-map-explorer Source maps do not currently work with MUI and Vite: https://github.com/vitejs/vite/issues/15012 Because of this, source map utilities are currently removed. * refactor(vite): use TypeScript for Vite config * chore(actions): update actions config for new paths * fix(service-worker): use VITE_HOMEPAGE for service worker resolution * fix(vercel): use quotes for build command * fix(vite): use import.meta.env.MODE * fix(service-worker): use correct definition for publicUrl * feat(vite): use vite-plugin-pwa * fix(pwa): make update prompt work * fix(types): use vite/client types * docs(readme): update building instructions * refactor(vite): simplify theme loading workaround * refactor(vite): use manifest object * docs(readme): update tool references * chore(deps): run `npm audit fix` * fix(vite): make syntax highlighter work consistently See: https://github.com/react-syntax-highlighter/react-syntax-highlighter/issues/513 * fix(pwa): remove manifest.json references * refactor(deps): remove jest references * refactor(types): remove react-scripts reference * chore(deps): use TypeScript 5 * refactor(tests): improve persisted storage mocking
2024-03-13 02:44:43 +00:00
const Bootstrap = lazy(() => import('./Bootstrap'))
feat(verification): [closes #209] Verified peers (#216) * refactor(bootstrap): add BootstrapShim * feat(security): [#209] generate public/private keys * refactor(encryption): move encryption utils to a service * feat(encryption): [wip] implement convertCryptoKeyToString * fix(user-settings): serialize crypto keys to strings * feat(user-settings): deserialize user settings from IndexedDB * feat(user-settings): upgrade persisted settings on boot * feat(user-settings): automatically migrate persisted user settings * refactor(encryption): simplify CryptoKey stringification * refactor(encryption): DRY up EncryptionService * feat(verification): send public key to new peers * refactor(encryption): use class instance * refactor(serialization): use class instance * refactor(verification): [wip] create usePeerVerification hook * feat(verification): encrypt verification token * feat(verification): send encrypted token to peer * feat(verification): verify peer * refactor(verification): use enum for verification state * feat(verification): expire verification requests * fix(updatePeer): update with fresh state data * feat(verification): display verification state * refactor(usePeerVerification): store verification timer in Peer * feat(verification): present tooltips explaining verification state * feat(ui): show full page loading indicator * feat(init): present bootup failure reasons * refactor(init): move init to its own file * feat(verification): show errors upon verification failure * refactor(verification): move workaround to usePeerVerification * feat(verification): present peer public keys * refactor(verification): move peer public key rendering to its own component * refactor(verification): only pass publicKey into renderer * feat(verification): show user's own public key * refactor(naming): rename Username to UserInfo * refactor(loading): encapsulate height styling * feat(verification): improve user messaging * refactor(style): improve formatting and variable names * feat(verification): add user info tooltip * docs(verification): explain verification
2023-12-09 23:47:05 +00:00
export interface InitProps extends Omit<BootstrapProps, 'initialUserSettings'> {
getUuid?: typeof uuid
}
// NOTE: This is meant to be a thin layer around the Bootstrap component that
// only handles asynchronous creation of the public/private keys that Bootstrap
// requires.
const Init = ({ getUuid = uuid, ...props }: InitProps) => {
const [userSettings, setUserSettings] = useState<UserSettings | null>(null)
const [errorMessage, setErrorMessage] = useState<string | null>(null)
useEffect(() => {
;(async () => {
if (userSettings !== null) return
try {
const { publicKey, privateKey } = await encryption.generateKeyPair()
feat(verification): [closes #209] Verified peers (#216) * refactor(bootstrap): add BootstrapShim * feat(security): [#209] generate public/private keys * refactor(encryption): move encryption utils to a service * feat(encryption): [wip] implement convertCryptoKeyToString * fix(user-settings): serialize crypto keys to strings * feat(user-settings): deserialize user settings from IndexedDB * feat(user-settings): upgrade persisted settings on boot * feat(user-settings): automatically migrate persisted user settings * refactor(encryption): simplify CryptoKey stringification * refactor(encryption): DRY up EncryptionService * feat(verification): send public key to new peers * refactor(encryption): use class instance * refactor(serialization): use class instance * refactor(verification): [wip] create usePeerVerification hook * feat(verification): encrypt verification token * feat(verification): send encrypted token to peer * feat(verification): verify peer * refactor(verification): use enum for verification state * feat(verification): expire verification requests * fix(updatePeer): update with fresh state data * feat(verification): display verification state * refactor(usePeerVerification): store verification timer in Peer * feat(verification): present tooltips explaining verification state * feat(ui): show full page loading indicator * feat(init): present bootup failure reasons * refactor(init): move init to its own file * feat(verification): show errors upon verification failure * refactor(verification): move workaround to usePeerVerification * feat(verification): present peer public keys * refactor(verification): move peer public key rendering to its own component * refactor(verification): only pass publicKey into renderer * feat(verification): show user's own public key * refactor(naming): rename Username to UserInfo * refactor(loading): encapsulate height styling * feat(verification): improve user messaging * refactor(style): improve formatting and variable names * feat(verification): add user info tooltip * docs(verification): explain verification
2023-12-09 23:47:05 +00:00
setUserSettings({
userId: getUuid(),
customUsername: '',
colorMode: ColorMode.DARK,
playSoundOnNewMessage: true,
showNotificationOnNewMessage: true,
showActiveTypingStatus: true,
publicKey,
privateKey,
})
} catch (e) {
console.error(e)
setErrorMessage(
'Chitchatter was unable to boot up. Please check the browser console.'
)
}
})()
}, [getUuid, userSettings])
if (!isEnvironmentSupported) {
return <EnvironmentUnsupportedDialog />
}
if (errorMessage) {
return (
<Box
sx={{
display: 'flex',
height: '100vh',
justifyContent: 'center',
alignItems: 'center',
}}
>
<Typography>{errorMessage}</Typography>
</Box>
)
}
if (userSettings === null) {
return <WholePageLoading />
}
return (
<Suspense fallback={<WholePageLoading />}>
<Bootstrap {...props} initialUserSettings={userSettings} />
</Suspense>
)
feat(verification): [closes #209] Verified peers (#216) * refactor(bootstrap): add BootstrapShim * feat(security): [#209] generate public/private keys * refactor(encryption): move encryption utils to a service * feat(encryption): [wip] implement convertCryptoKeyToString * fix(user-settings): serialize crypto keys to strings * feat(user-settings): deserialize user settings from IndexedDB * feat(user-settings): upgrade persisted settings on boot * feat(user-settings): automatically migrate persisted user settings * refactor(encryption): simplify CryptoKey stringification * refactor(encryption): DRY up EncryptionService * feat(verification): send public key to new peers * refactor(encryption): use class instance * refactor(serialization): use class instance * refactor(verification): [wip] create usePeerVerification hook * feat(verification): encrypt verification token * feat(verification): send encrypted token to peer * feat(verification): verify peer * refactor(verification): use enum for verification state * feat(verification): expire verification requests * fix(updatePeer): update with fresh state data * feat(verification): display verification state * refactor(usePeerVerification): store verification timer in Peer * feat(verification): present tooltips explaining verification state * feat(ui): show full page loading indicator * feat(init): present bootup failure reasons * refactor(init): move init to its own file * feat(verification): show errors upon verification failure * refactor(verification): move workaround to usePeerVerification * feat(verification): present peer public keys * refactor(verification): move peer public key rendering to its own component * refactor(verification): only pass publicKey into renderer * feat(verification): show user's own public key * refactor(naming): rename Username to UserInfo * refactor(loading): encapsulate height styling * feat(verification): improve user messaging * refactor(style): improve formatting and variable names * feat(verification): add user info tooltip * docs(verification): explain verification
2023-12-09 23:47:05 +00:00
}
export default Init