issue-166-open-timestamps #220

Merged
eugene merged 25 commits from issue-166-open-timestamps into staging 2024-10-25 11:18:47 +00:00
Showing only changes of commit 2b630c94b6 - Show all commits

View File

@ -9,8 +9,8 @@ import {
DocSignatureEvent, DocSignatureEvent,
Meta, Meta,
SignedEvent, SignedEvent,
Timestamp, OpenTimestamp,
TimestampUpgradeVerifyResponse OpenTimestampUpgradeVerifyResponse
} from '../../types' } from '../../types'
import { import {
decryptArrayBuffer, decryptArrayBuffer,
@ -43,7 +43,7 @@ import { saveAs } from 'file-saver'
import { Container } from '../../components/Container' import { Container } from '../../components/Container'
import { useSigitMeta } from '../../hooks/useSigitMeta.tsx' import { useSigitMeta } from '../../hooks/useSigitMeta.tsx'
import { StickySideColumns } from '../../layouts/StickySideColumns.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 FileList from '../../components/FileList'
import { CurrentUserFile } from '../../types/file.ts' import { CurrentUserFile } from '../../types/file.ts'
import { Mark } from '../../types/mark.ts' import { Mark } from '../../types/mark.ts'
@ -57,11 +57,7 @@ import {
faFile, faFile,
faFileDownload faFileDownload
} from '@fortawesome/free-solid-svg-icons' } from '@fortawesome/free-solid-svg-icons'
import { import { upgradeAndVerifyTimestamp } from '../../utils/opentimestamps.ts'
upgradeAndVerifyTimestamp,
upgradeTimestamps,
verifyTimestamps
} from '../../utils/opentimestamps.ts'
import _ from 'lodash' import _ from 'lodash'
interface PdfViewProps { interface PdfViewProps {
@ -207,7 +203,7 @@ export const VerifyPage = () => {
}>({}) }>({})
const signTimestampEvent = async (signerContent: { const signTimestampEvent = async (signerContent: {
timestamps: Timestamp[] timestamps: OpenTimestamp[]
}): Promise<SignedEvent | null> => { }): Promise<SignedEvent | null> => {
return await signEventForMetaFile( return await signEventForMetaFile(
JSON.stringify(signerContent), JSON.stringify(signerContent),
@ -224,82 +220,108 @@ export const VerifyPage = () => {
}, [currentFileHashes, fileHashes, files]) }, [currentFileHashes, fileHashes, files])
useEffect(() => { useEffect(() => {
console.log('timestamps: ', timestamps)
if (timestamps && timestamps.length > 0) { if (timestamps && timestamps.length > 0) {
console.log(timestamps.every((t) => !!t.verification))
if (timestamps.every((t) => !!t.verification)) { if (timestamps.every((t) => !!t.verification)) {
toast.success('All of your timestamps are fully verified on Bitcoin.')
return return
} }
const upgradeT = async (timestamps: Timestamp[]) => { const upgradeT = async (timestamps: OpenTimestamp[]) => {
const verifiedResults = await Promise.all( try {
timestamps.map(upgradeAndVerifyTimestamp) setLoadingSpinnerDesc('Upgrading and verifying your timestamps.')
) const verifiedResults = await Promise.all(
timestamps.map(upgradeAndVerifyTimestamp)
)
const upgradedTimestamps = verifiedResults /**
.filter((t) => t.upgraded || isNewlyVerified(t, timestamps)) * Checks if timestamp verification has been achieved for the first time.
.map((t) => { * Note that the upgrade flag is separate from verification. It is possible for a timestamp
const timestamp = t.value * to not be upgraded, but to be verified for the first time.
if (t.verified) { * @param upgradedTimestamp
timestamp.verification = t.verification * @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 = ( const updatedMeta = _.cloneDeep(meta)
upgradedTimestamp: TimestampUpgradeVerifyResponse, updatedMeta.timestamps = [...finalTimestamps]
timestamps: Timestamp[] updatedMeta.modifiedAt = unixNow()
) => {
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 signedEvent = await signTimestampEvent({ const updatedEvent = await updateUsersAppData(updatedMeta)
timestamps: upgradedTimestamps if (!updatedEvent) return
})
if (!signedEvent) return
const finalTimestamps = timestamps.map((t) => { const userSet = new Set<`npub1${string}`>()
const upgraded = upgradedTimestamps.find( signers.forEach((signer) => {
(tu) => tu.nostrId === t.nostrId if (signer !== usersPubkey) {
) userSet.add(signer)
if (upgraded) {
return {
...upgraded,
signature: JSON.stringify(signedEvent, null, 2)
} }
} })
return t
})
const updatedMeta = _.cloneDeep(meta) viewers.forEach((viewer) => {
updatedMeta.timestamps = [...finalTimestamps] userSet.add(viewer)
updatedMeta.modifiedAt = unixNow() })
const updatedEvent = await updateUsersAppData(updatedMeta) const users = Array.from(userSet)
if (!updatedEvent) return const promises = users.map((user) =>
sendNotification(npubToHex(user)!, updatedMeta)
)
const userSet = new Set<`npub1${string}`>() await Promise.all(promises)
signers.forEach((signer) => {
if (signer !== usersPubkey) {
userSet.add(signer)
}
})
viewers.forEach((viewer) => { toast.success('Timestamp updates have been sent successfully.')
userSet.add(viewer)
})
const users = Array.from(userSet) setMeta(meta)
const promises = users.map((user) => } catch (err) {
sendNotification(npubToHex(user)!, updatedMeta) console.error(err)
) toast.error(
'There was an error upgrading or verifying your timestamps!'
await Promise.all(promises) )
}
setTimestamps(finalTimestamps)
setMeta(meta)
} }
upgradeT(timestamps) upgradeT(timestamps)
} }