|
@@ -2,68 +2,93 @@ import { getEndpoint } from "utils/common/apiUtil";
|
|
|
import HTTPService from "./HTTPService";
|
|
|
import * as Comlink from "comlink";
|
|
|
|
|
|
-const CryptoWorker:any = typeof window !== 'undefined'
|
|
|
+const CryptoWorker: any = typeof window !== 'undefined'
|
|
|
&& Comlink.wrap(new Worker("worker/crypto.worker.js", { type: 'module' }));
|
|
|
const ENDPOINT = getEndpoint();
|
|
|
|
|
|
-export interface decryptionParams {
|
|
|
- encryptedKey: string;
|
|
|
- keyDecryptionNonce: string;
|
|
|
- header: string;
|
|
|
- nonce: string;
|
|
|
+export interface fileAttribute {
|
|
|
+ encryptedData: string;
|
|
|
+ decryptionHeader: string;
|
|
|
};
|
|
|
-export interface fileData {
|
|
|
+
|
|
|
+export interface collection {
|
|
|
id: number;
|
|
|
- file: {
|
|
|
- decryptionParams: decryptionParams;
|
|
|
- },
|
|
|
- thumbnail: {
|
|
|
- decryptionParams: decryptionParams;
|
|
|
- },
|
|
|
- metadata: {
|
|
|
- currentTime: number;
|
|
|
- modificationTime: number;
|
|
|
- latitude: number;
|
|
|
- longitude: number;
|
|
|
- title: string;
|
|
|
- deviceFolder: string;
|
|
|
- };
|
|
|
- src: string,
|
|
|
- w: number,
|
|
|
- h: number,
|
|
|
- data?: string;
|
|
|
+ ownerID: number;
|
|
|
+ key: string;
|
|
|
+ name: string;
|
|
|
+ type: string;
|
|
|
+ creationTime: number;
|
|
|
+}
|
|
|
+
|
|
|
+export interface file {
|
|
|
+ id: number;
|
|
|
+ collectionID: number;
|
|
|
+ file: fileAttribute;
|
|
|
+ thumbnail: fileAttribute;
|
|
|
+ metadata: fileAttribute;
|
|
|
+ encryptedKey: string;
|
|
|
+ keyDecryptionNonce: string;
|
|
|
+ key: Uint8Array;
|
|
|
+ src: string;
|
|
|
+ w: number;
|
|
|
+ h: number;
|
|
|
};
|
|
|
|
|
|
-const getFileMetaDataUsingWorker = async (data: any, key: string) => {
|
|
|
+const getCollectionKeyUsingWorker = async (collection: any, key: Uint8Array) => {
|
|
|
const worker = await new CryptoWorker();
|
|
|
- return worker.decryptMetadata({ data, key });
|
|
|
+ const collectionKey = await worker.decrypt(
|
|
|
+ await worker.fromB64(collection.encryptedKey),
|
|
|
+ await worker.fromB64(collection.keyDecryptionNonce),
|
|
|
+ key);
|
|
|
+ return {
|
|
|
+ ...collection,
|
|
|
+ key: collectionKey
|
|
|
+ };
|
|
|
}
|
|
|
|
|
|
-const getFileUsingWorker = async (data: any, key: string) => {
|
|
|
- const worker = await new CryptoWorker();
|
|
|
- return worker.decryptThumbnail({ data, key });
|
|
|
+const getCollections = async (token: string, key: Uint8Array): Promise<collection[]> => {
|
|
|
+ const resp = await HTTPService.get(`${ENDPOINT}/collections/owned`, {
|
|
|
+ token
|
|
|
+ });
|
|
|
+
|
|
|
+ const promises: Promise<collection>[] = resp.data.collections.map(
|
|
|
+ (collection: collection) => getCollectionKeyUsingWorker(collection, key));
|
|
|
+ return await Promise.all(promises);
|
|
|
}
|
|
|
|
|
|
export const getFiles = async (sinceTime: string, token: string, limit: string, key: string) => {
|
|
|
- const resp = await HTTPService.get(`${ENDPOINT}/encrypted-files/diff`, {
|
|
|
+ const worker = await new CryptoWorker();
|
|
|
+
|
|
|
+ const collections = await getCollections(token, await worker.fromB64(key));
|
|
|
+ const collectionMap = {}
|
|
|
+ for (const collectionIndex in collections) {
|
|
|
+ collectionMap[collections[collectionIndex].id] = collections[collectionIndex];
|
|
|
+ }
|
|
|
+ const resp = await HTTPService.get(`${ENDPOINT}/files/diff`, {
|
|
|
sinceTime, token, limit,
|
|
|
});
|
|
|
|
|
|
- const promises: Promise<fileData>[] = resp.data.diff.map((data) => getFileMetaDataUsingWorker(data, key));
|
|
|
- const decrypted = await Promise.all(promises);
|
|
|
-
|
|
|
- return decrypted;
|
|
|
+ const promises: Promise<file>[] = resp.data.diff.map(
|
|
|
+ async (file: file) => {
|
|
|
+ file.key = await worker.decrypt(
|
|
|
+ await worker.fromB64(file.encryptedKey),
|
|
|
+ await worker.fromB64(file.keyDecryptionNonce),
|
|
|
+ collectionMap[file.collectionID].key)
|
|
|
+ file.metadata = await worker.decryptMetadata(file);
|
|
|
+ return file;
|
|
|
+ });
|
|
|
+ return await Promise.all(promises);
|
|
|
}
|
|
|
|
|
|
-export const getPreview = async (token: string, data: fileData, key: string) => {
|
|
|
+export const getPreview = async (token: string, file: file) => {
|
|
|
const resp = await HTTPService.get(
|
|
|
- `${ENDPOINT}/encrypted-files/preview/${data.id}`,
|
|
|
+ `${ENDPOINT}/files/preview/${file.id}`,
|
|
|
{ token }, null, { responseType: 'arraybuffer' },
|
|
|
);
|
|
|
- const decrypted: any = await getFileUsingWorker({
|
|
|
- ...data,
|
|
|
- file: resp.data,
|
|
|
- }, key);
|
|
|
- const url = URL.createObjectURL(new Blob([decrypted.data]));
|
|
|
- return url;
|
|
|
+ const worker = await new CryptoWorker();
|
|
|
+ const decrypted: any = await worker.decryptFile(
|
|
|
+ new Uint8Array(resp.data),
|
|
|
+ await worker.fromB64(file.thumbnail.decryptionHeader),
|
|
|
+ file.key);
|
|
|
+ return URL.createObjectURL(new Blob([decrypted]));
|
|
|
}
|