mirror of
https://github.com/diegosouzapw/OmniRoute.git
synced 2026-08-17 20:52:15 +03:00
fix(sse): disambiguate compatible provider credential lookup
Co-authored-by: diegosouzapw <8016841+diegosouzapw@users.noreply.github.com>
This commit is contained in:
@@ -964,7 +964,17 @@ async function getProviderSearchPool(provider: string): Promise<string[]> {
|
||||
// internal provider ids like openai-compatible-responses-<uuid>.
|
||||
try {
|
||||
const providerNodes = await getCachedProviderNodes();
|
||||
for (const node of Array.isArray(providerNodes) ? providerNodes : []) {
|
||||
const compatibleNodes = Array.isArray(providerNodes) ? providerNodes : [];
|
||||
const nodeTypes = new Map<string, number>();
|
||||
for (const node of compatibleNodes) {
|
||||
const nodeRecord = asRecord(node);
|
||||
const nodeId = typeof nodeRecord.id === "string" ? nodeRecord.id.trim() : "";
|
||||
if (!nodeId) continue;
|
||||
const derivedType = nodeTypeFromId(nodeId);
|
||||
nodeTypes.set(derivedType, (nodeTypes.get(derivedType) || 0) + 1);
|
||||
}
|
||||
|
||||
for (const node of compatibleNodes) {
|
||||
const nodeRecord = asRecord(node);
|
||||
const nodePrefix = typeof nodeRecord.prefix === "string" ? nodeRecord.prefix.trim() : "";
|
||||
const nodeId = typeof nodeRecord.id === "string" ? nodeRecord.id.trim() : "";
|
||||
@@ -984,8 +994,9 @@ async function getProviderSearchPool(provider: string): Promise<string[]> {
|
||||
// looks up the concrete node id, and vice versa.
|
||||
const derivedType = nodeTypeFromId(nodeId);
|
||||
if (derivedType && derivedType !== nodeId) {
|
||||
const typeIsUnambiguous = nodeTypes.get(derivedType) === 1;
|
||||
if (nodeId === provider || nodeId === canonicalProvider || nodeId === canonicalAlias) {
|
||||
searchPool.add(derivedType);
|
||||
if (typeIsUnambiguous) searchPool.add(derivedType);
|
||||
}
|
||||
if (
|
||||
derivedType === provider ||
|
||||
|
||||
@@ -29,6 +29,7 @@ const auth = await import("../../src/sse/services/auth.ts");
|
||||
|
||||
const NODE_PREFIX = "my-compat-10085";
|
||||
const NODE_ID = `openai-compatible-chat-458d982b-0000-4000-8000-000000000000`;
|
||||
const NODE_B_ID = `openai-compatible-chat-558d982b-0000-4000-8000-000000000000`;
|
||||
|
||||
async function resetStorage() {
|
||||
core.resetDbInstance();
|
||||
@@ -52,6 +53,17 @@ async function seedNode() {
|
||||
});
|
||||
}
|
||||
|
||||
async function seedSecondNode() {
|
||||
await nodesDb.createProviderNode({
|
||||
id: NODE_B_ID,
|
||||
type: "openai-compatible",
|
||||
name: "My Compat B",
|
||||
prefix: "my-compat-10085-b",
|
||||
apiType: "chat",
|
||||
baseUrl: "https://example-b.test/v1",
|
||||
});
|
||||
}
|
||||
|
||||
test("a connection stored under the GENERIC type id is reachable when chat resolves the uuid node id (#10085)", async () => {
|
||||
await resetStorage();
|
||||
await seedNode();
|
||||
@@ -99,6 +111,34 @@ test("the bridge works in the other direction too: a uuid-stored connection is r
|
||||
);
|
||||
});
|
||||
|
||||
test("a concrete second node does not inherit the first node's generic credentials", async () => {
|
||||
await resetStorage();
|
||||
await seedNode();
|
||||
await seedSecondNode();
|
||||
await providersDb.createProviderConnection({
|
||||
provider: "openai-compatible-chat",
|
||||
authType: "apikey",
|
||||
apiKey: "sk-test-10085-node-a",
|
||||
name: "test-compat-node-a",
|
||||
isActive: true,
|
||||
testStatus: "active",
|
||||
priority: 1,
|
||||
providerSpecificData: {
|
||||
nodeId: NODE_ID,
|
||||
prefix: NODE_PREFIX,
|
||||
baseUrl: "https://example-a.test/v1",
|
||||
},
|
||||
});
|
||||
|
||||
const creds = await auth.getProviderCredentials(NODE_B_ID);
|
||||
|
||||
assert.equal(
|
||||
creds,
|
||||
null,
|
||||
"node B must not receive node A's generic connection when both nodes share a type"
|
||||
);
|
||||
});
|
||||
|
||||
test("control: a connection stored under the uuid node id is found by a uuid node id lookup", async () => {
|
||||
await resetStorage();
|
||||
await seedNode();
|
||||
|
||||
Reference in New Issue
Block a user