mirror of
https://github.com/Significant-Gravitas/AutoGPT.git
synced 2026-01-11 08:08:08 -05:00
refactor(platform): Combine per-provider credentials API calls (#8772)
- Add `/integrations/credentials` endpoint which lists all credentials for the authenticated user - Amend credential fetching logic in front end to fetch all at once instead of per provider - Resolves #8770 - Resolves (hopefully) #8613
This commit is contained in:
committed by
GitHub
parent
c6e838da37
commit
f1414550f9
@@ -65,6 +65,7 @@ def login(
|
||||
|
||||
class CredentialsMetaResponse(BaseModel):
|
||||
id: str
|
||||
provider: str
|
||||
type: CredentialsType
|
||||
title: str | None
|
||||
scopes: list[str] | None
|
||||
@@ -119,6 +120,7 @@ def callback(
|
||||
)
|
||||
return CredentialsMetaResponse(
|
||||
id=credentials.id,
|
||||
provider=credentials.provider,
|
||||
type=credentials.type,
|
||||
title=credentials.title,
|
||||
scopes=credentials.scopes,
|
||||
@@ -126,8 +128,26 @@ def callback(
|
||||
)
|
||||
|
||||
|
||||
@router.get("/{provider}/credentials")
|
||||
@router.get("/credentials")
|
||||
def list_credentials(
|
||||
user_id: Annotated[str, Depends(get_user_id)],
|
||||
) -> list[CredentialsMetaResponse]:
|
||||
credentials = creds_manager.store.get_all_creds(user_id)
|
||||
return [
|
||||
CredentialsMetaResponse(
|
||||
id=cred.id,
|
||||
provider=cred.provider,
|
||||
type=cred.type,
|
||||
title=cred.title,
|
||||
scopes=cred.scopes if isinstance(cred, OAuth2Credentials) else None,
|
||||
username=cred.username if isinstance(cred, OAuth2Credentials) else None,
|
||||
)
|
||||
for cred in credentials
|
||||
]
|
||||
|
||||
|
||||
@router.get("/{provider}/credentials")
|
||||
def list_credentials_by_provider(
|
||||
provider: Annotated[str, Path(title="The provider to list credentials for")],
|
||||
user_id: Annotated[str, Depends(get_user_id)],
|
||||
) -> list[CredentialsMetaResponse]:
|
||||
@@ -135,6 +155,7 @@ def list_credentials(
|
||||
return [
|
||||
CredentialsMetaResponse(
|
||||
id=cred.id,
|
||||
provider=cred.provider,
|
||||
type=cred.type,
|
||||
title=cred.title,
|
||||
scopes=cred.scopes if isinstance(cred, OAuth2Credentials) else None,
|
||||
|
||||
@@ -184,43 +184,64 @@ export default function CredentialsProvider({
|
||||
api.isAuthenticated().then((isAuthenticated) => {
|
||||
if (!isAuthenticated) return;
|
||||
|
||||
CREDENTIALS_PROVIDER_NAMES.forEach(
|
||||
(provider: CredentialsProviderName) => {
|
||||
api.listCredentials(provider).then((response) => {
|
||||
const { oauthCreds, apiKeys } = response.reduce<{
|
||||
api.listCredentials().then((response) => {
|
||||
const credentialsByProvider = response.reduce(
|
||||
(acc, cred) => {
|
||||
if (!acc[cred.provider]) {
|
||||
acc[cred.provider] = { oauthCreds: [], apiKeys: [] };
|
||||
}
|
||||
if (cred.type === "oauth2") {
|
||||
acc[cred.provider].oauthCreds.push(cred);
|
||||
} else if (cred.type === "api_key") {
|
||||
acc[cred.provider].apiKeys.push(cred);
|
||||
}
|
||||
return acc;
|
||||
},
|
||||
{} as Record<
|
||||
CredentialsProviderName,
|
||||
{
|
||||
oauthCreds: CredentialsMetaResponse[];
|
||||
apiKeys: CredentialsMetaResponse[];
|
||||
}>(
|
||||
(acc, cred) => {
|
||||
if (cred.type === "oauth2") {
|
||||
acc.oauthCreds.push(cred);
|
||||
} else if (cred.type === "api_key") {
|
||||
acc.apiKeys.push(cred);
|
||||
}
|
||||
return acc;
|
||||
},
|
||||
{ oauthCreds: [], apiKeys: [] },
|
||||
);
|
||||
}
|
||||
>,
|
||||
);
|
||||
|
||||
setProviders((prev) => ({
|
||||
...prev,
|
||||
setProviders((prev) => ({
|
||||
...prev,
|
||||
...Object.entries(credentialsByProvider).reduce(
|
||||
(acc, [provider, { apiKeys, oauthCreds }]) => ({
|
||||
...acc,
|
||||
[provider]: {
|
||||
provider,
|
||||
providerName: providerDisplayNames[provider],
|
||||
providerName:
|
||||
providerDisplayNames[provider as CredentialsProviderName],
|
||||
savedApiKeys: apiKeys,
|
||||
savedOAuthCredentials: oauthCreds,
|
||||
oAuthCallback: (code: string, state_token: string) =>
|
||||
oAuthCallback(provider, code, state_token),
|
||||
oAuthCallback(
|
||||
provider as CredentialsProviderName,
|
||||
code,
|
||||
state_token,
|
||||
),
|
||||
createAPIKeyCredentials: (
|
||||
credentials: APIKeyCredentialsCreatable,
|
||||
) => createAPIKeyCredentials(provider, credentials),
|
||||
) =>
|
||||
createAPIKeyCredentials(
|
||||
provider as CredentialsProviderName,
|
||||
credentials,
|
||||
),
|
||||
deleteCredentials: (id: string, force: boolean = false) =>
|
||||
deleteCredentials(provider, id, force),
|
||||
deleteCredentials(
|
||||
provider as CredentialsProviderName,
|
||||
id,
|
||||
force,
|
||||
),
|
||||
},
|
||||
}));
|
||||
});
|
||||
},
|
||||
);
|
||||
}),
|
||||
{},
|
||||
),
|
||||
}));
|
||||
});
|
||||
});
|
||||
}, [api, createAPIKeyCredentials, deleteCredentials, oAuthCallback]);
|
||||
|
||||
|
||||
@@ -212,8 +212,12 @@ export default class BaseAutoGPTServerAPI {
|
||||
);
|
||||
}
|
||||
|
||||
listCredentials(provider: string): Promise<CredentialsMetaResponse[]> {
|
||||
return this._get(`/integrations/${provider}/credentials`);
|
||||
listCredentials(provider?: string): Promise<CredentialsMetaResponse[]> {
|
||||
return this._get(
|
||||
provider
|
||||
? `/integrations/${provider}/credentials`
|
||||
: "/integrations/credentials",
|
||||
);
|
||||
}
|
||||
|
||||
getCredentials(
|
||||
|
||||
@@ -260,6 +260,7 @@ export type NodeExecutionResult = {
|
||||
/* Mirror of backend/server/integrations/router.py:CredentialsMetaResponse */
|
||||
export type CredentialsMetaResponse = {
|
||||
id: string;
|
||||
provider: CredentialsProviderName;
|
||||
type: CredentialsType;
|
||||
title?: string;
|
||||
scopes?: Array<string>;
|
||||
@@ -292,7 +293,7 @@ type BaseCredentials = {
|
||||
id: string;
|
||||
type: CredentialsType;
|
||||
title?: string;
|
||||
provider: string;
|
||||
provider: CredentialsProviderName;
|
||||
};
|
||||
|
||||
/* Mirror of autogpt_libs/supabase_integration_credentials_store/types.py:OAuth2Credentials */
|
||||
|
||||
Reference in New Issue
Block a user