diff --git a/web/packages/new/common/crypto/ente.ts b/web/packages/new/common/crypto/ente.ts index 4995942a87..5e95e77627 100644 --- a/web/packages/new/common/crypto/ente.ts +++ b/web/packages/new/common/crypto/ente.ts @@ -2,23 +2,51 @@ * @file Higher level functions that use the ontology of Ente's types * * These are thin wrappers over the (thin-) wrappers in internal/libsodium.ts. - * The main difference is that they don't name things in terms of the crypto - * algorithms, but rather by the specific Ente specific tasks we are trying to - * do. + * The main difference is that these functions don't talk in terms of the crypto + * algorithms, but rather in terms the higher-level Ente specific goal we are + * trying to accomplish. */ import * as libsodium from "@ente/shared/crypto/internal/libsodium"; /** - * Decrypt arbitrary metadata associated with a file using the its's key. + * Encrypt arbitrary metadata associated with a file using its key. * - * @param encryptedMetadataB64 The Base64 encoded string containing the - * encrypted data. + * @param metadata The metadata (string) to encrypt. * - * @param headerB64 The Base64 encoded string containing the decryption header + * @param keyB64 Base64 encoded string containing the encryption key (this'll + * generally be the file's key). + * + * @returns Base64 encoded strings containing the encrypted data and the + * decryption header. + */ +export const encryptFileMetadata = async ( + metadata: string, + keyB64: string, +): Promise<{ encryptedMetadataB64: string; decryptionHeaderB64: string }> => { + const encoder = new TextEncoder(); + const encodedMetadata = encoder.encode(metadata); + + const { file } = await libsodium.encryptChaChaOneShot( + encodedMetadata, + keyB64, + ); + return { + encryptedMetadataB64: await libsodium.toB64(file.encryptedData), + decryptionHeaderB64: file.decryptionHeader, + }; +}; + +/** + * Decrypt arbitrary metadata associated with a file using the its key. + * + * @param encryptedMetadataB64 Base64 encoded string containing the encrypted + * data. + * + * @param headerB64 Base64 encoded string containing the decryption header * produced during encryption. * - * @param keyB64 The Base64 encoded string containing the encryption key - * (this'll generally be the file's key). + * @param keyB64 Base64 encoded string containing the encryption key (this'll + * generally be the file's key). * * @returns The decrypted utf-8 string. */ diff --git a/web/packages/new/photos/services/ml/embedding.ts b/web/packages/new/photos/services/ml/embedding.ts index 3ae5d577c9..074d5d98f8 100644 --- a/web/packages/new/photos/services/ml/embedding.ts +++ b/web/packages/new/photos/services/ml/embedding.ts @@ -3,14 +3,17 @@ import { getAllLocalFiles, getLocalTrashedFiles, } from "@/new/photos/services/files"; +import type { EnteFile } from "@/new/photos/types/file"; import { authenticatedRequestHeaders } from "@/next/http"; import { getKV, setKV } from "@/next/kv"; import log from "@/next/log"; import { apiURL } from "@/next/origins"; +import ComlinkCryptoWorker from "@ente/shared/crypto"; import { z } from "zod"; import { saveFaceIndex } from "./db"; import { faceIndexingVersion } from "./f-index"; import { type FaceIndex } from "./types"; +// import { putEmbedding } from "services/embeddingService"; /** * The embeddings that we (the current client) knows how to handle. @@ -239,6 +242,29 @@ const getEmbeddingsDiff = async ( return z.array(RemoteEmbedding).parse(await res.json()); }; +export const putFaceIndex = async ( + enteFile: EnteFile, + faceIndex: FaceIndex, +) => { + log.debug(() => ({ + t: "Uploading faceEmbedding", + d: JSON.stringify(faceIndex), + })); + + const comlinkCryptoWorker = await ComlinkCryptoWorker.getInstance(); + const { file: encryptedEmbeddingData } = + await comlinkCryptoWorker.encryptMetadata(faceIndex, enteFile.key); + // TODO(MR): Indexing + console.log(encryptedEmbeddingData); + throw new Error("Unimplemented"); + // await putEmbedding({ + // fileID: enteFile.id, + // encryptedEmbedding: encryptedEmbeddingData.encryptedData, + // decryptionHeader: encryptedEmbeddingData.decryptionHeader, + // model: "file-ml-clip-face", + // }); +}; + // MARK: - Face /** diff --git a/web/packages/new/photos/services/ml/indexer.worker.ts b/web/packages/new/photos/services/ml/indexer.worker.ts index c6184679fd..b5fd600a50 100644 --- a/web/packages/new/photos/services/ml/indexer.worker.ts +++ b/web/packages/new/photos/services/ml/indexer.worker.ts @@ -7,8 +7,8 @@ import type { FaceIndex } from "@/new/photos/services/ml/types"; import type { EnteFile } from "@/new/photos/types/file"; import log from "@/next/log"; import { fileLogID } from "../../utils/file"; +import { putFaceIndex } from "./embedding"; import { indexFaces } from "./f-index"; -import { putFaceIndex } from "./remote"; /** * Index faces in a file, save the persist the results locally, and put them on diff --git a/web/packages/new/photos/services/ml/mlWorkManager.ts b/web/packages/new/photos/services/ml/mlWorkManager.ts index c2f4fdf476..d16f5afc63 100644 --- a/web/packages/new/photos/services/ml/mlWorkManager.ts +++ b/web/packages/new/photos/services/ml/mlWorkManager.ts @@ -295,7 +295,6 @@ class MLWorkManager { const userAgent = await getUserAgent(); const jobWorkerProxy = await this.getSyncJobWorker(); - return await jobWorkerProxy.sync(token, userID, userAgent); // this.terminateSyncJobWorker(); // TODO: redirect/refresh to gallery in case of session_expired, stop ml sync job diff --git a/web/packages/new/photos/services/ml/remote.ts b/web/packages/new/photos/services/ml/remote.ts deleted file mode 100644 index 869e56b4fd..0000000000 --- a/web/packages/new/photos/services/ml/remote.ts +++ /dev/null @@ -1,28 +0,0 @@ -import type { FaceIndex } from "@/new/photos/services/ml/types"; -import type { EnteFile } from "@/new/photos/types/file"; -import log from "@/next/log"; -import ComlinkCryptoWorker from "@ente/shared/crypto"; -// import { putEmbedding } from "services/embeddingService"; - -export const putFaceIndex = async ( - enteFile: EnteFile, - faceIndex: FaceIndex, -) => { - log.debug(() => ({ - t: "Uploading faceEmbedding", - d: JSON.stringify(faceIndex), - })); - - const comlinkCryptoWorker = await ComlinkCryptoWorker.getInstance(); - const { file: encryptedEmbeddingData } = - await comlinkCryptoWorker.encryptMetadata(faceIndex, enteFile.key); - // TODO(MR): Indexing - console.log(encryptedEmbeddingData); - throw new Error("Unimplemented"); - // await putEmbedding({ - // fileID: enteFile.id, - // encryptedEmbedding: encryptedEmbeddingData.encryptedData, - // decryptionHeader: encryptedEmbeddingData.decryptionHeader, - // model: "file-ml-clip-face", - // }); -};