mirror of
https://github.com/immich-app/immich.git
synced 2026-05-18 03:10:24 +03:00
fix(web): compute hashes for uploads in chunks (#27878)
* add @noble/hashes as a dep for web * hash files in chunks * drop old reference to crypto in test code * use web worker for file hashing
This commit is contained in:
@@ -20,9 +20,6 @@ describe('fileUploader error handling', () => {
|
||||
vi.spyOn(uploadManager, 'getExtensions').mockReturnValue(['.jpg']);
|
||||
uploadAssetsStore.reset();
|
||||
authManager.reset();
|
||||
|
||||
// Stub out crypto to avoid that branch
|
||||
vi.stubGlobal('crypto', undefined);
|
||||
});
|
||||
|
||||
for (const [name, mockUser] of [
|
||||
|
||||
@@ -127,6 +127,30 @@ function getDeviceAssetId(asset: File) {
|
||||
return 'web' + '-' + asset.name + '-' + asset.lastModified;
|
||||
}
|
||||
|
||||
function hashFile(file: File): Promise<string> {
|
||||
return new Promise<string>((resolve, reject) => {
|
||||
const worker = new Worker(new URL('$lib/workers/hash-file.ts', import.meta.url), { type: 'module' });
|
||||
|
||||
worker.addEventListener('message', ({ data }: MessageEvent<{ result?: string; error?: string }>) => {
|
||||
worker.terminate();
|
||||
|
||||
if (data.error) {
|
||||
reject(new Error(data.error));
|
||||
} else {
|
||||
resolve(data.result!);
|
||||
}
|
||||
});
|
||||
|
||||
worker.addEventListener('error', (event) => {
|
||||
worker.terminate();
|
||||
|
||||
reject(new Error(event.message));
|
||||
});
|
||||
|
||||
worker.postMessage(file);
|
||||
});
|
||||
}
|
||||
|
||||
type FileUploaderParams = {
|
||||
assetFile: File;
|
||||
albumId?: string;
|
||||
@@ -165,15 +189,11 @@ async function fileUploader({
|
||||
}
|
||||
|
||||
let responseData: { id: string; status: AssetMediaStatus; isTrashed?: boolean } | undefined;
|
||||
if (crypto?.subtle?.digest && !authManager.isSharedLink) {
|
||||
if (!authManager.isSharedLink) {
|
||||
uploadAssetsStore.updateItem(deviceAssetId, { message: $t('asset_hashing') });
|
||||
await tick();
|
||||
try {
|
||||
const bytes = await assetFile.arrayBuffer();
|
||||
const hash = await crypto.subtle.digest('SHA-1', bytes);
|
||||
const checksum = Array.from(new Uint8Array(hash))
|
||||
.map((b) => b.toString(16).padStart(2, '0'))
|
||||
.join('');
|
||||
const checksum = await hashFile(assetFile);
|
||||
|
||||
const {
|
||||
results: [checkUploadResult],
|
||||
|
||||
Reference in New Issue
Block a user