2020-09-19 21:20:10 +00:00
|
|
|
import { getEndpoint } from "utils/common/apiUtil";
|
|
|
|
import HTTPService from "./HTTPService";
|
2020-09-27 17:18:57 +00:00
|
|
|
import * as Comlink from "comlink";
|
2020-11-07 11:10:49 +00:00
|
|
|
import { getData, LS_KEYS } from "utils/storage/localStorage";
|
|
|
|
import { decrypt } from "utils/crypto/libsodium";
|
2020-09-27 17:18:57 +00:00
|
|
|
|
2020-10-19 03:01:34 +00:00
|
|
|
const CryptoWorker: any = typeof window !== 'undefined'
|
2020-09-30 21:22:58 +00:00
|
|
|
&& Comlink.wrap(new Worker("worker/crypto.worker.js", { type: 'module' }));
|
2020-09-19 21:20:10 +00:00
|
|
|
const ENDPOINT = getEndpoint();
|
|
|
|
|
2020-10-19 03:01:34 +00:00
|
|
|
export interface fileAttribute {
|
|
|
|
encryptedData: string;
|
|
|
|
decryptionHeader: string;
|
2020-09-26 17:16:16 +00:00
|
|
|
};
|
2020-10-19 03:01:34 +00:00
|
|
|
|
2020-11-07 11:10:49 +00:00
|
|
|
export interface user {
|
|
|
|
id: number;
|
|
|
|
name: string;
|
|
|
|
email: string;
|
|
|
|
}
|
|
|
|
|
2020-10-19 03:01:34 +00:00
|
|
|
export interface collection {
|
2020-09-19 21:20:10 +00:00
|
|
|
id: number;
|
2020-11-07 11:10:49 +00:00
|
|
|
owner: user;
|
2020-10-19 03:01:34 +00:00
|
|
|
key: string;
|
|
|
|
name: string;
|
|
|
|
type: string;
|
|
|
|
creationTime: number;
|
2020-11-07 11:10:49 +00:00
|
|
|
encryptedKey: string;
|
|
|
|
keyDecryptionNonce: string;
|
2020-10-19 03:01:34 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
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;
|
2020-09-19 21:20:10 +00:00
|
|
|
};
|
|
|
|
|
2020-11-07 11:10:49 +00:00
|
|
|
const getCollectionKey = async (collection: collection, key: Uint8Array) => {
|
2020-09-30 21:24:40 +00:00
|
|
|
const worker = await new CryptoWorker();
|
2020-11-07 11:10:49 +00:00
|
|
|
const userID = getData(LS_KEYS.USER).id;
|
|
|
|
var decryptedKey;
|
|
|
|
if (collection.owner.id == userID) {
|
|
|
|
decryptedKey = await worker.decrypt(
|
|
|
|
await worker.fromB64(collection.encryptedKey),
|
|
|
|
await worker.fromB64(collection.keyDecryptionNonce),
|
|
|
|
key);
|
|
|
|
} else {
|
|
|
|
// TODO
|
|
|
|
decryptedKey = null;
|
|
|
|
}
|
2020-10-19 03:01:34 +00:00
|
|
|
return {
|
|
|
|
...collection,
|
2020-11-07 11:10:49 +00:00
|
|
|
key: decryptedKey
|
2020-10-19 03:01:34 +00:00
|
|
|
};
|
2020-09-19 21:20:10 +00:00
|
|
|
}
|
|
|
|
|
2020-11-07 11:10:49 +00:00
|
|
|
const getCollections = async (token: string, sinceTime: string, key: Uint8Array): Promise<collection[]> => {
|
2020-11-14 12:13:49 +00:00
|
|
|
const resp = await HTTPService.get(`${ENDPOINT}/collections`, {
|
2020-11-07 11:10:49 +00:00
|
|
|
'token': token,
|
|
|
|
'sinceTime': sinceTime,
|
2020-10-19 03:01:34 +00:00
|
|
|
});
|
|
|
|
|
|
|
|
const promises: Promise<collection>[] = resp.data.collections.map(
|
2020-11-07 11:10:49 +00:00
|
|
|
(collection: collection) => getCollectionKey(collection, key));
|
2020-10-19 03:01:34 +00:00
|
|
|
return await Promise.all(promises);
|
2020-09-20 15:18:35 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
export const getFiles = async (sinceTime: string, token: string, limit: string, key: string) => {
|
2020-10-19 03:01:34 +00:00
|
|
|
const worker = await new CryptoWorker();
|
|
|
|
|
2020-11-07 11:10:49 +00:00
|
|
|
const collections = await getCollections(token, "0", await worker.fromB64(key));
|
|
|
|
var files: Array<file> = [];
|
|
|
|
for (const index in collections) {
|
|
|
|
const collection = collections[index];
|
|
|
|
if (collection.key == null) {
|
|
|
|
continue;
|
|
|
|
}
|
2020-11-07 15:43:00 +00:00
|
|
|
const resp = await HTTPService.get(`${ENDPOINT}/collections/diff`, {
|
2020-11-07 11:10:49 +00:00
|
|
|
'collectionID': collection.id.toString(), sinceTime, token, limit,
|
2020-10-19 03:01:34 +00:00
|
|
|
});
|
2020-11-07 11:10:49 +00:00
|
|
|
|
|
|
|
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),
|
|
|
|
collection.key)
|
|
|
|
file.metadata = await worker.decryptMetadata(file);
|
|
|
|
return file;
|
|
|
|
});
|
|
|
|
files.push(...await Promise.all(promises));
|
|
|
|
console.log(files);
|
|
|
|
}
|
|
|
|
return files;
|
2020-09-19 21:20:10 +00:00
|
|
|
}
|
2020-09-20 15:18:35 +00:00
|
|
|
|
2020-10-19 03:01:34 +00:00
|
|
|
export const getPreview = async (token: string, file: file) => {
|
2020-09-20 15:18:35 +00:00
|
|
|
const resp = await HTTPService.get(
|
2020-10-19 03:01:34 +00:00
|
|
|
`${ENDPOINT}/files/preview/${file.id}`,
|
2020-09-20 15:18:35 +00:00
|
|
|
{ token }, null, { responseType: 'arraybuffer' },
|
|
|
|
);
|
2020-10-19 03:01:34 +00:00
|
|
|
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]));
|
2020-09-20 15:18:35 +00:00
|
|
|
}
|
2020-10-19 03:07:16 +00:00
|
|
|
|
|
|
|
export const getFile = async (token: string, file: file) => {
|
|
|
|
const resp = await HTTPService.get(
|
|
|
|
`${ENDPOINT}/files/download/${file.id}`,
|
|
|
|
{ token }, null, { responseType: 'arraybuffer' },
|
|
|
|
);
|
|
|
|
const worker = await new CryptoWorker();
|
|
|
|
const decrypted: any = await worker.decryptFile(
|
|
|
|
new Uint8Array(resp.data),
|
|
|
|
await worker.fromB64(file.file.decryptionHeader),
|
|
|
|
file.key);
|
|
|
|
return URL.createObjectURL(new Blob([decrypted]));
|
|
|
|
}
|