mirror of
https://github.com/Significant-Gravitas/AutoGPT.git
synced 2026-04-08 03:00:28 -04: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):
|
class CredentialsMetaResponse(BaseModel):
|
||||||
id: str
|
id: str
|
||||||
|
provider: str
|
||||||
type: CredentialsType
|
type: CredentialsType
|
||||||
title: str | None
|
title: str | None
|
||||||
scopes: list[str] | None
|
scopes: list[str] | None
|
||||||
@@ -119,6 +120,7 @@ def callback(
|
|||||||
)
|
)
|
||||||
return CredentialsMetaResponse(
|
return CredentialsMetaResponse(
|
||||||
id=credentials.id,
|
id=credentials.id,
|
||||||
|
provider=credentials.provider,
|
||||||
type=credentials.type,
|
type=credentials.type,
|
||||||
title=credentials.title,
|
title=credentials.title,
|
||||||
scopes=credentials.scopes,
|
scopes=credentials.scopes,
|
||||||
@@ -126,8 +128,26 @@ def callback(
|
|||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
@router.get("/{provider}/credentials")
|
@router.get("/credentials")
|
||||||
def list_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")],
|
provider: Annotated[str, Path(title="The provider to list credentials for")],
|
||||||
user_id: Annotated[str, Depends(get_user_id)],
|
user_id: Annotated[str, Depends(get_user_id)],
|
||||||
) -> list[CredentialsMetaResponse]:
|
) -> list[CredentialsMetaResponse]:
|
||||||
@@ -135,6 +155,7 @@ def list_credentials(
|
|||||||
return [
|
return [
|
||||||
CredentialsMetaResponse(
|
CredentialsMetaResponse(
|
||||||
id=cred.id,
|
id=cred.id,
|
||||||
|
provider=cred.provider,
|
||||||
type=cred.type,
|
type=cred.type,
|
||||||
title=cred.title,
|
title=cred.title,
|
||||||
scopes=cred.scopes if isinstance(cred, OAuth2Credentials) else None,
|
scopes=cred.scopes if isinstance(cred, OAuth2Credentials) else None,
|
||||||
|
|||||||
@@ -184,43 +184,64 @@ export default function CredentialsProvider({
|
|||||||
api.isAuthenticated().then((isAuthenticated) => {
|
api.isAuthenticated().then((isAuthenticated) => {
|
||||||
if (!isAuthenticated) return;
|
if (!isAuthenticated) return;
|
||||||
|
|
||||||
CREDENTIALS_PROVIDER_NAMES.forEach(
|
api.listCredentials().then((response) => {
|
||||||
(provider: CredentialsProviderName) => {
|
const credentialsByProvider = response.reduce(
|
||||||
api.listCredentials(provider).then((response) => {
|
(acc, cred) => {
|
||||||
const { oauthCreds, apiKeys } = response.reduce<{
|
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[];
|
oauthCreds: CredentialsMetaResponse[];
|
||||||
apiKeys: 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) => ({
|
setProviders((prev) => ({
|
||||||
...prev,
|
...prev,
|
||||||
|
...Object.entries(credentialsByProvider).reduce(
|
||||||
|
(acc, [provider, { apiKeys, oauthCreds }]) => ({
|
||||||
|
...acc,
|
||||||
[provider]: {
|
[provider]: {
|
||||||
provider,
|
provider,
|
||||||
providerName: providerDisplayNames[provider],
|
providerName:
|
||||||
|
providerDisplayNames[provider as CredentialsProviderName],
|
||||||
savedApiKeys: apiKeys,
|
savedApiKeys: apiKeys,
|
||||||
savedOAuthCredentials: oauthCreds,
|
savedOAuthCredentials: oauthCreds,
|
||||||
oAuthCallback: (code: string, state_token: string) =>
|
oAuthCallback: (code: string, state_token: string) =>
|
||||||
oAuthCallback(provider, code, state_token),
|
oAuthCallback(
|
||||||
|
provider as CredentialsProviderName,
|
||||||
|
code,
|
||||||
|
state_token,
|
||||||
|
),
|
||||||
createAPIKeyCredentials: (
|
createAPIKeyCredentials: (
|
||||||
credentials: APIKeyCredentialsCreatable,
|
credentials: APIKeyCredentialsCreatable,
|
||||||
) => createAPIKeyCredentials(provider, credentials),
|
) =>
|
||||||
|
createAPIKeyCredentials(
|
||||||
|
provider as CredentialsProviderName,
|
||||||
|
credentials,
|
||||||
|
),
|
||||||
deleteCredentials: (id: string, force: boolean = false) =>
|
deleteCredentials: (id: string, force: boolean = false) =>
|
||||||
deleteCredentials(provider, id, force),
|
deleteCredentials(
|
||||||
|
provider as CredentialsProviderName,
|
||||||
|
id,
|
||||||
|
force,
|
||||||
|
),
|
||||||
},
|
},
|
||||||
}));
|
}),
|
||||||
});
|
{},
|
||||||
},
|
),
|
||||||
);
|
}));
|
||||||
|
});
|
||||||
});
|
});
|
||||||
}, [api, createAPIKeyCredentials, deleteCredentials, oAuthCallback]);
|
}, [api, createAPIKeyCredentials, deleteCredentials, oAuthCallback]);
|
||||||
|
|
||||||
|
|||||||
@@ -212,8 +212,12 @@ export default class BaseAutoGPTServerAPI {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
listCredentials(provider: string): Promise<CredentialsMetaResponse[]> {
|
listCredentials(provider?: string): Promise<CredentialsMetaResponse[]> {
|
||||||
return this._get(`/integrations/${provider}/credentials`);
|
return this._get(
|
||||||
|
provider
|
||||||
|
? `/integrations/${provider}/credentials`
|
||||||
|
: "/integrations/credentials",
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
getCredentials(
|
getCredentials(
|
||||||
|
|||||||
@@ -260,6 +260,7 @@ export type NodeExecutionResult = {
|
|||||||
/* Mirror of backend/server/integrations/router.py:CredentialsMetaResponse */
|
/* Mirror of backend/server/integrations/router.py:CredentialsMetaResponse */
|
||||||
export type CredentialsMetaResponse = {
|
export type CredentialsMetaResponse = {
|
||||||
id: string;
|
id: string;
|
||||||
|
provider: CredentialsProviderName;
|
||||||
type: CredentialsType;
|
type: CredentialsType;
|
||||||
title?: string;
|
title?: string;
|
||||||
scopes?: Array<string>;
|
scopes?: Array<string>;
|
||||||
@@ -292,7 +293,7 @@ type BaseCredentials = {
|
|||||||
id: string;
|
id: string;
|
||||||
type: CredentialsType;
|
type: CredentialsType;
|
||||||
title?: string;
|
title?: string;
|
||||||
provider: string;
|
provider: CredentialsProviderName;
|
||||||
};
|
};
|
||||||
|
|
||||||
/* Mirror of autogpt_libs/supabase_integration_credentials_store/types.py:OAuth2Credentials */
|
/* Mirror of autogpt_libs/supabase_integration_credentials_store/types.py:OAuth2Credentials */
|
||||||
|
|||||||
Reference in New Issue
Block a user