@anuma/sdk 6.31.0 → 6.31.2

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.
@@ -23828,14 +23828,14 @@ async function autoFilterClientTools(clientTools, promptEmbeddings, cache, embed
23828
23828
  const alwaysInclude = clientTools.filter(isAlwaysIncluded);
23829
23829
  const filterCandidates = clientTools.filter((t) => !isAlwaysIncluded(t));
23830
23830
  if (filterCandidates.length === 0) {
23831
- return { tools: clientTools, activatedSetNames: /* @__PURE__ */ new Set() };
23831
+ return { tools: clientTools, activatedSetNames: /* @__PURE__ */ new Set(), matchedSetNames: /* @__PURE__ */ new Set() };
23832
23832
  }
23833
23833
  if (!promptEmbeddings && noEmbeddingsReason === "error") {
23834
- return { tools: clientTools, activatedSetNames: /* @__PURE__ */ new Set() };
23834
+ return { tools: clientTools, activatedSetNames: /* @__PURE__ */ new Set(), matchedSetNames: /* @__PURE__ */ new Set() };
23835
23835
  }
23836
23836
  if (!promptEmbeddings) {
23837
23837
  if (activeToolSets.length === 0) {
23838
- return { tools: [], activatedSetNames: /* @__PURE__ */ new Set() };
23838
+ return { tools: [], activatedSetNames: /* @__PURE__ */ new Set(), matchedSetNames: /* @__PURE__ */ new Set() };
23839
23839
  }
23840
23840
  const allSets = extraToolSets.length > 0 ? [...BUILT_IN_TOOL_SETS, ...extraToolSets] : BUILT_IN_TOOL_SETS;
23841
23841
  const activeSets = allSets.filter((s) => activeToolSets.includes(s.name));
@@ -23845,7 +23845,8 @@ async function autoFilterClientTools(clientTools, promptEmbeddings, cache, embed
23845
23845
  ...alwaysInclude,
23846
23846
  ...filterCandidates.filter((t) => stickyMembers.has(getToolName2(t)))
23847
23847
  ],
23848
- activatedSetNames: new Set(activeSets.map((s) => s.name))
23848
+ activatedSetNames: new Set(activeSets.map((s) => s.name)),
23849
+ matchedSetNames: /* @__PURE__ */ new Set()
23849
23850
  };
23850
23851
  }
23851
23852
  const toolsNeedingEmbeddings = [];
@@ -23863,7 +23864,7 @@ async function autoFilterClientTools(clientTools, promptEmbeddings, cache, embed
23863
23864
  cache.set(toolsNeedingEmbeddings[i].name, embeddings[i]);
23864
23865
  }
23865
23866
  } catch {
23866
- return { tools: clientTools, activatedSetNames: /* @__PURE__ */ new Set() };
23867
+ return { tools: clientTools, activatedSetNames: /* @__PURE__ */ new Set(), matchedSetNames: /* @__PURE__ */ new Set() };
23867
23868
  }
23868
23869
  }
23869
23870
  const pseudoServerTools = [];
@@ -23909,15 +23910,170 @@ async function autoFilterClientTools(clientTools, promptEmbeddings, cache, embed
23909
23910
  activeSetNames
23910
23911
  );
23911
23912
  const activatedSetNames = activatedToolSetNames(scores, toolSets, activeSetNames);
23913
+ const matchedSetNames = activatedToolSetNames(scores, toolSets);
23912
23914
  if (finalNames.size === 0) {
23913
- return { tools: alwaysInclude, activatedSetNames };
23915
+ return { tools: alwaysInclude, activatedSetNames, matchedSetNames };
23914
23916
  }
23915
23917
  const filtered = filterCandidates.filter((t) => {
23916
23918
  const name = getToolName2(t);
23917
23919
  return name && finalNames.has(name);
23918
23920
  });
23919
- return { tools: [...alwaysInclude, ...filtered], activatedSetNames };
23921
+ return { tools: [...alwaysInclude, ...filtered], activatedSetNames, matchedSetNames };
23922
+ }
23923
+
23924
+ // src/lib/tools/toolCatalog.ts
23925
+ var TOOL_CATALOG = {
23926
+ // Gmail (src/tools/gmail.ts)
23927
+ gmail_search_messages: { label: "Search emails", provider: "gmail", connector: "Gmail" },
23928
+ gmail_get_message: { label: "Read an email", provider: "gmail", connector: "Gmail" },
23929
+ gmail_create_draft: { label: "Draft a reply", provider: "gmail", connector: "Gmail" },
23930
+ gmail_send_message: { label: "Send an email", provider: "gmail", connector: "Gmail" },
23931
+ // Google Calendar (src/tools/googleCalendar.ts)
23932
+ google_calendar_list_events: {
23933
+ label: "Search calendar events",
23934
+ provider: "gcalendar",
23935
+ connector: "Calendar"
23936
+ },
23937
+ google_calendar_create_event: {
23938
+ label: "Create calendar event",
23939
+ provider: "gcalendar",
23940
+ connector: "Calendar"
23941
+ },
23942
+ google_calendar_update_event: {
23943
+ label: "Update calendar event",
23944
+ provider: "gcalendar",
23945
+ connector: "Calendar"
23946
+ },
23947
+ // Google Drive (src/tools/googleDrive.ts)
23948
+ google_drive_search: { label: "Search files", provider: "gdrive", connector: "Drive" },
23949
+ google_drive_list_recent: { label: "List recent files", provider: "gdrive", connector: "Drive" },
23950
+ google_drive_get_content: { label: "Read file content", provider: "gdrive", connector: "Drive" },
23951
+ google_drive_create_file: {
23952
+ label: "Create a file in Drive",
23953
+ provider: "gdrive",
23954
+ connector: "Drive"
23955
+ },
23956
+ google_drive_update_file: {
23957
+ label: "Update a Drive file",
23958
+ provider: "gdrive",
23959
+ connector: "Drive"
23960
+ },
23961
+ // Notion (src/tools/notion.ts)
23962
+ "notion-search": { label: "Search", provider: "notion", connector: "Notion" },
23963
+ "notion-fetch": { label: "Read page", provider: "notion", connector: "Notion" },
23964
+ "notion-create-pages": { label: "Create page", provider: "notion", connector: "Notion" },
23965
+ "notion-update-page": { label: "Update page", provider: "notion", connector: "Notion" },
23966
+ "notion-move-pages": { label: "Move pages", provider: "notion", connector: "Notion" },
23967
+ "notion-duplicate-page": { label: "Duplicate page", provider: "notion", connector: "Notion" },
23968
+ "notion-create-database": { label: "Create database", provider: "notion", connector: "Notion" },
23969
+ "notion-update-data-source": {
23970
+ label: "Update data source",
23971
+ provider: "notion",
23972
+ connector: "Notion"
23973
+ },
23974
+ "notion-create-comment": { label: "Add a comment", provider: "notion", connector: "Notion" },
23975
+ "notion-get-comments": { label: "Read comments", provider: "notion", connector: "Notion" },
23976
+ "notion-get-users": {
23977
+ label: "List workspace members",
23978
+ provider: "notion",
23979
+ connector: "Notion"
23980
+ },
23981
+ "notion-get-teams": { label: "List teamspaces", provider: "notion", connector: "Notion" },
23982
+ // GitHub (src/tools/github.ts)
23983
+ github_api: { label: "Use GitHub", provider: "github", connector: "GitHub" },
23984
+ github_get_authenticated_user: {
23985
+ label: "Read GitHub profile",
23986
+ provider: "github",
23987
+ connector: "GitHub"
23988
+ },
23989
+ // X / Twitter (src/tools/x.ts)
23990
+ x_get_me: { label: "Get my X profile", provider: "x", connector: "X" },
23991
+ x_get_my_posts: { label: "Read my recent posts", provider: "x", connector: "X" },
23992
+ // Dropbox (src/tools/dropbox.ts)
23993
+ dropbox_list_folders: { label: "List files", provider: "dropbox", connector: "Dropbox" },
23994
+ dropbox_get_file_content: {
23995
+ label: "Read file content",
23996
+ provider: "dropbox",
23997
+ connector: "Dropbox"
23998
+ },
23999
+ dropbox_search: { label: "Search files", provider: "dropbox", connector: "Dropbox" },
24000
+ // Slack (src/tools/slack.ts)
24001
+ slack_get_me: { label: "Get my Slack profile", provider: "slack", connector: "Slack" },
24002
+ slack_list_channels: { label: "List channels", provider: "slack", connector: "Slack" },
24003
+ slack_list_dms: { label: "List direct messages", provider: "slack", connector: "Slack" },
24004
+ slack_search_messages: { label: "Search messages", provider: "slack", connector: "Slack" },
24005
+ slack_list_users: { label: "List members", provider: "slack", connector: "Slack" },
24006
+ slack_get_channel_history: {
24007
+ label: "Read channel history",
24008
+ provider: "slack",
24009
+ connector: "Slack"
24010
+ },
24011
+ slack_get_thread_replies: {
24012
+ label: "Read thread replies",
24013
+ provider: "slack",
24014
+ connector: "Slack"
24015
+ },
24016
+ slack_post_message: { label: "Post a message", provider: "slack", connector: "Slack" }
24017
+ };
24018
+
24019
+ // src/lib/tools/selection/activeToolSets.ts
24020
+ function mergeActiveToolSets(current, derived) {
24021
+ if (derived.length === 0) return current;
24022
+ const merged = Array.from(/* @__PURE__ */ new Set([...current, ...derived]));
24023
+ return merged.length === current.length ? current : merged;
24024
+ }
24025
+
24026
+ // src/lib/tools/selection/recentToolSets.ts
24027
+ var RECENT_TOOL_SET_TURNS = 2;
24028
+ var RECENT_TOOL_SET_CONVERSATION_LIMIT = 50;
24029
+ var CARRYABLE_TOOL_SETS = new Set(
24030
+ BUILT_IN_TOOL_SETS.filter(
24031
+ (s) => s.anchors.length > 0 && s.anchors.every((a) => a in TOOL_CATALOG)
24032
+ ).map((s) => s.name)
24033
+ );
24034
+ var recentToolSets = /* @__PURE__ */ new WeakMap();
24035
+ function touch(conversations, conversationId) {
24036
+ const turns = conversations.get(conversationId);
24037
+ if (!turns) return void 0;
24038
+ conversations.delete(conversationId);
24039
+ conversations.set(conversationId, turns);
24040
+ return turns;
24041
+ }
24042
+ function carriedToolSets(database, conversationId) {
24043
+ if (!conversationId) return [];
24044
+ const conversations = recentToolSets.get(database);
24045
+ if (!conversations) return [];
24046
+ return [...touch(conversations, conversationId)?.keys() ?? []];
24047
+ }
24048
+ function recordToolSetTurn(database, conversationId, matched) {
24049
+ if (!conversationId) return;
24050
+ let conversations = recentToolSets.get(database);
24051
+ if (!conversations) {
24052
+ conversations = /* @__PURE__ */ new Map();
24053
+ recentToolSets.set(database, conversations);
24054
+ }
24055
+ const turns = touch(conversations, conversationId) ?? /* @__PURE__ */ new Map();
24056
+ for (const [name, left] of turns) {
24057
+ if (left > 1) turns.set(name, left - 1);
24058
+ else turns.delete(name);
24059
+ }
24060
+ for (const name of matched) {
24061
+ if (CARRYABLE_TOOL_SETS.has(name)) turns.set(name, RECENT_TOOL_SET_TURNS);
24062
+ }
24063
+ if (turns.size === 0) {
24064
+ conversations.delete(conversationId);
24065
+ return;
24066
+ }
24067
+ conversations.set(conversationId, turns);
24068
+ if (conversations.size > RECENT_TOOL_SET_CONVERSATION_LIMIT) {
24069
+ const oldest = conversations.keys().next().value;
24070
+ if (oldest !== void 0) conversations.delete(oldest);
24071
+ }
24072
+ }
24073
+ function resetRecentToolSets() {
24074
+ recentToolSets = /* @__PURE__ */ new WeakMap();
23920
24075
  }
