issue-31 #35

Merged
y merged 3 commits from issue-31 into main 2024-05-15 11:02:48 +00:00
18 changed files with 122 additions and 110 deletions
Showing only changes of commit 819902eafb - Show all commits

7
.prettierrc Normal file
View File

@ -0,0 +1,7 @@
{
"trailingComma": "none",
"tabWidth": 2,
"semi": false,
"singleQuote": true,
"endOfLine": "auto"
}

View File

@ -9,6 +9,8 @@
"build": "tsc && vite build", "build": "tsc && vite build",
"lint": "eslint . --ext ts,tsx --report-unused-disable-directives --max-warnings 0", "lint": "eslint . --ext ts,tsx --report-unused-disable-directives --max-warnings 0",
"lint:fix": "eslint . --fix --ext ts,tsx --report-unused-disable-directives --max-warnings 0", "lint:fix": "eslint . --fix --ext ts,tsx --report-unused-disable-directives --max-warnings 0",
"formatter:check": "npx prettier --check \"src/**/*.{ts,tsx,js,jsx,html,css,sass,less,yml,md,graphql}\"",
"formatter:fix": "npx prettier --write \"src/**/*.{ts,tsx,js,jsx,html,css,sass,less,yml,md,graphql}\"",
"preview": "vite preview" "preview": "vite preview"
}, },
"dependencies": { "dependencies": {

View File

@ -67,7 +67,7 @@ const App = () => {
})} })}
<Route <Route
path='*' path="*"
element={ element={
<Navigate <Navigate
to={ to={

View File

@ -87,10 +87,10 @@ export const AppBar = () => {
const isAuthenticated = authState?.loggedIn === true const isAuthenticated = authState?.loggedIn === true
return ( return (
<AppBarMui position='fixed' className={styles.AppBar}> <AppBarMui position="fixed" className={styles.AppBar}>
<Toolbar className={styles.toolbar}> <Toolbar className={styles.toolbar}>
<Box className={styles.logoWrapper}> <Box className={styles.logoWrapper}>
<img src='/logo.png' alt='Logo' onClick={() => navigate('/')} /> <img src="/logo.png" alt="Logo" onClick={() => navigate('/')} />
</Box> </Box>
<Box className={styles.rightSideBox}> <Box className={styles.rightSideBox}>
@ -99,7 +99,7 @@ export const AppBar = () => {
onClick={() => { onClick={() => {
navigate(appPublicRoutes.login) navigate(appPublicRoutes.login)
}} }}
variant='contained' variant="contained"
> >
Sign in Sign in
</Button> </Button>
@ -113,7 +113,7 @@ export const AppBar = () => {
handleClick={handleOpenUserMenu} handleClick={handleOpenUserMenu}
/> />
<Menu <Menu
id='menu-appbar' id="menu-appbar"
anchorEl={anchorElUser} anchorEl={anchorElUser}
anchorOrigin={{ anchorOrigin={{
vertical: 'bottom', vertical: 'bottom',
@ -133,7 +133,7 @@ export const AppBar = () => {
display: { md: 'none' } display: { md: 'none' }
}} }}
> >
<Typography variant='h6'>{username}</Typography> <Typography variant="h6">{username}</Typography>
</MenuItem> </MenuItem>
<MenuItem <MenuItem
onClick={handleProfile} onClick={handleProfile}
@ -145,7 +145,7 @@ export const AppBar = () => {
</MenuItem> </MenuItem>
<Link <Link
to={appPublicRoutes.help} to={appPublicRoutes.help}
target='_blank' target="_blank"
style={{ color: 'inherit', textDecoration: 'inherit' }} style={{ color: 'inherit', textDecoration: 'inherit' }}
> >
<MenuItem <MenuItem

View File

@ -13,16 +13,16 @@ const Username = ({ username, avatarContent, handleClick }: Props) => {
return ( return (
<IconButton <IconButton
aria-label='account of current user' aria-label="account of current user"
aria-controls='menu-appbar' aria-controls="menu-appbar"
aria-haspopup='true' aria-haspopup="true"
onClick={handleClick} onClick={handleClick}
color='inherit' color="inherit"
> >
<img <img
src={avatarContent} src={avatarContent}
alt='user-avatar' alt="user-avatar"
className='profile-image' className="profile-image"
style={{ style={{
borderWidth: '3px', borderWidth: '3px',
borderStyle: hexKey ? 'solid' : 'none', borderStyle: hexKey ? 'solid' : 'none',
@ -30,7 +30,7 @@ const Username = ({ username, avatarContent, handleClick }: Props) => {
}} }}
/> />
<Typography <Typography
variant='h6' variant="h6"
sx={{ sx={{
color: '#3e3e3e', color: '#3e3e3e',
padding: '0 8px', padding: '0 8px',

View File

@ -152,9 +152,8 @@ export class MetadataController {
created_at: timestamp created_at: timestamp
} }
signedMetadataEvent = await this.nostrController.signEvent( signedMetadataEvent =
newMetadataEvent await this.nostrController.signEvent(newMetadataEvent)
)
} }
await this.nostrController await this.nostrController
@ -222,9 +221,8 @@ export class MetadataController {
} }
// sign job request event // sign job request event
const jobSignedEvent = await this.nostrController.signEvent( const jobSignedEvent =
jobEventTemplate await this.nostrController.signEvent(jobEventTemplate)
)
const relays = [ const relays = [
'wss://relay.damus.io', 'wss://relay.damus.io',

View File

@ -219,12 +219,10 @@ export class NostrController extends EventEmitter {
results.forEach((res, index) => { results.forEach((res, index) => {
if (res.status === 'rejected') { if (res.status === 'rejected') {
failedPublishes.push( failedPublishes.push({
{ relay: relays[index],
relay: relays[index], error: res.reason.message
error: res.reason.message })
}
)
} }
}) })

View File

@ -59,13 +59,13 @@ export const MainLayout = () => {
setIsLoading(false) setIsLoading(false)
}, [dispatch]) }, [dispatch])
if (isLoading) return <LoadingSpinner desc='Loading App' /> if (isLoading) return <LoadingSpinner desc="Loading App" />
return ( return (
<> <>
<AppBar /> <AppBar />
<Box className='main'> <Box className="main">
<Container <Container
sx={{ sx={{
position: 'relative', position: 'relative',

View File

@ -93,7 +93,7 @@ export const DecryptZip = () => {
<> <>
{isLoading && <LoadingSpinner desc={loadingSpinnerDesc} />} {isLoading && <LoadingSpinner desc={loadingSpinnerDesc} />}
<Box className={styles.container}> <Box className={styles.container}>
<Typography component='label' variant='h6'> <Typography component="label" variant="h6">
Select encrypted zip file Select encrypted zip file
</Typography> </Typography>
@ -104,11 +104,11 @@ export const DecryptZip = () => {
> >
{isDraggingOver && ( {isDraggingOver && (
<Box className={styles.fileDragOver}> <Box className={styles.fileDragOver}>
<Typography variant='body1'>Drop file here</Typography> <Typography variant="body1">Drop file here</Typography>
</Box> </Box>
)} )}
<MuiFileInput <MuiFileInput
placeholder='Drop file here, or click to select' placeholder="Drop file here, or click to select"
value={selectedFile} value={selectedFile}
onChange={(value) => setSelectedFile(value)} onChange={(value) => setSelectedFile(value)}
InputProps={{ InputProps={{
@ -119,8 +119,8 @@ export const DecryptZip = () => {
/> />
<TextField <TextField
label='Encryption Key' label="Encryption Key"
variant='outlined' variant="outlined"
value={encryptionKey} value={encryptionKey}
onChange={(e) => setEncryptionKey(e.target.value)} onChange={(e) => setEncryptionKey(e.target.value)}
/> />
@ -129,7 +129,7 @@ export const DecryptZip = () => {
<Box sx={{ mt: 1, display: 'flex', justifyContent: 'center' }}> <Box sx={{ mt: 1, display: 'flex', justifyContent: 'center' }}>
<Button <Button
onClick={handleDecrypt} onClick={handleDecrypt}
variant='contained' variant="contained"
disabled={!selectedFile || !encryptionKey} disabled={!selectedFile || !encryptionKey}
> >
Decrypt Decrypt

View File

@ -10,13 +10,13 @@ export const HomePage = () => {
<Box className={styles.container}> <Box className={styles.container}>
<Button <Button
onClick={() => navigate(appPrivateRoutes.sign)} onClick={() => navigate(appPrivateRoutes.sign)}
variant='contained' variant="contained"
> >
Sign Sign
</Button> </Button>
<Button <Button
onClick={() => navigate(appPrivateRoutes.verify)} onClick={() => navigate(appPrivateRoutes.verify)}
variant='contained' variant="contained"
> >
Verify Verify
</Button> </Button>

View File

@ -57,7 +57,7 @@ export const LandingPage = () => {
? theme.palette.getContrastText(bodyBackgroundColor) ? theme.palette.getContrastText(bodyBackgroundColor)
: '' : ''
}} }}
variant='h4' variant="h4"
> >
What is Nostr? What is Nostr?
</Typography> </Typography>
@ -67,14 +67,14 @@ export const LandingPage = () => {
? theme.palette.getContrastText(bodyBackgroundColor) ? theme.palette.getContrastText(bodyBackgroundColor)
: '' : ''
}} }}
variant='body1' variant="body1"
> >
Nostr is a decentralised messaging protocol where YOU own your Nostr is a decentralised messaging protocol where YOU own your
identity. To get started, you must have an existing{' '} identity. To get started, you must have an existing{' '}
<a <a
className='bold-link' className="bold-link"
target='_blank' target="_blank"
href='https://nostr.com/' href="https://nostr.com/"
> >
Nostr account Nostr account
</a> </a>
@ -95,7 +95,7 @@ export const LandingPage = () => {
<div className={styles.loginBottomBar}> <div className={styles.loginBottomBar}>
<Button <Button
className={styles.loginBtn} className={styles.loginBtn}
variant='contained' variant="contained"
onClick={onSignInClick} onClick={onSignInClick}
> >
GET STARTED GET STARTED

View File

@ -53,9 +53,8 @@ export const Login = () => {
dispatch(updateLoginMethod(LoginMethods.extension)) dispatch(updateLoginMethod(LoginMethods.extension))
setLoadingSpinnerDesc('Authenticating and finding metadata') setLoadingSpinnerDesc('Authenticating and finding metadata')
const redirectPath = await authController.authenticateAndFindMetadata( const redirectPath =
pubkey await authController.authenticateAndFindMetadata(pubkey)
)
navigate(redirectPath) navigate(redirectPath)
}) })
@ -290,10 +289,10 @@ export const Login = () => {
if (authUrl) { if (authUrl) {
return ( return (
<iframe <iframe
title='Nsecbunker auth' title="Nsecbunker auth"
src={authUrl} src={authUrl}
width='100%' width="100%"
height='500px' height="500px"
/> />
) )
} }
@ -302,21 +301,21 @@ export const Login = () => {
<> <>
{isLoading && <LoadingSpinner desc={loadingSpinnerDesc} />} {isLoading && <LoadingSpinner desc={loadingSpinnerDesc} />}
<div className={styles.loginPage}> <div className={styles.loginPage}>
<Typography variant='h4'>Welcome to Sigit</Typography> <Typography variant="h4">Welcome to Sigit</Typography>
<TextField <TextField
label='nip05 / npub / nsec / bunker connx string' label="nip05 / npub / nsec / bunker connx string"
value={inputValue} value={inputValue}
onChange={(e) => setInputValue(e.target.value)} onChange={(e) => setInputValue(e.target.value)}
sx={{ width: '100%', mt: 2 }} sx={{ width: '100%', mt: 2 }}
/> />
{isNostrExtensionAvailable && ( {isNostrExtensionAvailable && (
<Button onClick={loginWithExtension} variant='text'> <Button onClick={loginWithExtension} variant="text">
Login with extension Login with extension
</Button> </Button>
)} )}
<Box sx={{ mt: 1, display: 'flex', justifyContent: 'center' }}> <Box sx={{ mt: 1, display: 'flex', justifyContent: 'center' }}>
<Button disabled={!inputValue} onClick={login} variant='contained'> <Button disabled={!inputValue} onClick={login} variant="contained">
Login Login
</Button> </Button>
</Box> </Box>

View File

@ -127,7 +127,7 @@ export const ProfilePage = () => {
label={label} label={label}
id={label.split(' ').join('-')} id={label.split(' ').join('-')}
value={profileMetadata![key] || ''} value={profileMetadata![key] || ''}
size='small' size="small"
multiline={multiline} multiline={multiline}
rows={rows} rows={rows}
className={styles.textField} className={styles.textField}
@ -166,7 +166,7 @@ export const ProfilePage = () => {
label={label} label={label}
id={label.split(' ').join('-')} id={label.split(' ').join('-')}
defaultValue={value} defaultValue={value}
size='small' size="small"
className={styles.textField} className={styles.textField}
disabled disabled
type={isPassword ? 'password' : 'text'} type={isPassword ? 'password' : 'text'}
@ -230,18 +230,23 @@ export const ProfilePage = () => {
} }
/** /**
* *
* @returns robohash generate button, loading spinner or no button * @returns robohash generate button, loading spinner or no button
*/ */
const robohashButton = () => { const robohashButton = () => {
if (profileMetadata?.picture?.includes('robohash')) return null if (profileMetadata?.picture?.includes('robohash')) return null
return <Tooltip title="Generate a robohash avatar"> return (
{avatarLoading ? <CircularProgress style={{padding: 8}} size={22}/> <Tooltip title="Generate a robohash avatar">
: <IconButton onClick={generateRobotAvatar}> {avatarLoading ? (
<SmartToy/> <CircularProgress style={{ padding: 8 }} size={22} />
</IconButton>} ) : (
</Tooltip> <IconButton onClick={generateRobotAvatar}>
<SmartToy />
</IconButton>
)}
</Tooltip>
)
} }
return ( return (
@ -284,7 +289,7 @@ export const ProfilePage = () => {
}} }}
className={styles.img} className={styles.img}
src={profileMetadata.picture || placeholderAvatar} src={profileMetadata.picture || placeholderAvatar}
alt='Profile Image' alt="Profile Image"
/> />
{nostrJoiningBlock && ( {nostrJoiningBlock && (
@ -296,7 +301,7 @@ export const ProfilePage = () => {
}} }}
component={Link} component={Link}
to={`https://njump.me/${nostrJoiningBlock.encodedEventPointer}`} to={`https://njump.me/${nostrJoiningBlock.encodedEventPointer}`}
target='_blank' target="_blank"
> >
On nostr since {nostrJoiningBlock.block.toLocaleString()} On nostr since {nostrJoiningBlock.block.toLocaleString()}
</Typography> </Typography>
@ -333,7 +338,7 @@ export const ProfilePage = () => {
{isUsersOwnProfile && ( {isUsersOwnProfile && (
<LoadingButton <LoadingButton
loading={savingProfileMetadata} loading={savingProfileMetadata}
variant='contained' variant="contained"
onClick={handleSaveMetadata} onClick={handleSaveMetadata}
> >
SAVE SAVE

View File

@ -336,10 +336,10 @@ export const SignPage = () => {
if (authUrl) { if (authUrl) {
return ( return (
<iframe <iframe
title='Nsecbunker auth' title="Nsecbunker auth"
src={authUrl} src={authUrl}
width='100%' width="100%"
height='500px' height="500px"
/> />
) )
} }
@ -348,13 +348,13 @@ export const SignPage = () => {
<> <>
{isLoading && <LoadingSpinner desc={loadingSpinnerDesc} />} {isLoading && <LoadingSpinner desc={loadingSpinnerDesc} />}
<Box className={styles.container}> <Box className={styles.container}>
<Typography component='label' variant='h6'> <Typography component="label" variant="h6">
Select files Select files
</Typography> </Typography>
<MuiFileInput <MuiFileInput
multiple multiple
placeholder='Choose Files' placeholder="Choose Files"
value={selectedFiles} value={selectedFiles}
onChange={(value) => handleSelectFiles(value)} onChange={(value) => handleSelectFiles(value)}
/> />
@ -362,7 +362,7 @@ export const SignPage = () => {
<ul> <ul>
{selectedFiles.map((file, index) => ( {selectedFiles.map((file, index) => (
<li key={index}> <li key={index}>
<Typography component='label'>{file.name}</Typography> <Typography component="label">{file.name}</Typography>
<IconButton onClick={() => handleRemoveFile(file)}> <IconButton onClick={() => handleRemoveFile(file)}>
<Clear style={{ color: 'red' }} />{' '} <Clear style={{ color: 'red' }} />{' '}
</IconButton> </IconButton>
@ -372,24 +372,24 @@ export const SignPage = () => {
{displayUserInput && ( {displayUserInput && (
<> <>
<Typography component='label' variant='h6'> <Typography component="label" variant="h6">
Select signers and viewers Select signers and viewers
</Typography> </Typography>
<Box className={styles.inputBlock}> <Box className={styles.inputBlock}>
<TextField <TextField
label='nip05 / npub' label="nip05 / npub"
value={userInput} value={userInput}
onChange={(e) => setUserInput(e.target.value)} onChange={(e) => setUserInput(e.target.value)}
helperText={error} helperText={error}
error={!!error} error={!!error}
/> />
<FormControl fullWidth> <FormControl fullWidth>
<InputLabel id='select-role-label'>Role</InputLabel> <InputLabel id="select-role-label">Role</InputLabel>
<Select <Select
labelId='select-role-label' labelId="select-role-label"
id='demo-simple-select' id="demo-simple-select"
value={userRole} value={userRole}
label='Role' label="Role"
onChange={(e) => setUserRole(e.target.value as UserRole)} onChange={(e) => setUserRole(e.target.value as UserRole)}
> >
<MenuItem value={UserRole.signer}>{UserRole.signer}</MenuItem> <MenuItem value={UserRole.signer}>{UserRole.signer}</MenuItem>
@ -401,7 +401,7 @@ export const SignPage = () => {
<Button <Button
disabled={!userInput} disabled={!userInput}
onClick={handleAddUser} onClick={handleAddUser}
variant='contained' variant="contained"
> >
Add Add
</Button> </Button>
@ -413,7 +413,7 @@ export const SignPage = () => {
handleRemoveUser={handleRemoveUser} handleRemoveUser={handleRemoveUser}
/> />
<Box sx={{ mt: 1, display: 'flex', justifyContent: 'center' }}> <Box sx={{ mt: 1, display: 'flex', justifyContent: 'center' }}>
<Button onClick={handleSign} variant='contained'> <Button onClick={handleSign} variant="contained">
Sign Sign
</Button> </Button>
</Box> </Box>
@ -491,8 +491,8 @@ const DisplayUser = ({
<img <img
onError={imageLoadError} onError={imageLoadError}
src={userMeta?.picture || roboUrl} src={userMeta?.picture || roboUrl}
alt='Profile Image' alt="Profile Image"
className='profile-image' className="profile-image"
style={{ style={{
borderWidth: '3px', borderWidth: '3px',
borderStyle: 'solid', borderStyle: 'solid',
@ -500,7 +500,7 @@ const DisplayUser = ({
}} }}
/> />
<Link to={getProfileRoute(user.pubkey)}> <Link to={getProfileRoute(user.pubkey)}>
<Typography component='label' className={styles.name}> <Typography component="label" className={styles.name}>
{userMeta?.display_name || {userMeta?.display_name ||
userMeta?.name || userMeta?.name ||
shorten(npub)} shorten(npub)}
@ -525,7 +525,7 @@ const DisplayUser = ({
</Select> </Select>
</TableCell> </TableCell>
<TableCell> <TableCell>
<Tooltip title='Remove User' arrow> <Tooltip title="Remove User" arrow>
<IconButton onClick={() => handleRemoveUser(user.pubkey)}> <IconButton onClick={() => handleRemoveUser(user.pubkey)}>
<Clear style={{ color: 'red' }} /> <Clear style={{ color: 'red' }} />
</IconButton> </IconButton>

View File

@ -455,10 +455,10 @@ export const VerifyPage = () => {
if (authUrl) { if (authUrl) {
return ( return (
<iframe <iframe
title='Nsecbunker auth' title="Nsecbunker auth"
src={authUrl} src={authUrl}
width='100%' width="100%"
height='500px' height="500px"
/> />
) )
} }
@ -469,13 +469,13 @@ export const VerifyPage = () => {
<Box className={styles.container}> <Box className={styles.container}>
{displayInput && ( {displayInput && (
<> <>
<Typography component='label' variant='h6'> <Typography component="label" variant="h6">
Select sigit file Select sigit file
</Typography> </Typography>
<Box className={styles.inputBlock}> <Box className={styles.inputBlock}>
<MuiFileInput <MuiFileInput
placeholder='Select file' placeholder="Select file"
value={selectedFile} value={selectedFile}
onChange={(value) => setSelectedFile(value)} onChange={(value) => setSelectedFile(value)}
InputProps={{ InputProps={{
@ -487,8 +487,8 @@ export const VerifyPage = () => {
{selectedFile && ( {selectedFile && (
<TextField <TextField
label='Encryption Key' label="Encryption Key"
variant='outlined' variant="outlined"
value={encryptionKey} value={encryptionKey}
onChange={(e) => setEncryptionKey(e.target.value)} onChange={(e) => setEncryptionKey(e.target.value)}
/> />
@ -497,7 +497,7 @@ export const VerifyPage = () => {
{selectedFile && encryptionKey && ( {selectedFile && encryptionKey && (
<Box sx={{ mt: 2, display: 'flex', justifyContent: 'center' }}> <Box sx={{ mt: 2, display: 'flex', justifyContent: 'center' }}>
<Button onClick={handleDecrypt} variant='contained'> <Button onClick={handleDecrypt} variant="contained">
Decrypt Decrypt
</Button> </Button>
</Box> </Box>
@ -509,7 +509,7 @@ export const VerifyPage = () => {
<> <>
<DisplayMeta meta={meta} nextSigner={nextSinger} /> <DisplayMeta meta={meta} nextSigner={nextSinger} />
<Box sx={{ mt: 1, display: 'flex', justifyContent: 'center' }}> <Box sx={{ mt: 1, display: 'flex', justifyContent: 'center' }}>
<Button onClick={handleExport} variant='contained'> <Button onClick={handleExport} variant="contained">
Export Export
</Button> </Button>
</Box> </Box>
@ -524,7 +524,7 @@ export const VerifyPage = () => {
<> <>
<DisplayMeta meta={meta} nextSigner={nextSinger} /> <DisplayMeta meta={meta} nextSigner={nextSinger} />
<Box sx={{ mt: 1, display: 'flex', justifyContent: 'center' }}> <Box sx={{ mt: 1, display: 'flex', justifyContent: 'center' }}>
<Button onClick={handleSign} variant='contained'> <Button onClick={handleSign} variant="contained">
Sign Sign
</Button> </Button>
</Box> </Box>
@ -661,7 +661,7 @@ const DisplayMeta = ({ meta, nextSigner }: DisplayMetaProps) => {
gap: '15px' gap: '15px'
}} }}
> >
<Typography variant='h6' sx={{ color: textColor }}> <Typography variant="h6" sx={{ color: textColor }}>
Submitted By Submitted By
</Typography> </Typography>
<Box className={styles.user}> <Box className={styles.user}>
@ -671,8 +671,8 @@ const DisplayMeta = ({ meta, nextSigner }: DisplayMetaProps) => {
metadata[meta.submittedBy]?.picture || metadata[meta.submittedBy]?.picture ||
getRoboImageUrl(meta.submittedBy) getRoboImageUrl(meta.submittedBy)
} }
alt='Profile Image' alt="Profile Image"
className='profile-image' className="profile-image"
style={{ style={{
borderWidth: '3px', borderWidth: '3px',
borderStyle: 'solid', borderStyle: 'solid',
@ -680,7 +680,7 @@ const DisplayMeta = ({ meta, nextSigner }: DisplayMetaProps) => {
}} }}
/> />
<Link to={getProfileRoute(meta.submittedBy)}> <Link to={getProfileRoute(meta.submittedBy)}>
<Typography component='label' className={styles.name}> <Typography component="label" className={styles.name}>
{metadata[meta.submittedBy]?.display_name || {metadata[meta.submittedBy]?.display_name ||
metadata[meta.submittedBy]?.name || metadata[meta.submittedBy]?.name ||
shorten(hexToNpub(meta.submittedBy))} shorten(hexToNpub(meta.submittedBy))}
@ -695,7 +695,7 @@ const DisplayMeta = ({ meta, nextSigner }: DisplayMetaProps) => {
alignItems: 'flex-start' alignItems: 'flex-start'
}} }}
> >
<Typography variant='h6' sx={{ color: textColor }}> <Typography variant="h6" sx={{ color: textColor }}>
Files Files
</Typography> </Typography>
<ul> <ul>
@ -741,8 +741,8 @@ const DisplayMeta = ({ meta, nextSigner }: DisplayMetaProps) => {
<img <img
onError={imageLoadError} onError={imageLoadError}
src={userMeta?.picture || roboUrl} src={userMeta?.picture || roboUrl}
alt='Profile Image' alt="Profile Image"
className='profile-image' className="profile-image"
style={{ style={{
borderWidth: '3px', borderWidth: '3px',
borderStyle: 'solid', borderStyle: 'solid',
@ -750,7 +750,7 @@ const DisplayMeta = ({ meta, nextSigner }: DisplayMetaProps) => {
}} }}
/> />
<Link to={getProfileRoute(user.pubkey)}> <Link to={getProfileRoute(user.pubkey)}>
<Typography component='label' className={styles.name}> <Typography component="label" className={styles.name}>
{userMeta?.display_name || {userMeta?.display_name ||
userMeta?.name || userMeta?.name ||
shorten(npub)} shorten(npub)}

View File

@ -1,20 +1,21 @@
export class DecryptionError extends Error { export class DecryptionError extends Error {
public message: string = '' public message: string = ''
constructor( constructor(public inputError: any) {
public inputError: any
) {
super() super()
if (inputError.message.toLowerCase().includes('expected')) { if (inputError.message.toLowerCase().includes('expected')) {
this.message = `The decryption key length or format is invalid.` this.message = `The decryption key length or format is invalid.`
} else if (inputError.message.includes('The JWK "alg" member was inconsistent')) { } else if (
inputError.message.includes('The JWK "alg" member was inconsistent')
) {
this.message = `The decryption key is invalid.` this.message = `The decryption key is invalid.`
} else { } else {
this.message = inputError.message || 'An error occurred while decrypting file.' this.message =
inputError.message || 'An error occurred while decrypting file.'
} }
this.name = 'DecryptionError' this.name = 'DecryptionError'
Object.setPrototypeOf(this, DecryptionError.prototype) Object.setPrototypeOf(this, DecryptionError.prototype)
} }
} }

View File

@ -66,14 +66,14 @@ export const decryptArrayBuffer = async (
) => { ) => {
try { try {
const { cryptoKey, iv } = await importKey(key) const { cryptoKey, iv } = await importKey(key)
// Decrypt the data // Decrypt the data
const decryptedData = await window.crypto.subtle.decrypt( const decryptedData = await window.crypto.subtle.decrypt(
{ name: ENCRYPTION_ALGO_NAME, iv }, { name: ENCRYPTION_ALGO_NAME, iv },
cryptoKey, cryptoKey,
encryptedData encryptedData
) )
return decryptedData return decryptedData
} catch (err) { } catch (err) {
throw new DecryptionError(err) throw new DecryptionError(err)

View File

@ -166,7 +166,9 @@ export const sendDM = async (
toast.error('An error occurred while publishing DM') toast.error('An error occurred while publishing DM')
errResults.forEach((errResult: any) => { errResults.forEach((errResult: any) => {
toast.error(`Publishing to ${errResult.relay} caused the following error: ${errResult.error}`) toast.error(
`Publishing to ${errResult.relay} caused the following error: ${errResult.error}`
)
}) })
return null return null