diff --git a/package-lock.json b/package-lock.json index 9c91664..26a975e 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "proofsnap-extension", - "version": "1.1.1", + "version": "1.1.4", "lockfileVersion": 3, "requires": true, "packages": { "": { "name": "proofsnap-extension", - "version": "1.1.1", + "version": "1.1.4", "dependencies": { "react": "^19.0.0", "react-dom": "^19.0.0" @@ -49,7 +49,6 @@ "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.28.4.tgz", "integrity": "sha512-2BCOP7TN8M+gVDj7/ht3hsaO/B/n5oDbiAyyvnRlNOs+u1o+JWNYTQrmpuNp1/Wq2gcFrI01JAW+paEKDMx/CA==", "dev": true, - "peer": true, "dependencies": { "@babel/code-frame": "^7.27.1", "@babel/generator": "^7.28.3", @@ -1156,7 +1155,6 @@ "resolved": "https://registry.npmjs.org/@types/react/-/react-19.2.2.tgz", "integrity": "sha512-6mDvHUFSjyT2B2yeNx2nUgMxh9LtOWvkhIU3uePn2I2oyNymUAX1NIsdgviM4CH+JSrp2D2hsMvJOkxY+0wNRA==", "dev": true, - "peer": true, "dependencies": { "csstype": "^3.0.2" } @@ -1267,7 +1265,6 @@ "url": "https://github.com/sponsors/ai" } ], - "peer": true, "dependencies": { "baseline-browser-mapping": "^2.8.9", "caniuse-lite": "^1.0.30001746", @@ -1709,7 +1706,6 @@ "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-4.0.3.tgz", "integrity": "sha512-5gTmgEY/sqK6gFXLIsQNH19lWb4ebPDLA4SdLP7dsWkIXHWlG66oPuVvXSGFPppYZz8ZDZq0dYYrbHfBCVUb1Q==", "dev": true, - "peer": true, "engines": { "node": ">=12" }, @@ -1769,7 +1765,6 @@ "version": "19.2.0", "resolved": "https://registry.npmjs.org/react/-/react-19.2.0.tgz", "integrity": "sha512-tmbWg6W31tQLeB5cdIBOicJDJRR2KzXsV7uSK9iNfLWQ5bIZfxuPEHp7M8wiHyHnn0DD1i7w3Zmin0FtkrwoCQ==", - "peer": true, "engines": { "node": ">=0.10.0" } @@ -2000,7 +1995,6 @@ "resolved": "https://registry.npmjs.org/vite/-/vite-6.3.6.tgz", "integrity": "sha512-0msEVHJEScQbhkbVTb/4iHZdJ6SXp/AvxL2sjwYQFfBqleHtnCqv1J3sa9zbWz/6kW1m9Tfzn92vW+kZ1WV6QA==", "dev": true, - "peer": true, "dependencies": { "esbuild": "^0.25.0", "fdir": "^6.4.4", diff --git a/src/services/UploadService.ts b/src/services/UploadService.ts index 21dc47c..ba2dbb6 100644 --- a/src/services/UploadService.ts +++ b/src/services/UploadService.ts @@ -306,8 +306,8 @@ export class UploadService { const filename = `screenshot_${Date.now()}.${asset.mimeType.split('/')[1]}`; formData.append('asset_file', blob, filename); - const signedMetadata = this.createSignedMetadata(asset); - formData.append('signed_metadata', signedMetadata); + const metadata = await this.createMetadata(asset, blob); + formData.append('metadata', metadata); if (asset.metadata?.headline) { formData.append('headline', asset.metadata.headline); @@ -444,10 +444,25 @@ export class UploadService { } /** - * Create signed metadata for upload + * Compute SHA-256 hash of a Blob using the Web Crypto API. + * Returns a lowercase hex-encoded digest string. */ - private createSignedMetadata(asset: Asset): string { + private async computeSha256(blob: Blob): Promise { + const arrayBuffer = await blob.arrayBuffer(); + const hashBuffer = await crypto.subtle.digest('SHA-256', arrayBuffer); + const hashArray = Array.from(new Uint8Array(hashBuffer)); + return hashArray.map(b => b.toString(16).padStart(2, '0')).join(''); + } + + /** + * Create metadata for upload, including a SHA-256 hash of the asset blob + * to cryptographically bind the image to its provenance metadata. + */ + private async createMetadata(asset: Asset, blob: Blob): Promise { + const assetSha256 = await this.computeSha256(blob); + const metadata: any = { + asset_sha256: assetSha256, spec_version: '2.0.0', recorder: 'ProofSnap Browser Extension', created_at: asset.createdAt,