commit
6f3381c32f
|
@ -47,11 +47,17 @@ export function getLivePhotoFileType(
|
|||
};
|
||||
}
|
||||
|
||||
export function getLivePhotoMetadata(imageMetadata: Metadata) {
|
||||
export function getLivePhotoMetadata(
|
||||
imageMetadata: Metadata,
|
||||
videoMetadata: Metadata
|
||||
) {
|
||||
return {
|
||||
...imageMetadata,
|
||||
title: getLivePhotoName(imageMetadata.title),
|
||||
fileType: FILE_TYPE.LIVE_PHOTO,
|
||||
imageHash: imageMetadata.hash,
|
||||
videoHash: videoMetadata.hash,
|
||||
hash: undefined,
|
||||
};
|
||||
}
|
||||
|
||||
|
@ -181,7 +187,8 @@ export function clusterLivePhotoFiles(mediaFiles: FileWithCollection[]) {
|
|||
videoAsset.fileTypeInfo
|
||||
);
|
||||
const livePhotoMetadata: Metadata = getLivePhotoMetadata(
|
||||
imageAsset.metadata
|
||||
imageAsset.metadata,
|
||||
videoAsset.metadata
|
||||
);
|
||||
uploadService.setFileMetadataAndFileTypeInfo(livePhotoLocalID, {
|
||||
fileTypeInfo: { ...livePhotoFileTypeInfo },
|
||||
|
|
|
@ -19,6 +19,7 @@ import {
|
|||
getUnixTimeInMicroSeconds,
|
||||
tryToParseDateTime,
|
||||
} from 'utils/time';
|
||||
import { getFileHash } from 'utils/crypto';
|
||||
|
||||
interface ParsedMetadataJSONWithTitle {
|
||||
title: string;
|
||||
|
@ -50,6 +51,8 @@ export async function extractMetadata(
|
|||
);
|
||||
}
|
||||
|
||||
const fileHash = await getFileHash(receivedFile);
|
||||
|
||||
const metadata: Metadata = {
|
||||
title: `${splitFilenameAndExtension(receivedFile.name)[0]}.${
|
||||
fileTypeInfo.exactType
|
||||
|
@ -62,6 +65,7 @@ export async function extractMetadata(
|
|||
latitude: extractedMetadata.location.latitude,
|
||||
longitude: extractedMetadata.location.longitude,
|
||||
fileType: fileTypeInfo.fileType,
|
||||
hash: fileHash,
|
||||
};
|
||||
return metadata;
|
||||
}
|
||||
|
|
|
@ -25,6 +25,9 @@ export interface Metadata {
|
|||
longitude: number;
|
||||
fileType: FILE_TYPE;
|
||||
hasStaticThumbnail?: boolean;
|
||||
hash?: string;
|
||||
imageHash?: string;
|
||||
videoHash?: string;
|
||||
}
|
||||
|
||||
export interface Location {
|
||||
|
|
|
@ -7,6 +7,8 @@ import { getActualKey, getToken } from 'utils/common/key';
|
|||
import { setRecoveryKey } from 'services/userService';
|
||||
import { logError } from 'utils/sentry';
|
||||
import { ComlinkWorker } from 'utils/comlink';
|
||||
import { ElectronFile } from 'types/upload';
|
||||
import { cryptoGenericHash } from './libsodium';
|
||||
|
||||
export interface B64EncryptionResult {
|
||||
encryptedData: string;
|
||||
|
@ -196,3 +198,9 @@ export async function encryptWithRecoveryKey(key: string) {
|
|||
return encryptedKey;
|
||||
}
|
||||
export default CryptoWorker;
|
||||
|
||||
export async function getFileHash(file: File | ElectronFile) {
|
||||
const stream = await file.stream();
|
||||
const hash = await cryptoGenericHash(stream);
|
||||
return hash;
|
||||
}
|
||||
|
|
|
@ -252,6 +252,36 @@ export async function hash(input: string) {
|
|||
);
|
||||
}
|
||||
|
||||
export async function cryptoGenericHash(stream: ReadableStream) {
|
||||
await sodium.ready;
|
||||
|
||||
const state = sodium.crypto_generichash_init(
|
||||
null,
|
||||
sodium.crypto_generichash_BYTES_MAX
|
||||
);
|
||||
|
||||
const reader = stream.getReader();
|
||||
|
||||
let isDone = false;
|
||||
while (!isDone) {
|
||||
const { done, value: chunk } = await reader.read();
|
||||
if (done) {
|
||||
isDone = true;
|
||||
break;
|
||||
}
|
||||
const buffer = Uint8Array.from(chunk);
|
||||
sodium.crypto_generichash_update(state, buffer);
|
||||
}
|
||||
|
||||
const hash = sodium.crypto_generichash_final(
|
||||
state,
|
||||
sodium.crypto_generichash_BYTES_MAX
|
||||
);
|
||||
const hashString = sodium.to_base64(hash, sodium.base64_variants.ORIGINAL);
|
||||
|
||||
return hashString;
|
||||
}
|
||||
|
||||
export async function deriveKey(
|
||||
passphrase: string,
|
||||
salt: string,
|
||||
|
|
Loading…
Reference in a new issue