24076
+ onClearAllEncryptionState(resetRecentToolSets);
23921
24077
 
23922
24078
  // src/react/useChatMedia.ts
23923
24079
  var import_react4 = require("react");
@@ -25350,6 +25506,8 @@ function useChatStorage(options) {
25350
25506
  }
25351
25507
  let filteredClientTools2 = clientTools;
25352
25508
  let clientActivatedSetNames2;
25509
+ let matchedToolSets2 = /* @__PURE__ */ new Set();
25510
+ const toolSetConversationId = explicitConversationId ?? currentConversationId;
25353
25511
  if (clientToolsFilter && clientTools?.length) {
25354
25512
  if (!skipStorageEmbeddingsFailed) {
25355
25513
  const clientToolNames = clientToolsFilter(skipStorageEmbeddings, clientTools);
@@ -25366,11 +25524,15 @@ function useChatStorage(options) {
25366
25524
  clientToolEmbeddingsCacheRef.current,
25367
25525
  { getToken, baseUrl, model: embeddingModel },
25368
25526
  extraToolSets,
25369
- activeToolSetsRef.current,
25527
+ mergeActiveToolSets(
25528
+ activeToolSetsRef.current ?? [],
25529
+ carriedToolSets(database, toolSetConversationId)
25530
+ ),
25370
25531
  skipStorageEmbeddingsFailed ? "error" : "short-prompt"
25371
25532
  );
25372
25533
  filteredClientTools2 = clientFilterResult.tools;
25373
25534
  clientActivatedSetNames2 = clientFilterResult.activatedSetNames;
25535
+ matchedToolSets2 = clientFilterResult.matchedSetNames;
25374
25536
  }
25375
25537
  if (filteredServerTools2.length > 0 || filteredClientTools2 && filteredClientTools2.length > 0) {
25376
25538
  mergedTools2 = mergeTools(
@@ -25425,6 +25587,7 @@ function useChatStorage(options) {
25425
25587
  error: result2.error || "Unknown error"
25426
25588
  };
25427
25589
  }
25590
+ recordToolSetTurn(database, toolSetConversationId, matchedToolSets2);
25428
25591
  const refreshResponse = result2.data;
25429
25592
  if (getToken) {
25430
25593
  Promise.resolve().then(
@@ -25805,6 +25968,7 @@ function useChatStorage(options) {
25805
25968
  }
25806
25969
  let filteredClientTools = clientTools;
25807
25970
  let clientActivatedSetNames;
25971
+ let matchedToolSets = /* @__PURE__ */ new Set();
25808
25972
  if (clientToolsFilter && clientTools?.length) {
25809
25973
  if (!userMessageEmbeddingsFailed) {
25810
25974
  const clientToolNames = clientToolsFilter(userMessageEmbeddings ?? null, clientTools);
@@ -25821,11 +25985,12 @@ function useChatStorage(options) {
25821
25985
  clientToolEmbeddingsCacheRef.current,
25822
25986
  { getToken, baseUrl, model: embeddingModel },
25823
25987
  extraToolSets,
25824
- activeToolSetsRef.current,
25988
+ mergeActiveToolSets(activeToolSetsRef.current ?? [], carriedToolSets(database, convId)),
25825
25989
  userMessageEmbeddingsFailed ? "error" : "short-prompt"
25826
25990
  );
25827
25991
  filteredClientTools = clientFilterResult.tools;
25828
25992
  clientActivatedSetNames = clientFilterResult.activatedSetNames;
25993
+ matchedToolSets = clientFilterResult.matchedSetNames;
25829
25994
  }
25830
25995
  if (!userMsgQueueId) {
25831
25996
  if (userMessageEmbeddings && autoEmbedMessages) {
@@ -25950,6 +26115,7 @@ function useChatStorage(options) {
25950
26115
  ],
25951
26116
  usage: void 0
25952
26117
  };
26118
+ recordToolSetTurn(database, convId, matchedToolSets);
25953
26119
  return {
25954
26120
  data: responseData2,
25955
26121
  error: null,
@@ -25987,6 +26153,7 @@ function useChatStorage(options) {
25987
26153
  userMessage: { ...storedUserMessage, error: errorMessage }
25988
26154
  };
25989
26155
  }
26156
+ recordToolSetTurn(database, convId, matchedToolSets);
25990
26157
  const responseData = result.data;
25991
26158
  let assistantContent = "";
25992
26159
  let thinkingContent;
@@ -31373,79 +31540,159 @@ var import_react19 = require("react");
31373
31540
  // src/lib/backup/dropbox/auth.ts
31374
31541
  init_logger();
31375
31542
 
31543
+ // src/lib/auth/tokenRows.ts
31544
+ var ENCRYPTED_PREFIX = "enc:oauth:";
31545
+ function parsePlaintextToken(raw, walletAddress) {
31546
+ let parsed;
31547
+ try {
31548
+ parsed = JSON.parse(raw);
31549
+ } catch {
31550
+ return null;
31551
+ }
31552
+ if (!parsed || typeof parsed !== "object") return null;
31553
+ const record = parsed;
31554
+ const data = record.token?.accessToken ? record.token : record;
31555
+ if (!data?.accessToken) return null;
31556
+ if (record.wallet && record.wallet !== walletAddress) return null;
31557
+ return data;
31558
+ }
31559
+ function promoteUnscopedRow(raw, data, store, scopedKey, unscopedKey, walletAddress) {
31560
+ const row = raw.startsWith(ENCRYPTED_PREFIX) ? raw : JSON.stringify({ wallet: walletAddress, token: data });
31561
+ if (!store.getItem(scopedKey)) {
31562
+ store.setItem(scopedKey, row);
31563
+ }
31564
+ store.removeItem(unscopedKey);
31565
+ }
31566
+ function readPlaintextToken(scopedKey, unscopedKey, walletAddress) {
31567
+ if (typeof window === "undefined") return null;
31568
+ const keys = scopedKey === unscopedKey ? [scopedKey] : [scopedKey, unscopedKey];
31569
+ for (const key of keys) {
31570
+ const candidates = [
31571
+ [localStorage.getItem(key), localStorage],
31572
+ [sessionStorage.getItem(key), sessionStorage]
31573
+ ];
31574
+ for (const [raw, store] of candidates) {
31575
+ if (!raw) continue;
31576
+ const data = parsePlaintextToken(raw, walletAddress);
31577
+ if (!data) continue;
31578
+ if (walletAddress && key === unscopedKey) {
31579
+ promoteUnscopedRow(raw, data, store, scopedKey, unscopedKey, walletAddress);
31580
+ }
31581
+ return data;
31582
+ }
31583
+ }
31584
+ return null;
31585
+ }
31586
+
31376
31587
  // src/lib/backup/oauth/storage.ts
31377
31588
  init_logger();
31378
31589
  var STORAGE_KEY_PREFIX = "oauth_token_";
31379
- var ENCRYPTED_PREFIX = "enc:oauth:";
31380
- function getStorageKey(provider) {
31381
- return `${STORAGE_KEY_PREFIX}${provider}`;
31590
+ var ENCRYPTED_PREFIX2 = "enc:oauth:";
31591
+ function getStorageKey(provider, walletAddress) {
31592
+ const base = `${STORAGE_KEY_PREFIX}${provider}`;
31593
+ return walletAddress ? `${base}:${walletAddress}` : base;
31594
+ }
31595
+ function readRawRows(keys) {
31596
+ const rows = [];
31597
+ for (const key of keys) {
31598
+ for (const store of [localStorage, sessionStorage]) {
31599
+ const raw = store.getItem(key);
31600
+ if (raw) rows.push({ raw, key, store });
31601
+ }
31602
+ }
31603
+ return rows;
31382
31604
  }
31383
31605
  async function getStoredTokenData(provider, walletAddress) {
31384
31606
  if (typeof window === "undefined") return null;
31385
31607
  try {
31386
- const key = getStorageKey(provider);
31387
- let stored = localStorage.getItem(key);
31388
- if (!stored) {
31389
- stored = sessionStorage.getItem(key);
31390
- }
31391
- if (!stored) return null;
31392
- if (stored.startsWith(ENCRYPTED_PREFIX)) {
31393
- if (!walletAddress) {
31394
- getLogger().warn(
31395
- `Encrypted OAuth token found for ${provider} but no wallet address provided`
31396
- );
31397
- return null;
31398
- }
31399
- try {
31400
- const encryptedData = stored.slice(ENCRYPTED_PREFIX.length);
31401
- let decryptedJson;
31402
- try {
31403
- decryptedJson = await decryptData(encryptedData, walletAddress);
31404
- } catch {
31405
- decryptedJson = await decryptData(encryptedData, walletAddress, "v2");
31406
- }
31407
- const data2 = JSON.parse(decryptedJson);
31408
- if (!data2.accessToken) return null;
31409
- return data2;
31410
- } catch (error) {
31411
- getLogger().error(`Failed to decrypt OAuth token for ${provider}:`, error);
31412
- return null;
31608
+ const scopedKey = getStorageKey(provider, walletAddress);
31609
+ const legacyKey = getStorageKey(provider);
31610
+ const keys = scopedKey === legacyKey ? [legacyKey] : [scopedKey, legacyKey];
31611
+ for (const row of readRawRows(keys)) {
31612
+ const data = await readTokenRow(row.raw, provider, walletAddress);
31613
+ if (!data) continue;
31614
+ if (walletAddress && row.key === legacyKey) {
31615
+ promoteUnscopedRow(row.raw, data, row.store, scopedKey, legacyKey, walletAddress);
31413
31616
  }
31617
+ return data;
31414
31618
  }
31415
- const data = JSON.parse(stored);
31416
- if (!data.accessToken) return null;
31417
- return data;
31619
+ return null;
31418
31620
  } catch {
31419
31621
  return null;
31420
31622
  }
31421
31623
  }
31624
+ async function readTokenRow(stored, provider, walletAddress) {
31625
+ if (stored.startsWith(ENCRYPTED_PREFIX2)) {
31626
+ if (!walletAddress) {
31627
+ getLogger().warn(
31628
+ `Encrypted OAuth token found for ${provider} but no wallet address provided`
31629
+ );
31630
+ return null;
31631
+ }
31632
+ try {
31633
+ const encryptedData = stored.slice(ENCRYPTED_PREFIX2.length);
31634
+ let decryptedJson;
31635
+ try {
31636
+ decryptedJson = await decryptData(encryptedData, walletAddress);
31637
+ } catch {
31638
+ decryptedJson = await decryptData(encryptedData, walletAddress, "v2");
31639
+ }
31640
+ const data = JSON.parse(decryptedJson);
31641
+ if (!data.accessToken) return null;
31642
+ return data;
31643
+ } catch (error) {
31644
+ getLogger().error(`Failed to decrypt OAuth token for ${provider}:`, error);
31645
+ return null;
31646
+ }
31647
+ }
31648
+ return parsePlaintextToken(stored, walletAddress);
31649
+ }
31422
31650
  async function storeTokenData(provider, data, walletAddress) {
31423
31651
  if (typeof window === "undefined") return;
31424
- const key = getStorageKey(provider);
31652
+ const key = getStorageKey(provider, walletAddress);
31425
31653
  const json4 = JSON.stringify(data);
31654
+ const plaintextRecord = JSON.stringify({
31655
+ wallet: walletAddress,
31656
+ token: data
31657
+ });
31426
31658
  if (walletAddress) {
31427
31659
  try {
31428
31660
  const encrypted = await encryptData(json4, walletAddress);
31429
- localStorage.setItem(key, `${ENCRYPTED_PREFIX}${encrypted}`);
31661
+ localStorage.setItem(key, `${ENCRYPTED_PREFIX2}${encrypted}`);
31662
+ sessionStorage.removeItem(key);
31430
31663
  } catch (error) {
31431
31664
  getLogger().warn(
31432
31665
  `Failed to encrypt OAuth token for ${provider}, storing temporarily:`,
31433
31666
  error
31434
31667
  );
31435
- sessionStorage.setItem(key, json4);
31668
+ sessionStorage.setItem(key, plaintextRecord);
31436
31669
  throw new Error(
31437
31670
  `OAuth token encryption failed: ${error instanceof Error ? error.message : String(error)}`
31438
31671
  );
31439
31672
  }
31440
31673
  } else {
31441
- sessionStorage.setItem(key, json4);
31674
+ sessionStorage.setItem(key, plaintextRecord);
31442
31675
  }
31443
31676
  }
31444
- function clearTokenData(provider) {
31677
+ function clearTokenData(provider, walletAddress) {
31445
31678
  if (typeof window === "undefined") return;
31446
- const key = getStorageKey(provider);
31447
- localStorage.removeItem(key);
31448
- sessionStorage.removeItem(key);
31679
+ const base = getStorageKey(provider);
31680
+ const keys = walletAddress ? [getStorageKey(provider, walletAddress), base] : [base];
31681
+ if (!walletAddress) keys.push(...suffixedKeys(base));
31682
+ for (const key of keys) {
31683
+ localStorage.removeItem(key);
31684
+ sessionStorage.removeItem(key);
31685
+ }
31686
+ }
31687
+ function suffixedKeys(base) {
31688
+ const found = [];
31689
+ for (const storage of [localStorage, sessionStorage]) {
31690
+ for (let i = 0; i < storage.length; i++) {
31691
+ const key = storage.key(i);
31692
+ if (key && key.startsWith(`${base}:`) && !found.includes(key)) found.push(key);
31693
+ }
31694
+ }
31695
+ return found;
31449
31696
  }
31450
31697
  function isTokenExpired(data, bufferSeconds = 60) {
31451
31698
  if (!data) return true;
@@ -31469,22 +31716,40 @@ async function getRefreshToken(provider, walletAddress) {
31469
31716
  async function migrateUnencryptedTokens(provider, walletAddress) {
31470
31717
  if (typeof window === "undefined") return false;
31471
31718
  try {
31472
- const key = getStorageKey(provider);
31473
- const localStored = localStorage.getItem(key);
31474
- const sessionStored = sessionStorage.getItem(key);
31475
- const isEncrypted2 = (value) => !!value && value.startsWith(ENCRYPTED_PREFIX);
31476
- const tokenToMigrate = sessionStored && !isEncrypted2(sessionStored) ? sessionStored : localStored && !isEncrypted2(localStored) ? localStored : null;
31719
+ const scopedKey = getStorageKey(provider, walletAddress);
31720
+ const legacyKey = getStorageKey(provider);
31721
+ const keys = [scopedKey, legacyKey];
31722
+ const isEncrypted2 = (value) => !!value && value.startsWith(ENCRYPTED_PREFIX2);
31723
+ const plaintextAt = (key) => {
31724
+ const stored = sessionStorage.getItem(key) ?? localStorage.getItem(key);
31725
+ return stored && !isEncrypted2(stored) ? stored : null;
31726
+ };
31727
+ let tokenToMigrate = null;
31728
+ for (const key of keys) {
31729
+ const value = plaintextAt(key);
31730
+ if (value) {
31731
+ tokenToMigrate = value;
31732
+ break;
31733
+ }
31734
+ }
31477
31735
  if (!tokenToMigrate) {
31478
- if (isEncrypted2(localStored) && sessionStored && !isEncrypted2(sessionStored)) {
31479
- sessionStorage.removeItem(key);
31736
+ for (const key of keys) {
31737
+ const stored = sessionStorage.getItem(key);
31738
+ if (isEncrypted2(localStorage.getItem(key)) && stored && !isEncrypted2(stored)) {
31739
+ sessionStorage.removeItem(key);
31740
+ }
31480
31741
  }
31481
31742
  return false;
31482
31743
  }
31483
31744
  try {
31484
- const data = JSON.parse(tokenToMigrate);
31745
+ const data = parsePlaintextToken(tokenToMigrate, walletAddress);
31746
+ if (!data) return false;
31485
31747
  await storeTokenData(provider, data, walletAddress);
31486
- if (sessionStored && !isEncrypted2(sessionStored)) {
31487
- sessionStorage.removeItem(key);
31748
+ for (const key of keys) {
31749
+ if (plaintextAt(key)) sessionStorage.removeItem(key);
31750
+ if (key === legacyKey && !isEncrypted2(localStorage.getItem(key))) {
31751
+ localStorage.removeItem(key);
31752
+ }
31488
31753
  }
31489
31754
  return true;
31490
31755
  } catch (error) {
@@ -31653,7 +31918,7 @@ async function refreshDropboxToken(apiClient, walletAddress) {
31653
31918
  await storeTokenData(PROVIDER, tokenData, walletAddress);
31654
31919
  return response.data.access_token;
31655
31920
  } catch {
31656
- clearTokenData(PROVIDER);
31921
+ clearTokenData(PROVIDER, walletAddress);
31657
31922
  return null;
31658
31923
  }
31659
31924
  }
@@ -31669,7 +31934,7 @@ async function revokeDropboxToken(apiClient, walletAddress) {
31669
31934
  });
31670
31935
  } catch {
31671
31936
  } finally {
31672
- clearTokenData(PROVIDER);
31937
+ clearTokenData(PROVIDER, walletAddress);
31673
31938
  }
31674
31939
  }
31675
31940
  async function getDropboxAccessToken(apiClient, walletAddress) {
@@ -32273,7 +32538,7 @@ async function refreshGoogleDriveToken(apiClient, walletAddress) {
32273
32538
  await storeTokenData(PROVIDER2, tokenData, walletAddress);
32274
32539
  return response.data.access_token;
32275
32540
  } catch {
32276
- clearTokenData(PROVIDER2);
32541
+ clearTokenData(PROVIDER2, walletAddress);
32277
32542
  return null;
32278
32543
  }
32279
32544
  }
@@ -32289,7 +32554,7 @@ async function revokeGoogleDriveToken(apiClient, walletAddress) {
32289
32554
  });
32290
32555
  } catch {
32291
32556
  } finally {
32292
- clearTokenData(PROVIDER2);
32557
+ clearTokenData(PROVIDER2, walletAddress);
32293
32558
  }
32294
32559
  }
32295
32560
  async function getGoogleDriveAccessToken(apiClient, walletAddress) {
@@ -33923,7 +34188,7 @@ var CODE_STORAGE_KEY2 = "google_calendar_oauth_state";
33923
34188
  var TOKEN_STORAGE_KEY = "oauth_token_google-calendar";
33924
34189
  var RETURN_URL_KEY = "google_calendar_return_url";
33925
34190
  var PENDING_MESSAGE_KEY = "google_calendar_pending_message";
33926
- var ENCRYPTED_PREFIX2 = "enc:oauth:";
34191
+ var ENCRYPTED_PREFIX3 = "enc:oauth:";
33927
34192
  var cachedAccessToken = null;
33928
34193
  var cachedExpiresAt = null;
33929
34194
  var cachedRefreshToken = null;
@@ -33954,9 +34219,9 @@ async function getStoredTokenData2(walletAddress) {
33954
34219
  }
33955
34220
  try {
33956
34221
  const scopedStored = localStorage.getItem(getTokenStorageKey(walletAddress));
33957
- if (scopedStored && scopedStored.startsWith(ENCRYPTED_PREFIX2) && walletAddress && hasEncryptionKey(walletAddress)) {
34222
+ if (scopedStored && scopedStored.startsWith(ENCRYPTED_PREFIX3) && walletAddress && hasEncryptionKey(walletAddress)) {
33958
34223
  try {
33959
- const encryptedData = scopedStored.slice(ENCRYPTED_PREFIX2.length);
34224
+ const encryptedData = scopedStored.slice(ENCRYPTED_PREFIX3.length);
33960
34225
  const cryptoKey = await getEncryptionKey(walletAddress);
33961
34226
  const decryptedJson = await decryptDataWithKey(encryptedData, cryptoKey);
33962
34227
  const data = JSON.parse(decryptedJson);
@@ -33971,33 +34236,18 @@ async function getStoredTokenData2(walletAddress) {
33971
34236
  getLogger().error("Failed to decrypt Calendar OAuth token:", error);
33972
34237
  }
33973
34238
  }
33974
- const legacyStored = localStorage.getItem(TOKEN_STORAGE_KEY);
33975
- if (legacyStored && !legacyStored.startsWith(ENCRYPTED_PREFIX2)) {
33976
- try {
33977
- const data = JSON.parse(legacyStored);
33978
- if (data.accessToken) {
33979
- cachedAccessToken = data.accessToken;
33980
- cachedExpiresAt = data.expiresAt ?? null;
33981
- cachedRefreshToken = data.refreshToken ?? null;
33982
- cachedWalletAddress = walletAddress ?? null;
33983
- return data;
33984
- }
33985
- } catch {
33986
- }
33987
- }
33988
- const sessionStored = sessionStorage.getItem(TOKEN_STORAGE_KEY);
33989
- if (sessionStored) {
33990
- try {
33991
- const data = JSON.parse(sessionStored);
33992
- if (!data.accessToken) return null;
33993
- cachedAccessToken = data.accessToken;
33994
- cachedExpiresAt = data.expiresAt ?? null;
33995
- cachedRefreshToken = data.refreshToken ?? null;
33996
- cachedScope = data.scope ?? null;
33997
- cachedWalletAddress = walletAddress ?? null;
33998
- return data;
33999
- } catch {
34000
- }
34239
+ const plaintext = readPlaintextToken(
34240
+ getTokenStorageKey(walletAddress),
34241
+ TOKEN_STORAGE_KEY,
34242
+ walletAddress
34243
+ );
34244
+ if (plaintext) {
34245
+ cachedAccessToken = plaintext.accessToken;
34246
+ cachedExpiresAt = plaintext.expiresAt ?? null;
34247
+ cachedRefreshToken = plaintext.refreshToken ?? null;
34248
+ cachedScope = plaintext.scope ?? null;
34249
+ cachedWalletAddress = walletAddress ?? null;
34250
+ return plaintext;
34001
34251
  }
34002
34252
  return null;
34003
34253
  } catch {
@@ -34012,16 +34262,19 @@ async function storeTokenData2(data, walletAddress) {
34012
34262
  cachedScope = data.scope ?? null;
34013
34263
  cachedWalletAddress = walletAddress ?? null;
34014
34264
  const json4 = JSON.stringify(data);
34015
- sessionStorage.setItem(TOKEN_STORAGE_KEY, json4);
34016
34265
  if (walletAddress && hasEncryptionKey(walletAddress)) {
34017
34266
  try {
34018
34267
  const cryptoKey = await getEncryptionKey(walletAddress);
34019
34268
  const encrypted = await encryptDataWithKey(json4, cryptoKey);
34020
- localStorage.setItem(getTokenStorageKey(walletAddress), ENCRYPTED_PREFIX2 + encrypted);
34269
+ localStorage.setItem(getTokenStorageKey(walletAddress), ENCRYPTED_PREFIX3 + encrypted);
34270
+ sessionStorage.removeItem(getTokenStorageKey(walletAddress));
34271
+ return;
34021
34272
  } catch (error) {
34022
34273
  getLogger().warn("Failed to encrypt Calendar OAuth token:", error);
34023
34274
  }
34024
34275
  }
34276
+ const record = { wallet: walletAddress, token: data };
34277
+ sessionStorage.setItem(getTokenStorageKey(walletAddress), JSON.stringify(record));
34025
34278
  }
34026
34279
  function clearCalendarToken(walletAddress) {
34027
34280
  if (typeof window === "undefined") return;
@@ -34035,6 +34288,7 @@ function clearCalendarToken(walletAddress) {
34035
34288
  localStorage.removeItem(TOKEN_STORAGE_KEY);
34036
34289
  }
34037
34290
  sessionStorage.removeItem(TOKEN_STORAGE_KEY);
34291
+ sessionStorage.removeItem(getTokenStorageKey(walletAddress));
34038
34292
  }
34039
34293
  function isTokenExpired2(data, bufferSeconds = 60) {
34040
34294
  if (!data) return true;
@@ -34216,24 +34470,38 @@ async function migrateCalendarToken(walletAddress) {
34216
34470
  if (typeof window === "undefined") return false;
34217
34471
  if (!walletAddress || !hasEncryptionKey(walletAddress)) return false;
34218
34472
  try {
34219
- const sessionStored = sessionStorage.getItem(TOKEN_STORAGE_KEY);
34220
- const legacyStored = localStorage.getItem(TOKEN_STORAGE_KEY);
34221
- const isLegacyUnencrypted = legacyStored && !legacyStored.startsWith(ENCRYPTED_PREFIX2);
34222
- const unencryptedJson = sessionStored || (isLegacyUnencrypted ? legacyStored : null);
34223
- if (!unencryptedJson) return false;
34224
34473
  const scopedKey = getTokenStorageKey(walletAddress);
34474
+ const sources = [
34475
+ { key: scopedKey, store: sessionStorage },
34476
+ // A read moves a legacy localStorage row here as plain text.
34477
+ { key: scopedKey, store: localStorage },
34478
+ { key: TOKEN_STORAGE_KEY, store: sessionStorage },
34479
+ { key: TOKEN_STORAGE_KEY, store: localStorage }
34480
+ ];
34481
+ let used = null;
34482
+ let unencryptedJson = "";
34483
+ for (const source of sources) {
34484
+ const value = source.store.getItem(source.key);
34485
+ if (value && !value.startsWith(ENCRYPTED_PREFIX3)) {
34486
+ unencryptedJson = value;
34487
+ used = source;
34488
+ break;
34489
+ }
34490
+ }
34491
+ if (!used) return false;
34225
34492
  const existingEncrypted = localStorage.getItem(scopedKey);
34226
- if (existingEncrypted?.startsWith(ENCRYPTED_PREFIX2)) {
34227
- sessionStorage.removeItem(TOKEN_STORAGE_KEY);
34228
- if (isLegacyUnencrypted) localStorage.removeItem(TOKEN_STORAGE_KEY);
34493
+ if (existingEncrypted?.startsWith(ENCRYPTED_PREFIX3)) {
34494
+ used.store.removeItem(used.key);
34229
34495
  return true;
34230
34496
  }
34231
- const data = JSON.parse(unencryptedJson);
34497
+ const data = parsePlaintextToken(unencryptedJson, walletAddress);
34498
+ if (!data) return false;
34232
34499
  await storeTokenData2(data, walletAddress);
34233
34500
  const migrated = localStorage.getItem(scopedKey);
34234
- if (!migrated?.startsWith(ENCRYPTED_PREFIX2)) return false;
34235
- sessionStorage.removeItem(TOKEN_STORAGE_KEY);
34236
- if (isLegacyUnencrypted) localStorage.removeItem(TOKEN_STORAGE_KEY);
34501
+ if (!migrated?.startsWith(ENCRYPTED_PREFIX3)) return false;
34502
+ if (used.store !== localStorage || used.key !== scopedKey) {
34503
+ used.store.removeItem(used.key);
34504
+ }
34237
34505
  return true;
34238
34506
  } catch {
34239
34507
  return false;
@@ -34247,7 +34515,7 @@ var CODE_STORAGE_KEY3 = "google_drive_oauth_state";
34247
34515
  var TOKEN_STORAGE_KEY2 = "oauth_token_google-drive-full";
34248
34516
  var RETURN_URL_KEY2 = "google_drive_return_url";
34249
34517
  var PENDING_MESSAGE_KEY2 = "google_drive_pending_message";
34250
- var ENCRYPTED_PREFIX3 = "enc:oauth:";
34518
+ var ENCRYPTED_PREFIX4 = "enc:oauth:";
34251
34519
  var cachedAccessToken2 = null;
34252
34520
  var cachedExpiresAt2 = null;
34253
34521
  var cachedRefreshToken2 = null;
@@ -34278,9 +34546,9 @@ async function getStoredTokenData3(walletAddress) {
34278
34546
  }
34279
34547
  try {
34280
34548
  const scopedStored = localStorage.getItem(getTokenStorageKey2(walletAddress));
34281
- if (scopedStored && scopedStored.startsWith(ENCRYPTED_PREFIX3) && walletAddress && hasEncryptionKey(walletAddress)) {
34549
+ if (scopedStored && scopedStored.startsWith(ENCRYPTED_PREFIX4) && walletAddress && hasEncryptionKey(walletAddress)) {
34282
34550
  try {
34283
- const encryptedData = scopedStored.slice(ENCRYPTED_PREFIX3.length);
34551
+ const encryptedData = scopedStored.slice(ENCRYPTED_PREFIX4.length);
34284
34552
  const cryptoKey = await getEncryptionKey(walletAddress);
34285
34553
  const decryptedJson = await decryptDataWithKey(encryptedData, cryptoKey);
34286
34554
  const data = JSON.parse(decryptedJson);
@@ -34295,33 +34563,18 @@ async function getStoredTokenData3(walletAddress) {
34295
34563
  getLogger().error("Failed to decrypt Drive OAuth token:", error);
34296
34564
  }
34297
34565
  }
34298
- const legacyStored = localStorage.getItem(TOKEN_STORAGE_KEY2);
34299
- if (legacyStored && !legacyStored.startsWith(ENCRYPTED_PREFIX3)) {
34300
- try {
34301
- const data = JSON.parse(legacyStored);
34302
- if (data.accessToken) {
34303
- cachedAccessToken2 = data.accessToken;
34304
- cachedExpiresAt2 = data.expiresAt ?? null;
34305
- cachedRefreshToken2 = data.refreshToken ?? null;
34306
- cachedWalletAddress2 = walletAddress ?? null;
34307
- return data;
34308
- }
34309
- } catch {
34310
- }
34311
- }
34312
- const sessionStored = sessionStorage.getItem(TOKEN_STORAGE_KEY2);
34313
- if (sessionStored) {
34314
- try {
34315
- const data = JSON.parse(sessionStored);
34316
- if (!data.accessToken) return null;
34317
- cachedAccessToken2 = data.accessToken;
34318
- cachedExpiresAt2 = data.expiresAt ?? null;
34319
- cachedRefreshToken2 = data.refreshToken ?? null;
34320
- cachedScope2 = data.scope ?? null;
34321
- cachedWalletAddress2 = walletAddress ?? null;
34322
- return data;
34323
- } catch {
34324
- }
34566
+ const plaintext = readPlaintextToken(
34567
+ getTokenStorageKey2(walletAddress),
34568
+ TOKEN_STORAGE_KEY2,
34569
+ walletAddress
34570
+ );
34571
+ if (plaintext) {
34572
+ cachedAccessToken2 = plaintext.accessToken;
34573
+ cachedExpiresAt2 = plaintext.expiresAt ?? null;
34574
+ cachedRefreshToken2 = plaintext.refreshToken ?? null;
34575
+ cachedScope2 = plaintext.scope ?? null;
34576
+ cachedWalletAddress2 = walletAddress ?? null;
34577
+ return plaintext;
34325
34578
  }
34326
34579
  return null;
34327
34580
  } catch {
@@ -34336,16 +34589,19 @@ async function storeTokenData3(data, walletAddress) {
34336
34589
  cachedScope2 = data.scope ?? null;
34337
34590
  cachedWalletAddress2 = walletAddress ?? null;
34338
34591
  const json4 = JSON.stringify(data);
34339
- sessionStorage.setItem(TOKEN_STORAGE_KEY2, json4);
34340
34592
  if (walletAddress && hasEncryptionKey(walletAddress)) {
34341
34593
  try {
34342
34594
  const cryptoKey = await getEncryptionKey(walletAddress);
34343
34595
  const encrypted = await encryptDataWithKey(json4, cryptoKey);
34344
- localStorage.setItem(getTokenStorageKey2(walletAddress), `${ENCRYPTED_PREFIX3}${encrypted}`);
34596
+ localStorage.setItem(getTokenStorageKey2(walletAddress), `${ENCRYPTED_PREFIX4}${encrypted}`);
34597
+ sessionStorage.removeItem(getTokenStorageKey2(walletAddress));
34598
+ return;
34345
34599
  } catch (error) {
34346
34600
  getLogger().warn("Failed to encrypt Drive OAuth token:", error);
34347
34601
  }
34348
34602
  }
34603
+ const record = { wallet: walletAddress, token: data };
34604
+ sessionStorage.setItem(getTokenStorageKey2(walletAddress), JSON.stringify(record));
34349
34605
  }
34350
34606
  function clearDriveToken(walletAddress) {
34351
34607
  if (typeof window === "undefined") return;
@@ -34359,6 +34615,7 @@ function clearDriveToken(walletAddress) {
34359
34615
  localStorage.removeItem(TOKEN_STORAGE_KEY2);
34360
34616
  }
34361
34617
  sessionStorage.removeItem(TOKEN_STORAGE_KEY2);
34618
+ sessionStorage.removeItem(getTokenStorageKey2(walletAddress));
34362
34619
  }
34363
34620
  function isTokenExpired3(data, bufferSeconds = 60) {
34364
34621
  if (!data) return true;
@@ -34540,24 +34797,38 @@ async function migrateDriveToken(walletAddress) {
34540
34797
  if (typeof window === "undefined") return false;
34541
34798
  if (!walletAddress || !hasEncryptionKey(walletAddress)) return false;
34542
34799
  try {
34543
- const sessionStored = sessionStorage.getItem(TOKEN_STORAGE_KEY2);
34544
- const legacyStored = localStorage.getItem(TOKEN_STORAGE_KEY2);
34545
- const isLegacyUnencrypted = legacyStored && !legacyStored.startsWith(ENCRYPTED_PREFIX3);
34546
- const unencryptedJson = sessionStored || (isLegacyUnencrypted ? legacyStored : null);
34547
- if (!unencryptedJson) return false;
34548
34800
  const scopedKey = getTokenStorageKey2(walletAddress);
34801
+ const sources = [
34802
+ { key: scopedKey, store: sessionStorage },
34803
+ // A read moves a legacy localStorage row here as plain text.
34804
+ { key: scopedKey, store: localStorage },
34805
+ { key: TOKEN_STORAGE_KEY2, store: sessionStorage },
34806
+ { key: TOKEN_STORAGE_KEY2, store: localStorage }
34807
+ ];
34808
+ let used = null;
34809
+ let unencryptedJson = "";
34810
+ for (const source of sources) {
34811
+ const value = source.store.getItem(source.key);
34812
+ if (value && !value.startsWith(ENCRYPTED_PREFIX4)) {
34813
+ unencryptedJson = value;
34814
+ used = source;
34815
+ break;
34816
+ }
34817
+ }
34818
+ if (!used) return false;
34549
34819
  const existingEncrypted = localStorage.getItem(scopedKey);
34550
- if (existingEncrypted?.startsWith(ENCRYPTED_PREFIX3)) {
34551
- sessionStorage.removeItem(TOKEN_STORAGE_KEY2);
34552
- if (isLegacyUnencrypted) localStorage.removeItem(TOKEN_STORAGE_KEY2);
34820
+ if (existingEncrypted?.startsWith(ENCRYPTED_PREFIX4)) {
34821
+ used.store.removeItem(used.key);
34553
34822
  return true;
34554
34823
  }
34555
- const data = JSON.parse(unencryptedJson);
34824
+ const data = parsePlaintextToken(unencryptedJson, walletAddress);
34825
+ if (!data) return false;
34556
34826
  await storeTokenData3(data, walletAddress);
34557
34827
  const migrated = localStorage.getItem(scopedKey);
34558
- if (!migrated?.startsWith(ENCRYPTED_PREFIX3)) return false;
34559
- sessionStorage.removeItem(TOKEN_STORAGE_KEY2);
34560
- if (isLegacyUnencrypted) localStorage.removeItem(TOKEN_STORAGE_KEY2);
34828
+ if (!migrated?.startsWith(ENCRYPTED_PREFIX4)) return false;
34829
+ if (used.store !== localStorage || used.key !== scopedKey) {
34830
+ used.store.removeItem(used.key);
34831
+ }
34561
34832
  return true;
34562
34833
  } catch {
34563
34834
  return false;
@@ -34590,7 +34861,7 @@ var FALLBACK_OAUTH_AUTHORIZE = "https://api.notion.com/v1/oauth/authorize";
34590
34861
  var FALLBACK_OAUTH_TOKEN = "https://api.notion.com/v1/oauth/token";
34591
34862
  var FALLBACK_REGISTRATION = "https://api.notion.com/v1/oauth/register";
34592
34863
  var DEFAULT_TOKEN_EXPIRY_SECONDS = 8 * 3600;
34593
- var ENCRYPTED_PREFIX4 = "enc:oauth:";
34864
+ var ENCRYPTED_PREFIX5 = "enc:oauth:";
34594
34865
  var cachedAccessToken3 = null;
34595
34866
  var cachedExpiresAt3 = null;
34596
34867
  var cachedWalletAddress3 = null;
@@ -34728,12 +34999,14 @@ async function storeTokenData4(data, walletAddress) {
34728
34999
  try {
34729
35000
  const cryptoKey = await getEncryptionKey(walletAddress);
34730
35001
  const encrypted = await encryptDataWithKey(json4, cryptoKey);
34731
- localStorage.setItem(getTokenStorageKey3(walletAddress), `${ENCRYPTED_PREFIX4}${encrypted}`);
35002
+ localStorage.setItem(getTokenStorageKey3(walletAddress), `${ENCRYPTED_PREFIX5}${encrypted}`);
35003
+ sessionStorage.removeItem(getTokenStorageKey3(walletAddress));
34732
35004
  return;
34733
35005
  } catch {
34734
35006
  }
34735
35007
  }
34736
- sessionStorage.setItem(TOKEN_STORAGE_KEY3, json4);
35008
+ const record = { wallet: walletAddress, token: data };
35009
+ sessionStorage.setItem(getTokenStorageKey3(walletAddress), JSON.stringify(record));
34737
35010
  }
34738
35011
  async function getStoredTokenData4(walletAddress) {
34739
35012
  if (typeof window === "undefined") return null;
@@ -34750,11 +35023,11 @@ async function getStoredTokenData4(walletAddress) {
34750
35023
  }
34751
35024
  try {
34752
35025
  const stored = localStorage.getItem(getTokenStorageKey3(walletAddress));
34753
- if (stored?.startsWith(ENCRYPTED_PREFIX4)) {
35026
+ if (stored?.startsWith(ENCRYPTED_PREFIX5)) {
34754
35027
  if (walletAddress && hasEncryptionKey(walletAddress)) {
34755
35028
  try {
34756
35029
  const cryptoKey = await getEncryptionKey(walletAddress);
34757
- const encrypted = stored.slice(ENCRYPTED_PREFIX4.length);
35030
+ const encrypted = stored.slice(ENCRYPTED_PREFIX5.length);
34758
35031
  const decrypted = await decryptDataWithKey(encrypted, cryptoKey);
34759
35032
  const data = JSON.parse(decrypted);
34760
35033
  if (data.accessToken) return data;
@@ -34762,12 +35035,12 @@ async function getStoredTokenData4(walletAddress) {
34762
35035
  }
34763
35036
  }
34764
35037
  }
34765
- const sessionStored = sessionStorage.getItem(TOKEN_STORAGE_KEY3);
34766
- if (sessionStored) {
34767
- const data = JSON.parse(sessionStored);
34768
- if (!data.accessToken) return null;
34769
- return data;
34770
- }
35038
+ const plaintext = readPlaintextToken(
35039
+ getTokenStorageKey3(walletAddress),
35040
+ TOKEN_STORAGE_KEY3,
35041
+ walletAddress
35042
+ );
35043
+ if (plaintext) return plaintext;
34771
35044
  return null;
34772
35045
  } catch {
34773
35046
  return null;
@@ -34777,6 +35050,7 @@ function clearNotionToken(walletAddress) {
34777
35050
  if (typeof window === "undefined") return;
34778
35051
  localStorage.removeItem(getTokenStorageKey3(walletAddress));
34779
35052
  sessionStorage.removeItem(TOKEN_STORAGE_KEY3);
35053
+ sessionStorage.removeItem(getTokenStorageKey3(walletAddress));
34780
35054
  cachedAccessToken3 = null;
34781
35055
  cachedExpiresAt3 = null;
34782
35056
  cachedWalletAddress3 = null;
@@ -34792,20 +35066,34 @@ async function migrateNotionToken(walletAddress) {
34792
35066
  if (typeof window === "undefined") return false;
34793
35067
  if (!walletAddress || !hasEncryptionKey(walletAddress)) return false;
34794
35068
  try {
34795
- const sessionStored = sessionStorage.getItem(TOKEN_STORAGE_KEY3);
34796
- if (!sessionStored) return false;
34797
35069
  const scopedKey = getTokenStorageKey3(walletAddress);
35070
+ const sources = [
35071
+ { key: scopedKey, store: sessionStorage },
35072
+ { key: TOKEN_STORAGE_KEY3, store: sessionStorage }
35073
+ ];
35074
+ let used = null;
35075
+ let unencryptedJson = "";
35076
+ for (const source of sources) {
35077
+ const value = source.store.getItem(source.key);
35078
+ if (value && !value.startsWith(ENCRYPTED_PREFIX5)) {
35079
+ unencryptedJson = value;
35080
+ used = source;
35081
+ break;
35082
+ }
35083
+ }
35084
+ if (!used) return false;
34798
35085
  const localStored = localStorage.getItem(scopedKey);
34799
- if (localStored?.startsWith(ENCRYPTED_PREFIX4)) {
35086
+ if (localStored?.startsWith(ENCRYPTED_PREFIX5)) {
34800
35087
  localStorage.removeItem(scopedKey);
34801
35088
  }
34802
- const data = JSON.parse(sessionStored);
35089
+ const data = parsePlaintextToken(unencryptedJson, walletAddress);
35090
+ if (!data) return false;
34803
35091
  await storeTokenData4(data, walletAddress);
34804
35092
  const migrated = localStorage.getItem(scopedKey);
34805
- if (!migrated?.startsWith(ENCRYPTED_PREFIX4)) {
35093
+ if (!migrated?.startsWith(ENCRYPTED_PREFIX5)) {
34806
35094
  return false;
34807
35095
  }
34808
- sessionStorage.removeItem(TOKEN_STORAGE_KEY3);
35096
+ used.store.removeItem(used.key);
34809
35097
  return true;
34810
35098
  } catch {
34811
35099
  return false;
@@ -34817,12 +35105,12 @@ async function migrateNotionClientRegistration(walletAddress) {
34817
35105
  try {
34818
35106
  const sessionStored = sessionStorage.getItem(CLIENT_REGISTRATION_KEY);
34819
35107
  const legacyStored = localStorage.getItem(CLIENT_REGISTRATION_KEY);
34820
- const isLegacyUnencrypted = legacyStored && !legacyStored.startsWith(ENCRYPTED_PREFIX4);
35108
+ const isLegacyUnencrypted = legacyStored && !legacyStored.startsWith(ENCRYPTED_PREFIX5);
34821
35109
  const unencryptedJson = sessionStored || (isLegacyUnencrypted ? legacyStored : null);
34822
35110
  if (!unencryptedJson) return false;
34823
35111
  const scopedKey = getClientRegistrationStorageKey(walletAddress);
34824
35112
  const existingEncrypted = localStorage.getItem(scopedKey);
34825
- if (existingEncrypted?.startsWith(ENCRYPTED_PREFIX4)) {
35113
+ if (existingEncrypted?.startsWith(ENCRYPTED_PREFIX5)) {
34826
35114
  sessionStorage.removeItem(CLIENT_REGISTRATION_KEY);
34827
35115
  if (isLegacyUnencrypted) {
34828
35116
  localStorage.removeItem(CLIENT_REGISTRATION_KEY);
@@ -34832,7 +35120,7 @@ async function migrateNotionClientRegistration(walletAddress) {
34832
35120
  const data = JSON.parse(unencryptedJson);
34833
35121
  await storeClientRegistration(data, walletAddress);
34834
35122
  const migrated = localStorage.getItem(scopedKey);
34835
- if (!migrated?.startsWith(ENCRYPTED_PREFIX4)) {
35123
+ if (!migrated?.startsWith(ENCRYPTED_PREFIX5)) {
34836
35124
  return false;
34837
35125
  }
34838
35126
  sessionStorage.removeItem(CLIENT_REGISTRATION_KEY);
@@ -34849,11 +35137,11 @@ async function getClientRegistration(walletAddress) {
34849
35137
  try {
34850
35138
  const scopedKey = getClientRegistrationStorageKey(walletAddress);
34851
35139
  const stored = localStorage.getItem(scopedKey);
34852
- if (stored?.startsWith(ENCRYPTED_PREFIX4)) {
35140
+ if (stored?.startsWith(ENCRYPTED_PREFIX5)) {
34853
35141
  if (walletAddress && hasEncryptionKey(walletAddress)) {
34854
35142
  try {
34855
35143
  const cryptoKey = await getEncryptionKey(walletAddress);
34856
- const encrypted = stored.slice(ENCRYPTED_PREFIX4.length);
35144
+ const encrypted = stored.slice(ENCRYPTED_PREFIX5.length);
34857
35145
  const decrypted = await decryptDataWithKey(encrypted, cryptoKey);
34858
35146
  const data = JSON.parse(decrypted);
34859
35147
  if (data.clientId) {
@@ -34863,7 +35151,7 @@ async function getClientRegistration(walletAddress) {
34863
35151
  }
34864
35152
  }
34865
35153
  }
34866
- if (stored && !stored.startsWith(ENCRYPTED_PREFIX4)) {
35154
+ if (stored && !stored.startsWith(ENCRYPTED_PREFIX5)) {
34867
35155
  const data = JSON.parse(stored);
34868
35156
  if (!data.clientId) return null;
34869
35157
  return data;
@@ -34888,7 +35176,7 @@ async function storeClientRegistration(registration, walletAddress) {
34888
35176
  const cryptoKey = await getEncryptionKey(walletAddress);
34889
35177
  const encrypted = await encryptDataWithKey(json4, cryptoKey);
34890
35178
  const scopedKey = getClientRegistrationStorageKey(walletAddress);
34891
- localStorage.setItem(scopedKey, `${ENCRYPTED_PREFIX4}${encrypted}`);
35179
+ localStorage.setItem(scopedKey, `${ENCRYPTED_PREFIX5}${encrypted}`);
34892
35180
  } catch {
34893
35181
  }
34894
35182
  }
@@ -35121,7 +35409,7 @@ var CODE_STORAGE_KEY4 = "github_oauth_state";
35121
35409
  var TOKEN_STORAGE_KEY4 = "oauth_token_github";
35122
35410
  var RETURN_URL_KEY4 = "github_return_url";
35123
35411
  var PENDING_MESSAGE_KEY4 = "github_pending_message";
35124
- var ENCRYPTED_PREFIX5 = "enc:oauth:";
35412
+ var ENCRYPTED_PREFIX6 = "enc:oauth:";
35125
35413
  var cachedAccessToken4 = null;
35126
35414
  var cachedExpiresAt4 = null;
35127
35415
  var cachedRefreshToken3 = null;
@@ -35154,9 +35442,9 @@ async function getStoredTokenData5(walletAddress) {
35154
35442
  }
35155
35443
  try {
35156
35444
  const scopedStored = localStorage.getItem(getTokenStorageKey4(walletAddress));
35157
- if (scopedStored && scopedStored.startsWith(ENCRYPTED_PREFIX5) && walletAddress && hasEncryptionKey(walletAddress)) {
35445
+ if (scopedStored && scopedStored.startsWith(ENCRYPTED_PREFIX6) && walletAddress && hasEncryptionKey(walletAddress)) {
35158
35446
  try {
35159
- const encryptedData = scopedStored.slice(ENCRYPTED_PREFIX5.length);
35447
+ const encryptedData = scopedStored.slice(ENCRYPTED_PREFIX6.length);
35160
35448
  const cryptoKey = await getEncryptionKey(walletAddress);
35161
35449
  const decryptedJson = await decryptDataWithKey(encryptedData, cryptoKey);
35162
35450
  const data = JSON.parse(decryptedJson);
@@ -35171,34 +35459,18 @@ async function getStoredTokenData5(walletAddress) {
35171
35459
  getLogger().error("Failed to decrypt GitHub OAuth token:", error);
35172
35460
  }
35173
35461
  }
35174
- const legacyStored = localStorage.getItem(TOKEN_STORAGE_KEY4);
35175
- if (legacyStored && !legacyStored.startsWith(ENCRYPTED_PREFIX5)) {
35176
- try {
35177
- const data = JSON.parse(legacyStored);
35178
- if (data.accessToken) {
35179
- cachedAccessToken4 = data.accessToken;
35180
- cachedExpiresAt4 = data.expiresAt ?? null;
35181
- cachedRefreshToken3 = data.refreshToken ?? null;
35182
- cachedScope3 = data.scope ?? null;
35183
- cachedWalletAddress4 = walletAddress ?? null;
35184
- return data;
35185
- }
35186
- } catch {
35187
- }
35188
- }
35189
- const sessionStored = sessionStorage.getItem(TOKEN_STORAGE_KEY4);
35190
- if (sessionStored) {
35191
- try {
35192
- const data = JSON.parse(sessionStored);
35193
- if (!data.accessToken) return null;
35194
- cachedAccessToken4 = data.accessToken;
35195
- cachedExpiresAt4 = data.expiresAt ?? null;
35196
- cachedRefreshToken3 = data.refreshToken ?? null;
35197
- cachedScope3 = data.scope ?? null;
35198
- cachedWalletAddress4 = walletAddress ?? null;
35199
- return data;
35200
- } catch {
35201
- }
35462
+ const plaintext = readPlaintextToken(
35463
+ getTokenStorageKey4(walletAddress),
35464
+ TOKEN_STORAGE_KEY4,
35465
+ walletAddress
35466
+ );
35467
+ if (plaintext) {
35468
+ cachedAccessToken4 = plaintext.accessToken;
35469
+ cachedExpiresAt4 = plaintext.expiresAt ?? null;
35470
+ cachedRefreshToken3 = plaintext.refreshToken ?? null;
35471
+ cachedScope3 = plaintext.scope ?? null;
35472
+ cachedWalletAddress4 = walletAddress ?? null;
35473
+ return plaintext;
35202
35474
  }
35203
35475
  return null;
35204
35476
  } catch {
@@ -35213,16 +35485,19 @@ async function storeTokenData5(data, walletAddress) {
35213
35485
  cachedScope3 = data.scope ?? null;
35214
35486
  cachedWalletAddress4 = walletAddress ?? null;
35215
35487
  const json4 = JSON.stringify(data);
35216
- sessionStorage.setItem(TOKEN_STORAGE_KEY4, json4);
35217
35488
  if (walletAddress && hasEncryptionKey(walletAddress)) {
35218
35489
  try {
35219
35490
  const cryptoKey = await getEncryptionKey(walletAddress);
35220
35491
  const encrypted = await encryptDataWithKey(json4, cryptoKey);
35221
- localStorage.setItem(getTokenStorageKey4(walletAddress), `${ENCRYPTED_PREFIX5}${encrypted}`);
35492
+ localStorage.setItem(getTokenStorageKey4(walletAddress), `${ENCRYPTED_PREFIX6}${encrypted}`);
35493
+ sessionStorage.removeItem(getTokenStorageKey4(walletAddress));
35494
+ return;
35222
35495
  } catch (error) {
35223
35496
  getLogger().warn("Failed to encrypt GitHub OAuth token:", error);
35224
35497
  }
35225
35498
  }
35499
+ const record = { wallet: walletAddress, token: data };
35500
+ sessionStorage.setItem(getTokenStorageKey4(walletAddress), JSON.stringify(record));
35226
35501
  }
35227
35502
  function clearGithubToken(walletAddress) {
35228
35503
  if (typeof window === "undefined") return;
@@ -35236,6 +35511,7 @@ function clearGithubToken(walletAddress) {
35236
35511
  localStorage.removeItem(TOKEN_STORAGE_KEY4);
35237
35512
  }
35238
35513
  sessionStorage.removeItem(TOKEN_STORAGE_KEY4);
35514
+ sessionStorage.removeItem(getTokenStorageKey4(walletAddress));
35239
35515
  }
35240
35516
  function isTokenExpired5(data, bufferSeconds = 60) {
35241
35517
  if (!data) return true;
@@ -35444,24 +35720,38 @@ async function migrateGithubToken(walletAddress) {
35444
35720
  if (typeof window === "undefined") return false;
35445
35721
  if (!walletAddress || !hasEncryptionKey(walletAddress)) return false;
35446
35722
  try {
35447
- const sessionStored = sessionStorage.getItem(TOKEN_STORAGE_KEY4);
35448
- const legacyStored = localStorage.getItem(TOKEN_STORAGE_KEY4);
35449
- const isLegacyUnencrypted = legacyStored && !legacyStored.startsWith(ENCRYPTED_PREFIX5);
35450
- const unencryptedJson = sessionStored || (isLegacyUnencrypted ? legacyStored : null);
35451
- if (!unencryptedJson) return false;
35452
35723
  const scopedKey = getTokenStorageKey4(walletAddress);
35724
+ const sources = [
35725
+ { key: scopedKey, store: sessionStorage },
35726
+ // A read moves a legacy localStorage row here as plain text.
35727
+ { key: scopedKey, store: localStorage },
35728
+ { key: TOKEN_STORAGE_KEY4, store: sessionStorage },
35729
+ { key: TOKEN_STORAGE_KEY4, store: localStorage }
35730
+ ];
35731
+ let used = null;
35732
+ let unencryptedJson = "";
35733
+ for (const source of sources) {
35734
+ const value = source.store.getItem(source.key);
35735
+ if (value && !value.startsWith(ENCRYPTED_PREFIX6)) {
35736
+ unencryptedJson = value;
35737
+ used = source;
35738
+ break;
35739
+ }
35740
+ }
35741
+ if (!used) return false;
35453
35742
  const existingEncrypted = localStorage.getItem(scopedKey);
35454
- if (existingEncrypted?.startsWith(ENCRYPTED_PREFIX5)) {
35455
- sessionStorage.removeItem(TOKEN_STORAGE_KEY4);
35456
- if (isLegacyUnencrypted) localStorage.removeItem(TOKEN_STORAGE_KEY4);
35743
+ if (existingEncrypted?.startsWith(ENCRYPTED_PREFIX6)) {
35744
+ used.store.removeItem(used.key);
35457
35745
  return true;
35458
35746
  }
35459
- const data = JSON.parse(unencryptedJson);
35747
+ const data = parsePlaintextToken(unencryptedJson, walletAddress);
35748
+ if (!data) return false;
35460
35749
  await storeTokenData5(data, walletAddress);
35461
35750
  const migrated = localStorage.getItem(scopedKey);
35462
- if (!migrated?.startsWith(ENCRYPTED_PREFIX5)) return false;
35463
- sessionStorage.removeItem(TOKEN_STORAGE_KEY4);
35464
- if (isLegacyUnencrypted) localStorage.removeItem(TOKEN_STORAGE_KEY4);
35751
+ if (!migrated?.startsWith(ENCRYPTED_PREFIX6)) return false;
35752
+ if (used.store !== localStorage || used.key !== scopedKey) {
35753
+ used.store.removeItem(used.key);
35754
+ }
35465
35755
  return true;
35466
35756
  } catch {
35467
35757
  return false;