mirror of
https://github.com/diegosouzapw/OmniRoute.git
synced 2026-08-05 06:42:12 +03:00
* fix(providers): accept m365.cloud.microsoft for copilot-m365-web token (#7078) * test: regression for #7078 m365.cloud.microsoft token extraction * fix(7078): match on url.hostname and anchor path with startsWith * test(7078): cover explicit :443 port via url.hostname
This commit is contained in:
@@ -292,7 +292,7 @@ export async function validateCopilotWebProvider({ apiKey, providerSpecificData
|
||||
}
|
||||
}
|
||||
|
||||
function extractM365CredentialParts(raw: string, providerSpecificData: Record<string, unknown>) {
|
||||
export function extractM365CredentialParts(raw: string, providerSpecificData: Record<string, unknown>) {
|
||||
const text = raw.trim();
|
||||
const parts: Record<string, string> = {};
|
||||
|
||||
@@ -304,13 +304,22 @@ function extractM365CredentialParts(raw: string, providerSpecificData: Record<st
|
||||
if (key && value) parts[key] = value;
|
||||
}
|
||||
|
||||
if (/^wss:\/\/substrate\.office\.com\/m365Copilot\/Chathub\//i.test(text)) {
|
||||
// Accept the current M365 web endpoint (m365.cloud.microsoft, including
|
||||
// regional subdomains) plus the two legacy hosts (substrate.office.com,
|
||||
// copilot.microsoft.com). The path still carries /m365Copilot/Chathub/<tenant>,
|
||||
// so extraction is unchanged. (OmniRoute issue #7078)
|
||||
if (/^wss:\/\//i.test(text)) {
|
||||
try {
|
||||
const url = new URL(text);
|
||||
parts.access_token ||= url.searchParams.get("access_token") || "";
|
||||
parts.chathubPath ||= decodeURIComponent(
|
||||
url.pathname.split("/m365Copilot/Chathub/")[1] || ""
|
||||
const hostOk = /^(?:[\w-]+\.)*(?:m365\.cloud\.microsoft|copilot\.microsoft\.com|substrate\.office\.com)$/i.test(
|
||||
url.hostname
|
||||
);
|
||||
if (hostOk && url.pathname.startsWith("/m365Copilot/Chathub/")) {
|
||||
parts.access_token ||= url.searchParams.get("access_token") || "";
|
||||
parts.chathubPath ||= decodeURIComponent(
|
||||
url.pathname.split("/m365Copilot/Chathub/")[1] || ""
|
||||
);
|
||||
}
|
||||
} catch {
|
||||
// Fall through to the structured key/value parser result.
|
||||
}
|
||||
|
||||
48
tests/unit/m365-web-token-extraction-7078.test.ts
Normal file
48
tests/unit/m365-web-token-extraction-7078.test.ts
Normal file
@@ -0,0 +1,48 @@
|
||||
// Issue #7078 — Microsoft 365 Copilot web token extraction must accept the current
|
||||
// m365.cloud.microsoft endpoint (and legacy substrate.office.com / copilot.microsoft.com),
|
||||
// not just the old substrate.office.com WS host. Verifies access_token + chathubPath parse.
|
||||
import test from "node:test";
|
||||
import assert from "node:assert/strict";
|
||||
|
||||
const B = await import("../../src/lib/providers/validation/webProvidersB.ts");
|
||||
const extract = (raw: string) =>
|
||||
(B as Record<string, any>).extractM365CredentialParts(raw, {});
|
||||
|
||||
test("#7078 m365.cloud.microsoft wss URL extracts access_token + chathubPath", () => {
|
||||
const raw =
|
||||
"wss://m365.cloud.microsoft/m365Copilot/Chathub/user@tenant.example.com?access_token=TOKEN123";
|
||||
const parts = extract(raw);
|
||||
assert.equal(parts.accessToken, "TOKEN123");
|
||||
assert.equal(parts.chathubPath, "user@tenant.example.com");
|
||||
});
|
||||
|
||||
test("#7078 regional subdomain m365.cloud.microsoft also accepted", () => {
|
||||
const raw =
|
||||
"wss://eu.m365.cloud.microsoft/m365Copilot/Chathub/user@tenant?access_token=TOKEN456";
|
||||
const parts = extract(raw);
|
||||
assert.equal(parts.accessToken, "TOKEN456");
|
||||
assert.equal(parts.chathubPath, "user@tenant");
|
||||
});
|
||||
|
||||
test("#7078 legacy substrate.office.com still works (no regression)", () => {
|
||||
const raw =
|
||||
"wss://substrate.office.com/m365Copilot/Chathub/user@tenant?access_token=LEGACY";
|
||||
const parts = extract(raw);
|
||||
assert.equal(parts.accessToken, "LEGACY");
|
||||
assert.equal(parts.chathubPath, "user@tenant");
|
||||
});
|
||||
|
||||
test("#7078 key/value string form still parsed", () => {
|
||||
const raw = "access_token=KV;chathubPath=user@tenant";
|
||||
const parts = extract(raw);
|
||||
assert.equal(parts.accessToken, "KV");
|
||||
assert.equal(parts.chathubPath, "user@tenant");
|
||||
});
|
||||
|
||||
test("#7078 m365.cloud.microsoft with explicit :443 port still extracts (hostname, not host)", () => {
|
||||
const raw =
|
||||
"wss://m365.cloud.microsoft:443/m365Copilot/Chathub/user@tenant?access_token=TOKENPORT";
|
||||
const parts = extract(raw);
|
||||
assert.equal(parts.accessToken, "TOKENPORT");
|
||||
assert.equal(parts.chathubPath, "user@tenant");
|
||||
});
|
||||
Reference in New Issue
Block a user