Google reCAPTCHA challenge
You can use defineAuth and defineFunction to create an auth experience that requires a reCAPTCHA v3 token. This can be accomplished by leveraging Amazon Cognito's feature to define a custom auth challenge and 3 triggers:
Create auth challenge trigger
To get started, create the first of the three triggers, create-auth-challenge. This is the trigger responsible for creating the reCAPTCHA challenge after a password is verified.
import { defineFunction } from "@aws-amplify/backend"
export const createAuthChallenge = defineFunction({  name: "create-auth-challenge",  resourceGroupName: 'auth'})After creating the resource file, create the handler with the following contents:
import type { CreateAuthChallengeTriggerHandler } from "aws-lambda"
export const handler: CreateAuthChallengeTriggerHandler = async (event) => {  const { request, response } = event
  if (    // session will contain 3 "steps": SRP, password verification, custom challenge    request.session.length === 2 &&    request.challengeName === "CUSTOM_CHALLENGE"  ) {    response.publicChallengeParameters = { trigger: "true" }    response.privateChallengeParameters = { answer: "" }    // optionally set challenge metadata    response.challengeMetadata = "CAPTCHA_CHALLENGE"  }
  return event}Define auth challenge trigger
Next, you will want to create the trigger responsible for defining the auth challenge flow, define-auth-challenge.
import { defineFunction } from "@aws-amplify/backend"
export const defineAuthChallenge = defineFunction({  name: "define-auth-challenge",  resourceGroupName: 'auth'})After creating the resource file, create the handler with the following contents:
import type { DefineAuthChallengeTriggerHandler } from "aws-lambda"
export const handler: DefineAuthChallengeTriggerHandler = async (event) => {  const { response } = event  const [srp, password, captcha] = event.request.session
  // deny by default  response.issueTokens = false  response.failAuthentication = true
  if (srp?.challengeName === "SRP_A") {    response.failAuthentication = false    response.challengeName = "PASSWORD_VERIFIER"  }
  if (    password?.challengeName === "PASSWORD_VERIFIER" &&    password.challengeResult === true  ) {    response.failAuthentication = false    response.challengeName = "CUSTOM_CHALLENGE"  }
  if (    captcha?.challengeName === "CUSTOM_CHALLENGE" &&    // check for the challenge metadata set in "create-auth-challenge"    captcha?.challengeMetadata === "CAPTCHA_CHALLENGE" &&    captcha.challengeResult === true  ) {    response.issueTokens = true    response.failAuthentication = false  }
  return event}Verify auth challenge response trigger
Lastly, create the trigger responsible for verifying the challenge response, which in this case is the reCAPTCHA token verification.
import { defineFunction, secret } from "@aws-amplify/backend"
export const verifyAuthChallengeResponse = defineFunction({  name: "verify-auth-challenge-response",  environment: {    GOOGLE_RECAPTCHA_SECRET_KEY: secret("GOOGLE_RECAPTCHA_SECRET_KEY"),  },  resourceGroupName: 'auth'})After creating the resource file, create the handler with the following contents:
import type { VerifyAuthChallengeResponseTriggerHandler } from "aws-lambda"import { env } from "$amplify/env/verify-auth-challenge-response"
/** * Google ReCAPTCHA verification response * @see https://developers.google.com/recaptcha/docs/v3#site_verify_response */type GoogleRecaptchaVerifyResponse = {  // whether this request was a valid reCAPTCHA token for your site  success: boolean  // the score for this request (0.0 - 1.0)  score: number  // the action name for this request (important to verify)  action: string  // timestamp of the challenge load (ISO format yyyy-MM-dd'T'HH:mm:ssZZ)  challenge_ts: string  // the hostname of the site where the reCAPTCHA was solved  hostname: string  // optional error codes  "error-codes"?: unknown[]}
export const handler: VerifyAuthChallengeResponseTriggerHandler = async (  event) => {  if (!event.request.challengeAnswer) {    throw new Error("Missing challenge answer")  }
  // https://developers.google.com/recaptcha/docs/verify#api_request  const url = new URL("https://www.google.com/recaptcha/api/siteverify")  const params = new URLSearchParams({    secret: env.GOOGLE_RECAPTCHA_SECRET_KEY,    response: event.request.challengeAnswer,  })  url.search = params.toString()
  const request = new Request(url, {    method: "POST",  })
  const response = await fetch(request)  const result = (await response.json()) as GoogleRecaptchaVerifyResponse
  if (!result.success) {    throw new Error("Verification failed", { cause: result["error-codes"] })  }
  // indicate whether the answer is correct  event.response.answerCorrect = result.success
  return event}Configure auth resource
Finally, import and set the three triggers on your auth resource:
import { defineAuth } from "@aws-amplify/backend"import { createAuthChallenge } from "./create-auth-challenge/resource"import { defineAuthChallenge } from "./define-auth-challenge/resource"import { verifyAuthChallengeResponse } from "./verify-auth-challenge-response/resource"
/** * Define and configure your auth resource * @see https://docs.amplify.aws/gen2/build-a-backend/auth */export const auth = defineAuth({  loginWith: {    email: true,  },  triggers: {    createAuthChallenge,    defineAuthChallenge,    verifyAuthChallengeResponse,  },})