Home / Function/ SecondStep() — supabase Function Reference

SecondStep() — supabase Function Reference

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

Entity Profile

Relationship Graph

Source Code

apps/studio/components/interfaces/Account/TOTPFactors/AddNewFactorModal.tsx lines 109–220

const SecondStep = ({
  visible,
  factorName,
  factor: outerFactor,
  isLoading,
  onClose,
}: SecondStepProps) => {
  const [code, setCode] = useState('')
  const queryClient = useQueryClient()

  const [lastVisitedOrganization] = useLocalStorageQuery(
    LOCAL_STORAGE_KEYS.LAST_VISITED_ORGANIZATION,
    ''
  )

  const { mutate: unenroll } = useMfaUnenrollMutation({ onSuccess: () => onClose() })
  const { mutate: challengeAndVerify, isPending: isVerifying } = useMfaChallengeAndVerifyMutation({
    onError: (error) => {
      toast.error(`Failed to add a second factor authentication:  ${error?.message}`)
    },
    onSuccess: async () => {
      if (lastVisitedOrganization) {
        await queryClient.invalidateQueries({
          queryKey: organizationKeys.members(lastVisitedOrganization),
        })
      }
      toast.success(`Successfully added a second factor authentication`)
      onClose()
    },
  })

  const [factor, setFactor] = useState<{
    id: string
    type: 'totp'
    totp: {
      qr_code: string
      secret: string
      uri: string
    }
  } | null>(null)

  // this useEffect is to keep the factor until a new one comes. This is a fix to an issue which
  // happens when closing the modal, the outer factor is reset to null too soon and the modal
  // removes a big div mid transition.
  useEffect(() => {
    if (outerFactor && factor?.id !== outerFactor.id) {
      setFactor(outerFactor)
    }
  }, [outerFactor])

  return (
    <ConfirmationModal
      size="medium"
      visible={visible}
      title={`Verify new factor ${factorName}`}
      confirmLabel="Confirm"
      confirmLabelLoading="Confirming"
      loading={isVerifying}
      onCancel={() => {
        // If a factor has been created (but not verified), unenroll it. This will be run as a
        // side effect so that it's not confusing to the user why the modal stays open while
        // unenrolling.
        if (factor) unenroll({ factorId: factor.id })
      }}
      onConfirm={() => factor && challengeAndVerify({ factorId: factor.id, code })}
    >
      <div className="py-4 pb-0 text-sm">
        <span>
          Use an authenticator app to scan the following QR code, and provide the code from the app
          to complete the enrolment.
        </span>
      </div>
      {isLoading && (
        <div className="pb-4 px-4">
          <GenericSkeletonLoader />
        </div>
      )}
      {factor && (
        <>
          <div className="flex justify-center py-6">
            <div className="h-48 w-48 bg-white rounded">
              <img width={190} height={190} src={factor.totp.qr_code} alt={factor.totp.uri} />
            </div>
          </div>
          <div>
            <InformationBox
              title="Unable to scan?"
              description={
                <Input
                  copy
                  disabled
                  id="ref"
                  size="small"
                  label="You can also enter this secret key into your authenticator app"
                  value={factor.totp.secret}
                />
              }
            />
          </div>
          <div className="pt-2 pb-4">
            <Input
              label="Authentication code"
              value={code}
              placeholder="XXXXXX"
              onChange={(e) => setCode(e.target.value)}
            />
          </div>
        </>
      )}
    </ConfirmationModal>
  )
}

Subdomains

Analyze Your Own Codebase

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

Try Supermodel Free