@reverbia/sdk 1.0.0-next.20251229084841 → 1.1.0-next.20251230221037
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/expo/index.cjs +18 -0
- package/dist/expo/index.d.mts +12 -0
- package/dist/expo/index.d.ts +12 -0
- package/dist/expo/index.mjs +18 -0
- package/dist/react/chunk-KUFGQF6E.mjs +290 -0
- package/dist/react/chunk-T56Y62G7.mjs +410 -0
- package/dist/react/index.cjs +1617 -281
- package/dist/react/index.d.mts +205 -2
- package/dist/react/index.d.ts +205 -2
- package/dist/react/index.mjs +901 -279
- package/dist/react/storage-Z2NBANCK.mjs +29 -0
- package/dist/react/useEncryption-5RTXKDNZ.mjs +31 -0
- package/package.json +2 -1
package/dist/react/index.mjs
CHANGED
|
@@ -1,13 +1,32 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
1
|
+
import {
|
|
2
|
+
clearTokenData,
|
|
3
|
+
getRefreshToken,
|
|
4
|
+
getRefreshTokenSync,
|
|
5
|
+
getStoredTokenData,
|
|
6
|
+
getStoredTokenDataSync,
|
|
7
|
+
getValidAccessToken,
|
|
8
|
+
getValidAccessTokenSync,
|
|
9
|
+
hasStoredCredentialsSync,
|
|
10
|
+
isTokenExpired,
|
|
11
|
+
storeTokenData,
|
|
12
|
+
tokenResponseToStoredData
|
|
13
|
+
} from "./chunk-KUFGQF6E.mjs";
|
|
14
|
+
import {
|
|
15
|
+
__decorateClass,
|
|
16
|
+
clearAllEncryptionKeys,
|
|
17
|
+
clearAllKeyPairs,
|
|
18
|
+
clearEncryptionKey,
|
|
19
|
+
clearKeyPair,
|
|
20
|
+
decryptData,
|
|
21
|
+
decryptDataBytes,
|
|
22
|
+
encryptData,
|
|
23
|
+
exportPublicKey,
|
|
24
|
+
hasEncryptionKey,
|
|
25
|
+
hasKeyPair,
|
|
26
|
+
requestEncryptionKey,
|
|
27
|
+
requestKeyPair,
|
|
28
|
+
useEncryption
|
|
29
|
+
} from "./chunk-T56Y62G7.mjs";
|
|
11
30
|
|
|
12
31
|
// src/react/useChat.ts
|
|
13
32
|
import { useCallback, useEffect, useRef, useState } from "react";
|
|
@@ -1229,123 +1248,6 @@ function useChat(options) {
|
|
|
1229
1248
|
};
|
|
1230
1249
|
}
|
|
1231
1250
|
|
|
1232
|
-
// src/react/useEncryption.ts
|
|
1233
|
-
var SIGN_MESSAGE = "The app is asking you to sign this message to generate a key, which will be used to encrypt data.";
|
|
1234
|
-
var encryptionKeyStore = /* @__PURE__ */ new Map();
|
|
1235
|
-
function getStoredKey(address) {
|
|
1236
|
-
return encryptionKeyStore.get(address) ?? null;
|
|
1237
|
-
}
|
|
1238
|
-
function setStoredKey(address, keyHex) {
|
|
1239
|
-
encryptionKeyStore.set(address, keyHex);
|
|
1240
|
-
}
|
|
1241
|
-
function clearEncryptionKey(address) {
|
|
1242
|
-
encryptionKeyStore.delete(address);
|
|
1243
|
-
}
|
|
1244
|
-
function clearAllEncryptionKeys() {
|
|
1245
|
-
encryptionKeyStore.clear();
|
|
1246
|
-
}
|
|
1247
|
-
function hexToBytes(hex) {
|
|
1248
|
-
const cleanHex = hex.startsWith("0x") ? hex.slice(2) : hex;
|
|
1249
|
-
const bytes = new Uint8Array(cleanHex.length / 2);
|
|
1250
|
-
for (let i = 0; i < cleanHex.length; i += 2) {
|
|
1251
|
-
bytes[i / 2] = parseInt(cleanHex.slice(i, i + 2), 16);
|
|
1252
|
-
}
|
|
1253
|
-
return bytes;
|
|
1254
|
-
}
|
|
1255
|
-
function bytesToHex(bytes) {
|
|
1256
|
-
return Array.from(bytes).map((b) => b.toString(16).padStart(2, "0")).join("");
|
|
1257
|
-
}
|
|
1258
|
-
async function deriveKeyFromSignature(signature) {
|
|
1259
|
-
const sigBytes = hexToBytes(signature);
|
|
1260
|
-
const hashBuffer = await crypto.subtle.digest(
|
|
1261
|
-
"SHA-256",
|
|
1262
|
-
sigBytes.buffer
|
|
1263
|
-
);
|
|
1264
|
-
const hashBytes = new Uint8Array(hashBuffer);
|
|
1265
|
-
return bytesToHex(hashBytes);
|
|
1266
|
-
}
|
|
1267
|
-
async function getEncryptionKey(address) {
|
|
1268
|
-
const keyHex = getStoredKey(address);
|
|
1269
|
-
if (!keyHex) {
|
|
1270
|
-
throw new Error(
|
|
1271
|
-
"Encryption key not found. Please sign a message to generate your encryption key."
|
|
1272
|
-
);
|
|
1273
|
-
}
|
|
1274
|
-
const keyBytes = hexToBytes(keyHex);
|
|
1275
|
-
return crypto.subtle.importKey(
|
|
1276
|
-
"raw",
|
|
1277
|
-
keyBytes.buffer,
|
|
1278
|
-
{ name: "AES-GCM" },
|
|
1279
|
-
false,
|
|
1280
|
-
["encrypt", "decrypt"]
|
|
1281
|
-
);
|
|
1282
|
-
}
|
|
1283
|
-
async function encryptData(plaintext, address) {
|
|
1284
|
-
const key = await getEncryptionKey(address);
|
|
1285
|
-
const plaintextBytes = typeof plaintext === "string" ? new TextEncoder().encode(plaintext) : plaintext;
|
|
1286
|
-
const iv = crypto.getRandomValues(new Uint8Array(12));
|
|
1287
|
-
const encryptedData = await crypto.subtle.encrypt(
|
|
1288
|
-
{
|
|
1289
|
-
name: "AES-GCM",
|
|
1290
|
-
iv
|
|
1291
|
-
},
|
|
1292
|
-
key,
|
|
1293
|
-
plaintextBytes.buffer
|
|
1294
|
-
);
|
|
1295
|
-
const encryptedBytes = new Uint8Array(encryptedData);
|
|
1296
|
-
const combined = new Uint8Array(iv.length + encryptedBytes.length);
|
|
1297
|
-
combined.set(iv, 0);
|
|
1298
|
-
combined.set(encryptedBytes, iv.length);
|
|
1299
|
-
return bytesToHex(combined);
|
|
1300
|
-
}
|
|
1301
|
-
async function decryptData(encryptedHex, address) {
|
|
1302
|
-
const key = await getEncryptionKey(address);
|
|
1303
|
-
const combined = hexToBytes(encryptedHex);
|
|
1304
|
-
const iv = combined.slice(0, 12);
|
|
1305
|
-
const encryptedData = combined.slice(12);
|
|
1306
|
-
const decryptedData = await crypto.subtle.decrypt(
|
|
1307
|
-
{
|
|
1308
|
-
name: "AES-GCM",
|
|
1309
|
-
iv
|
|
1310
|
-
},
|
|
1311
|
-
key,
|
|
1312
|
-
encryptedData
|
|
1313
|
-
);
|
|
1314
|
-
return new TextDecoder().decode(decryptedData);
|
|
1315
|
-
}
|
|
1316
|
-
async function decryptDataBytes(encryptedHex, address) {
|
|
1317
|
-
const key = await getEncryptionKey(address);
|
|
1318
|
-
const combined = hexToBytes(encryptedHex);
|
|
1319
|
-
const iv = combined.slice(0, 12);
|
|
1320
|
-
const encryptedData = combined.slice(12);
|
|
1321
|
-
const decryptedData = await crypto.subtle.decrypt(
|
|
1322
|
-
{
|
|
1323
|
-
name: "AES-GCM",
|
|
1324
|
-
iv
|
|
1325
|
-
},
|
|
1326
|
-
key,
|
|
1327
|
-
encryptedData
|
|
1328
|
-
);
|
|
1329
|
-
return new Uint8Array(decryptedData);
|
|
1330
|
-
}
|
|
1331
|
-
function hasEncryptionKey(address) {
|
|
1332
|
-
return getStoredKey(address) !== null;
|
|
1333
|
-
}
|
|
1334
|
-
async function requestEncryptionKey(walletAddress, signMessage) {
|
|
1335
|
-
const existingKey = getStoredKey(walletAddress);
|
|
1336
|
-
if (existingKey) {
|
|
1337
|
-
return;
|
|
1338
|
-
}
|
|
1339
|
-
const signature = await signMessage(SIGN_MESSAGE);
|
|
1340
|
-
const encryptionKey = await deriveKeyFromSignature(signature);
|
|
1341
|
-
setStoredKey(walletAddress, encryptionKey);
|
|
1342
|
-
}
|
|
1343
|
-
function useEncryption(signMessage) {
|
|
1344
|
-
return {
|
|
1345
|
-
requestEncryptionKey: (walletAddress) => requestEncryptionKey(walletAddress, signMessage)
|
|
1346
|
-
};
|
|
1347
|
-
}
|
|
1348
|
-
|
|
1349
1251
|
// src/react/useChatStorage.ts
|
|
1350
1252
|
import { useCallback as useCallback2, useState as useState2, useMemo } from "react";
|
|
1351
1253
|
|
|
@@ -2420,7 +2322,7 @@ var sdkModelClasses = [
|
|
|
2420
2322
|
];
|
|
2421
2323
|
|
|
2422
2324
|
// src/react/useMemoryStorage.ts
|
|
2423
|
-
import { useCallback as useCallback3, useState as useState3, useMemo as useMemo2, useRef as useRef2 } from "react";
|
|
2325
|
+
import { useCallback as useCallback3, useState as useState3, useMemo as useMemo2, useRef as useRef2, useEffect as useEffect2 } from "react";
|
|
2424
2326
|
import { postApiV1ChatCompletions } from "@reverbia/sdk";
|
|
2425
2327
|
|
|
2426
2328
|
// src/lib/db/memory/schema.ts
|
|
@@ -2528,6 +2430,24 @@ async function getMemoriesByKeyOp(ctx, namespace, key) {
|
|
|
2528
2430
|
return results.map(memoryToStored);
|
|
2529
2431
|
}
|
|
2530
2432
|
async function saveMemoryOp(ctx, opts) {
|
|
2433
|
+
if (!opts.namespace || typeof opts.namespace !== "string") {
|
|
2434
|
+
throw new Error("Namespace is required and must be a string");
|
|
2435
|
+
}
|
|
2436
|
+
if (!opts.key || typeof opts.key !== "string") {
|
|
2437
|
+
throw new Error("Key is required and must be a string");
|
|
2438
|
+
}
|
|
2439
|
+
if (!opts.value || typeof opts.value !== "string") {
|
|
2440
|
+
throw new Error("Value is required and must be a string");
|
|
2441
|
+
}
|
|
2442
|
+
if (!opts.type || typeof opts.type !== "string") {
|
|
2443
|
+
throw new Error("Type is required and must be a string");
|
|
2444
|
+
}
|
|
2445
|
+
if (typeof opts.confidence !== "number" || opts.confidence < 0 || opts.confidence > 1) {
|
|
2446
|
+
throw new Error("Confidence must be a number between 0 and 1");
|
|
2447
|
+
}
|
|
2448
|
+
if (typeof opts.pii !== "boolean") {
|
|
2449
|
+
throw new Error("PII must be a boolean");
|
|
2450
|
+
}
|
|
2531
2451
|
const compositeKey = generateCompositeKey(opts.namespace, opts.key);
|
|
2532
2452
|
const uniqueKey = generateUniqueKey(opts.namespace, opts.key, opts.value);
|
|
2533
2453
|
const result = await ctx.database.write(async () => {
|
|
@@ -2962,6 +2882,275 @@ var generateEmbeddingForMemory = async (memory, options = {}) => {
|
|
|
2962
2882
|
return generateEmbeddingForText(text4, options);
|
|
2963
2883
|
};
|
|
2964
2884
|
|
|
2885
|
+
// src/lib/db/migration.ts
|
|
2886
|
+
var ENCRYPTION_PREFIX_V1 = "enc:v1:";
|
|
2887
|
+
var ENCRYPTION_PREFIX_V2 = "enc:v2:";
|
|
2888
|
+
var ENCRYPTION_PREFIX_LEGACY = "enc:";
|
|
2889
|
+
function getEncryptionVersion(value) {
|
|
2890
|
+
if (value.startsWith(ENCRYPTION_PREFIX_V2)) return "v2";
|
|
2891
|
+
if (value.startsWith(ENCRYPTION_PREFIX_V1)) return "v1";
|
|
2892
|
+
if (value.startsWith(ENCRYPTION_PREFIX_LEGACY)) return "v1";
|
|
2893
|
+
return null;
|
|
2894
|
+
}
|
|
2895
|
+
function isOldEncryption(value) {
|
|
2896
|
+
const version2 = getEncryptionVersion(value);
|
|
2897
|
+
return version2 === "v1";
|
|
2898
|
+
}
|
|
2899
|
+
async function encryptNewValue(plaintext, walletAddress) {
|
|
2900
|
+
if (!hasEncryptionKey(walletAddress)) {
|
|
2901
|
+
throw new Error("Encryption key not available for new scheme");
|
|
2902
|
+
}
|
|
2903
|
+
const encrypted = await encryptData(plaintext, walletAddress);
|
|
2904
|
+
return `enc:v2:${encrypted}`;
|
|
2905
|
+
}
|
|
2906
|
+
async function migrateEncryptedValue(encryptedValue, walletAddress, signMessage) {
|
|
2907
|
+
if (getEncryptionVersion(encryptedValue) === "v2") {
|
|
2908
|
+
return encryptedValue;
|
|
2909
|
+
}
|
|
2910
|
+
if (!getEncryptionVersion(encryptedValue)) {
|
|
2911
|
+
return encryptedValue;
|
|
2912
|
+
}
|
|
2913
|
+
if (!hasEncryptionKey(walletAddress)) {
|
|
2914
|
+
const { requestEncryptionKey: requestEncryptionKey2 } = await import("./useEncryption-5RTXKDNZ.mjs");
|
|
2915
|
+
await requestEncryptionKey2(walletAddress, signMessage);
|
|
2916
|
+
if (!hasEncryptionKey(walletAddress)) {
|
|
2917
|
+
throw new Error("Encryption key not available after signing");
|
|
2918
|
+
}
|
|
2919
|
+
}
|
|
2920
|
+
let encryptedPayload;
|
|
2921
|
+
if (encryptedValue.startsWith(ENCRYPTION_PREFIX_V1)) {
|
|
2922
|
+
encryptedPayload = encryptedValue.slice(ENCRYPTION_PREFIX_V1.length);
|
|
2923
|
+
} else if (encryptedValue.startsWith(ENCRYPTION_PREFIX_LEGACY)) {
|
|
2924
|
+
encryptedPayload = encryptedValue.slice(ENCRYPTION_PREFIX_LEGACY.length);
|
|
2925
|
+
} else {
|
|
2926
|
+
throw new Error("Invalid old encryption format");
|
|
2927
|
+
}
|
|
2928
|
+
const plaintext = await decryptData(encryptedPayload, walletAddress);
|
|
2929
|
+
return await encryptNewValue(plaintext, walletAddress);
|
|
2930
|
+
}
|
|
2931
|
+
|
|
2932
|
+
// src/lib/db/memory/encryption.ts
|
|
2933
|
+
var ENCRYPTED_FIELDS = ["value", "rawEvidence", "key", "namespace"];
|
|
2934
|
+
var ENCRYPTION_PREFIX_V12 = "enc:v1:";
|
|
2935
|
+
var ENCRYPTION_PREFIX_V22 = "enc:v2:";
|
|
2936
|
+
var ENCRYPTION_PREFIX_LEGACY2 = "enc:";
|
|
2937
|
+
var CURRENT_ENCRYPTION_VERSION = "v2";
|
|
2938
|
+
var ENCRYPTION_PREFIX = `enc:${CURRENT_ENCRYPTION_VERSION}:`;
|
|
2939
|
+
var MAX_FIELD_SIZE = 1024 * 1024;
|
|
2940
|
+
function isEncrypted(value) {
|
|
2941
|
+
return value.startsWith(ENCRYPTION_PREFIX) || value.startsWith(ENCRYPTION_PREFIX_V12) || value.startsWith(ENCRYPTION_PREFIX_LEGACY2);
|
|
2942
|
+
}
|
|
2943
|
+
function getEncryptionVersion2(value) {
|
|
2944
|
+
if (value.startsWith(ENCRYPTION_PREFIX_V22)) return "v2";
|
|
2945
|
+
if (value.startsWith(ENCRYPTION_PREFIX_V12)) return "v1";
|
|
2946
|
+
if (value.startsWith(ENCRYPTION_PREFIX_LEGACY2)) return "v1";
|
|
2947
|
+
return null;
|
|
2948
|
+
}
|
|
2949
|
+
async function encryptField(value, address) {
|
|
2950
|
+
if (!value || isEncrypted(value)) {
|
|
2951
|
+
return value;
|
|
2952
|
+
}
|
|
2953
|
+
if (value.length > MAX_FIELD_SIZE) {
|
|
2954
|
+
throw new Error(
|
|
2955
|
+
`Field value too large: ${value.length} bytes (max: ${MAX_FIELD_SIZE} bytes)`
|
|
2956
|
+
);
|
|
2957
|
+
}
|
|
2958
|
+
try {
|
|
2959
|
+
const encrypted = await encryptData(value, address);
|
|
2960
|
+
return `${ENCRYPTION_PREFIX}${encrypted}`;
|
|
2961
|
+
} catch (error) {
|
|
2962
|
+
const message = error instanceof Error ? error.message : "Unknown encryption error";
|
|
2963
|
+
throw new Error(`Encryption failed: ${message}`);
|
|
2964
|
+
}
|
|
2965
|
+
}
|
|
2966
|
+
var DECRYPTION_FAILED_PLACEHOLDER = "[Decryption Failed]";
|
|
2967
|
+
async function decryptField(value, address, signMessage, onMigrated) {
|
|
2968
|
+
if (!value || !isEncrypted(value)) {
|
|
2969
|
+
return value;
|
|
2970
|
+
}
|
|
2971
|
+
try {
|
|
2972
|
+
if (isOldEncryption(value) && signMessage && onMigrated) {
|
|
2973
|
+
try {
|
|
2974
|
+
const migratedValue = await migrateEncryptedValue(value, address, signMessage);
|
|
2975
|
+
await onMigrated(migratedValue);
|
|
2976
|
+
const encryptedPayload2 = migratedValue.slice(ENCRYPTION_PREFIX_V22.length);
|
|
2977
|
+
return await decryptData(encryptedPayload2, address);
|
|
2978
|
+
} catch (migrationError) {
|
|
2979
|
+
const errorMessage = migrationError instanceof Error ? migrationError.message : "Unknown migration error";
|
|
2980
|
+
console.warn("Migration failed, attempting decryption with current key:", {
|
|
2981
|
+
error: errorMessage,
|
|
2982
|
+
address
|
|
2983
|
+
});
|
|
2984
|
+
}
|
|
2985
|
+
}
|
|
2986
|
+
let encryptedPayload;
|
|
2987
|
+
if (value.startsWith(ENCRYPTION_PREFIX_V22)) {
|
|
2988
|
+
encryptedPayload = value.slice(ENCRYPTION_PREFIX_V22.length);
|
|
2989
|
+
} else if (value.startsWith(ENCRYPTION_PREFIX_V12)) {
|
|
2990
|
+
encryptedPayload = value.slice(ENCRYPTION_PREFIX_V12.length);
|
|
2991
|
+
} else if (value.startsWith(ENCRYPTION_PREFIX_LEGACY2)) {
|
|
2992
|
+
encryptedPayload = value.slice(ENCRYPTION_PREFIX_LEGACY2.length);
|
|
2993
|
+
} else {
|
|
2994
|
+
return value;
|
|
2995
|
+
}
|
|
2996
|
+
return await decryptData(encryptedPayload, address);
|
|
2997
|
+
} catch (error) {
|
|
2998
|
+
const errorMessage = error instanceof Error ? error.message : "Unknown decryption error";
|
|
2999
|
+
console.error("Decryption failed for field:", {
|
|
3000
|
+
address,
|
|
3001
|
+
valueLength: value.length,
|
|
3002
|
+
error: errorMessage
|
|
3003
|
+
});
|
|
3004
|
+
throw new Error(`Decryption failed: ${errorMessage}`);
|
|
3005
|
+
}
|
|
3006
|
+
}
|
|
3007
|
+
async function encryptMemoryFields(memory, address) {
|
|
3008
|
+
const encrypted = { ...memory };
|
|
3009
|
+
const encryptionPromises = ENCRYPTED_FIELDS.map(async (field3) => {
|
|
3010
|
+
const value = memory[field3];
|
|
3011
|
+
if (typeof value === "string" && value.length > 0) {
|
|
3012
|
+
try {
|
|
3013
|
+
encrypted[field3] = await encryptField(value, address);
|
|
3014
|
+
} catch (error) {
|
|
3015
|
+
throw new Error(`Failed to encrypt field ${field3}: ${error instanceof Error ? error.message : "Unknown error"}`);
|
|
3016
|
+
}
|
|
3017
|
+
}
|
|
3018
|
+
});
|
|
3019
|
+
const results = await Promise.allSettled(encryptionPromises);
|
|
3020
|
+
const failures = results.filter((r) => r.status === "rejected");
|
|
3021
|
+
if (failures.length > 0) {
|
|
3022
|
+
const errorMessages = failures.map(
|
|
3023
|
+
(f) => f.status === "rejected" ? f.reason instanceof Error ? f.reason.message : String(f.reason) : ""
|
|
3024
|
+
).join("; ");
|
|
3025
|
+
throw new Error(`Encryption failed for ${failures.length} field(s): ${errorMessages}`);
|
|
3026
|
+
}
|
|
3027
|
+
return encrypted;
|
|
3028
|
+
}
|
|
3029
|
+
async function decryptMemoryFields(memory, address, signMessage, updateMemory) {
|
|
3030
|
+
const decrypted = { ...memory };
|
|
3031
|
+
const decryptionPromises = ENCRYPTED_FIELDS.map(async (field3) => {
|
|
3032
|
+
const value = memory[field3];
|
|
3033
|
+
if (typeof value === "string" && value.length > 0) {
|
|
3034
|
+
if (!isEncrypted(value)) {
|
|
3035
|
+
if (updateMemory && memory.uniqueId) {
|
|
3036
|
+
try {
|
|
3037
|
+
const encryptedValue = await encryptField(value, address);
|
|
3038
|
+
await updateMemory(memory.uniqueId, {
|
|
3039
|
+
[field3]: encryptedValue
|
|
3040
|
+
});
|
|
3041
|
+
decrypted[field3] = value;
|
|
3042
|
+
} catch (error) {
|
|
3043
|
+
if (process.env.NODE_ENV === "development") {
|
|
3044
|
+
console.warn(`Failed to encrypt field ${field3}:`, error);
|
|
3045
|
+
}
|
|
3046
|
+
decrypted[field3] = value;
|
|
3047
|
+
}
|
|
3048
|
+
} else {
|
|
3049
|
+
decrypted[field3] = value;
|
|
3050
|
+
}
|
|
3051
|
+
} else {
|
|
3052
|
+
const onMigrated = updateMemory && memory.uniqueId ? async (migratedValue) => {
|
|
3053
|
+
await updateMemory(memory.uniqueId, {
|
|
3054
|
+
[field3]: migratedValue
|
|
3055
|
+
});
|
|
3056
|
+
} : void 0;
|
|
3057
|
+
decrypted[field3] = await decryptField(value, address, signMessage, onMigrated);
|
|
3058
|
+
}
|
|
3059
|
+
}
|
|
3060
|
+
});
|
|
3061
|
+
await Promise.all(decryptionPromises);
|
|
3062
|
+
return decrypted;
|
|
3063
|
+
}
|
|
3064
|
+
async function encryptMemoriesBatch(memories, address) {
|
|
3065
|
+
return Promise.all(
|
|
3066
|
+
memories.map((memory) => encryptMemoryFields(memory, address))
|
|
3067
|
+
);
|
|
3068
|
+
}
|
|
3069
|
+
async function decryptMemoriesBatch(memories, address, signMessage, updateMemory) {
|
|
3070
|
+
return Promise.all(
|
|
3071
|
+
memories.map(
|
|
3072
|
+
(memory) => decryptMemoryFields(memory, address, signMessage, updateMemory)
|
|
3073
|
+
)
|
|
3074
|
+
);
|
|
3075
|
+
}
|
|
3076
|
+
function hasEncryptedFields(memory) {
|
|
3077
|
+
return ENCRYPTED_FIELDS.some((field3) => {
|
|
3078
|
+
const value = memory[field3];
|
|
3079
|
+
return typeof value === "string" && isEncrypted(value);
|
|
3080
|
+
});
|
|
3081
|
+
}
|
|
3082
|
+
function needsEncryption(memory) {
|
|
3083
|
+
return ENCRYPTED_FIELDS.some((field3) => {
|
|
3084
|
+
const value = memory[field3];
|
|
3085
|
+
return typeof value === "string" && value.length > 0 && !isEncrypted(value);
|
|
3086
|
+
});
|
|
3087
|
+
}
|
|
3088
|
+
function extractMemoryFieldsForEncryption(memory) {
|
|
3089
|
+
return {
|
|
3090
|
+
type: memory.type,
|
|
3091
|
+
namespace: memory.namespace,
|
|
3092
|
+
key: memory.key,
|
|
3093
|
+
value: memory.value,
|
|
3094
|
+
rawEvidence: memory.rawEvidence,
|
|
3095
|
+
confidence: memory.confidence,
|
|
3096
|
+
pii: memory.pii
|
|
3097
|
+
};
|
|
3098
|
+
}
|
|
3099
|
+
async function retryEncryption(operation, maxRetries = 3, initialDelay = 500) {
|
|
3100
|
+
let lastError;
|
|
3101
|
+
for (let attempt = 0; attempt <= maxRetries; attempt++) {
|
|
3102
|
+
try {
|
|
3103
|
+
return await operation();
|
|
3104
|
+
} catch (error) {
|
|
3105
|
+
lastError = error;
|
|
3106
|
+
if (attempt === maxRetries) {
|
|
3107
|
+
throw lastError;
|
|
3108
|
+
}
|
|
3109
|
+
const delay = initialDelay * Math.pow(2, attempt);
|
|
3110
|
+
await new Promise((resolve) => setTimeout(resolve, delay));
|
|
3111
|
+
}
|
|
3112
|
+
}
|
|
3113
|
+
throw lastError;
|
|
3114
|
+
}
|
|
3115
|
+
async function encryptMemoriesBatchInPlace(memories, address, updateFn, batchSize = 5) {
|
|
3116
|
+
const failed = [];
|
|
3117
|
+
const errors = [];
|
|
3118
|
+
let success = 0;
|
|
3119
|
+
for (let i = 0; i < memories.length; i += batchSize) {
|
|
3120
|
+
const batch = memories.slice(i, i + batchSize);
|
|
3121
|
+
const results = await Promise.allSettled(
|
|
3122
|
+
batch.map(async (memory) => {
|
|
3123
|
+
await retryEncryption(async () => {
|
|
3124
|
+
const fields = extractMemoryFieldsForEncryption(memory);
|
|
3125
|
+
const encryptedData = await encryptMemoryFields(fields, address);
|
|
3126
|
+
await updateFn(memory.uniqueId, encryptedData);
|
|
3127
|
+
});
|
|
3128
|
+
})
|
|
3129
|
+
);
|
|
3130
|
+
results.forEach((result, index) => {
|
|
3131
|
+
if (result.status === "fulfilled") {
|
|
3132
|
+
success++;
|
|
3133
|
+
} else {
|
|
3134
|
+
const memory = batch[index];
|
|
3135
|
+
if (memory) {
|
|
3136
|
+
failed.push(memory.uniqueId);
|
|
3137
|
+
const errorMessage = result.reason instanceof Error ? result.reason.message : String(result.reason);
|
|
3138
|
+
errors.push({
|
|
3139
|
+
id: memory.uniqueId,
|
|
3140
|
+
error: errorMessage
|
|
3141
|
+
});
|
|
3142
|
+
console.error(
|
|
3143
|
+
"Failed to encrypt memory:",
|
|
3144
|
+
memory.uniqueId,
|
|
3145
|
+
errorMessage
|
|
3146
|
+
);
|
|
3147
|
+
}
|
|
3148
|
+
}
|
|
3149
|
+
});
|
|
3150
|
+
}
|
|
3151
|
+
return { success, failed, errors };
|
|
3152
|
+
}
|
|
3153
|
+
|
|
2965
3154
|
// src/react/useMemoryStorage.ts
|
|
2966
3155
|
function useMemoryStorage(options) {
|
|
2967
3156
|
const {
|
|
@@ -2971,7 +3160,10 @@ function useMemoryStorage(options) {
|
|
|
2971
3160
|
generateEmbeddings = true,
|
|
2972
3161
|
onFactsExtracted,
|
|
2973
3162
|
getToken,
|
|
2974
|
-
baseUrl = BASE_URL
|
|
3163
|
+
baseUrl = BASE_URL,
|
|
3164
|
+
walletAddress,
|
|
3165
|
+
requestEncryptionKey: requestEncryptionKey2,
|
|
3166
|
+
signMessage
|
|
2975
3167
|
} = options;
|
|
2976
3168
|
const embeddingModel = userEmbeddingModel === void 0 ? DEFAULT_API_EMBEDDING_MODEL : userEmbeddingModel;
|
|
2977
3169
|
const [memories, setMemories] = useState3([]);
|
|
@@ -2999,10 +3191,127 @@ function useMemoryStorage(options) {
|
|
|
2999
3191
|
}),
|
|
3000
3192
|
[effectiveEmbeddingModel, getToken, baseUrl]
|
|
3001
3193
|
);
|
|
3194
|
+
const isEncryptionEnabled = useMemo2(
|
|
3195
|
+
() => !!walletAddress && !!requestEncryptionKey2,
|
|
3196
|
+
[walletAddress, requestEncryptionKey2]
|
|
3197
|
+
);
|
|
3198
|
+
const ensureEncryptionReady = useCallback3(async () => {
|
|
3199
|
+
if (!isEncryptionEnabled || !walletAddress) {
|
|
3200
|
+
return null;
|
|
3201
|
+
}
|
|
3202
|
+
if (hasEncryptionKey(walletAddress)) {
|
|
3203
|
+
return walletAddress;
|
|
3204
|
+
}
|
|
3205
|
+
if (requestEncryptionKey2) {
|
|
3206
|
+
try {
|
|
3207
|
+
await requestEncryptionKey2(walletAddress);
|
|
3208
|
+
return walletAddress;
|
|
3209
|
+
} catch {
|
|
3210
|
+
return null;
|
|
3211
|
+
}
|
|
3212
|
+
}
|
|
3213
|
+
return null;
|
|
3214
|
+
}, [isEncryptionEnabled, walletAddress, requestEncryptionKey2]);
|
|
3215
|
+
const getSignMessageForMigration = useCallback3(() => {
|
|
3216
|
+
return signMessage;
|
|
3217
|
+
}, [signMessage]);
|
|
3218
|
+
const encryptUnencryptedMemories = useCallback3(
|
|
3219
|
+
async (address) => {
|
|
3220
|
+
if (!isEncryptionEnabled) return;
|
|
3221
|
+
try {
|
|
3222
|
+
const allMemories = await getAllMemoriesOp(storageCtx);
|
|
3223
|
+
if (!allMemories || allMemories.length === 0) return;
|
|
3224
|
+
const memoriesToEncrypt = allMemories.filter(
|
|
3225
|
+
(m) => needsEncryption(m)
|
|
3226
|
+
);
|
|
3227
|
+
if (memoriesToEncrypt.length === 0) return;
|
|
3228
|
+
await encryptMemoriesBatchInPlace(
|
|
3229
|
+
memoriesToEncrypt,
|
|
3230
|
+
address,
|
|
3231
|
+
async (id, data) => {
|
|
3232
|
+
const result = await updateMemoryOp(storageCtx, id, data);
|
|
3233
|
+
if (!result.ok) {
|
|
3234
|
+
throw new Error(`Failed to update memory ${id}`);
|
|
3235
|
+
}
|
|
3236
|
+
}
|
|
3237
|
+
);
|
|
3238
|
+
} catch (error) {
|
|
3239
|
+
if (process.env.NODE_ENV === "development") {
|
|
3240
|
+
console.error("Failed to encrypt unencrypted memories:", error);
|
|
3241
|
+
}
|
|
3242
|
+
}
|
|
3243
|
+
},
|
|
3244
|
+
[isEncryptionEnabled, storageCtx]
|
|
3245
|
+
);
|
|
3246
|
+
const encryptionLockRef = useRef2(null);
|
|
3247
|
+
const autoEncryptionRunRef = useRef2(false);
|
|
3248
|
+
useEffect2(() => {
|
|
3249
|
+
if (!isEncryptionEnabled || !walletAddress) {
|
|
3250
|
+
autoEncryptionRunRef.current = false;
|
|
3251
|
+
encryptionLockRef.current = null;
|
|
3252
|
+
return;
|
|
3253
|
+
}
|
|
3254
|
+
if (encryptionLockRef.current) {
|
|
3255
|
+
encryptionLockRef.current.then(() => {
|
|
3256
|
+
if (isEncryptionEnabled && walletAddress && !autoEncryptionRunRef.current) {
|
|
3257
|
+
ensureEncryptionReady().then((address) => {
|
|
3258
|
+
if (address) {
|
|
3259
|
+
autoEncryptionRunRef.current = true;
|
|
3260
|
+
const encryptionPromise2 = encryptUnencryptedMemories(address).catch((err) => {
|
|
3261
|
+
if (process.env.NODE_ENV === "development") {
|
|
3262
|
+
console.error("Failed to automatically encrypt memories:", err);
|
|
3263
|
+
}
|
|
3264
|
+
}).finally(() => {
|
|
3265
|
+
encryptionLockRef.current = null;
|
|
3266
|
+
});
|
|
3267
|
+
encryptionLockRef.current = encryptionPromise2;
|
|
3268
|
+
}
|
|
3269
|
+
});
|
|
3270
|
+
}
|
|
3271
|
+
});
|
|
3272
|
+
return;
|
|
3273
|
+
}
|
|
3274
|
+
if (autoEncryptionRunRef.current) {
|
|
3275
|
+
return;
|
|
3276
|
+
}
|
|
3277
|
+
autoEncryptionRunRef.current = true;
|
|
3278
|
+
const encryptionPromise = ensureEncryptionReady().then((address) => {
|
|
3279
|
+
if (address) {
|
|
3280
|
+
return encryptUnencryptedMemories(address);
|
|
3281
|
+
}
|
|
3282
|
+
}).catch((err) => {
|
|
3283
|
+
if (process.env.NODE_ENV === "development") {
|
|
3284
|
+
console.error("Failed to automatically encrypt memories:", err);
|
|
3285
|
+
}
|
|
3286
|
+
}).finally(() => {
|
|
3287
|
+
encryptionLockRef.current = null;
|
|
3288
|
+
});
|
|
3289
|
+
encryptionLockRef.current = encryptionPromise;
|
|
3290
|
+
}, [isEncryptionEnabled, walletAddress, ensureEncryptionReady, encryptUnencryptedMemories]);
|
|
3002
3291
|
const refreshMemories = useCallback3(async () => {
|
|
3003
3292
|
const storedMemories = await getAllMemoriesOp(storageCtx);
|
|
3293
|
+
if (isEncryptionEnabled && walletAddress) {
|
|
3294
|
+
const address = await ensureEncryptionReady();
|
|
3295
|
+
if (address) {
|
|
3296
|
+
const signMsg = getSignMessageForMigration();
|
|
3297
|
+
const updateMemoryFn = async (id, data) => {
|
|
3298
|
+
const result = await updateMemoryOp(storageCtx, id, data);
|
|
3299
|
+
if (!result.ok) {
|
|
3300
|
+
throw new Error(`Failed to update memory ${id} during migration`);
|
|
3301
|
+
}
|
|
3302
|
+
};
|
|
3303
|
+
const decrypted = await decryptMemoriesBatch(
|
|
3304
|
+
storedMemories,
|
|
3305
|
+
address,
|
|
3306
|
+
signMsg,
|
|
3307
|
+
updateMemoryFn
|
|
3308
|
+
);
|
|
3309
|
+
setMemories(decrypted);
|
|
3310
|
+
return;
|
|
3311
|
+
}
|
|
3312
|
+
}
|
|
3004
3313
|
setMemories(storedMemories);
|
|
3005
|
-
}, [storageCtx]);
|
|
3314
|
+
}, [storageCtx, isEncryptionEnabled, walletAddress, ensureEncryptionReady, getSignMessageForMigration]);
|
|
3006
3315
|
const extractMemoriesFromMessage = useCallback3(
|
|
3007
3316
|
async (opts) => {
|
|
3008
3317
|
const { messages, model } = opts;
|
|
@@ -3136,21 +3445,38 @@ function useMemoryStorage(options) {
|
|
|
3136
3445
|
pii: item.pii
|
|
3137
3446
|
})
|
|
3138
3447
|
);
|
|
3139
|
-
|
|
3448
|
+
let optionsToSave = createOptions;
|
|
3449
|
+
if (isEncryptionEnabled && walletAddress) {
|
|
3450
|
+
const address = await ensureEncryptionReady();
|
|
3451
|
+
if (address) {
|
|
3452
|
+
optionsToSave = await Promise.all(
|
|
3453
|
+
createOptions.map(async (opt) => {
|
|
3454
|
+
const encrypted = await encryptMemoryFields(
|
|
3455
|
+
opt,
|
|
3456
|
+
address
|
|
3457
|
+
);
|
|
3458
|
+
return encrypted;
|
|
3459
|
+
})
|
|
3460
|
+
);
|
|
3461
|
+
}
|
|
3462
|
+
}
|
|
3463
|
+
const savedMemories = await saveMemoriesOp(storageCtx, optionsToSave);
|
|
3140
3464
|
console.log(
|
|
3141
3465
|
`Saved ${savedMemories.length} memories to WatermelonDB`
|
|
3142
3466
|
);
|
|
3143
3467
|
if (generateEmbeddings && embeddingModel) {
|
|
3144
3468
|
try {
|
|
3145
|
-
for (
|
|
3469
|
+
for (let i = 0; i < savedMemories.length; i++) {
|
|
3470
|
+
const memory = createOptions[i];
|
|
3471
|
+
const saved = savedMemories[i];
|
|
3146
3472
|
const memoryItem = {
|
|
3147
|
-
type:
|
|
3148
|
-
namespace:
|
|
3149
|
-
key:
|
|
3150
|
-
value:
|
|
3151
|
-
rawEvidence:
|
|
3152
|
-
confidence:
|
|
3153
|
-
pii:
|
|
3473
|
+
type: memory.type,
|
|
3474
|
+
namespace: memory.namespace,
|
|
3475
|
+
key: memory.key,
|
|
3476
|
+
value: memory.value,
|
|
3477
|
+
rawEvidence: memory.rawEvidence,
|
|
3478
|
+
confidence: memory.confidence,
|
|
3479
|
+
pii: memory.pii
|
|
3154
3480
|
};
|
|
3155
3481
|
const embedding = await generateEmbeddingForMemory(
|
|
3156
3482
|
memoryItem,
|
|
@@ -3171,6 +3497,19 @@ function useMemoryStorage(options) {
|
|
|
3171
3497
|
}
|
|
3172
3498
|
}
|
|
3173
3499
|
await refreshMemories();
|
|
3500
|
+
if (isEncryptionEnabled && walletAddress && !encryptionLockRef.current) {
|
|
3501
|
+
const address = await ensureEncryptionReady();
|
|
3502
|
+
if (address) {
|
|
3503
|
+
const encryptionPromise = encryptUnencryptedMemories(address).catch((err) => {
|
|
3504
|
+
if (process.env.NODE_ENV === "development") {
|
|
3505
|
+
console.error("Failed to encrypt memories:", err);
|
|
3506
|
+
}
|
|
3507
|
+
}).finally(() => {
|
|
3508
|
+
encryptionLockRef.current = null;
|
|
3509
|
+
});
|
|
3510
|
+
encryptionLockRef.current = encryptionPromise;
|
|
3511
|
+
}
|
|
3512
|
+
}
|
|
3174
3513
|
} catch (error) {
|
|
3175
3514
|
console.error("Failed to save memories to WatermelonDB:", error);
|
|
3176
3515
|
}
|
|
@@ -3195,7 +3534,11 @@ function useMemoryStorage(options) {
|
|
|
3195
3534
|
onFactsExtracted,
|
|
3196
3535
|
baseUrl,
|
|
3197
3536
|
storageCtx,
|
|
3198
|
-
refreshMemories
|
|
3537
|
+
refreshMemories,
|
|
3538
|
+
isEncryptionEnabled,
|
|
3539
|
+
walletAddress,
|
|
3540
|
+
ensureEncryptionReady,
|
|
3541
|
+
encryptUnencryptedMemories
|
|
3199
3542
|
]
|
|
3200
3543
|
);
|
|
3201
3544
|
const searchMemories = useCallback3(
|
|
@@ -3215,6 +3558,25 @@ function useMemoryStorage(options) {
|
|
|
3215
3558
|
limit,
|
|
3216
3559
|
minSimilarity
|
|
3217
3560
|
);
|
|
3561
|
+
if (isEncryptionEnabled && walletAddress && results.length > 0) {
|
|
3562
|
+
const address = await ensureEncryptionReady();
|
|
3563
|
+
if (address) {
|
|
3564
|
+
const signMsg = getSignMessageForMigration();
|
|
3565
|
+
const updateMemoryFn = async (id, data) => {
|
|
3566
|
+
const result = await updateMemoryOp(storageCtx, id, data);
|
|
3567
|
+
if (!result.ok) {
|
|
3568
|
+
throw new Error(`Failed to update memory ${id} during migration`);
|
|
3569
|
+
}
|
|
3570
|
+
};
|
|
3571
|
+
const decrypted = await decryptMemoriesBatch(
|
|
3572
|
+
results,
|
|
3573
|
+
address,
|
|
3574
|
+
signMsg,
|
|
3575
|
+
updateMemoryFn
|
|
3576
|
+
);
|
|
3577
|
+
return decrypted;
|
|
3578
|
+
}
|
|
3579
|
+
}
|
|
3218
3580
|
if (results.length === 0) {
|
|
3219
3581
|
console.warn(
|
|
3220
3582
|
`[Memory Search] No memories found above similarity threshold ${minSimilarity}.`
|
|
@@ -3229,31 +3591,71 @@ function useMemoryStorage(options) {
|
|
|
3229
3591
|
return [];
|
|
3230
3592
|
}
|
|
3231
3593
|
},
|
|
3232
|
-
[embeddingModel, embeddingOptions, storageCtx]
|
|
3594
|
+
[embeddingModel, embeddingOptions, storageCtx, isEncryptionEnabled, walletAddress, ensureEncryptionReady, getSignMessageForMigration]
|
|
3233
3595
|
);
|
|
3234
3596
|
const fetchAllMemories = useCallback3(async () => {
|
|
3235
3597
|
try {
|
|
3236
|
-
|
|
3598
|
+
const memories2 = await getAllMemoriesOp(storageCtx);
|
|
3599
|
+
if (isEncryptionEnabled && walletAddress && memories2.length > 0) {
|
|
3600
|
+
const address = await ensureEncryptionReady();
|
|
3601
|
+
if (address) {
|
|
3602
|
+
const signMsg = getSignMessageForMigration();
|
|
3603
|
+
const updateMemoryFn = async (id, data) => {
|
|
3604
|
+
const result = await updateMemoryOp(storageCtx, id, data);
|
|
3605
|
+
if (!result.ok) {
|
|
3606
|
+
throw new Error(`Failed to update memory ${id} during migration`);
|
|
3607
|
+
}
|
|
3608
|
+
};
|
|
3609
|
+
const decrypted = await decryptMemoriesBatch(
|
|
3610
|
+
memories2,
|
|
3611
|
+
address,
|
|
3612
|
+
signMsg,
|
|
3613
|
+
updateMemoryFn
|
|
3614
|
+
);
|
|
3615
|
+
return decrypted;
|
|
3616
|
+
}
|
|
3617
|
+
}
|
|
3618
|
+
return memories2;
|
|
3237
3619
|
} catch (error) {
|
|
3238
3620
|
throw new Error(
|
|
3239
3621
|
"Failed to fetch all memories: " + (error instanceof Error ? error.message : String(error))
|
|
3240
3622
|
);
|
|
3241
3623
|
}
|
|
3242
|
-
}, [storageCtx]);
|
|
3624
|
+
}, [storageCtx, isEncryptionEnabled, walletAddress, ensureEncryptionReady, getSignMessageForMigration]);
|
|
3243
3625
|
const fetchMemoriesByNamespace = useCallback3(
|
|
3244
3626
|
async (namespace) => {
|
|
3245
3627
|
if (!namespace) {
|
|
3246
3628
|
throw new Error("Missing required field: namespace");
|
|
3247
3629
|
}
|
|
3248
3630
|
try {
|
|
3249
|
-
|
|
3631
|
+
const memories2 = await getMemoriesByNamespaceOp(storageCtx, namespace);
|
|
3632
|
+
if (isEncryptionEnabled && walletAddress && memories2.length > 0) {
|
|
3633
|
+
const address = await ensureEncryptionReady();
|
|
3634
|
+
if (address) {
|
|
3635
|
+
const signMsg = getSignMessageForMigration();
|
|
3636
|
+
const updateMemoryFn = async (id, data) => {
|
|
3637
|
+
const result = await updateMemoryOp(storageCtx, id, data);
|
|
3638
|
+
if (!result.ok) {
|
|
3639
|
+
throw new Error(`Failed to update memory ${id} during migration`);
|
|
3640
|
+
}
|
|
3641
|
+
};
|
|
3642
|
+
const decrypted = await decryptMemoriesBatch(
|
|
3643
|
+
memories2,
|
|
3644
|
+
address,
|
|
3645
|
+
signMsg,
|
|
3646
|
+
updateMemoryFn
|
|
3647
|
+
);
|
|
3648
|
+
return decrypted;
|
|
3649
|
+
}
|
|
3650
|
+
}
|
|
3651
|
+
return memories2;
|
|
3250
3652
|
} catch (error) {
|
|
3251
3653
|
throw new Error(
|
|
3252
3654
|
`Failed to fetch memories for namespace "${namespace}": ` + (error instanceof Error ? error.message : String(error))
|
|
3253
3655
|
);
|
|
3254
3656
|
}
|
|
3255
3657
|
},
|
|
3256
|
-
[storageCtx]
|
|
3658
|
+
[storageCtx, isEncryptionEnabled, walletAddress, ensureEncryptionReady, getSignMessageForMigration]
|
|
3257
3659
|
);
|
|
3258
3660
|
const fetchMemoriesByKey = useCallback3(
|
|
3259
3661
|
async (namespace, key) => {
|
|
@@ -3261,31 +3663,82 @@ function useMemoryStorage(options) {
|
|
|
3261
3663
|
throw new Error("Missing required fields: namespace, key");
|
|
3262
3664
|
}
|
|
3263
3665
|
try {
|
|
3264
|
-
|
|
3666
|
+
const memories2 = await getMemoriesByKeyOp(storageCtx, namespace, key);
|
|
3667
|
+
if (isEncryptionEnabled && walletAddress && memories2.length > 0) {
|
|
3668
|
+
const address = await ensureEncryptionReady();
|
|
3669
|
+
if (address) {
|
|
3670
|
+
const signMsg = getSignMessageForMigration();
|
|
3671
|
+
const updateMemoryFn = async (id, data) => {
|
|
3672
|
+
const result = await updateMemoryOp(storageCtx, id, data);
|
|
3673
|
+
if (!result.ok) {
|
|
3674
|
+
throw new Error(`Failed to update memory ${id} during migration`);
|
|
3675
|
+
}
|
|
3676
|
+
};
|
|
3677
|
+
const decrypted = await decryptMemoriesBatch(
|
|
3678
|
+
memories2,
|
|
3679
|
+
address,
|
|
3680
|
+
signMsg,
|
|
3681
|
+
updateMemoryFn
|
|
3682
|
+
);
|
|
3683
|
+
return decrypted;
|
|
3684
|
+
}
|
|
3685
|
+
}
|
|
3686
|
+
return memories2;
|
|
3265
3687
|
} catch (error) {
|
|
3266
3688
|
throw new Error(
|
|
3267
3689
|
`Failed to fetch memories for "${namespace}:${key}": ` + (error instanceof Error ? error.message : String(error))
|
|
3268
3690
|
);
|
|
3269
3691
|
}
|
|
3270
3692
|
},
|
|
3271
|
-
[storageCtx]
|
|
3693
|
+
[storageCtx, isEncryptionEnabled, walletAddress, ensureEncryptionReady, getSignMessageForMigration]
|
|
3272
3694
|
);
|
|
3273
3695
|
const getMemoryById = useCallback3(
|
|
3274
3696
|
async (id) => {
|
|
3275
3697
|
try {
|
|
3276
|
-
|
|
3698
|
+
const memory = await getMemoryByIdOp(storageCtx, id);
|
|
3699
|
+
if (!memory) return null;
|
|
3700
|
+
if (isEncryptionEnabled && walletAddress) {
|
|
3701
|
+
const address = await ensureEncryptionReady();
|
|
3702
|
+
if (address) {
|
|
3703
|
+
const signMsg = getSignMessageForMigration();
|
|
3704
|
+
const updateMemoryFn = async (id2, data) => {
|
|
3705
|
+
const result = await updateMemoryOp(storageCtx, id2, data);
|
|
3706
|
+
if (!result.ok) {
|
|
3707
|
+
throw new Error(`Failed to update memory ${id2} during migration`);
|
|
3708
|
+
}
|
|
3709
|
+
};
|
|
3710
|
+
const decrypted = await decryptMemoryFields(
|
|
3711
|
+
memory,
|
|
3712
|
+
address,
|
|
3713
|
+
signMsg,
|
|
3714
|
+
updateMemoryFn
|
|
3715
|
+
);
|
|
3716
|
+
return decrypted;
|
|
3717
|
+
}
|
|
3718
|
+
}
|
|
3719
|
+
return memory;
|
|
3277
3720
|
} catch (error) {
|
|
3278
3721
|
throw new Error(
|
|
3279
3722
|
`Failed to get memory ${id}: ` + (error instanceof Error ? error.message : String(error))
|
|
3280
3723
|
);
|
|
3281
3724
|
}
|
|
3282
3725
|
},
|
|
3283
|
-
[storageCtx]
|
|
3726
|
+
[storageCtx, isEncryptionEnabled, walletAddress, ensureEncryptionReady, getSignMessageForMigration]
|
|
3284
3727
|
);
|
|
3285
3728
|
const saveMemory = useCallback3(
|
|
3286
3729
|
async (memory) => {
|
|
3287
3730
|
try {
|
|
3288
|
-
|
|
3731
|
+
let memoryToSave = memory;
|
|
3732
|
+
if (isEncryptionEnabled && walletAddress) {
|
|
3733
|
+
const address = await ensureEncryptionReady();
|
|
3734
|
+
if (address) {
|
|
3735
|
+
memoryToSave = await encryptMemoryFields(
|
|
3736
|
+
memory,
|
|
3737
|
+
address
|
|
3738
|
+
);
|
|
3739
|
+
}
|
|
3740
|
+
}
|
|
3741
|
+
const saved = await saveMemoryOp(storageCtx, memoryToSave);
|
|
3289
3742
|
if (generateEmbeddings && embeddingModel && !memory.embedding) {
|
|
3290
3743
|
try {
|
|
3291
3744
|
const memoryItem = {
|
|
@@ -3311,26 +3764,60 @@ function useMemoryStorage(options) {
|
|
|
3311
3764
|
console.error("Failed to generate embedding:", error);
|
|
3312
3765
|
}
|
|
3313
3766
|
}
|
|
3767
|
+
let savedForState = saved;
|
|
3768
|
+
if (isEncryptionEnabled && walletAddress) {
|
|
3769
|
+
const address = await ensureEncryptionReady();
|
|
3770
|
+
if (address) {
|
|
3771
|
+
const signMsg = getSignMessageForMigration();
|
|
3772
|
+
const updateMemoryFn = async (id, data) => {
|
|
3773
|
+
const result = await updateMemoryOp(storageCtx, id, data);
|
|
3774
|
+
if (!result.ok) {
|
|
3775
|
+
throw new Error(`Failed to update memory ${id} during migration`);
|
|
3776
|
+
}
|
|
3777
|
+
};
|
|
3778
|
+
savedForState = await decryptMemoryFields(
|
|
3779
|
+
saved,
|
|
3780
|
+
address,
|
|
3781
|
+
signMsg,
|
|
3782
|
+
updateMemoryFn
|
|
3783
|
+
);
|
|
3784
|
+
}
|
|
3785
|
+
}
|
|
3314
3786
|
setMemories((prev) => {
|
|
3315
|
-
const existing = prev.find((m) => m.uniqueId ===
|
|
3787
|
+
const existing = prev.find((m) => m.uniqueId === savedForState.uniqueId);
|
|
3316
3788
|
if (existing) {
|
|
3317
|
-
return prev.map((m) => m.uniqueId ===
|
|
3789
|
+
return prev.map((m) => m.uniqueId === savedForState.uniqueId ? savedForState : m);
|
|
3318
3790
|
}
|
|
3319
|
-
return [
|
|
3791
|
+
return [savedForState, ...prev];
|
|
3320
3792
|
});
|
|
3321
|
-
return
|
|
3793
|
+
return savedForState;
|
|
3322
3794
|
} catch (error) {
|
|
3323
3795
|
throw new Error(
|
|
3324
3796
|
"Failed to save memory: " + (error instanceof Error ? error.message : String(error))
|
|
3325
3797
|
);
|
|
3326
3798
|
}
|
|
3327
3799
|
},
|
|
3328
|
-
[storageCtx, generateEmbeddings, embeddingModel, embeddingOptions]
|
|
3800
|
+
[storageCtx, generateEmbeddings, embeddingModel, embeddingOptions, isEncryptionEnabled, walletAddress, ensureEncryptionReady, getSignMessageForMigration]
|
|
3329
3801
|
);
|
|
3330
3802
|
const saveMemories = useCallback3(
|
|
3331
3803
|
async (memoriesToSave) => {
|
|
3332
3804
|
try {
|
|
3333
|
-
|
|
3805
|
+
let optionsToSave = memoriesToSave;
|
|
3806
|
+
if (isEncryptionEnabled && walletAddress) {
|
|
3807
|
+
const address = await ensureEncryptionReady();
|
|
3808
|
+
if (address) {
|
|
3809
|
+
optionsToSave = await Promise.all(
|
|
3810
|
+
memoriesToSave.map(async (opt) => {
|
|
3811
|
+
const encrypted = await encryptMemoryFields(
|
|
3812
|
+
opt,
|
|
3813
|
+
address
|
|
3814
|
+
);
|
|
3815
|
+
return encrypted;
|
|
3816
|
+
})
|
|
3817
|
+
);
|
|
3818
|
+
}
|
|
3819
|
+
}
|
|
3820
|
+
const saved = await saveMemoriesOp(storageCtx, optionsToSave);
|
|
3334
3821
|
if (generateEmbeddings && embeddingModel) {
|
|
3335
3822
|
for (let i = 0; i < saved.length; i++) {
|
|
3336
3823
|
const memory = memoriesToSave[i];
|
|
@@ -3361,8 +3848,27 @@ function useMemoryStorage(options) {
|
|
|
3361
3848
|
}
|
|
3362
3849
|
}
|
|
3363
3850
|
}
|
|
3851
|
+
let savedForReturn = saved;
|
|
3852
|
+
if (isEncryptionEnabled && walletAddress) {
|
|
3853
|
+
const address = await ensureEncryptionReady();
|
|
3854
|
+
if (address) {
|
|
3855
|
+
const signMsg = getSignMessageForMigration();
|
|
3856
|
+
const updateMemoryFn = async (id, data) => {
|
|
3857
|
+
const result = await updateMemoryOp(storageCtx, id, data);
|
|
3858
|
+
if (!result.ok) {
|
|
3859
|
+
throw new Error(`Failed to update memory ${id} during migration`);
|
|
3860
|
+
}
|
|
3861
|
+
};
|
|
3862
|
+
savedForReturn = await decryptMemoriesBatch(
|
|
3863
|
+
saved,
|
|
3864
|
+
address,
|
|
3865
|
+
signMsg,
|
|
3866
|
+
updateMemoryFn
|
|
3867
|
+
);
|
|
3868
|
+
}
|
|
3869
|
+
}
|
|
3364
3870
|
await refreshMemories();
|
|
3365
|
-
return
|
|
3871
|
+
return savedForReturn;
|
|
3366
3872
|
} catch (error) {
|
|
3367
3873
|
throw new Error(
|
|
3368
3874
|
"Failed to save memories: " + (error instanceof Error ? error.message : String(error))
|
|
@@ -3374,12 +3880,56 @@ function useMemoryStorage(options) {
|
|
|
3374
3880
|
generateEmbeddings,
|
|
3375
3881
|
embeddingModel,
|
|
3376
3882
|
embeddingOptions,
|
|
3377
|
-
refreshMemories
|
|
3883
|
+
refreshMemories,
|
|
3884
|
+
isEncryptionEnabled,
|
|
3885
|
+
walletAddress,
|
|
3886
|
+
ensureEncryptionReady,
|
|
3887
|
+
getSignMessageForMigration
|
|
3378
3888
|
]
|
|
3379
3889
|
);
|
|
3380
3890
|
const updateMemory = useCallback3(
|
|
3381
3891
|
async (id, updates) => {
|
|
3382
|
-
|
|
3892
|
+
let updatesToSave = updates;
|
|
3893
|
+
if (isEncryptionEnabled && walletAddress) {
|
|
3894
|
+
const address = await ensureEncryptionReady();
|
|
3895
|
+
if (address) {
|
|
3896
|
+
try {
|
|
3897
|
+
const fieldsToEncrypt = {};
|
|
3898
|
+
if (updates.value !== void 0) {
|
|
3899
|
+
fieldsToEncrypt.value = updates.value;
|
|
3900
|
+
}
|
|
3901
|
+
if (updates.rawEvidence !== void 0) {
|
|
3902
|
+
fieldsToEncrypt.rawEvidence = updates.rawEvidence;
|
|
3903
|
+
}
|
|
3904
|
+
if (updates.key !== void 0) {
|
|
3905
|
+
fieldsToEncrypt.key = updates.key;
|
|
3906
|
+
}
|
|
3907
|
+
if (updates.namespace !== void 0) {
|
|
3908
|
+
fieldsToEncrypt.namespace = updates.namespace;
|
|
3909
|
+
}
|
|
3910
|
+
const encrypted = await encryptMemoryFields(fieldsToEncrypt, address);
|
|
3911
|
+
const encryptedUpdates = { ...updates };
|
|
3912
|
+
if (updates.value !== void 0) {
|
|
3913
|
+
encryptedUpdates.value = encrypted.value;
|
|
3914
|
+
}
|
|
3915
|
+
if (updates.rawEvidence !== void 0) {
|
|
3916
|
+
encryptedUpdates.rawEvidence = encrypted.rawEvidence;
|
|
3917
|
+
}
|
|
3918
|
+
if (updates.key !== void 0) {
|
|
3919
|
+
encryptedUpdates.key = encrypted.key;
|
|
3920
|
+
}
|
|
3921
|
+
if (updates.namespace !== void 0) {
|
|
3922
|
+
encryptedUpdates.namespace = encrypted.namespace;
|
|
3923
|
+
}
|
|
3924
|
+
updatesToSave = encryptedUpdates;
|
|
3925
|
+
} catch (error) {
|
|
3926
|
+
throw new Error(
|
|
3927
|
+
`Failed to encrypt memory fields: ${error instanceof Error ? error.message : "Unknown error"}`
|
|
3928
|
+
);
|
|
3929
|
+
}
|
|
3930
|
+
}
|
|
3931
|
+
}
|
|
3932
|
+
const result = await updateMemoryOp(storageCtx, id, updatesToSave);
|
|
3383
3933
|
if (!result.ok) {
|
|
3384
3934
|
if (result.reason === "not_found") {
|
|
3385
3935
|
return null;
|
|
@@ -3393,7 +3943,25 @@ function useMemoryStorage(options) {
|
|
|
3393
3943
|
`Failed to update memory ${id}: ${result.error.message}`
|
|
3394
3944
|
);
|
|
3395
3945
|
}
|
|
3396
|
-
|
|
3946
|
+
let updated = result.memory;
|
|
3947
|
+
if (isEncryptionEnabled && walletAddress) {
|
|
3948
|
+
const address = await ensureEncryptionReady();
|
|
3949
|
+
if (address) {
|
|
3950
|
+
const signMsg = getSignMessageForMigration();
|
|
3951
|
+
const updateMemoryFn = async (id2, data) => {
|
|
3952
|
+
const result2 = await updateMemoryOp(storageCtx, id2, data);
|
|
3953
|
+
if (!result2.ok) {
|
|
3954
|
+
throw new Error(`Failed to update memory ${id2} during migration`);
|
|
3955
|
+
}
|
|
3956
|
+
};
|
|
3957
|
+
updated = await decryptMemoryFields(
|
|
3958
|
+
updated,
|
|
3959
|
+
address,
|
|
3960
|
+
signMsg,
|
|
3961
|
+
updateMemoryFn
|
|
3962
|
+
);
|
|
3963
|
+
}
|
|
3964
|
+
}
|
|
3397
3965
|
const contentChanged = updates.value !== void 0 || updates.rawEvidence !== void 0 || updates.type !== void 0 || updates.namespace !== void 0 || updates.key !== void 0;
|
|
3398
3966
|
if (contentChanged && generateEmbeddings && embeddingModel && !updates.embedding) {
|
|
3399
3967
|
try {
|
|
@@ -3425,7 +3993,7 @@ function useMemoryStorage(options) {
|
|
|
3425
3993
|
);
|
|
3426
3994
|
return updated;
|
|
3427
3995
|
},
|
|
3428
|
-
[storageCtx, generateEmbeddings, embeddingModel, embeddingOptions]
|
|
3996
|
+
[storageCtx, generateEmbeddings, embeddingModel, embeddingOptions, isEncryptionEnabled, walletAddress, ensureEncryptionReady, getSignMessageForMigration]
|
|
3429
3997
|
);
|
|
3430
3998
|
const removeMemory = useCallback3(
|
|
3431
3999
|
async (namespace, key, value) => {
|
|
@@ -3510,7 +4078,7 @@ function useMemoryStorage(options) {
|
|
|
3510
4078
|
}
|
|
3511
4079
|
|
|
3512
4080
|
// src/react/useSettings.ts
|
|
3513
|
-
import { useCallback as useCallback4, useState as useState4, useMemo as useMemo3, useEffect as
|
|
4081
|
+
import { useCallback as useCallback4, useState as useState4, useMemo as useMemo3, useEffect as useEffect3 } from "react";
|
|
3514
4082
|
|
|
3515
4083
|
// src/lib/db/settings/schema.ts
|
|
3516
4084
|
import { appSchema as appSchema4, tableSchema as tableSchema4 } from "@nozbe/watermelondb";
|
|
@@ -3632,7 +4200,7 @@ function useSettings(options) {
|
|
|
3632
4200
|
},
|
|
3633
4201
|
[storageCtx, walletAddress]
|
|
3634
4202
|
);
|
|
3635
|
-
|
|
4203
|
+
useEffect3(() => {
|
|
3636
4204
|
if (!walletAddress) {
|
|
3637
4205
|
setModelPreferenceState(null);
|
|
3638
4206
|
return;
|
|
@@ -3859,7 +4427,7 @@ ${text4}`;
|
|
|
3859
4427
|
}
|
|
3860
4428
|
|
|
3861
4429
|
// src/react/useModels.ts
|
|
3862
|
-
import { useCallback as useCallback7, useEffect as
|
|
4430
|
+
import { useCallback as useCallback7, useEffect as useEffect4, useRef as useRef3, useState as useState7 } from "react";
|
|
3863
4431
|
function useModels(options = {}) {
|
|
3864
4432
|
const { getToken, baseUrl = BASE_URL, provider, autoFetch = true } = options;
|
|
3865
4433
|
const [models, setModels] = useState7([]);
|
|
@@ -3869,12 +4437,12 @@ function useModels(options = {}) {
|
|
|
3869
4437
|
const baseUrlRef = useRef3(baseUrl);
|
|
3870
4438
|
const providerRef = useRef3(provider);
|
|
3871
4439
|
const abortControllerRef = useRef3(null);
|
|
3872
|
-
|
|
4440
|
+
useEffect4(() => {
|
|
3873
4441
|
getTokenRef.current = getToken;
|
|
3874
4442
|
baseUrlRef.current = baseUrl;
|
|
3875
4443
|
providerRef.current = provider;
|
|
3876
4444
|
});
|
|
3877
|
-
|
|
4445
|
+
useEffect4(() => {
|
|
3878
4446
|
return () => {
|
|
3879
4447
|
if (abortControllerRef.current) {
|
|
3880
4448
|
abortControllerRef.current.abort();
|
|
@@ -3945,7 +4513,7 @@ function useModels(options = {}) {
|
|
|
3945
4513
|
await fetchModels();
|
|
3946
4514
|
}, [fetchModels]);
|
|
3947
4515
|
const hasFetchedRef = useRef3(false);
|
|
3948
|
-
|
|
4516
|
+
useEffect4(() => {
|
|
3949
4517
|
if (autoFetch && !hasFetchedRef.current) {
|
|
3950
4518
|
hasFetchedRef.current = true;
|
|
3951
4519
|
fetchModels();
|
|
@@ -3963,7 +4531,7 @@ function useModels(options = {}) {
|
|
|
3963
4531
|
}
|
|
3964
4532
|
|
|
3965
4533
|
// src/react/useSearch.ts
|
|
3966
|
-
import { useCallback as useCallback8, useEffect as
|
|
4534
|
+
import { useCallback as useCallback8, useEffect as useEffect5, useRef as useRef4, useState as useState8 } from "react";
|
|
3967
4535
|
function useSearch(options = {}) {
|
|
3968
4536
|
const { getToken, baseUrl = BASE_URL, onError } = options;
|
|
3969
4537
|
const [isLoading, setIsLoading] = useState8(false);
|
|
@@ -3971,7 +4539,7 @@ function useSearch(options = {}) {
|
|
|
3971
4539
|
const [response, setResponse] = useState8(null);
|
|
3972
4540
|
const [error, setError] = useState8(null);
|
|
3973
4541
|
const abortControllerRef = useRef4(null);
|
|
3974
|
-
|
|
4542
|
+
useEffect5(() => {
|
|
3975
4543
|
return () => {
|
|
3976
4544
|
if (abortControllerRef.current) {
|
|
3977
4545
|
abortControllerRef.current.abort();
|
|
@@ -4047,12 +4615,12 @@ function useSearch(options = {}) {
|
|
|
4047
4615
|
}
|
|
4048
4616
|
|
|
4049
4617
|
// src/react/useImageGeneration.ts
|
|
4050
|
-
import { useCallback as useCallback9, useEffect as
|
|
4618
|
+
import { useCallback as useCallback9, useEffect as useEffect6, useRef as useRef5, useState as useState9 } from "react";
|
|
4051
4619
|
function useImageGeneration(options = {}) {
|
|
4052
4620
|
const { getToken, baseUrl = BASE_URL, onFinish, onError } = options;
|
|
4053
4621
|
const [isLoading, setIsLoading] = useState9(false);
|
|
4054
4622
|
const abortControllerRef = useRef5(null);
|
|
4055
|
-
|
|
4623
|
+
useEffect6(() => {
|
|
4056
4624
|
return () => {
|
|
4057
4625
|
if (abortControllerRef.current) {
|
|
4058
4626
|
abortControllerRef.current.abort();
|
|
@@ -4434,66 +5002,10 @@ import {
|
|
|
4434
5002
|
createElement,
|
|
4435
5003
|
useCallback as useCallback10,
|
|
4436
5004
|
useContext,
|
|
4437
|
-
useEffect as
|
|
5005
|
+
useEffect as useEffect7,
|
|
4438
5006
|
useState as useState10
|
|
4439
5007
|
} from "react";
|
|
4440
5008
|
|
|
4441
|
-
// src/lib/backup/oauth/storage.ts
|
|
4442
|
-
var STORAGE_KEY_PREFIX = "oauth_token_";
|
|
4443
|
-
function getStorageKey(provider) {
|
|
4444
|
-
return `${STORAGE_KEY_PREFIX}${provider}`;
|
|
4445
|
-
}
|
|
4446
|
-
function getStoredTokenData(provider) {
|
|
4447
|
-
if (typeof window === "undefined") return null;
|
|
4448
|
-
try {
|
|
4449
|
-
const stored = localStorage.getItem(getStorageKey(provider));
|
|
4450
|
-
if (!stored) return null;
|
|
4451
|
-
const data = JSON.parse(stored);
|
|
4452
|
-
if (!data.accessToken) return null;
|
|
4453
|
-
return data;
|
|
4454
|
-
} catch {
|
|
4455
|
-
return null;
|
|
4456
|
-
}
|
|
4457
|
-
}
|
|
4458
|
-
function storeTokenData(provider, data) {
|
|
4459
|
-
if (typeof window === "undefined") return;
|
|
4460
|
-
localStorage.setItem(getStorageKey(provider), JSON.stringify(data));
|
|
4461
|
-
}
|
|
4462
|
-
function clearTokenData(provider) {
|
|
4463
|
-
if (typeof window === "undefined") return;
|
|
4464
|
-
localStorage.removeItem(getStorageKey(provider));
|
|
4465
|
-
}
|
|
4466
|
-
function isTokenExpired(data, bufferSeconds = 60) {
|
|
4467
|
-
if (!data) return true;
|
|
4468
|
-
if (!data.expiresAt) return false;
|
|
4469
|
-
const now = Date.now();
|
|
4470
|
-
const bufferMs = bufferSeconds * 1e3;
|
|
4471
|
-
return data.expiresAt - bufferMs <= now;
|
|
4472
|
-
}
|
|
4473
|
-
function getValidAccessToken(provider) {
|
|
4474
|
-
const data = getStoredTokenData(provider);
|
|
4475
|
-
if (!data) return null;
|
|
4476
|
-
if (data.expiresAt && isTokenExpired(data)) {
|
|
4477
|
-
return null;
|
|
4478
|
-
}
|
|
4479
|
-
return data.accessToken;
|
|
4480
|
-
}
|
|
4481
|
-
function getRefreshToken(provider) {
|
|
4482
|
-
const data = getStoredTokenData(provider);
|
|
4483
|
-
return data?.refreshToken ?? null;
|
|
4484
|
-
}
|
|
4485
|
-
function tokenResponseToStoredData(accessToken, expiresIn, refreshToken, scope) {
|
|
4486
|
-
const data = {
|
|
4487
|
-
accessToken,
|
|
4488
|
-
refreshToken,
|
|
4489
|
-
scope
|
|
4490
|
-
};
|
|
4491
|
-
if (expiresIn) {
|
|
4492
|
-
data.expiresAt = Date.now() + expiresIn * 1e3;
|
|
4493
|
-
}
|
|
4494
|
-
return data;
|
|
4495
|
-
}
|
|
4496
|
-
|
|
4497
5009
|
// src/lib/backup/dropbox/auth.ts
|
|
4498
5010
|
var PROVIDER = "dropbox";
|
|
4499
5011
|
var STATE_STORAGE_KEY = "dropbox_oauth_state";
|
|
@@ -4502,6 +5014,7 @@ function getRedirectUri(callbackPath) {
|
|
|
4502
5014
|
if (typeof window === "undefined") return "";
|
|
4503
5015
|
return `${window.location.origin}${callbackPath}`;
|
|
4504
5016
|
}
|
|
5017
|
+
var MAX_STATE_AGE_MS = 10 * 60 * 1e3;
|
|
4505
5018
|
function generateState() {
|
|
4506
5019
|
const array = new Uint8Array(16);
|
|
4507
5020
|
crypto.getRandomValues(array);
|
|
@@ -4511,21 +5024,48 @@ function generateState() {
|
|
|
4511
5024
|
}
|
|
4512
5025
|
function storeOAuthState(state) {
|
|
4513
5026
|
if (typeof window === "undefined") return;
|
|
4514
|
-
|
|
5027
|
+
const stateData = {
|
|
5028
|
+
state,
|
|
5029
|
+
timestamp: Date.now()
|
|
5030
|
+
};
|
|
5031
|
+
sessionStorage.setItem(STATE_STORAGE_KEY, JSON.stringify(stateData));
|
|
4515
5032
|
}
|
|
4516
5033
|
function getAndClearOAuthState() {
|
|
4517
5034
|
if (typeof window === "undefined") return null;
|
|
4518
|
-
|
|
4519
|
-
|
|
4520
|
-
|
|
5035
|
+
try {
|
|
5036
|
+
const stored = sessionStorage.getItem(STATE_STORAGE_KEY);
|
|
5037
|
+
if (!stored) return null;
|
|
5038
|
+
const stateData = JSON.parse(stored);
|
|
5039
|
+
const age = Date.now() - stateData.timestamp;
|
|
5040
|
+
if (age > MAX_STATE_AGE_MS) {
|
|
5041
|
+
sessionStorage.removeItem(STATE_STORAGE_KEY);
|
|
5042
|
+
return null;
|
|
5043
|
+
}
|
|
5044
|
+
sessionStorage.removeItem(STATE_STORAGE_KEY);
|
|
5045
|
+
return stateData.state;
|
|
5046
|
+
} catch {
|
|
5047
|
+
sessionStorage.removeItem(STATE_STORAGE_KEY);
|
|
5048
|
+
return null;
|
|
5049
|
+
}
|
|
4521
5050
|
}
|
|
4522
5051
|
function isDropboxCallback() {
|
|
4523
5052
|
if (typeof window === "undefined") return false;
|
|
4524
5053
|
const url = new URL(window.location.href);
|
|
4525
5054
|
const code = url.searchParams.get("code");
|
|
4526
5055
|
const state = url.searchParams.get("state");
|
|
4527
|
-
|
|
4528
|
-
|
|
5056
|
+
if (!code || !state) return false;
|
|
5057
|
+
try {
|
|
5058
|
+
const stored = sessionStorage.getItem(STATE_STORAGE_KEY);
|
|
5059
|
+
if (!stored) return false;
|
|
5060
|
+
const stateData = JSON.parse(stored);
|
|
5061
|
+
const age = Date.now() - stateData.timestamp;
|
|
5062
|
+
if (age > MAX_STATE_AGE_MS) {
|
|
5063
|
+
return false;
|
|
5064
|
+
}
|
|
5065
|
+
return state === stateData.state;
|
|
5066
|
+
} catch {
|
|
5067
|
+
return false;
|
|
5068
|
+
}
|
|
4529
5069
|
}
|
|
4530
5070
|
async function handleDropboxCallback(callbackPath, apiClient) {
|
|
4531
5071
|
if (typeof window === "undefined") return null;
|
|
@@ -4554,15 +5094,35 @@ async function handleDropboxCallback(callbackPath, apiClient) {
|
|
|
4554
5094
|
response.data.refresh_token,
|
|
4555
5095
|
response.data.scope
|
|
4556
5096
|
);
|
|
4557
|
-
|
|
5097
|
+
try {
|
|
5098
|
+
await storeTokenData(PROVIDER, tokenData);
|
|
5099
|
+
} catch (error) {
|
|
5100
|
+
const errorMessage = error instanceof Error ? error.message : "Unknown encryption error";
|
|
5101
|
+
console.error("OAuth token encryption failed in Dropbox callback:", errorMessage);
|
|
5102
|
+
console.warn("OAuth token encryption failed - tokens not stored securely");
|
|
5103
|
+
return null;
|
|
5104
|
+
}
|
|
4558
5105
|
window.history.replaceState({}, "", window.location.pathname);
|
|
4559
5106
|
return response.data.access_token;
|
|
4560
|
-
} catch {
|
|
5107
|
+
} catch (error) {
|
|
5108
|
+
const errorMessage = error instanceof Error ? error.message : "Unknown error";
|
|
5109
|
+
const errorName = error instanceof Error ? error.name : "Error";
|
|
5110
|
+
console.error(`Dropbox OAuth callback error: ${errorName}: ${errorMessage}`);
|
|
5111
|
+
console.error("Error details:", {
|
|
5112
|
+
name: errorName,
|
|
5113
|
+
message: errorMessage,
|
|
5114
|
+
stack: error instanceof Error ? error.stack : void 0
|
|
5115
|
+
});
|
|
5116
|
+
console.warn(`Dropbox OAuth callback failed: ${errorMessage}`);
|
|
5117
|
+
if (errorMessage.includes("encryption failed") || errorMessage.includes("OAuth token encryption")) {
|
|
5118
|
+
console.warn("OAuth callback failed due to encryption error - this is a security issue");
|
|
5119
|
+
throw error;
|
|
5120
|
+
}
|
|
4561
5121
|
return null;
|
|
4562
5122
|
}
|
|
4563
5123
|
}
|
|
4564
|
-
async function refreshDropboxToken(apiClient) {
|
|
4565
|
-
const refreshToken = getRefreshToken(PROVIDER);
|
|
5124
|
+
async function refreshDropboxToken(apiClient, walletAddress) {
|
|
5125
|
+
const refreshToken = walletAddress ? await getRefreshToken(PROVIDER, walletAddress) : getRefreshTokenSync(PROVIDER);
|
|
4566
5126
|
if (!refreshToken) return null;
|
|
4567
5127
|
try {
|
|
4568
5128
|
const response = await postAuthOauthByProviderRefresh({
|
|
@@ -4573,22 +5133,22 @@ async function refreshDropboxToken(apiClient) {
|
|
|
4573
5133
|
if (!response.data?.access_token) {
|
|
4574
5134
|
throw new Error("No access token in refresh response");
|
|
4575
5135
|
}
|
|
4576
|
-
const currentData = getStoredTokenData(PROVIDER);
|
|
5136
|
+
const currentData = walletAddress ? await getStoredTokenData(PROVIDER, walletAddress) : getStoredTokenDataSync(PROVIDER);
|
|
4577
5137
|
const tokenData = tokenResponseToStoredData(
|
|
4578
5138
|
response.data.access_token,
|
|
4579
5139
|
response.data.expires_in,
|
|
4580
5140
|
response.data.refresh_token ?? currentData?.refreshToken,
|
|
4581
5141
|
response.data.scope ?? currentData?.scope
|
|
4582
5142
|
);
|
|
4583
|
-
storeTokenData(PROVIDER, tokenData);
|
|
5143
|
+
await storeTokenData(PROVIDER, tokenData, walletAddress);
|
|
4584
5144
|
return response.data.access_token;
|
|
4585
5145
|
} catch {
|
|
4586
5146
|
clearTokenData(PROVIDER);
|
|
4587
5147
|
return null;
|
|
4588
5148
|
}
|
|
4589
5149
|
}
|
|
4590
|
-
async function revokeDropboxToken(apiClient) {
|
|
4591
|
-
const tokenData = getStoredTokenData(PROVIDER);
|
|
5150
|
+
async function revokeDropboxToken(apiClient, walletAddress) {
|
|
5151
|
+
const tokenData = walletAddress ? await getStoredTokenData(PROVIDER, walletAddress) : getStoredTokenDataSync(PROVIDER);
|
|
4592
5152
|
if (!tokenData) return;
|
|
4593
5153
|
try {
|
|
4594
5154
|
const tokenToRevoke = tokenData.refreshToken ?? tokenData.accessToken;
|
|
@@ -4602,10 +5162,10 @@ async function revokeDropboxToken(apiClient) {
|
|
|
4602
5162
|
clearTokenData(PROVIDER);
|
|
4603
5163
|
}
|
|
4604
5164
|
}
|
|
4605
|
-
async function getDropboxAccessToken(apiClient) {
|
|
4606
|
-
const validToken = getValidAccessToken(PROVIDER);
|
|
5165
|
+
async function getDropboxAccessToken(apiClient, walletAddress) {
|
|
5166
|
+
const validToken = walletAddress ? await getValidAccessToken(PROVIDER, walletAddress) : getValidAccessTokenSync(PROVIDER);
|
|
4607
5167
|
if (validToken) return validToken;
|
|
4608
|
-
return refreshDropboxToken(apiClient);
|
|
5168
|
+
return refreshDropboxToken(apiClient, walletAddress);
|
|
4609
5169
|
}
|
|
4610
5170
|
async function startDropboxAuth(appKey, callbackPath) {
|
|
4611
5171
|
const state = generateState();
|
|
@@ -4626,8 +5186,7 @@ function clearToken() {
|
|
|
4626
5186
|
clearTokenData(PROVIDER);
|
|
4627
5187
|
}
|
|
4628
5188
|
function hasDropboxCredentials() {
|
|
4629
|
-
|
|
4630
|
-
return !!(data?.accessToken || data?.refreshToken);
|
|
5189
|
+
return hasStoredCredentialsSync(PROVIDER);
|
|
4631
5190
|
}
|
|
4632
5191
|
|
|
4633
5192
|
// src/react/useDropboxAuth.ts
|
|
@@ -4640,7 +5199,7 @@ function DropboxAuthProvider({
|
|
|
4640
5199
|
}) {
|
|
4641
5200
|
const [accessToken, setAccessToken] = useState10(null);
|
|
4642
5201
|
const isConfigured = !!appKey;
|
|
4643
|
-
|
|
5202
|
+
useEffect7(() => {
|
|
4644
5203
|
const checkStoredToken = async () => {
|
|
4645
5204
|
if (hasDropboxCredentials()) {
|
|
4646
5205
|
const token = await getDropboxAccessToken(apiClient);
|
|
@@ -4651,7 +5210,7 @@ function DropboxAuthProvider({
|
|
|
4651
5210
|
};
|
|
4652
5211
|
checkStoredToken();
|
|
4653
5212
|
}, [apiClient]);
|
|
4654
|
-
|
|
5213
|
+
useEffect7(() => {
|
|
4655
5214
|
if (!isConfigured) return;
|
|
4656
5215
|
const handleCallback = async () => {
|
|
4657
5216
|
if (isDropboxCallback()) {
|
|
@@ -4808,7 +5367,7 @@ import {
|
|
|
4808
5367
|
createElement as createElement2,
|
|
4809
5368
|
useCallback as useCallback12,
|
|
4810
5369
|
useContext as useContext2,
|
|
4811
|
-
useEffect as
|
|
5370
|
+
useEffect as useEffect8,
|
|
4812
5371
|
useState as useState11
|
|
4813
5372
|
} from "react";
|
|
4814
5373
|
|
|
@@ -4824,6 +5383,7 @@ function getRedirectUri2(callbackPath) {
|
|
|
4824
5383
|
if (typeof window === "undefined") return "";
|
|
4825
5384
|
return `${window.location.origin}${callbackPath}`;
|
|
4826
5385
|
}
|
|
5386
|
+
var MAX_STATE_AGE_MS2 = 10 * 60 * 1e3;
|
|
4827
5387
|
function generateState2() {
|
|
4828
5388
|
const array = new Uint8Array(16);
|
|
4829
5389
|
crypto.getRandomValues(array);
|
|
@@ -4833,21 +5393,48 @@ function generateState2() {
|
|
|
4833
5393
|
}
|
|
4834
5394
|
function storeOAuthState2(state) {
|
|
4835
5395
|
if (typeof window === "undefined") return;
|
|
4836
|
-
|
|
5396
|
+
const stateData = {
|
|
5397
|
+
state,
|
|
5398
|
+
timestamp: Date.now()
|
|
5399
|
+
};
|
|
5400
|
+
sessionStorage.setItem(CODE_STORAGE_KEY, JSON.stringify(stateData));
|
|
4837
5401
|
}
|
|
4838
5402
|
function getAndClearOAuthState2() {
|
|
4839
5403
|
if (typeof window === "undefined") return null;
|
|
4840
|
-
|
|
4841
|
-
|
|
4842
|
-
|
|
5404
|
+
try {
|
|
5405
|
+
const stored = sessionStorage.getItem(CODE_STORAGE_KEY);
|
|
5406
|
+
if (!stored) return null;
|
|
5407
|
+
const stateData = JSON.parse(stored);
|
|
5408
|
+
const age = Date.now() - stateData.timestamp;
|
|
5409
|
+
if (age > MAX_STATE_AGE_MS2) {
|
|
5410
|
+
sessionStorage.removeItem(CODE_STORAGE_KEY);
|
|
5411
|
+
return null;
|
|
5412
|
+
}
|
|
5413
|
+
sessionStorage.removeItem(CODE_STORAGE_KEY);
|
|
5414
|
+
return stateData.state;
|
|
5415
|
+
} catch {
|
|
5416
|
+
sessionStorage.removeItem(CODE_STORAGE_KEY);
|
|
5417
|
+
return null;
|
|
5418
|
+
}
|
|
4843
5419
|
}
|
|
4844
5420
|
function isGoogleDriveCallback() {
|
|
4845
5421
|
if (typeof window === "undefined") return false;
|
|
4846
5422
|
const url = new URL(window.location.href);
|
|
4847
5423
|
const code = url.searchParams.get("code");
|
|
4848
5424
|
const state = url.searchParams.get("state");
|
|
4849
|
-
|
|
4850
|
-
|
|
5425
|
+
if (!code || !state) return false;
|
|
5426
|
+
try {
|
|
5427
|
+
const stored = sessionStorage.getItem(CODE_STORAGE_KEY);
|
|
5428
|
+
if (!stored) return false;
|
|
5429
|
+
const stateData = JSON.parse(stored);
|
|
5430
|
+
const age = Date.now() - stateData.timestamp;
|
|
5431
|
+
if (age > MAX_STATE_AGE_MS2) {
|
|
5432
|
+
return false;
|
|
5433
|
+
}
|
|
5434
|
+
return state === stateData.state;
|
|
5435
|
+
} catch {
|
|
5436
|
+
return false;
|
|
5437
|
+
}
|
|
4851
5438
|
}
|
|
4852
5439
|
async function handleGoogleDriveCallback(callbackPath, apiClient) {
|
|
4853
5440
|
if (typeof window === "undefined") return null;
|
|
@@ -4876,15 +5463,35 @@ async function handleGoogleDriveCallback(callbackPath, apiClient) {
|
|
|
4876
5463
|
response.data.refresh_token,
|
|
4877
5464
|
response.data.scope
|
|
4878
5465
|
);
|
|
4879
|
-
|
|
5466
|
+
try {
|
|
5467
|
+
await storeTokenData(PROVIDER2, tokenData);
|
|
5468
|
+
} catch (error) {
|
|
5469
|
+
const errorMessage = error instanceof Error ? error.message : "Unknown encryption error";
|
|
5470
|
+
console.error("OAuth token encryption failed in Google Drive callback:", errorMessage);
|
|
5471
|
+
console.warn("OAuth token encryption failed - tokens not stored securely");
|
|
5472
|
+
return null;
|
|
5473
|
+
}
|
|
4880
5474
|
window.history.replaceState({}, "", window.location.pathname);
|
|
4881
5475
|
return response.data.access_token;
|
|
4882
|
-
} catch {
|
|
5476
|
+
} catch (error) {
|
|
5477
|
+
const errorMessage = error instanceof Error ? error.message : "Unknown error";
|
|
5478
|
+
const errorName = error instanceof Error ? error.name : "Error";
|
|
5479
|
+
console.error(`Google Drive OAuth callback error: ${errorName}: ${errorMessage}`);
|
|
5480
|
+
console.error("Error details:", {
|
|
5481
|
+
name: errorName,
|
|
5482
|
+
message: errorMessage,
|
|
5483
|
+
stack: error instanceof Error ? error.stack : void 0
|
|
5484
|
+
});
|
|
5485
|
+
console.warn(`Google Drive OAuth callback failed: ${errorMessage}`);
|
|
5486
|
+
if (errorMessage.includes("encryption failed") || errorMessage.includes("OAuth token encryption")) {
|
|
5487
|
+
console.warn("OAuth callback failed due to encryption error - this is a security issue");
|
|
5488
|
+
throw error;
|
|
5489
|
+
}
|
|
4883
5490
|
return null;
|
|
4884
5491
|
}
|
|
4885
5492
|
}
|
|
4886
|
-
async function refreshGoogleDriveToken(apiClient) {
|
|
4887
|
-
const refreshToken = getRefreshToken(PROVIDER2);
|
|
5493
|
+
async function refreshGoogleDriveToken(apiClient, walletAddress) {
|
|
5494
|
+
const refreshToken = walletAddress ? await getRefreshToken(PROVIDER2, walletAddress) : getRefreshTokenSync(PROVIDER2);
|
|
4888
5495
|
if (!refreshToken) return null;
|
|
4889
5496
|
try {
|
|
4890
5497
|
const response = await postAuthOauthByProviderRefresh({
|
|
@@ -4895,22 +5502,22 @@ async function refreshGoogleDriveToken(apiClient) {
|
|
|
4895
5502
|
if (!response.data?.access_token) {
|
|
4896
5503
|
throw new Error("No access token in refresh response");
|
|
4897
5504
|
}
|
|
4898
|
-
const currentData = getStoredTokenData(PROVIDER2);
|
|
5505
|
+
const currentData = walletAddress ? await getStoredTokenData(PROVIDER2, walletAddress) : getStoredTokenDataSync(PROVIDER2);
|
|
4899
5506
|
const tokenData = tokenResponseToStoredData(
|
|
4900
5507
|
response.data.access_token,
|
|
4901
5508
|
response.data.expires_in,
|
|
4902
5509
|
response.data.refresh_token ?? currentData?.refreshToken,
|
|
4903
5510
|
response.data.scope ?? currentData?.scope
|
|
4904
5511
|
);
|
|
4905
|
-
storeTokenData(PROVIDER2, tokenData);
|
|
5512
|
+
await storeTokenData(PROVIDER2, tokenData, walletAddress);
|
|
4906
5513
|
return response.data.access_token;
|
|
4907
5514
|
} catch {
|
|
4908
5515
|
clearTokenData(PROVIDER2);
|
|
4909
5516
|
return null;
|
|
4910
5517
|
}
|
|
4911
5518
|
}
|
|
4912
|
-
async function revokeGoogleDriveToken(apiClient) {
|
|
4913
|
-
const tokenData = getStoredTokenData(PROVIDER2);
|
|
5519
|
+
async function revokeGoogleDriveToken(apiClient, walletAddress) {
|
|
5520
|
+
const tokenData = walletAddress ? await getStoredTokenData(PROVIDER2, walletAddress) : getStoredTokenDataSync(PROVIDER2);
|
|
4914
5521
|
if (!tokenData) return;
|
|
4915
5522
|
try {
|
|
4916
5523
|
const tokenToRevoke = tokenData.refreshToken ?? tokenData.accessToken;
|
|
@@ -4924,8 +5531,8 @@ async function revokeGoogleDriveToken(apiClient) {
|
|
|
4924
5531
|
clearTokenData(PROVIDER2);
|
|
4925
5532
|
}
|
|
4926
5533
|
}
|
|
4927
|
-
async function getGoogleDriveAccessToken(apiClient) {
|
|
4928
|
-
const storedData = getStoredTokenData(PROVIDER2);
|
|
5534
|
+
async function getGoogleDriveAccessToken(apiClient, walletAddress) {
|
|
5535
|
+
const storedData = walletAddress ? await getStoredTokenData(PROVIDER2, walletAddress) : getStoredTokenDataSync(PROVIDER2);
|
|
4929
5536
|
if (!storedData) {
|
|
4930
5537
|
return null;
|
|
4931
5538
|
}
|
|
@@ -4933,7 +5540,7 @@ async function getGoogleDriveAccessToken(apiClient) {
|
|
|
4933
5540
|
return storedData.accessToken;
|
|
4934
5541
|
}
|
|
4935
5542
|
if (storedData.refreshToken) {
|
|
4936
|
-
const refreshedToken = await refreshGoogleDriveToken(apiClient);
|
|
5543
|
+
const refreshedToken = await refreshGoogleDriveToken(apiClient, walletAddress);
|
|
4937
5544
|
if (refreshedToken) {
|
|
4938
5545
|
return refreshedToken;
|
|
4939
5546
|
}
|
|
@@ -4962,14 +5569,13 @@ async function startGoogleDriveAuth(clientId, callbackPath) {
|
|
|
4962
5569
|
});
|
|
4963
5570
|
}
|
|
4964
5571
|
function getGoogleDriveStoredToken() {
|
|
4965
|
-
return
|
|
5572
|
+
return getValidAccessTokenSync(PROVIDER2);
|
|
4966
5573
|
}
|
|
4967
5574
|
function clearGoogleDriveToken() {
|
|
4968
5575
|
clearTokenData(PROVIDER2);
|
|
4969
5576
|
}
|
|
4970
5577
|
function hasGoogleDriveCredentials() {
|
|
4971
|
-
|
|
4972
|
-
return !!(data?.accessToken || data?.refreshToken);
|
|
5578
|
+
return hasStoredCredentialsSync(PROVIDER2);
|
|
4973
5579
|
}
|
|
4974
5580
|
|
|
4975
5581
|
// src/react/useGoogleDriveAuth.ts
|
|
@@ -4982,7 +5588,7 @@ function GoogleDriveAuthProvider({
|
|
|
4982
5588
|
}) {
|
|
4983
5589
|
const [accessToken, setAccessToken] = useState11(null);
|
|
4984
5590
|
const isConfigured = !!clientId;
|
|
4985
|
-
|
|
5591
|
+
useEffect8(() => {
|
|
4986
5592
|
const checkStoredToken = async () => {
|
|
4987
5593
|
if (hasGoogleDriveCredentials()) {
|
|
4988
5594
|
const token = await getGoogleDriveAccessToken(apiClient);
|
|
@@ -4993,7 +5599,7 @@ function GoogleDriveAuthProvider({
|
|
|
4993
5599
|
};
|
|
4994
5600
|
checkStoredToken();
|
|
4995
5601
|
}, [apiClient]);
|
|
4996
|
-
|
|
5602
|
+
useEffect8(() => {
|
|
4997
5603
|
if (!isConfigured) return;
|
|
4998
5604
|
const handleCallback = async () => {
|
|
4999
5605
|
if (isGoogleDriveCallback()) {
|
|
@@ -5458,7 +6064,7 @@ import {
|
|
|
5458
6064
|
createElement as createElement3,
|
|
5459
6065
|
useCallback as useCallback14,
|
|
5460
6066
|
useContext as useContext3,
|
|
5461
|
-
useEffect as
|
|
6067
|
+
useEffect as useEffect9,
|
|
5462
6068
|
useState as useState12
|
|
5463
6069
|
} from "react";
|
|
5464
6070
|
|
|
@@ -5708,7 +6314,7 @@ function ICloudAuthProvider({
|
|
|
5708
6314
|
const [isAvailable, setIsAvailable] = useState12(false);
|
|
5709
6315
|
const [isConfigured, setIsConfigured] = useState12(false);
|
|
5710
6316
|
const [isLoading, setIsLoading] = useState12(false);
|
|
5711
|
-
|
|
6317
|
+
useEffect9(() => {
|
|
5712
6318
|
if (!apiToken || typeof window === "undefined") {
|
|
5713
6319
|
return;
|
|
5714
6320
|
}
|
|
@@ -6024,7 +6630,7 @@ import {
|
|
|
6024
6630
|
createElement as createElement4,
|
|
6025
6631
|
useCallback as useCallback16,
|
|
6026
6632
|
useContext as useContext4,
|
|
6027
|
-
useEffect as
|
|
6633
|
+
useEffect as useEffect10,
|
|
6028
6634
|
useState as useState13
|
|
6029
6635
|
} from "react";
|
|
6030
6636
|
var BackupAuthContext = createContext4(null);
|
|
@@ -6047,7 +6653,7 @@ function BackupAuthProvider({
|
|
|
6047
6653
|
const [icloudUserRecordName, setIcloudUserRecordName] = useState13(null);
|
|
6048
6654
|
const [isIcloudAvailable, setIsIcloudAvailable] = useState13(false);
|
|
6049
6655
|
const isIcloudConfigured = isIcloudAvailable && !!icloudApiToken;
|
|
6050
|
-
|
|
6656
|
+
useEffect10(() => {
|
|
6051
6657
|
const checkStoredTokens = async () => {
|
|
6052
6658
|
if (hasDropboxCredentials()) {
|
|
6053
6659
|
const token = await getDropboxAccessToken(apiClient);
|
|
@@ -6064,7 +6670,7 @@ function BackupAuthProvider({
|
|
|
6064
6670
|
};
|
|
6065
6671
|
checkStoredTokens();
|
|
6066
6672
|
}, [apiClient]);
|
|
6067
|
-
|
|
6673
|
+
useEffect10(() => {
|
|
6068
6674
|
if (!icloudApiToken || typeof window === "undefined") {
|
|
6069
6675
|
return;
|
|
6070
6676
|
}
|
|
@@ -6092,7 +6698,7 @@ function BackupAuthProvider({
|
|
|
6092
6698
|
};
|
|
6093
6699
|
initCloudKit();
|
|
6094
6700
|
}, [icloudApiToken, icloudContainerIdentifier, icloudEnvironment]);
|
|
6095
|
-
|
|
6701
|
+
useEffect10(() => {
|
|
6096
6702
|
if (!isDropboxConfigured) return;
|
|
6097
6703
|
const handleCallback = async () => {
|
|
6098
6704
|
if (isDropboxCallback()) {
|
|
@@ -6107,7 +6713,7 @@ function BackupAuthProvider({
|
|
|
6107
6713
|
};
|
|
6108
6714
|
handleCallback();
|
|
6109
6715
|
}, [dropboxCallbackPath, isDropboxConfigured, apiClient]);
|
|
6110
|
-
|
|
6716
|
+
useEffect10(() => {
|
|
6111
6717
|
if (!isGoogleConfigured) return;
|
|
6112
6718
|
const handleCallback = async () => {
|
|
6113
6719
|
if (isGoogleDriveCallback()) {
|
|
@@ -6529,6 +7135,7 @@ export {
|
|
|
6529
7135
|
BackupAuthProvider,
|
|
6530
7136
|
Conversation as ChatConversation,
|
|
6531
7137
|
Message as ChatMessage,
|
|
7138
|
+
DECRYPTION_FAILED_PLACEHOLDER,
|
|
6532
7139
|
DEFAULT_BACKUP_FOLDER,
|
|
6533
7140
|
DEFAULT_CONVERSATIONS_FOLDER as DEFAULT_DRIVE_CONVERSATIONS_FOLDER,
|
|
6534
7141
|
DEFAULT_ROOT_FOLDER as DEFAULT_DRIVE_ROOT_FOLDER,
|
|
@@ -6542,26 +7149,41 @@ export {
|
|
|
6542
7149
|
chatStorageMigrations,
|
|
6543
7150
|
chatStorageSchema,
|
|
6544
7151
|
clearAllEncryptionKeys,
|
|
7152
|
+
clearAllKeyPairs,
|
|
6545
7153
|
clearToken as clearDropboxToken,
|
|
6546
7154
|
clearEncryptionKey,
|
|
6547
7155
|
clearGoogleDriveToken,
|
|
6548
7156
|
clearICloudAuth,
|
|
7157
|
+
clearKeyPair,
|
|
6549
7158
|
createMemoryContextSystemMessage,
|
|
6550
7159
|
decryptData,
|
|
6551
7160
|
decryptDataBytes,
|
|
7161
|
+
decryptField,
|
|
7162
|
+
decryptMemoriesBatch,
|
|
7163
|
+
decryptMemoryFields,
|
|
6552
7164
|
encryptData,
|
|
7165
|
+
encryptField,
|
|
7166
|
+
encryptMemoriesBatch,
|
|
7167
|
+
encryptMemoriesBatchInPlace,
|
|
7168
|
+
encryptMemoryFields,
|
|
7169
|
+
exportPublicKey,
|
|
6553
7170
|
extractConversationContext,
|
|
6554
7171
|
formatMemoriesForChat,
|
|
6555
7172
|
generateCompositeKey,
|
|
6556
7173
|
generateConversationId,
|
|
6557
7174
|
generateUniqueKey,
|
|
7175
|
+
getEncryptionVersion2 as getEncryptionVersion,
|
|
6558
7176
|
getGoogleDriveStoredToken,
|
|
6559
7177
|
hasDropboxCredentials,
|
|
7178
|
+
hasEncryptedFields,
|
|
6560
7179
|
hasEncryptionKey,
|
|
6561
7180
|
hasGoogleDriveCredentials,
|
|
6562
7181
|
hasICloudCredentials,
|
|
7182
|
+
hasKeyPair,
|
|
6563
7183
|
memoryStorageSchema,
|
|
7184
|
+
needsEncryption,
|
|
6564
7185
|
requestEncryptionKey,
|
|
7186
|
+
requestKeyPair,
|
|
6565
7187
|
sdkMigrations,
|
|
6566
7188
|
sdkModelClasses,
|
|
6567
7189
|
sdkSchema,
|