diff --git a/src/pages/create/index.tsx b/src/pages/create/index.tsx index 2f9fc67..78f604a 100644 --- a/src/pages/create/index.tsx +++ b/src/pages/create/index.tsx @@ -29,13 +29,13 @@ import { UserComponent } from '../../components/username' import { MetadataController, NostrController } from '../../controllers' import { appPrivateRoutes } from '../../routes' import { State } from '../../store/rootReducer' -import { ProfileMetadata, User, UserRole } from '../../types' +import { Meta, ProfileMetadata, User, UserRole } from '../../types' import { encryptArrayBuffer, generateEncryptionKey, getHash, hexToNpub, - pubToHex, + npubToHex, queryNip05, sendDM, shorten, @@ -109,7 +109,7 @@ export const CreatePage = () => { } if (userInput.startsWith('npub')) { - const pubkey = await pubToHex(userInput) + const pubkey = npubToHex(userInput) if (pubkey) { addUser(pubkey) setUserInput('') @@ -246,13 +246,13 @@ export const CreatePage = () => { if (!signedEvent) return // create content for meta file - const meta = { - signers: signers.map((signer) => signer.pubkey), - viewers: viewers.map((viewer) => viewer.pubkey), + const meta: Meta = { + signers: signers.map((signer) => hexToNpub(signer.pubkey)), + viewers: viewers.map((viewer) => hexToNpub(viewer.pubkey)), fileHashes, - submittedBy: usersPubkey, + submittedBy: hexToNpub(usersPubkey!), signedEvents: { - [signedEvent.pubkey]: JSON.stringify(signedEvent, null, 2) + [hexToNpub(signedEvent.pubkey)]: JSON.stringify(signedEvent, null, 2) } } diff --git a/src/pages/login/index.tsx b/src/pages/login/index.tsx index d05edb8..b14e714 100644 --- a/src/pages/login/index.tsx +++ b/src/pages/login/index.tsx @@ -18,7 +18,7 @@ import { } from '../../store/actions' import { LoginMethods } from '../../store/auth/types' import { Dispatch } from '../../store/store' -import { pubToHex, queryNip05 } from '../../utils' +import { npubToHex, queryNip05 } from '../../utils' import styles from './style.module.scss' export const Login = () => { @@ -53,8 +53,9 @@ export const Login = () => { dispatch(updateLoginMethod(LoginMethods.extension)) setLoadingSpinnerDesc('Authenticating and finding metadata') - const redirectPath = - await authController.authenticateAndFindMetadata(pubkey) + const redirectPath = await authController.authenticateAndFindMetadata( + pubkey + ) navigate(redirectPath) }) @@ -213,7 +214,7 @@ export const Login = () => { const keyEndIndex = inputValue.indexOf('?relay=') const key = inputValue.substring(keyStartIndex, keyEndIndex) - const pubkey = await pubToHex(key) + const pubkey = npubToHex(key) if (!pubkey) { toast.error('Invalid pubkey in bunker connection string.') diff --git a/src/pages/sign/index.tsx b/src/pages/sign/index.tsx index d91c5e6..a3c7e87 100644 --- a/src/pages/sign/index.tsx +++ b/src/pages/sign/index.tsx @@ -36,6 +36,7 @@ import { getHash, hexToNpub, parseJson, + npubToHex, readContentOfZipEntry, sendDM, shorten, @@ -88,9 +89,11 @@ export const SignPage = () => { } else { for (const signer of meta.signers) { if (!signedBy.includes(signer)) { - setNextSinger(signer) + setNextSinger(npubToHex(signer)!) - if (signer === usersPubkey) { + const usersNpub = hexToNpub(usersPubkey!) + + if (signer === usersNpub) { // logged in user is the next signer setSignedStatus(SignedStatus.User_Is_Next_Signer) } else { @@ -287,7 +290,7 @@ export const SignPage = () => { metaCopy.signedEvents = { ...metaCopy.signedEvents, - [signedEvent.pubkey]: JSON.stringify(signedEvent, null, 2) + [hexToNpub(signedEvent.pubkey)]: JSON.stringify(signedEvent, null, 2) } const stringifiedMeta = JSON.stringify(metaCopy, null, 2) @@ -320,13 +323,10 @@ export const SignPage = () => { if (!arrayBuffer) return - const encryptionKey = await generateEncryptionKey() + const key = await generateEncryptionKey() setLoadingSpinnerDesc('Encrypting zip file') - const encryptedArrayBuffer = await encryptArrayBuffer( - arrayBuffer, - encryptionKey - ) + const encryptedArrayBuffer = await encryptArrayBuffer(arrayBuffer, key) const blob = new Blob([encryptedArrayBuffer]) @@ -346,13 +346,14 @@ export const SignPage = () => { if (!fileUrl) return // check if the current user is the last signer + const usersNpub = hexToNpub(usersPubkey!) const lastSignerIndex = meta.signers.length - 1 - const signerIndex = meta.signers.indexOf(usersPubkey!) + const signerIndex = meta.signers.indexOf(usersNpub) const isLastSigner = signerIndex === lastSignerIndex // if current user is the last signer, then send DMs to all signers and viewers if (isLastSigner) { - const userSet = new Set() + const userSet = new Set<`npub1${string}`>() userSet.add(meta.submittedBy) @@ -370,27 +371,19 @@ export const SignPage = () => { // todo: execute in parallel await sendDM( fileUrl, - encryptionKey, - user, + key, + npubToHex(user)!, nostrController, false, setAuthUrl ) } - - // when user is the last signer and has sent - // the final document to all the signers and viewers - // update search params with updated file url and encryption key - setSearchParams({ - file: fileUrl, - key: encryptionKey - }) } else { const nextSigner = meta.signers[signerIndex + 1] await sendDM( fileUrl, - encryptionKey, - nextSigner, + key, + npubToHex(nextSigner)!, nostrController, false, setAuthUrl @@ -398,15 +391,22 @@ export const SignPage = () => { } setIsLoading(false) + + // update search params with updated file url and encryption key + setSearchParams({ + file: fileUrl, + key: key + }) } const handleExport = async () => { if (!meta || !zip || !usersPubkey) return + const usersNpub = hexToNpub(usersPubkey) if ( - !meta.signers.includes(usersPubkey) && - !meta.viewers.includes(usersPubkey) && - meta.submittedBy !== usersPubkey + !meta.signers.includes(usersNpub) && + !meta.viewers.includes(usersNpub) && + meta.submittedBy !== usersNpub ) return @@ -563,13 +563,14 @@ const DisplayMeta = ({ meta, nextSigner }: DisplayMetaProps) => { useEffect(() => { meta.signers.forEach((signer) => { + const hexKey = npubToHex(signer) setUsers((prev) => { - if (prev.findIndex((user) => user.pubkey === signer) !== -1) return prev + if (prev.findIndex((user) => user.pubkey === hexKey) !== -1) return prev return [ ...prev, { - pubkey: signer, + pubkey: hexKey!, role: UserRole.signer } ] @@ -577,13 +578,14 @@ const DisplayMeta = ({ meta, nextSigner }: DisplayMetaProps) => { }) meta.viewers.forEach((viewer) => { + const hexKey = npubToHex(viewer) setUsers((prev) => { - if (prev.findIndex((user) => user.pubkey === viewer) !== -1) return prev + if (prev.findIndex((user) => user.pubkey === hexKey) !== -1) return prev return [ ...prev, { - pubkey: viewer, + pubkey: hexKey!, role: UserRole.viewer } ] @@ -594,42 +596,27 @@ const DisplayMeta = ({ meta, nextSigner }: DisplayMetaProps) => { useEffect(() => { const metadataController = new MetadataController() - metadataController - .findMetadata(meta.submittedBy) - .then((metadataEvent) => { - const metadataContent = - metadataController.extractProfileMetadataContent(metadataEvent) - if (metadataContent) - setMetadata((prev) => ({ - ...prev, - [meta.submittedBy]: metadataContent - })) - }) - .catch((err) => { - console.error( - `error occurred in finding metadata for: ${meta.submittedBy}`, - err - ) - }) + const hexKeys: string[] = [ + npubToHex(meta.submittedBy)!, + ...users.map((user) => user.pubkey) + ] - users.forEach((user) => { - if (!(user.pubkey in metadata)) { + hexKeys.forEach((key) => { + if (!(key in metadata)) { metadataController - .findMetadata(user.pubkey) + .findMetadata(key) .then((metadataEvent) => { const metadataContent = metadataController.extractProfileMetadataContent(metadataEvent) + if (metadataContent) setMetadata((prev) => ({ ...prev, - [user.pubkey]: metadataContent + [key]: metadataContent })) }) .catch((err) => { - console.error( - `error occurred in finding metadata for: ${user.pubkey}`, - err - ) + console.error(`error occurred in finding metadata for: ${key}`, err) }) } }) @@ -664,15 +651,21 @@ const DisplayMeta = ({ meta, nextSigner }: DisplayMetaProps) => { Submitted By - + {(function () { + const pubkey = npubToHex(meta.submittedBy) + const profile = metadata[pubkey!] + return ( + + ) + })()} { if (user.role === UserRole.signer) { // check if user has signed the document - if (user.pubkey in meta.signedEvents) { + const usersNpub = hexToNpub(user.pubkey) + if (usersNpub in meta.signedEvents) { signedStatus = 'Signed' } // check if user is the next signer diff --git a/src/pages/verify/index.tsx b/src/pages/verify/index.tsx index 61372c3..6f8b9e1 100644 --- a/src/pages/verify/index.tsx +++ b/src/pages/verify/index.tsx @@ -18,6 +18,7 @@ import { MetadataController } from '../../controllers' import { Meta, ProfileMetadata } from '../../types' import { hexToNpub, + npubToHex, parseJson, readContentOfZipEntry, shorten @@ -48,16 +49,18 @@ export const VerifyPage = () => { const users = [meta.submittedBy, ...meta.signers, ...meta.viewers] users.forEach((user) => { - if (!(user in metadata)) { + const pubkey = npubToHex(user)! + + if (!(pubkey in metadata)) { metadataController - .findMetadata(user) + .findMetadata(pubkey) .then((metadataEvent) => { const metadataContent = metadataController.extractProfileMetadataContent(metadataEvent) if (metadataContent) setMetadata((prev) => ({ ...prev, - [user]: metadataContent + [pubkey]: metadataContent })) }) .catch((err) => { @@ -117,7 +120,8 @@ export const VerifyPage = () => { let isValidSignature = false if (verifySignature) { - const signedEventString = meta ? meta.signedEvents[pubkey] : null + const npub = hexToNpub(pubkey) + const signedEventString = meta ? meta.signedEvents[npub] : null if (signedEventString) { try { const signedEvent = JSON.parse(signedEventString) @@ -142,8 +146,15 @@ export const VerifyPage = () => { /> {verifySignature && ( - - ({isValidSignature ? 'Valid' : 'Not Valid'} Signature) + + ({isValidSignature ? 'Valid' : 'Invalid'} Signature) )} @@ -227,7 +238,7 @@ export const VerifyPage = () => { Submitted By - {displayUser(meta.submittedBy)} + {displayUser(npubToHex(meta.submittedBy)!)} { gap: '15px' }} > - {displayUser(signer, true)} + {displayUser(npubToHex(signer)!, true)} ))} @@ -285,7 +296,7 @@ export const VerifyPage = () => {
    {meta.viewers.map((viewer) => (
  • - {displayUser(viewer)} + {displayUser(npubToHex(viewer)!)}
  • ))}
diff --git a/src/types/core.ts b/src/types/core.ts index a328ac0..4ce1bcb 100644 --- a/src/types/core.ts +++ b/src/types/core.ts @@ -9,10 +9,10 @@ export interface User { } export interface Meta { - signers: string[] - viewers: string[] + signers: `npub1${string}`[] + viewers: `npub1${string}`[] fileHashes: { [key: string]: string } - submittedBy: string - signedEvents: { [key: string]: string } + submittedBy: `npub1${string}` + signedEvents: { [key: `npub1${string}`]: string } exportSignature?: string } diff --git a/src/utils/nostr.ts b/src/utils/nostr.ts index a39502f..3a62414 100644 --- a/src/utils/nostr.ts +++ b/src/utils/nostr.ts @@ -17,21 +17,21 @@ const validateHex = (hexKey: string) => { * @param pubKey in NPUB, HEX format * @returns HEX format */ -export const pubToHex = async (pubKey: string): Promise => { +export const npubToHex = (pubKey: string): string | null => { // If key is NPUB - if (pubKey.startsWith('npub')) { + if (pubKey.startsWith('npub1')) { try { return nip19.decode(pubKey).data as string } catch (error) { - return Promise.resolve(null) + return null } } // valid hex key - if (validateHex(pubKey)) return Promise.resolve(pubKey) + if (validateHex(pubKey)) return pubKey // Not a valid hex key - return Promise.resolve(null) + return null } /** @@ -56,9 +56,8 @@ export const nsecToHex = (nsec: string): string | null => { return null } -export const hexToNpub = (hexPubkey: string | undefined): string => { - if (!hexPubkey) return 'n/a' - if (hexPubkey.includes('npub')) return hexPubkey +export const hexToNpub = (hexPubkey: string): `npub1${string}` => { + if (hexPubkey.startsWith('npub1')) return hexPubkey as `npub1${string}` return nip19.npubEncode(hexPubkey) } @@ -141,8 +140,7 @@ export const base64DecodeAuthToken = (authToken: string): SignedEvent => { } /** - * - * @param pubkey in hex or npub format + * @param pubkey in hex or npub format * @returns robohash.org url for the avatar */ export const getRoboHashPicture = (pubkey: string): string => {