Token handling fix

This commit is contained in:
Sumit Gautam
2026-06-19 20:20:23 +05:30
parent f790ccbe04
commit 2a8654a6e4
2 changed files with 27 additions and 6 deletions
+17 -3
View File
@@ -58,18 +58,32 @@ async () => {
}
"""
# Best-effort discovery of an MSAL access token from localStorage. Returns null
# for anonymous sessions (anonymous chat may still work via cookies alone).
# Discover the Copilot chat MSAL access token from localStorage. The cache holds
# several tokens for different scopes; the chat WebSocket only accepts the one
# scoped 'ChatAI.ReadWrite' — a wrong-audience token (e.g. the Graph
# User.Read/Files.Read token) makes the WS upgrade 401. We therefore PREFER the
# ChatAI token and only fall back to the first token found if none matches.
# Returns null for anonymous sessions (anonymous chat may still work via cookies).
_FIND_TOKEN_JS = """
() => {
try {
let fallback = null;
for (let i = 0; i < localStorage.length; i++) {
const k = localStorage.key(i);
const v = localStorage.getItem(k);
if (v && v.indexOf('"credentialType":"AccessToken"') !== -1) {
try { const o = JSON.parse(v); if (o && o.secret) return o.secret; } catch (e) {}
try {
const o = JSON.parse(v);
if (o && o.secret) {
// Match the chat scope (e.g. '<resource>/ChatAI.ReadWrite'); take the
// first non-matching token only as a last-resort fallback.
if (o.target && o.target.indexOf('ChatAI') !== -1) return o.secret;
if (!fallback) fallback = o.secret;
}
} catch (e) {}
}
}
return fallback;
} catch (e) {}
return null;
}
+10 -3
View File
@@ -69,18 +69,25 @@ class Copilot(AbstractProvider):
if access_token is None and conversation is not None:
access_token = conversation.access_token
# Auth model mirrors the browser:
# * REST calls (conversation create, attachment upload) authenticate by
# COOKIE only. Sending the token as an Authorization: Bearer header
# there gets a 401 (browsers never do it), so we don't.
# * the chat WebSocket carries the signed-in identity via its
# ?accessToken= param. This must be the Copilot chat token (MSAL scope
# ChatAI.ReadWrite, selected in browser._FIND_TOKEN_JS): a
# wrong-audience token 401s the WS upgrade, while *no* token makes the
# chat backend treat the session as anonymous -> chat-service-
# unavailable in geo-restricted regions (e.g. India).
websocket_url = self.websocket_url
headers = None
if access_token:
websocket_url = f"{websocket_url}&accessToken={quote(access_token)}"
headers = {"authorization": f"Bearer {access_token}"}
with Session(
timeout=timeout,
proxy=proxy,
impersonate="chrome",
cookies=cookies,
headers=headers,
) as session:
# Establish cookies + Cloudflare clearance (anonymous is fine).
session.get(f"{self.url}/")