SiteParent extends EscapablePageParent {
  receiveMessage(msg) {
    switch (msg.name) {
      case "Browser:SiteBlockedError":
        this._onAboutBlocked(
          msg.data.elementId,
          msg.data.reason,
          this.browsingContext === this.browsingContext.top,
          msg.data.blockedInfo
        );
        break;
    }
  }

  _onAboutBlocked(elementId, reason, isTopFrame, blockedInfo) {
    let browser = this.browsingContext.top.embedderElement;
    if (!browser) {
      return;
    }
    // Depending on what page we are displaying here (malware/phishing/unwanted)
    // use the right strings and links for each.
    let bucketName = "";
    let sendTelemetry = false;
    if (reason === "malware") {
      sendTelemetry = true;
      bucketName = "WARNING_MALWARE_PAGE_";
    } else if (reason === "phishing") {
      sendTelemetry = true;
      bucketName = "WARNING_PHISHING_PAGE_";
    } else if (reason === "unwanted") {
      sendTelemetry = true;
      bucketName = "WARNING_UNWANTED_PAGE_";
    } else if (reason === "harmful") {
      sendTelemetry = true;
      bucketName = "WARNING_HARMFUL_PAGE_";
    }
    let nsISecTel = Ci.IUrlClassifierUITelemetry;
    bucketName += isTopFrame ? "TOP_" : "FRAME_";

    switch (elementId) {
      case "goBackButton":
        if (sendTelemetry) {
          Glean.urlclassifier.uiEvents.accumulateSingleSample(
            nsISecTel[bucketName + "GET_ME_OUT_OF_HERE"]
          );
        }
        this.leaveErrorPage(browser, /* Never go back */ false);
        break;
      case "ignore_warning_link":
        if (Services.prefs.getBoolPref("browser.safebrowsing.allowOverride")) {
          if (sendTelemetry) {
            Glean.urlclassifier.uiEvents.accumulateSingleSample(
              nsISecTel[bucketName + "IGNORE_WARNING"]
            );
          }
          this.ignoreWarningLink(reason, blockedInfo);
        }
        break;
    }
  }

  ignoreWarningLink(reason, blockedInfo) {
    let { browsingContext } = this;
    // Add a notify bar before allowing the user to continue through to the
    // site, so that they don't lose track after, e.g., tab switching.
    // We can't use browser.contentPrincipal which is principal of about:blocked
    // Create one from uri with current principal origin attributes
    let principal = Services.scriptSecurityManager.createContentPrincipal(
      Services.io.newURI(blockedInfo.uri),
      browsingContext.currentWindowGlobal.documentPrincipal.originAttributes
    );
    Services.perms.addFromPrincipal(
      principal,
      "safe-browsing",
      Ci.nsIPermissionManager.ALLOW_ACTION,
      Ci.nsIPermissionManager.EXPIRE_SESSION
    );

    let buttons = [
      {
        label: lazy.browserBundle.GetStringFromName(
          "safebrowsing.getMeOutOfHereButton.label"
        ),
        accessKey: lazy.browserBundle.GetStringFromName(
          "safebrowsing.getMeOutOfHereButton.accessKey"
        ),
        callback: () => {
          let browser = browsingContext.top.embedderElement;
          this.leaveErrorPage(browser, /* Never go back */ false);
        },
      },
    ];

    let title;
    let chromeWin = browsingContext.topChromeWindow;
    if (reason === "malware") {
      let reportUrl = lazy.SafeBrowsing.getReportURL(
        "MalwareMistake",
        blockedInfo
      );
      title = lazy.browserBundle.GetStringFromName(
        "safebrowsing.reportedAttackSite"
      );
      // There's no button if we can not get report url, for example if the provider
      // of blockedInfo is not Google
      if (reportUrl) {
        buttons[1] = {
          label: lazy.browserBundle.GetStringFromName(
            "safebrowsing.notAnAttackButton.label"
          ),
          accessKey: lazy.browserBundle.GetStringFromName(
            "safebrowsing.notAnAttackButton.accessKey"
          ),
          callback() {
            lazy.URILoadingHelper.openTrustedLinkIn(
              chromeWin,
              reportUrl,
              "tab"
            );
          },
        };
      }
    } else if (reason === "phishing") {
      let reportUrl = lazy.SafeBrowsing.getReportURL(
        "PhishMistake",
        blockedInfo
      );
      title = lazy.browserBundle.GetStringFromName(
        "safebrowsing.deceptiveSite"
      );
      // There's no button if we can not get report url, for example if the provider
      // of blockedInfo is not Google
      if (reportUrl) {
        buttons[1] = {
          label: lazy.browserBundle.GetStringFromName(
            "safebrowsing.notADeceptiveSiteButton.label"
          ),
          accessKey: lazy.browserBundle.GetStringFromName(
            "safebrowsing.notADeceptiveSiteButton.accessKey"
          ),
          callback() {
            lazy.URILoadingHelper.openTrustedLinkIn(
              chromeWin,
              reportUrl,
              "tab"
            );
          },
        };
      }
    } else if (reason === "unwanted") {
      title = lazy.browserBundle.GetStringFromName(
        "safebrowsing.reportedUnwantedSite"
      );
      // There is no button for reporting errors since Google doesn't currently
      // provide a URL endpoint for these reports.
    } else if (reason === "harmful") {
      title = lazy.browserBundle.GetStringFromName(
        "safebrowsing.reportedHarmfulSite"
      );
      // There is no button for reporting errors since Google doesn't currently
      // provide a URL endpoint for these reports.
    }

    let browser = browsingContext.top.embedderElement;
    browser.safeBrowsingNotification?.cleanup();
    browser.safeBrowsingNotification = new SafeBrowsingNotificationBox(
      browser,
      title,
      buttons
    );

    // Allow users to override and continue through to the site.
    // Note that we have to use the passed URI info and can't just
    // rely on the document URI, because the latter contains
    // additional query parameters that should be stripped.
    let triggeringPrincipal =
      blockedInfo.triggeringPrincipal ||
      Services.scriptSecurityManager.createNullPrincipal({});

    browsingContext.fixupAndLoadURIString(blockedInfo.uri, {
      triggeringPrincipal,
      loadFlags: Ci.nsIWebNavigation.LOAD_FLAGS_BYPASS_CLASSIFIER,
    });
  }
}
PK