summaryrefslogtreecommitdiffstats
path: root/toolkit/components/httpsonlyerror/content/errorpage.js
blob: f2933252ba68fcf8651d903e8a928f6cf0962638 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
/* This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */

/* eslint-env mozilla/remote-page */

"use strict";

const searchParams = new URLSearchParams(document.documentURI.split("?")[1]);

function initPage() {
  if (!searchParams.get("e")) {
    document.getElementById("error").remove();
  }

  const explanation1 = document.getElementById(
    "insecure-explanation-unavailable"
  );

  const pageUrl = new URL(window.location.href.replace(/^view-source:/, ""));

  document.l10n.setAttributes(
    explanation1,
    "about-httpsonly-explanation-unavailable2",
    { websiteUrl: pageUrl.host }
  );

  const baseSupportURL = RPMGetFormatURLPref("app.support.baseURL");
  document
    .getElementById("learnMoreLink")
    .setAttribute("href", baseSupportURL + "https-only-prefs");

  document
    .getElementById("openInsecure")
    .addEventListener("click", onOpenInsecureButtonClick);

  const delay = RPMGetIntPref("security.dialog_enable_delay", 1000);
  setTimeout(() => {
    document.getElementById("openInsecure").removeAttribute("inert");
  }, delay);

  if (window.top == window) {
    document
      .getElementById("goBack")
      .addEventListener("click", onReturnButtonClick);
    addAutofocus("#goBack", "beforeend");
  } else {
    document.getElementById("goBack").remove();
  }

  const isTopLevel = window.top == window;
  const hasWWWPrefix = pageUrl.href.startsWith("https://www.");
  if (isTopLevel && !hasWWWPrefix) {
    // HTTPS-Only generally simply replaces http: with https:;
    // here we additionally try to add www and see if that allows to upgrade the connection if it is top level

    window.addEventListener("pingSecureWWWLinkSuccess", () => {
      activateSuggestionBox();
      displayWWWSuggestion(pageUrl.host);
    });

    // try to ping secure www link in the AboutHttpsOnlyErrorChild
    RPMTryPingSecureWWWLink();
  }
}

/*  Suggestion Box */

function activateSuggestionBox() {
  const suggestionBox = document.querySelector(".suggestion-box");
  suggestionBox.hidden = false;
}

function displayWWWSuggestion(aURL) {
  const suggestionBox = document.querySelector(".suggestion-box");
  const suggestionWWWText = document.createElement("p");
  const suggestionWWWButton = document.createElement("button");
  const suggestionButtonContainer = document.createElement("div");

  document.l10n.setAttributes(
    suggestionWWWText,
    "about-httpsonly-suggestion-box-www-text",
    { websiteUrl: aURL }
  );

  suggestionWWWButton.setAttribute("id", "openWWW");
  document.l10n.setAttributes(
    suggestionWWWButton,
    "about-httpsonly-suggestion-box-www-button",
    { websiteUrl: aURL }
  );
  suggestionWWWButton.addEventListener("click", openSecureWWWButtonClick);

  suggestionButtonContainer.classList.add("button-container");

  suggestionBox.appendChild(suggestionWWWText);
  suggestionButtonContainer.appendChild(suggestionWWWButton);
  suggestionBox.appendChild(suggestionButtonContainer);
}

/*  Button Events  */

function openSecureWWWButtonClick() {
  RPMOpenSecureWWWLink();
}

function onOpenInsecureButtonClick() {
  document.reloadWithHttpsOnlyException();
}

function onReturnButtonClick() {
  RPMSendAsyncMessage("goBack");
}

/*  Utils */

function addAutofocus(selector, position = "afterbegin") {
  if (window.top != window) {
    return;
  }
  var button = document.querySelector(selector);
  var parent = button.parentNode;
  button.remove();
  button.setAttribute("autofocus", "true");
  parent.insertAdjacentElement(position, button);
}

/* Initialize Page */

initPage();
// Dispatch this event so tests can detect that we finished loading the error page.
// We're using the same event name as neterror because BrowserTestUtils.sys.mjs relies on that.
let event = new CustomEvent("AboutNetErrorLoad", { bubbles: true });
document.dispatchEvent(event);