import {RefreshCw, Trash2} from 'lucide-react' import {useMutation, useQuery, useQueryClient} from '@tanstack/react-query' import {useEffect, useState} from 'react' import {deleteFlatItem, getCloudResource, listFlatItems, listUserPoolGroups, putFlatItem} from '@/api/cloudProxyClient' import {CognitoAppClientSettings} from '@/components/CognitoAppClientSettings' import {CognitoGroupsSection} from '@/components/CognitoGroupsSection' import {CognitoSignInTest} from '@/components/CognitoSignInTest' import {CognitoTriggersSection} from '@/components/CognitoTriggersSection' import {CognitoUserDetail} from '@/components/CognitoUserDetail' import {CopyValueButton} from '@/components/CopyValueButton' import {useAccountId} from '@/lib/accountStore' import {formatDateTime} from '@/lib/format' import type {CloudResource} from '@/types/resource' type Props = { resource?: CloudResource runtimeReachable: boolean } type AppClient = {clientId: string; clientName: string} export function CognitoUsersPanel({resource, runtimeReachable}: Props) { const accountId = useAccountId() const queryClient = useQueryClient() const [login, setLogin] = useState('') const [password, setPassword] = useState('') const [permanent, setPermanent] = useState(true) const [openUser, setOpenUser] = useState(null) const [openClient, setOpenClient] = useState(null) const usersKey = ['cognito-users', accountId, resource?.id] const groupsKey = ['cognito-groups', accountId, resource?.id] // The table row is a list summary; sign-in method and app clients come from the full pool. const poolQuery = useQuery({ queryKey: ['cognito-pool', accountId, resource?.id], queryFn: ({signal}) => getCloudResource('aws', 'userpools', resource?.id ?? '', signal), enabled: Boolean(resource) && runtimeReachable, }) const usersQuery = useQuery({ queryKey: usersKey, queryFn: ({signal}) => listFlatItems('aws', 'userpools', resource?.id ?? '', undefined, signal), enabled: Boolean(resource) && runtimeReachable, }) const groupsQuery = useQuery({ queryKey: groupsKey, queryFn: ({signal}) => listUserPoolGroups('aws', resource?.id ?? '', signal), enabled: Boolean(resource) && runtimeReachable, }) useEffect(() => { setLogin('') setPassword('') setPermanent(true) setOpenUser(null) }, [resource?.id]) // The pool list carries each pool's user count, which the delete confirmation reads. const refreshUsers = () => Promise.all([ queryClient.invalidateQueries({queryKey: usersKey}), queryClient.invalidateQueries({queryKey: ['cloud-resources', 'aws', 'userpools']}), ]) const signInWithEmail = poolQuery.data?.metadata.signInWith !== 'username' const createMutation = useMutation({ mutationFn: () => putFlatItem('aws', 'userpools', resource?.id ?? '', { ...(signInWithEmail ? {email: login.trim()} : {username: login.trim()}), password, permanent, }), onSuccess: () => { setLogin('') setPassword('') return refreshUsers() }, }) const deleteMutation = useMutation({ mutationFn: (username: string) => deleteFlatItem('aws', 'userpools', resource?.id ?? '', username), onSuccess: (_result, username) => { if (openUser === username) setOpenUser(null) return refreshUsers() }, }) if (!resource) { return

Select a user pool

Choose a user pool to manage its app clients and users.

} const users = usersQuery.data?.items ?? [] const appClients = appClientsOf(poolQuery.data) const pending = createMutation.isPending || deleteMutation.isPending const error = poolQuery.error ?? usersQuery.error ?? createMutation.error ?? deleteMutation.error const loginLabel = signInWithEmail ? 'Email' : 'Username' return

App clients

Use a client ID with the pool ID to sign users in from your app
{poolQuery.isSuccess && appClients.length === 0 &&

This pool has no app clients.

} {appClients.length > 0 &&
{appClients.map((client) => ( ))}
NameClient ID
{client.clientName || '—'} {client.clientId}
} {openClient && setOpenClient(null)}/>}

Users

{users.length} {users.length === 1 ? 'user' : 'users'} in {resource.name}
{ event.preventDefault(); if (login.trim() && password) createMutation.mutate() }}>
{error instanceof Error &&

{error.message}

} {usersQuery.isLoading &&
Loading users
} {usersQuery.isSuccess && users.length === 0 &&

No users

Create a user to sign in to apps that use this pool.

} {users.length > 0 &&
{users.map((user) => { const name = stringValue(user.body.email) || stringValue(user.body.username) return })}
{loginLabel}StatusEnabledCreated
{name} {stringValue(user.body.status) || '—'} {user.body.enabled === false ? 'No' : 'Yes'} {formatDateTime(user.timestamp) ?? '—'}
} {openUser && setOpenUser(null)}/>}
} function appClientsOf(pool?: CloudResource): AppClient[] { const clients = pool?.metadata.appClients if (!Array.isArray(clients)) return [] return clients.filter((client): client is AppClient => typeof client?.clientId === 'string' && client.clientId !== '') } function stringValue(value: unknown): string { return typeof value === 'string' ? value : '' }