Sniff image MIME for ZK viewer blobs so save-as gets a real extension.
This commit is contained in:
@@ -3,6 +3,7 @@ import { ref } from 'vue';
|
||||
import { api } from '@/plugins/axios';
|
||||
import type { GetZkUploadCiphertextResult } from '@/types/upload/GetZkUploadCiphertextResult';
|
||||
import { base64ToBytes } from '@/utils/encoding/base64ToBytes';
|
||||
import { detectImageMimeType } from '@/utils/file/detectImageMimeType';
|
||||
import { toArrayBuffer } from '@/utils/toArrayBuffer';
|
||||
import { decryptPasswordProtectedZkUpload } from '@/utils/upload/decryptPasswordProtectedZkUpload';
|
||||
import { decryptZkUpload } from '@/utils/upload/decryptZkUpload';
|
||||
@@ -67,7 +68,9 @@ export const useZkViewStore = defineStore('zkView', () => {
|
||||
throw new Error('Could not build image blob');
|
||||
}
|
||||
|
||||
imageObjectUrl.value = URL.createObjectURL(new Blob([buffer]));
|
||||
const mimeType = await detectImageMimeType(plaintext);
|
||||
|
||||
imageObjectUrl.value = URL.createObjectURL(new Blob([buffer], { type: mimeType }));
|
||||
};
|
||||
|
||||
return {
|
||||
|
||||
@@ -0,0 +1,30 @@
|
||||
import { describe, expect, it } from 'vitest';
|
||||
import { detectImageMimeType } from '@/utils/file/detectImageMimeType';
|
||||
|
||||
const padToMinDetectLength = (header: number[]): Uint8Array => {
|
||||
const out = new Uint8Array(4100);
|
||||
|
||||
out.set(header);
|
||||
|
||||
return out;
|
||||
};
|
||||
|
||||
describe('detectImageMimeType', () => {
|
||||
it('detects PNG', async () => {
|
||||
const png = padToMinDetectLength([0x89, 0x50, 0x4e, 0x47, 0x0d, 0x0a, 0x1a, 0x0a]);
|
||||
|
||||
await expect(detectImageMimeType(png)).resolves.toBe('image/png');
|
||||
});
|
||||
|
||||
it('detects JPEG', async () => {
|
||||
const jpeg = padToMinDetectLength([0xff, 0xd8, 0xff, 0xe0]);
|
||||
|
||||
await expect(detectImageMimeType(jpeg)).resolves.toBe('image/jpeg');
|
||||
});
|
||||
|
||||
it('falls back for unknown bytes', async () => {
|
||||
await expect(detectImageMimeType(new Uint8Array(4100))).resolves.toBe(
|
||||
'application/octet-stream'
|
||||
);
|
||||
});
|
||||
});
|
||||
@@ -0,0 +1,7 @@
|
||||
import imageType from 'image-type';
|
||||
|
||||
export const detectImageMimeType = async (data: Uint8Array): Promise<string> => {
|
||||
const result = await imageType(data);
|
||||
|
||||
return result?.mime ?? 'application/octet-stream';
|
||||
};
|
||||
Reference in New Issue
Block a user