80 lines
2.4 KiB
TypeScript
80 lines
2.4 KiB
TypeScript
import { defineStore } from 'pinia';
|
|
import { ref } from 'vue';
|
|
import { api } from '@/plugins/axios';
|
|
import type { GetZkUploadCiphertextResult } from '@/types/upload/GetZkUploadCiphertextResult';
|
|
import { base64ToBytes } from '@/utils/encoding/base64ToBytes';
|
|
import { toArrayBuffer } from '@/utils/toArrayBuffer';
|
|
import { decryptPasswordProtectedZkUpload } from '@/utils/upload/decryptPasswordProtectedZkUpload';
|
|
import { decryptZkUpload } from '@/utils/upload/decryptZkUpload';
|
|
|
|
export const useViewStore = defineStore('view', () => {
|
|
const imageObjectUrl = ref<string | null>(null);
|
|
|
|
const clearImage = (): void => {
|
|
if (imageObjectUrl.value) {
|
|
URL.revokeObjectURL(imageObjectUrl.value);
|
|
imageObjectUrl.value = null;
|
|
}
|
|
};
|
|
|
|
const fetchZkCiphertext = async (uploadId: string): Promise<GetZkUploadCiphertextResult> => {
|
|
const { data } = await api.get<GetZkUploadCiphertextResult>(`/uploads/${uploadId}`);
|
|
|
|
return data;
|
|
};
|
|
|
|
const loadZk = async (
|
|
payload: GetZkUploadCiphertextResult,
|
|
fragmentKey: string,
|
|
password?: string
|
|
): Promise<void> => {
|
|
clearImage();
|
|
|
|
const iv = base64ToBytes(payload.iv);
|
|
const ciphertext = base64ToBytes(payload.ciphertext);
|
|
|
|
let plaintext: Uint8Array;
|
|
|
|
if (payload.passwordProtected) {
|
|
if (!password) {
|
|
throw new Error('Password required');
|
|
}
|
|
|
|
if (!payload.wrappedDek || !payload.wrapIv || !payload.salt) {
|
|
throw new Error('Incomplete password protection data');
|
|
}
|
|
|
|
const wrappedDek = base64ToBytes(payload.wrappedDek);
|
|
const wrapIv = base64ToBytes(payload.wrapIv);
|
|
const salt = base64ToBytes(payload.salt);
|
|
|
|
plaintext = await decryptPasswordProtectedZkUpload(
|
|
ciphertext,
|
|
iv,
|
|
fragmentKey,
|
|
password,
|
|
wrappedDek,
|
|
wrapIv,
|
|
salt
|
|
);
|
|
} else {
|
|
plaintext = await decryptZkUpload(ciphertext, iv, fragmentKey);
|
|
}
|
|
|
|
const buffer = toArrayBuffer(plaintext);
|
|
|
|
if (!buffer) {
|
|
throw new Error('Could not build image blob');
|
|
}
|
|
|
|
imageObjectUrl.value = URL.createObjectURL(new Blob([buffer]));
|
|
};
|
|
|
|
return {
|
|
imageObjectUrl,
|
|
fetchZkCiphertext,
|
|
loadZk,
|
|
clearImage
|
|
};
|
|
});
|