| 1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495 |
- // @ts-nocheck
- import { PermissionAction } from '@supabase/shared-types/out/constants'
- import { useParams } from 'common'
- import { Dispatch, SetStateAction, useEffect, useRef } from 'react'
- import { toast } from 'sonner'
- import { RealtimeConfig } from './useRealtimeMessages'
- import { RoleImpersonationPopover } from '@/components/interfaces/RoleImpersonationSelector/RoleImpersonationPopover'
- import { getKeys, useAPIKeysQuery } from '@/data/api-keys/api-keys-query'
- import { getTemporaryAPIKey } from '@/data/api-keys/temp-api-keys-query'
- import { useProjectPostgrestConfigQuery } from '@/data/config/project-postgrest-config-query'
- import { useSendEventMutation } from '@/data/telemetry/send-event-mutation'
- import { useAsyncCheckPermissions } from '@/hooks/misc/useCheckPermissions'
- import { useSelectedOrganizationQuery } from '@/hooks/misc/useSelectedOrganization'
- import { IS_PLATFORM } from '@/lib/constants'
- import { getRoleImpersonationJWT } from '@/lib/role-impersonation'
- import { useRoleImpersonationStateSnapshot } from '@/state/role-impersonation-state'
- interface RealtimeTokensPopoverProps {
- config: RealtimeConfig
- onChangeConfig: Dispatch<SetStateAction<RealtimeConfig>>
- }
- export const RealtimeTokensPopover = ({ config, onChangeConfig }: RealtimeTokensPopoverProps) => {
- const { ref } = useParams()
- const { data: org } = useSelectedOrganizationQuery()
- const snap = useRoleImpersonationStateSnapshot()
- const { can: canReadAPIKeys } = useAsyncCheckPermissions(PermissionAction.SECRETS_READ, '*')
- const { data: apiKeys } = useAPIKeysQuery(
- {
- projectRef: config.projectRef,
- reveal: true,
- },
- { enabled: canReadAPIKeys }
- )
- const { anonKey, publishableKey } = getKeys(apiKeys)
- const { data: postgrestConfig } = useProjectPostgrestConfigQuery(
- { projectRef: config.projectRef },
- { enabled: IS_PLATFORM }
- )
- const jwtSecret = postgrestConfig?.jwt_secret
- const { mutate: sendEvent } = useSendEventMutation()
- // only send a telemetry event if the user changes the role. Don't send an event during initial render.
- const isMounted = useRef(false)
- useEffect(() => {
- if (isMounted.current) {
- sendEvent({
- action: 'realtime_inspector_database_role_updated',
- groups: { project: ref ?? 'Unknown', organization: org?.slug ?? 'Unknown' },
- })
- }
- isMounted.current = true
- // eslint-disable-next-line react-hooks/exhaustive-deps
- }, [snap.role])
- useEffect(() => {
- const triggerUpdateTokenBearer = async () => {
- let token: string | undefined
- let bearer: string | null = null
- if (
- config.projectRef !== undefined &&
- jwtSecret !== undefined &&
- snap.role !== undefined &&
- snap.role.type === 'postgrest'
- ) {
- token = publishableKey?.api_key ?? anonKey?.api_key
- await getRoleImpersonationJWT(config.projectRef, jwtSecret, snap.role)
- .then((b) => (bearer = b))
- .catch((err) => toast.error(`Failed to get JWT for role: ${err.message}`))
- } else {
- try {
- const data = await getTemporaryAPIKey({ projectRef: config.projectRef, expiry: 3600 })
- token = data.api_key
- } catch (error) {
- token = publishableKey?.api_key
- }
- }
- if (token) {
- onChangeConfig({ ...config, token, bearer })
- }
- }
- triggerUpdateTokenBearer()
- // eslint-disable-next-line react-hooks/exhaustive-deps
- }, [snap.role, anonKey])
- return <RoleImpersonationPopover align="start" variant="connected-on-both" />
- }
|