Files
floci-ui/packages/api/src/cloudProxy.ts
T
Zakaria 4156afccfe feat(api): add Cognito user pools to the cloud explorer
Adds a userpools catalog entry, schema and AwsUserPoolsAdapter, verified
against Floci core:

- list/get/create/delete user pools; create can set email or username
  sign-in, a relaxed password policy for local test users, and a public
  app client (on by default) whose id is surfaced in the pool metadata
- users as the pool's child items: list (paged), get, create and delete;
  passwords are set permanent by default so users can sign in at once
- map Cognito's HTTP-400 error names (UserNotFoundException,
  UsernameExistsException, AliasExistsException, InvalidPasswordException)
- link Floci's cognito-idp service to the new page on the diagnostics page
2026-10-23 12:12:40 -04:00

137 lines
7.1 KiB
TypeScript

import {CloudAdapterRegistry} from './registry/CloudAdapterRegistry'
import {AwsComputeAdapter} from './adapter-aws/AwsComputeAdapter'
import {AwsNetworkingAdapter} from './adapter-aws/AwsNetworkingAdapter'
import {AwsDatabaseAdapter} from './adapter-aws/AwsDatabaseAdapter'
import {AwsEksAdapter} from './adapter-aws/AwsEksAdapter'
import {AwsStorageAdapter} from './adapter-aws/AwsStorageAdapter'
import {AwsLogsAdapter} from './adapter-aws/AwsLogsAdapter'
import {AzureNoSqlAdapter} from './adapter-azure/AzureNoSqlAdapter'
import {AwsDynamoDbAdapter} from './adapter-aws/AwsDynamoDbAdapter'
import {AzureDatabaseAdapter} from './adapter-azure/AzureDatabaseAdapter'
import {AzureServiceBusAdapter} from './adapter-azure/AzureServiceBusAdapter'
import {AzureStorageAdapter} from './adapter-azure/AzureStorageAdapter'
import {AzureAksAdapter} from './adapter-azure/AzureAksAdapter'
import {AzureComputeAdapter} from './adapter-azure/AzureComputeAdapter'
import {GcpStorageAdapter} from './adapter-gcp/GcpStorageAdapter'
import {GcpCloudFunctionsAdapter} from './adapter-gcp/GcpCloudFunctionsAdapter'
import {GcpCloudSqlAdapter} from './adapter-gcp/GcpCloudSqlAdapter'
import {GcpGkeAdapter} from './adapter-gcp/GcpGkeAdapter'
import {GcpCloudRunAdapter} from './adapter-gcp/GcpCloudRunAdapter'
import {GcpPubSubAdapter} from './adapter-gcp/GcpPubSubAdapter'
import {GcpSecretManagerAdapter} from './adapter-gcp/GcpSecretManagerAdapter'
import {GcpSchedulerAdapter} from './adapter-gcp/GcpSchedulerAdapter'
import {AwsSqsAdapter} from './adapter-aws/AwsSqsAdapter'
import {CloudProxyService} from './service/CloudProxyService'
import {AzureServerlessAdapter} from './adapter-azure/AzureServerlessAdapter'
import {AzureKeyVaultAdapter} from './adapter-azure/AzureKeyVaultAdapter'
import {AwsServerlessAdapter} from './adapter-aws/AwsServerlessAdapter'
import {AwsParameterStoreAdapter} from './adapter-aws/AwsParameterStoreAdapter'
import {AwsKmsAdapter} from './adapter-aws/AwsKmsAdapter'
import {AwsStepFunctionsAdapter} from './adapter-aws/AwsStepFunctionsAdapter'
import {AwsLoadBalancingAdapter} from './adapter-aws/AwsLoadBalancingAdapter'
import {AwsTargetGroupAdapter} from './adapter-aws/AwsTargetGroupAdapter'
import {AwsEventBridgeAdapter} from './adapter-aws/AwsEventBridgeAdapter'
import {AwsIamAdapter} from './adapter-aws/AwsIamAdapter'
import {AwsApiGatewayAdapter} from './adapter-aws/AwsApiGatewayAdapter'
import {AwsCloudFormationAdapter} from './adapter-aws/AwsCloudFormationAdapter'
import {AwsSecretsAdapter} from './adapter-aws/AwsSecretsAdapter'
import {AwsSesAdapter} from './adapter-aws/AwsSesAdapter'
import {AwsAppConfigAdapter} from './adapter-aws/AwsAppConfigAdapter'
import {AwsSnsAdapter} from './adapter-aws/AwsSnsAdapter'
import {AwsEcrAdapter} from './adapter-aws/AwsEcrAdapter'
import {AwsCodeBuildAdapter} from './adapter-aws/AwsCodeBuildAdapter'
import {AwsCodePipelineAdapter} from './adapter-aws/AwsCodePipelineAdapter'
import {AwsCodeDeployAdapter} from './adapter-aws/AwsCodeDeployAdapter'
import {AwsEcsAdapter} from './adapter-aws/AwsEcsAdapter'
import {AwsFargateAdapter} from './adapter-aws/AwsFargateAdapter'
import {AwsKinesisAdapter} from './adapter-aws/AwsKinesisAdapter'
import {AwsElastiCacheAdapter} from './adapter-aws/AwsElastiCacheAdapter'
import {AwsLightsailAdapter} from './adapter-aws/AwsLightsailAdapter'
import {AwsUserPoolsAdapter} from './adapter-aws/AwsUserPoolsAdapter'
import {awsClientsForAccount, resolveAccountId} from './aws'
import {createEc2Service} from './services/ec2'
import {createEksService} from './services/eks'
import {createRdsService} from './services/rds'
/**
* Build the adapter registry for an account. The account id drives the AWS SDK
* credentials (see aws.ts), so every AWS call is isolated to that account; Azure
* and GCP adapters use their own runtime auth model and are account-neutral.
*
* Exported separately from the service so tests can assert registry contents —
* notably that every adapter implements what its schema advertises — without
* reaching into private state.
*/
export function createCloudAdapterRegistry(accountId?: string | null): CloudAdapterRegistry {
const clients = awsClientsForAccount(accountId)
const ec2Service = createEc2Service(clients.ec2)
return new CloudAdapterRegistry([
new AwsStorageAdapter(clients.s3, clients.lambda, resolveAccountId(accountId)),
new AwsDynamoDbAdapter(clients.dynamodb),
new AwsEksAdapter(createEksService(clients.eks)),
new AwsDatabaseAdapter(createRdsService(clients.rds), clients.rds, clients.rdsData),
new AwsComputeAdapter(ec2Service),
new AwsNetworkingAdapter(ec2Service),
new AwsServerlessAdapter(clients.lambda, clients.eventbridge),
new AwsLogsAdapter(clients.logs),
new AwsParameterStoreAdapter(clients.ssm),
new AwsKmsAdapter(clients.kms),
new AwsStepFunctionsAdapter(clients.sfn),
new AwsLoadBalancingAdapter(clients.elbv2, clients.ec2),
new AwsTargetGroupAdapter(clients.elbv2, clients.ec2),
new AwsEventBridgeAdapter(clients.eventbridge, clients.lambda),
new AwsIamAdapter(clients.iam),
new AwsApiGatewayAdapter(clients.apiGateway, clients.lambda, resolveAccountId(accountId)),
new AwsCloudFormationAdapter(clients.cloudformation),
new AwsSecretsAdapter(clients.secretsManager),
new AwsSesAdapter(),
new AwsAppConfigAdapter(clients.appConfig),
new AwsSnsAdapter(clients.sns),
new AwsEcrAdapter(clients.ecr),
new AwsCodeBuildAdapter(clients.codebuild),
new AwsCodePipelineAdapter(clients.codepipeline),
new AwsCodeDeployAdapter(clients.codedeploy, clients.lambda),
new AwsEcsAdapter(clients.ecs, clients.elbv2),
new AwsFargateAdapter(new AwsEcsAdapter(clients.ecs, clients.elbv2)),
new AwsKinesisAdapter(clients.kinesis),
new AwsElastiCacheAdapter(clients.elasticache),
new AwsLightsailAdapter(clients.lightsail),
new AwsUserPoolsAdapter(clients.cognito),
new AzureStorageAdapter(),
new AzureServiceBusAdapter(),
new AzureDatabaseAdapter(),
new AzureAksAdapter(),
new AzureNoSqlAdapter(),
new AzureComputeAdapter(),
new GcpStorageAdapter(),
new GcpCloudFunctionsAdapter(),
new GcpCloudSqlAdapter(),
new GcpGkeAdapter(),
new GcpCloudRunAdapter(),
new GcpPubSubAdapter(),
new GcpSecretManagerAdapter(),
new GcpSchedulerAdapter(),
new AwsSqsAdapter(clients.sqs),
new AzureServerlessAdapter(),
new AzureKeyVaultAdapter(),
])
}
export function createCloudProxyService(accountId?: string | null): CloudProxyService {
return new CloudProxyService(createCloudAdapterRegistry(accountId))
}
const serviceCache = new Map<string, CloudProxyService>()
/** Return a cached account-scoped CloudProxyService, building it on first use. */
export function serviceForAccount(accountId?: string | null): CloudProxyService {
const id = resolveAccountId(accountId)
let service = serviceCache.get(id)
if (!service) {
service = createCloudProxyService(id)
serviceCache.set(id, service)
}
return service
}