From d15943f61bdac9573d528795ff43903459c0da3b Mon Sep 17 00:00:00 2001 From: Davinci Date: Wed, 15 May 2024 13:14:21 +0200 Subject: [PATCH 1/7] fix: placeholder avatar is incosistent across components --- src/pages/create/index.tsx | 2 +- src/pages/profile/index.tsx | 2 +- src/pages/verify/index.tsx | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/pages/create/index.tsx b/src/pages/create/index.tsx index b7e568d..7d072ab 100644 --- a/src/pages/create/index.tsx +++ b/src/pages/create/index.tsx @@ -21,7 +21,7 @@ import { import { MuiFileInput } from 'mui-file-input' import { useEffect, useState } from 'react' import { Link, useNavigate } from 'react-router-dom' -import placeholderAvatar from '../../assets/images/nostr-logo.jpg' +import placeholderAvatar from '../../assets/images/avatar.png' import { LoadingSpinner } from '../../components/LoadingSpinner' import { MetadataController, NostrController } from '../../controllers' import { appPrivateRoutes, getProfileRoute } from '../../routes' diff --git a/src/pages/profile/index.tsx b/src/pages/profile/index.tsx index 5a38b2f..6a2ade5 100644 --- a/src/pages/profile/index.tsx +++ b/src/pages/profile/index.tsx @@ -15,7 +15,7 @@ import { UnsignedEvent, nip19, kinds, VerifiedEvent } from 'nostr-tools' import { useEffect, useMemo, useState } from 'react' import { Link, useParams } from 'react-router-dom' import { toast } from 'react-toastify' -import placeholderAvatar from '../../assets/images/nostr-logo.jpg' +import placeholderAvatar from '../../assets/images/avatar.png' import { MetadataController, NostrController } from '../../controllers' import { NostrJoiningBlock, ProfileMetadata } from '../../types' import styles from './style.module.scss' diff --git a/src/pages/verify/index.tsx b/src/pages/verify/index.tsx index 6f165b9..7b2a2bd 100644 --- a/src/pages/verify/index.tsx +++ b/src/pages/verify/index.tsx @@ -23,7 +23,7 @@ import { useEffect, useState } from 'react' import { useSelector } from 'react-redux' import { Link, useSearchParams } from 'react-router-dom' import { toast } from 'react-toastify' -import placeholderAvatar from '../../assets/images/nostr-logo.jpg' +import placeholderAvatar from '../../assets/images/avatar.png' import { LoadingSpinner } from '../../components/LoadingSpinner' import { MetadataController, NostrController } from '../../controllers' import { getProfileRoute } from '../../routes' -- 2.34.1 From 4f4f7fb5c1ed21747b4b3bea5771674cf8d159a5 Mon Sep 17 00:00:00 2001 From: Davinci Date: Wed, 15 May 2024 13:57:54 +0200 Subject: [PATCH 2/7] fix: remove nostr image for placeholder avatar, use robohash instead --- src/components/AppBar/AppBar.tsx | 12 +++++++++--- src/pages/create/index.tsx | 9 +++++---- src/pages/profile/index.tsx | 6 +++--- src/pages/verify/index.tsx | 15 ++++++++------- src/utils/nostr.ts | 5 +++++ 5 files changed, 30 insertions(+), 17 deletions(-) diff --git a/src/components/AppBar/AppBar.tsx b/src/components/AppBar/AppBar.tsx index 40ca9de..57acf7f 100644 --- a/src/components/AppBar/AppBar.tsx +++ b/src/components/AppBar/AppBar.tsx @@ -16,11 +16,12 @@ import { Dispatch } from '../../store/store' import Username from '../username' import { Link, useNavigate } from 'react-router-dom' -import nostrichAvatar from '../../assets/images/avatar.png' import { NostrController } from '../../controllers' import { appPublicRoutes, getProfileRoute } from '../../routes' import { clearAuthToken, + getRoboHashPicture, + hexToNpub, saveNsecBunkerDelegatedKey, shorten } from '../../utils' @@ -32,7 +33,7 @@ export const AppBar = () => { const dispatch: Dispatch = useDispatch() const [username, setUsername] = useState('') - const [userAvatar, setUserAvatar] = useState(nostrichAvatar) + const [userAvatar, setUserAvatar] = useState('') const [anchorElUser, setAnchorElUser] = useState(null) const authState = useSelector((state: State) => state.auth) @@ -41,8 +42,13 @@ export const AppBar = () => { useEffect(() => { if (metadataState && metadataState.content) { const { picture, display_name, name } = JSON.parse(metadataState.content) + const npub = authState?.usersPubkey ? hexToNpub(authState.usersPubkey) : '' - if (picture) setUserAvatar(picture) + if (picture) { + setUserAvatar(picture) + } else { + setUserAvatar(getRoboHashPicture(npub)) + } setUsername(shorten(display_name || name || '', 7)) } diff --git a/src/pages/create/index.tsx b/src/pages/create/index.tsx index 7d072ab..c154385 100644 --- a/src/pages/create/index.tsx +++ b/src/pages/create/index.tsx @@ -21,7 +21,6 @@ import { import { MuiFileInput } from 'mui-file-input' import { useEffect, useState } from 'react' import { Link, useNavigate } from 'react-router-dom' -import placeholderAvatar from '../../assets/images/avatar.png' import { LoadingSpinner } from '../../components/LoadingSpinner' import { MetadataController, NostrController } from '../../controllers' import { appPrivateRoutes, getProfileRoute } from '../../routes' @@ -30,6 +29,7 @@ import { encryptArrayBuffer, generateEncryptionKey, getHash, + getRoboHashPicture, hexToNpub, pubToHex, queryNip05, @@ -489,8 +489,9 @@ const DisplayUser = ({ }) }, [users]) - const imageLoadError = (event: any) => { - event.target.src = placeholderAvatar + const imageLoadError = (event: any, pubkey: string) => { + const npub = hexToNpub(pubkey) + event.target.src = getRoboHashPicture(npub) } return ( @@ -513,7 +514,7 @@ const DisplayUser = ({ {imageLoadError(event, user.pubkey)}} src={userMeta?.picture || roboUrl} alt="Profile Image" className="profile-image" diff --git a/src/pages/profile/index.tsx b/src/pages/profile/index.tsx index 6a2ade5..e57e9f7 100644 --- a/src/pages/profile/index.tsx +++ b/src/pages/profile/index.tsx @@ -15,7 +15,6 @@ import { UnsignedEvent, nip19, kinds, VerifiedEvent } from 'nostr-tools' import { useEffect, useMemo, useState } from 'react' import { Link, useParams } from 'react-router-dom' import { toast } from 'react-toastify' -import placeholderAvatar from '../../assets/images/avatar.png' import { MetadataController, NostrController } from '../../controllers' import { NostrJoiningBlock, ProfileMetadata } from '../../types' import styles from './style.module.scss' @@ -27,6 +26,7 @@ import { setMetadataEvent } from '../../store/actions' import { LoadingSpinner } from '../../components/LoadingSpinner' import { LoginMethods } from '../../store/auth/types' import { SmartToy } from '@mui/icons-material' +import { getRoboHashPicture } from '../../utils' export const ProfilePage = () => { const theme = useTheme() @@ -282,13 +282,13 @@ export const ProfilePage = () => { > { - event.target.src = placeholderAvatar + event.target.src = npub ? getRoboHashPicture(npub) : '' }} onLoad={() => { setAvatarLoading(false) }} className={styles.img} - src={profileMetadata.picture || placeholderAvatar} + src={profileMetadata.picture || npub ? getRoboHashPicture(npub!) : ''} alt="Profile Image" /> diff --git a/src/pages/verify/index.tsx b/src/pages/verify/index.tsx index 7b2a2bd..af7da88 100644 --- a/src/pages/verify/index.tsx +++ b/src/pages/verify/index.tsx @@ -23,7 +23,6 @@ import { useEffect, useState } from 'react' import { useSelector } from 'react-redux' import { Link, useSearchParams } from 'react-router-dom' import { toast } from 'react-toastify' -import placeholderAvatar from '../../assets/images/avatar.png' import { LoadingSpinner } from '../../components/LoadingSpinner' import { MetadataController, NostrController } from '../../controllers' import { getProfileRoute } from '../../routes' @@ -34,6 +33,7 @@ import { encryptArrayBuffer, generateEncryptionKey, getHash, + getRoboHashPicture, hexToNpub, parseJson, readContentOfZipEntry, @@ -626,13 +626,14 @@ const DisplayMeta = ({ meta, nextSigner }: DisplayMetaProps) => { }) }, [users, meta.submittedBy]) - const imageLoadError = (event: any) => { - event.target.src = placeholderAvatar + const imageLoadError = (event: any, pubkey: string) => { + const npub = hexToNpub(pubkey) + event.target.src = npub } const getRoboImageUrl = (pubkey: string) => { const npub = hexToNpub(pubkey) - return `https://robohash.org/${npub}.png?set=set3` + return getRoboHashPicture(npub) } return ( @@ -666,7 +667,7 @@ const DisplayMeta = ({ meta, nextSigner }: DisplayMetaProps) => { {imageLoadError(event, meta.submittedBy)}} src={ metadata[meta.submittedBy]?.picture || getRoboImageUrl(meta.submittedBy) @@ -719,7 +720,7 @@ const DisplayMeta = ({ meta, nextSigner }: DisplayMetaProps) => { {users.map((user, index) => { const userMeta = metadata[user.pubkey] const npub = hexToNpub(user.pubkey) - const roboUrl = `https://robohash.org/${npub}.png?set=set3` + const roboUrl = getRoboHashPicture(npub) let signedStatus = '-' @@ -739,7 +740,7 @@ const DisplayMeta = ({ meta, nextSigner }: DisplayMetaProps) => { {imageLoadError(event, meta.submittedBy)}} src={userMeta?.picture || roboUrl} alt="Profile Image" className="profile-image" diff --git a/src/utils/nostr.ts b/src/utils/nostr.ts index 8f074c0..d3eba8b 100644 --- a/src/utils/nostr.ts +++ b/src/utils/nostr.ts @@ -58,6 +58,7 @@ export const nsecToHex = (nsec: string): string | null => { export const hexToNpub = (hexPubkey: string | undefined): string => { if (!hexPubkey) return 'n/a' + if (hexPubkey.includes('npub')) return hexPubkey return nip19.npubEncode(hexPubkey) } @@ -138,3 +139,7 @@ export const base64DecodeAuthToken = (authToken: string): SignedEvent => { throw new Error('An error occurred in JSON.parse of the auth token') } } + +export const getRoboHashPicture = (npub: string): string => { + return `https://robohash.org/${npub}.png?set=set3` +} -- 2.34.1 From 9aa10664a7e5b9af4bde3cb6f5cc55d0334eaa54 Mon Sep 17 00:00:00 2001 From: Davinci Date: Thu, 16 May 2024 08:55:24 +0200 Subject: [PATCH 3/7] fix: getRobohash function will do the conversion of pubkey --- src/components/AppBar/AppBar.tsx | 4 ++-- src/pages/create/index.tsx | 3 +-- src/pages/verify/index.tsx | 6 ++---- src/utils/nostr.ts | 8 +++++++- 4 files changed, 12 insertions(+), 9 deletions(-) diff --git a/src/components/AppBar/AppBar.tsx b/src/components/AppBar/AppBar.tsx index 57acf7f..d20bc8c 100644 --- a/src/components/AppBar/AppBar.tsx +++ b/src/components/AppBar/AppBar.tsx @@ -42,12 +42,12 @@ export const AppBar = () => { useEffect(() => { if (metadataState && metadataState.content) { const { picture, display_name, name } = JSON.parse(metadataState.content) - const npub = authState?.usersPubkey ? hexToNpub(authState.usersPubkey) : '' + const pubkey = authState?.usersPubkey || '' if (picture) { setUserAvatar(picture) } else { - setUserAvatar(getRoboHashPicture(npub)) + setUserAvatar(getRoboHashPicture(pubkey)) } setUsername(shorten(display_name || name || '', 7)) diff --git a/src/pages/create/index.tsx b/src/pages/create/index.tsx index c154385..2847c76 100644 --- a/src/pages/create/index.tsx +++ b/src/pages/create/index.tsx @@ -490,8 +490,7 @@ const DisplayUser = ({ }, [users]) const imageLoadError = (event: any, pubkey: string) => { - const npub = hexToNpub(pubkey) - event.target.src = getRoboHashPicture(npub) + event.target.src = getRoboHashPicture(pubkey) } return ( diff --git a/src/pages/verify/index.tsx b/src/pages/verify/index.tsx index af7da88..9a884d3 100644 --- a/src/pages/verify/index.tsx +++ b/src/pages/verify/index.tsx @@ -632,8 +632,7 @@ const DisplayMeta = ({ meta, nextSigner }: DisplayMetaProps) => { } const getRoboImageUrl = (pubkey: string) => { - const npub = hexToNpub(pubkey) - return getRoboHashPicture(npub) + return getRoboHashPicture(pubkey) } return ( @@ -719,8 +718,7 @@ const DisplayMeta = ({ meta, nextSigner }: DisplayMetaProps) => { {users.map((user, index) => { const userMeta = metadata[user.pubkey] - const npub = hexToNpub(user.pubkey) - const roboUrl = getRoboHashPicture(npub) + const roboUrl = getRoboHashPicture(user.pubkey) let signedStatus = '-' diff --git a/src/utils/nostr.ts b/src/utils/nostr.ts index d3eba8b..a39502f 100644 --- a/src/utils/nostr.ts +++ b/src/utils/nostr.ts @@ -140,6 +140,12 @@ export const base64DecodeAuthToken = (authToken: string): SignedEvent => { } } -export const getRoboHashPicture = (npub: string): string => { +/** + * + * @param pubkey in hex or npub format + * @returns robohash.org url for the avatar + */ +export const getRoboHashPicture = (pubkey: string): string => { + const npub = hexToNpub(pubkey) return `https://robohash.org/${npub}.png?set=set3` } -- 2.34.1 From e9369f855412d9d1dae09e7d41d7d2f8bf49f4fa Mon Sep 17 00:00:00 2001 From: Davinci Date: Thu, 16 May 2024 09:13:47 +0200 Subject: [PATCH 4/7] chore: typo --- src/pages/verify/index.tsx | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/pages/verify/index.tsx b/src/pages/verify/index.tsx index 9a884d3..b7900d4 100644 --- a/src/pages/verify/index.tsx +++ b/src/pages/verify/index.tsx @@ -718,7 +718,8 @@ const DisplayMeta = ({ meta, nextSigner }: DisplayMetaProps) => { {users.map((user, index) => { const userMeta = metadata[user.pubkey] - const roboUrl = getRoboHashPicture(user.pubkey) + const npub = hexToNpub(user.pubkey) + const roboUrl = getRoboHashPicture(npub) let signedStatus = '-' -- 2.34.1 From 60a7140c6a662c225c63108707ac9dd67990f88a Mon Sep 17 00:00:00 2001 From: Davinci Date: Thu, 16 May 2024 09:23:08 +0200 Subject: [PATCH 5/7] fix: removal of create nostr auth token --- src/controllers/AuthController.ts | 14 -------------- src/pages/verify/index.tsx | 4 ++++ 2 files changed, 4 insertions(+), 14 deletions(-) diff --git a/src/controllers/AuthController.ts b/src/controllers/AuthController.ts index 8e488c5..2ed2677 100644 --- a/src/controllers/AuthController.ts +++ b/src/controllers/AuthController.ts @@ -40,20 +40,6 @@ export class AuthController { console.error('Error occurred while finding metadata', err) }) - // Nostr uses unix timestamps - const timestamp = Math.floor(Date.now() / 1000) - const { hostname } = window.location - - const authEvent: EventTemplate = { - kind: 1, - tags: [], - content: `${hostname}-${timestamp}`, - created_at: timestamp - } - - const signedAuthEvent = await this.nostrController.signEvent(authEvent) - this.createAndSaveAuthToken(signedAuthEvent) - store.dispatch( setAuthState({ loggedIn: true, diff --git a/src/pages/verify/index.tsx b/src/pages/verify/index.tsx index b7900d4..09133e8 100644 --- a/src/pages/verify/index.tsx +++ b/src/pages/verify/index.tsx @@ -388,6 +388,10 @@ export const VerifyPage = () => { setIsLoading(false) } + /** + * + * @returns exported.zip including signed files and meta info (about signers and viewers) + */ const handleExport = async () => { if (!meta || !zip || !usersPubkey) return -- 2.34.1 From 5e114f7fb86b4205aefd6125fe5fc2348d3cfb0b Mon Sep 17 00:00:00 2001 From: Davinci Date: Thu, 16 May 2024 10:26:30 +0200 Subject: [PATCH 6/7] fix: verify page robohash --- src/pages/verify/index.tsx | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/src/pages/verify/index.tsx b/src/pages/verify/index.tsx index eeedcec..08dd2df 100644 --- a/src/pages/verify/index.tsx +++ b/src/pages/verify/index.tsx @@ -17,6 +17,7 @@ import { MetadataController } from '../../controllers' import { getProfileRoute } from '../../routes' import { Meta, ProfileMetadata } from '../../types' import { + getRoboHashPicture, hexToNpub, parseJson, readContentOfZipEntry, @@ -112,8 +113,9 @@ export const VerifyPage = () => { setIsLoading(false) } - const imageLoadError = (event: any) => { - event.target.src = placeholderAvatar + const imageLoadError = (event: any, pubkey: string) => { + const npub = hexToNpub(pubkey) + event.target.src = npub } const getRoboImageUrl = (pubkey: string) => { @@ -143,7 +145,7 @@ export const VerifyPage = () => { return ( {imageLoadError(event, pubkey)}} src={profile?.picture || getRoboImageUrl(pubkey)} alt="Profile Image" className="profile-image" -- 2.34.1 From 38913e770de8b1900a58d21354963dadf6180d57 Mon Sep 17 00:00:00 2001 From: Davinci Date: Thu, 16 May 2024 10:56:08 +0200 Subject: [PATCH 7/7] fix: reverting signing of nostr auth token --- src/controllers/AuthController.ts | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/src/controllers/AuthController.ts b/src/controllers/AuthController.ts index 2ed2677..8e488c5 100644 --- a/src/controllers/AuthController.ts +++ b/src/controllers/AuthController.ts @@ -40,6 +40,20 @@ export class AuthController { console.error('Error occurred while finding metadata', err) }) + // Nostr uses unix timestamps + const timestamp = Math.floor(Date.now() / 1000) + const { hostname } = window.location + + const authEvent: EventTemplate = { + kind: 1, + tags: [], + content: `${hostname}-${timestamp}`, + created_at: timestamp + } + + const signedAuthEvent = await this.nostrController.signEvent(authEvent) + this.createAndSaveAuthToken(signedAuthEvent) + store.dispatch( setAuthState({ loggedIn: true, -- 2.34.1