export async function applyPreRequestActions()

in src/policy.ts [167:234]


export async function applyPreRequestActions(
  context: RecaptchaContext,
  req: EdgeRequest,
  actions: action.Action[],
): Promise<EdgeResponse | null> {
  let terminalAction: action.Action = action.createAllowAction();
  const reqNonterminalActions: action.RequestNonTerminalAction[] = [];

  for (const action of actions) {
    if (isTerminalAction(action)) {
      terminalAction = action;
    } else if (isRequestNonTerminalAction(action)) {
      reqNonterminalActions.push(action);
    } else if (isResponseNonTerminalAction(action)) {
      context.log("debug", "Applying request actions, ignoring response actions");
    } else {
      /* v8 ignore next */
      throw new Error("Unsupported action: " + action);
    }
  }
  if (isBlockAction(terminalAction)) {
    context.log("debug", "terminalAction: block");
    return context.createResponse("", { status: 403 }); // TODO: custom html
  }

  if (isRedirectAction(terminalAction)) {
    context.log("debug", "terminalAction: redirect");
    // TODO: consider caching event.
    const event = await context.buildEvent(req);
    const url = new URL(req.url);
    if (!context.config.challengePageSiteKey) {
      context.log("error", "[!] attempt to redirect without challenge page site key!");
    }
    const soz = createSoz(
      context,
      url.hostname,
      event.userIpAddress ?? "",
      context.config.projectNumber,
      context.config.challengePageSiteKey ?? "", // TODO: default site key?
    );
    const reqOptions = {
      method: "POST",
      headers: {
        "content-type": "application/json;charset=UTF-8",
        "X-ReCaptcha-Soz": soz,
      },
    };
    return context.fetch_challenge_page(reqOptions);
  }

  // Handle Pre-Request actions.
  for (const action of reqNonterminalActions) {
    context.log("debug", "reqNonterminal action: setHeader");
    if (isSetHeaderAction(action)) {
      req.addHeader(action.setHeader.key ?? "", action.setHeader.value ?? "");
    } else if (isSubstituteAction(action)) {
      context.log("debug", "reqNonterminal action: substitute");
      const url = new URL(req.url);
      req.url = `${url.origin}${action.substitute.path}`;
    } else {
      /* v8 ignore next 2 lines */
      throw new Error("Unsupported pre-request action: " + action);
    }
  }

  context.log("debug", "terminalAction: allow");
  return null;
}