Home / Function/ HooksListing() — supabase Function Reference

HooksListing() — supabase Function Reference

Architecture documentation for the HooksListing() function in HooksListing.tsx from the supabase codebase.

Entity Profile

Dependency Diagram

graph TD
  dd52c5dc_b7d0_44e1_518c_ed23612e4645["HooksListing()"]
  53875c04_b5ee_2f68_7ad7_2d91dfb75f9f["getRevokePermissionStatements()"]
  dd52c5dc_b7d0_44e1_518c_ed23612e4645 -->|calls| 53875c04_b5ee_2f68_7ad7_2d91dfb75f9f
  44a1d22a_5d71_8dd5_1cd2_b6af6a48cf0f["extractMethod()"]
  dd52c5dc_b7d0_44e1_518c_ed23612e4645 -->|calls| 44a1d22a_5d71_8dd5_1cd2_b6af6a48cf0f
  2b26d2a1_635d_8e95_7c0f_a3382ff8636f["isValidHook()"]
  dd52c5dc_b7d0_44e1_518c_ed23612e4645 -->|calls| 2b26d2a1_635d_8e95_7c0f_a3382ff8636f
  style dd52c5dc_b7d0_44e1_518c_ed23612e4645 fill:#6366f1,stroke:#818cf8,color:#fff

Relationship Graph

Source Code

apps/studio/components/interfaces/Auth/Hooks/HooksListing.tsx lines 29–212

export const HooksListing = () => {
  const { ref: projectRef } = useParams()
  const { data: project } = useSelectedProjectQuery()
  const {
    data: authConfig,
    error: authConfigError,
    isError,
    isPending: isLoading,
  } = useAuthConfigQuery({ projectRef })

  const [hook, setHook] = useQueryState('hook', parseAsString)

  const [selectedHookForDeletion, setSelectedHookForDeletion] = useState<Hook | null>(null)

  const { mutate: updateAuthHooks, isPending: isDeletingAuthHook } = useAuthHooksUpdateMutation({
    onSuccess: async () => {
      if (!selectedHookForDeletion) return

      const { method } = selectedHookForDeletion
      if (method.type === 'postgres') {
        const revokeStatements = getRevokePermissionStatements(method.schema, method.functionName)
        await executeSql({
          projectRef,
          connectionString: project!.connectionString,
          sql: revokeStatements.join('\n'),
        })
      }
      toast.success(`${selectedHookForDeletion.title} has been deleted.`)
      setSelectedHookForDeletion(null)
      setHook(null)
    },
    onError: (error) => {
      toast.error(`Failed to delete hook: ${error.message}`)
    },
  })

  const hooks: Hook[] = HOOKS_DEFINITIONS.map((definition) => {
    return {
      ...definition,
      enabled: authConfig?.[definition.enabledKey] || false,
      method: extractMethod(
        authConfig?.[definition.uriKey] || '',
        authConfig?.[definition.secretsKey] || ''
      ),
    }
  })

  const selectedHook = hooks.find((h) => h.id === hook)

  useEffect(() => {
    if (!!hook && !selectedHook) {
      toast('Hook not found')
      setHook(null)
    }
  }, [hook, selectedHook, setHook])

  if (isError) {
    return (
      <PageSection>
        <PageSectionContent>
          <AlertError
            error={authConfigError}
            subject="Failed to retrieve auth configuration for hooks"
          />
        </PageSectionContent>
      </PageSection>
    )
  }

  if (isLoading) {
    return (
      <PageSection>
        <PageSectionContent>
          <GenericSkeletonLoader />
        </PageSectionContent>
      </PageSection>
    )
  }

  return (
    <PageSection>
      <PageSectionMeta>
        <PageSectionSummary>
          <PageSectionTitle>Hooks</PageSectionTitle>
        </PageSectionSummary>
        <PageSectionAside>
          <AddHookDropdown
            onSelectHook={(title) => {
              const hook = hooks.find((h) => h.title === title)
              if (hook) setHook(hook.id)
            }}
          />
        </PageSectionAside>
      </PageSectionMeta>
      <PageSectionContent>
        {hooks.filter((h) => isValidHook(h)).length === 0 && (
          <EmptyStatePresentational
            title="Create an auth hook"
            description="Use Postgres functions or HTTP endpoints to customize your authentication flow."
          >
            <AddHookDropdown
              type="default"
              align="center"
              buttonText="Add a new hook"
              onSelectHook={(title) => {
                const hook = hooks.find((h) => h.title === title)
                if (hook) setHook(hook.id)
              }}
            />
          </EmptyStatePresentational>
        )}

        <div className="-space-y-px">
          {hooks
            .filter((h) => isValidHook(h))
            .map((hook) => {
              return (
                <HookCard key={hook.enabledKey} hook={hook} onSelect={() => setHook(hook.id)} />
              )
            })}
        </div>

        <CreateHookSheet
          title={selectedHook?.title ?? null}
          visible={!!selectedHook}
          onDelete={() => {
            const hook = hooks.find((h) => h.title === selectedHook?.title)
            if (hook) setSelectedHookForDeletion(hook)
          }}
          onClose={() => setHook(null)}
          authConfig={authConfig!}
        />

        <ConfirmationModal
          visible={!!selectedHookForDeletion}
          size="large"
          variant="destructive"
          loading={isDeletingAuthHook}
          title={`Confirm to delete ${selectedHookForDeletion?.title}`}
          confirmLabel="Delete"
          confirmLabelLoading="Deleting"
          onCancel={() => setSelectedHookForDeletion(null)}
          onConfirm={() => {
            if (!selectedHookForDeletion) return
            updateAuthHooks({
              projectRef: projectRef!,
              config: {
                [selectedHookForDeletion.enabledKey]: false,
                [selectedHookForDeletion.uriKey]: null,
                [selectedHookForDeletion.secretsKey]: null,
              },
            })
          }}
        >
          <div>
            <p className="text-sm text-foreground-light">
              Are you sure you want to delete the {selectedHookForDeletion?.title}?
            </p>
            {selectedHookForDeletion?.method.type === 'postgres' && (
              <>
                <p className="text-sm text-foreground-light">
                  The following statements will be executed on the{' '}
                  {selectedHookForDeletion?.method.schema}.
                  {selectedHookForDeletion?.method.functionName} function:
                </p>
                <div className={cn('mt-4', 'h-72')}>
                  <CodeEditor
                    id="deletion-hook-editor"
                    isReadOnly={true}
                    language="pgsql"
                    value={getRevokePermissionStatements(
                      selectedHookForDeletion?.method.schema,
                      selectedHookForDeletion?.method.functionName
                    ).join('\n\n')}
                  />
                </div>
              </>
            )}
          </div>
        </ConfirmationModal>
      </PageSectionContent>
    </PageSection>
  )
}

Subdomains

Frequently Asked Questions

What does HooksListing() do?
HooksListing() is a function in the supabase codebase.
What does HooksListing() call?
HooksListing() calls 3 function(s): extractMethod, getRevokePermissionStatements, isValidHook.

Analyze Your Own Codebase

Get architecture documentation, dependency graphs, and domain analysis for your codebase in minutes.

Try Supermodel Free