mirror of
https://github.com/Significant-Gravitas/AutoGPT.git
synced 2026-02-10 06:45:28 -05:00
fix(frontend/mcp): Filter credential auto-select by server URL discriminator
Prevent MCP credential cross-contamination where a credential for one server (e.g. Sentry) fills credential fields for other servers (e.g. Linear). Adds matchesDiscriminatorValues() to match credentials by host against discriminator_values from the schema.
This commit is contained in:
@@ -86,11 +86,13 @@ export function CredentialsGroupedView({
|
||||
const providerNames = schema.credentials_provider || [];
|
||||
const credentialTypes = schema.credentials_types || [];
|
||||
const requiredScopes = schema.credentials_scopes;
|
||||
const discriminatorValues = schema.discriminator_values;
|
||||
const savedCredential = findSavedCredentialByProviderAndType(
|
||||
providerNames,
|
||||
credentialTypes,
|
||||
requiredScopes,
|
||||
allProviders,
|
||||
discriminatorValues,
|
||||
);
|
||||
|
||||
if (savedCredential) {
|
||||
|
||||
@@ -23,6 +23,32 @@ function hasRequiredScopes(
|
||||
return true;
|
||||
}
|
||||
|
||||
/** Check if a credential matches the discriminator values (e.g. MCP server URL). */
|
||||
function matchesDiscriminatorValues(
|
||||
credential: { host?: string | null; provider: string; type: string },
|
||||
discriminatorValues?: string[],
|
||||
) {
|
||||
// MCP OAuth2 credentials must match by server URL
|
||||
if (credential.type === "oauth2" && credential.provider === "mcp") {
|
||||
if (!discriminatorValues || discriminatorValues.length === 0) return false;
|
||||
return (
|
||||
credential.host != null && discriminatorValues.includes(credential.host)
|
||||
);
|
||||
}
|
||||
// Host-scoped credentials match by host
|
||||
if (credential.type === "host_scoped" && credential.host) {
|
||||
if (!discriminatorValues || discriminatorValues.length === 0) return true;
|
||||
return discriminatorValues.some((v) => {
|
||||
try {
|
||||
return new URL(v).hostname === credential.host;
|
||||
} catch {
|
||||
return false;
|
||||
}
|
||||
});
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
export function splitCredentialFieldsBySystem(
|
||||
credentialFields: CredentialField[],
|
||||
allProviders: CredentialsProvidersContextType | null,
|
||||
@@ -160,6 +186,7 @@ export function findSavedCredentialByProviderAndType(
|
||||
credentialTypes: string[],
|
||||
requiredScopes: string[] | undefined,
|
||||
allProviders: CredentialsProvidersContextType | null,
|
||||
discriminatorValues?: string[],
|
||||
): SavedCredential | undefined {
|
||||
for (const providerName of providerNames) {
|
||||
const providerData = allProviders?.[providerName];
|
||||
@@ -176,9 +203,14 @@ export function findSavedCredentialByProviderAndType(
|
||||
credentialTypes.length === 0 ||
|
||||
credentialTypes.includes(credential.type);
|
||||
const scopesMatch = hasRequiredScopes(credential, requiredScopes);
|
||||
const hostMatches = matchesDiscriminatorValues(
|
||||
credential,
|
||||
discriminatorValues,
|
||||
);
|
||||
|
||||
if (!typeMatches) continue;
|
||||
if (!scopesMatch) continue;
|
||||
if (!hostMatches) continue;
|
||||
|
||||
matchingCredentials.push(credential as SavedCredential);
|
||||
}
|
||||
@@ -190,9 +222,14 @@ export function findSavedCredentialByProviderAndType(
|
||||
credentialTypes.length === 0 ||
|
||||
credentialTypes.includes(credential.type);
|
||||
const scopesMatch = hasRequiredScopes(credential, requiredScopes);
|
||||
const hostMatches = matchesDiscriminatorValues(
|
||||
credential,
|
||||
discriminatorValues,
|
||||
);
|
||||
|
||||
if (!typeMatches) continue;
|
||||
if (!scopesMatch) continue;
|
||||
if (!hostMatches) continue;
|
||||
|
||||
matchingCredentials.push(credential as SavedCredential);
|
||||
}
|
||||
@@ -214,6 +251,7 @@ export function findSavedUserCredentialByProviderAndType(
|
||||
credentialTypes: string[],
|
||||
requiredScopes: string[] | undefined,
|
||||
allProviders: CredentialsProvidersContextType | null,
|
||||
discriminatorValues?: string[],
|
||||
): SavedCredential | undefined {
|
||||
for (const providerName of providerNames) {
|
||||
const providerData = allProviders?.[providerName];
|
||||
@@ -230,9 +268,14 @@ export function findSavedUserCredentialByProviderAndType(
|
||||
credentialTypes.length === 0 ||
|
||||
credentialTypes.includes(credential.type);
|
||||
const scopesMatch = hasRequiredScopes(credential, requiredScopes);
|
||||
const hostMatches = matchesDiscriminatorValues(
|
||||
credential,
|
||||
discriminatorValues,
|
||||
);
|
||||
|
||||
if (!typeMatches) continue;
|
||||
if (!scopesMatch) continue;
|
||||
if (!hostMatches) continue;
|
||||
|
||||
matchingCredentials.push(credential as SavedCredential);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user