From 2b630c94b639368d5d4789f38c747c190dfec547 Mon Sep 17 00:00:00 2001 From: Eugene Date: Mon, 7 Oct 2024 17:19:32 +0200 Subject: [PATCH] feat(opentimestamps): updates the flow and adds notifications --- src/pages/verify/index.tsx | 160 +++++++++++++++++++++---------------- 1 file changed, 91 insertions(+), 69 deletions(-) diff --git a/src/pages/verify/index.tsx b/src/pages/verify/index.tsx index f470b49..abbaaae 100644 --- a/src/pages/verify/index.tsx +++ b/src/pages/verify/index.tsx @@ -9,8 +9,8 @@ import { DocSignatureEvent, Meta, SignedEvent, - Timestamp, - TimestampUpgradeVerifyResponse + OpenTimestamp, + OpenTimestampUpgradeVerifyResponse } from '../../types' import { decryptArrayBuffer, @@ -43,7 +43,7 @@ import { saveAs } from 'file-saver' import { Container } from '../../components/Container' import { useSigitMeta } from '../../hooks/useSigitMeta.tsx' import { StickySideColumns } from '../../layouts/StickySideColumns.tsx' -import { UsersDetails } from '../../components/UsersDetails.tsx/index.tsx' +import { UsersDetails } from '../../components/UsersDetails.tsx' import FileList from '../../components/FileList' import { CurrentUserFile } from '../../types/file.ts' import { Mark } from '../../types/mark.ts' @@ -57,11 +57,7 @@ import { faFile, faFileDownload } from '@fortawesome/free-solid-svg-icons' -import { - upgradeAndVerifyTimestamp, - upgradeTimestamps, - verifyTimestamps -} from '../../utils/opentimestamps.ts' +import { upgradeAndVerifyTimestamp } from '../../utils/opentimestamps.ts' import _ from 'lodash' interface PdfViewProps { @@ -207,7 +203,7 @@ export const VerifyPage = () => { }>({}) const signTimestampEvent = async (signerContent: { - timestamps: Timestamp[] + timestamps: OpenTimestamp[] }): Promise => { return await signEventForMetaFile( JSON.stringify(signerContent), @@ -224,82 +220,108 @@ export const VerifyPage = () => { }, [currentFileHashes, fileHashes, files]) useEffect(() => { + console.log('timestamps: ', timestamps) if (timestamps && timestamps.length > 0) { + console.log(timestamps.every((t) => !!t.verification)) if (timestamps.every((t) => !!t.verification)) { + toast.success('All of your timestamps are fully verified on Bitcoin.') return } - const upgradeT = async (timestamps: Timestamp[]) => { - const verifiedResults = await Promise.all( - timestamps.map(upgradeAndVerifyTimestamp) - ) + const upgradeT = async (timestamps: OpenTimestamp[]) => { + try { + setLoadingSpinnerDesc('Upgrading and verifying your timestamps.') + const verifiedResults = await Promise.all( + timestamps.map(upgradeAndVerifyTimestamp) + ) - const upgradedTimestamps = verifiedResults - .filter((t) => t.upgraded || isNewlyVerified(t, timestamps)) - .map((t) => { - const timestamp = t.value - if (t.verified) { - timestamp.verification = t.verification + /** + * Checks if timestamp verification has been achieved for the first time. + * Note that the upgrade flag is separate from verification. It is possible for a timestamp + * to not be upgraded, but to be verified for the first time. + * @param upgradedTimestamp + * @param timestamps + */ + const isNewlyVerified = ( + upgradedTimestamp: OpenTimestampUpgradeVerifyResponse, + timestamps: OpenTimestamp[] + ) => { + if (!upgradedTimestamp.verified) return false + const oldT = timestamps.find( + (t) => t.nostrId === upgradedTimestamp.timestamp.nostrId + ) + if (!oldT) return false + if (!oldT.verification && upgradedTimestamp.verified) return true + } + + const upgradedTimestamps = verifiedResults + .filter((t) => t.upgraded || isNewlyVerified(t, timestamps)) + .map((t) => { + const timestamp = t.timestamp + if (t.verified) { + timestamp.verification = t.verification + } + return timestamp + }) + + if (upgradedTimestamps.length === 0) { + toast.success('No further timestamp upgrades found.') + return + } + + setLoadingSpinnerDesc('Signing a timestamp upgrade event.') + + const signedEvent = await signTimestampEvent({ + timestamps: upgradedTimestamps + }) + if (!signedEvent) return + + const finalTimestamps = timestamps.map((t) => { + const upgraded = upgradedTimestamps.find( + (tu) => tu.nostrId === t.nostrId + ) + if (upgraded) { + return { + ...upgraded, + signature: JSON.stringify(signedEvent, null, 2) + } } - return timestamp + return t }) - const isNewlyVerified = ( - upgradedTimestamp: TimestampUpgradeVerifyResponse, - timestamps: Timestamp[] - ) => { - if (!upgradedTimestamp.verified) return false - const oldT = timestamps.find( - (t) => t.nostrId === upgradedTimestamp.value.nostrId - ) - if (!oldT) return false - if (!oldT.verification && upgradedTimestamp.verified) return true - } + const updatedMeta = _.cloneDeep(meta) + updatedMeta.timestamps = [...finalTimestamps] + updatedMeta.modifiedAt = unixNow() - const signedEvent = await signTimestampEvent({ - timestamps: upgradedTimestamps - }) - if (!signedEvent) return + const updatedEvent = await updateUsersAppData(updatedMeta) + if (!updatedEvent) return - const finalTimestamps = timestamps.map((t) => { - const upgraded = upgradedTimestamps.find( - (tu) => tu.nostrId === t.nostrId - ) - if (upgraded) { - return { - ...upgraded, - signature: JSON.stringify(signedEvent, null, 2) + const userSet = new Set<`npub1${string}`>() + signers.forEach((signer) => { + if (signer !== usersPubkey) { + userSet.add(signer) } - } - return t - }) + }) - const updatedMeta = _.cloneDeep(meta) - updatedMeta.timestamps = [...finalTimestamps] - updatedMeta.modifiedAt = unixNow() + viewers.forEach((viewer) => { + userSet.add(viewer) + }) - const updatedEvent = await updateUsersAppData(updatedMeta) - if (!updatedEvent) return + const users = Array.from(userSet) + const promises = users.map((user) => + sendNotification(npubToHex(user)!, updatedMeta) + ) - const userSet = new Set<`npub1${string}`>() - signers.forEach((signer) => { - if (signer !== usersPubkey) { - userSet.add(signer) - } - }) + await Promise.all(promises) - viewers.forEach((viewer) => { - userSet.add(viewer) - }) + toast.success('Timestamp updates have been sent successfully.') - const users = Array.from(userSet) - const promises = users.map((user) => - sendNotification(npubToHex(user)!, updatedMeta) - ) - - await Promise.all(promises) - - setTimestamps(finalTimestamps) - setMeta(meta) + setMeta(meta) + } catch (err) { + console.error(err) + toast.error( + 'There was an error upgrading or verifying your timestamps!' + ) + } } upgradeT(timestamps) }