From 1c6cd80b6414a0e1025720093111971343712acb Mon Sep 17 00:00:00 2001 From: Andras Schmelczer Date: Sat, 28 Mar 2026 12:07:44 +0000 Subject: [PATCH] Update hashing --- .../sync-client/src/sync-operations/syncer.ts | 2 +- .../src/sync-operations/unrestricted-syncer.ts | 6 +++--- frontend/sync-client/src/utils/hash.ts | 15 +++++---------- 3 files changed, 9 insertions(+), 14 deletions(-) diff --git a/frontend/sync-client/src/sync-operations/syncer.ts b/frontend/sync-client/src/sync-operations/syncer.ts index eb5336f4..4cf92097 100644 --- a/frontend/sync-client/src/sync-operations/syncer.ts +++ b/frontend/sync-client/src/sync-operations/syncer.ts @@ -348,7 +348,7 @@ export class Syncer { try { const contentBytes = await this.operations.read(relativePath); // this can throw FileNotFoundError - return hash(contentBytes); + return await hash(contentBytes); } catch (e) { if ( e instanceof Error && diff --git a/frontend/sync-client/src/sync-operations/unrestricted-syncer.ts b/frontend/sync-client/src/sync-operations/unrestricted-syncer.ts index d32e983e..98a64f5d 100644 --- a/frontend/sync-client/src/sync-operations/unrestricted-syncer.ts +++ b/frontend/sync-client/src/sync-operations/unrestricted-syncer.ts @@ -101,7 +101,7 @@ export class UnrestrictedSyncer { const contentBytes = await this.operations.read( document.relativePath ); // this can throw FileNotFoundError - const contentHash = hash(contentBytes); + const contentHash = await hash(contentBytes); let response: DocumentVersion | DocumentUpdateResponse | undefined = undefined; @@ -342,7 +342,7 @@ export class UnrestrictedSyncer { { documentId: remoteVersion.documentId, parentVersionId: remoteVersion.vaultUpdateId, - hash: hash(contentBytes), + hash: await hash(contentBytes), remoteRelativePath: remoteVersion.relativePath }, this.database.createNewPendingDocument( @@ -513,7 +513,7 @@ export class UnrestrictedSyncer { if (!("type" in response) || response.type === "MergingUpdate") { const responseBytes = base64ToBytes(response.contentBase64); - contentHash = hash(responseBytes); + contentHash = await hash(responseBytes); this.database.updateDocumentMetadata( { diff --git a/frontend/sync-client/src/utils/hash.ts b/frontend/sync-client/src/utils/hash.ts index 906b6fad..814faefa 100644 --- a/frontend/sync-client/src/utils/hash.ts +++ b/frontend/sync-client/src/utils/hash.ts @@ -1,12 +1,7 @@ -// https://stackoverflow.com/questions/7616461/generate-a-hash-from-string-in-javascript -export function hash(content: Uint8Array): string { - let result = 0; - // eslint-disable-next-line @typescript-eslint/prefer-for-of - for (let i = 0; i < content.length; i++) { - result = (result << 5) - result + content[i]; - result |= 0; // Convert to 32bit integer - } - return Math.abs(result).toString(16).padStart(8, "0"); +export async function hash(content: Uint8Array): Promise { + const digest = await crypto.subtle.digest("SHA-256", content); + const bytes = new Uint8Array(digest); + return Array.from(bytes, (b) => b.toString(16).padStart(2, "0")).join(""); } -export const EMPTY_HASH = hash(new Uint8Array(0)); +export const EMPTY_HASH = await hash(new Uint8Array(0));